First experiment to implement
@@ -29,6 +29,38 @@ use std::{
};
use tracing::instrument;
+
+// TODO this is the section for the example Implementation of the Dialects
+struct HonoDialect;
+struct LongTopicDialect;
+
+struct ParseError;
+
+struct ParsedTopic<'a> {
+ channel: &'a str,
+ device: Option<&'a str>,
+}
+
+struct TopicHandler<D> {
+ dialect: D
+}
+
+trait Dialect {
+ fn handle(&self, path: &str) -> Result<ParsedTopic, ParseError>;
+}
+
+impl Dialect for TopicHandler<HonoDialect> {
+ fn handle(&self, path: &str) -> Result<ParsedTopic, ParseError> {
+ Ok(ParsedTopic { channel: path, device: Some(path) })
+ }
+}
+
+impl Dialect for TopicHandler<LongTopicDialect> {
+ fn handle(&self, path: &str) -> Result<ParsedTopic, ParseError> {
+ Ok(ParsedTopic { channel: path, device: None })
+ }
+}
+
#[derive(Clone)]
pub struct Session<S>
where
@@ -114,16 +146,21 @@ where
let topic = publish.topic().path().split('/').collect::<Vec<_>>();
log::debug!("Topic: {:?}", topic);
- match topic.as_slice() {
- [channel] => Ok((channel.to_string(), self.device.clone())),
- [channel, as_device] => self
+ // TODO this should be removed and is just there as an example
+ let handler = TopicHandler {dialect: HonoDialect};
+
+ match handler.handle(publish.topic().path()) {
+ Ok(topic) => {
+ match topic.device {
+ Some(device) => {
+ self
.device_cache
- .fetch(as_device, |as_device| {
+ .fetch(device, |device| {
self.auth
.authorize_as(
&self.application.metadata.name,
&self.device.metadata.name,
- as_device,
+ device,
)
.map_ok(|result| match result.outcome {
GatewayOutcome::Pass { r#as } => Some(r#as),
@@ -131,9 +168,35 @@ where
})
})
.await
- .map(|r| (channel.to_string(), r)),
- _ => Err(PublishError::TopicNameInvalid),
+ .map(|r| (topic.channel.to_string(), r))
}
+ None => {
+ Ok((topic.channel.to_string(), self.device.clone()))
+ }
+ }
+ }
+ Err(_) => Err(PublishError::TopicNameInvalid),
+ }
+ // match topic.as_slice() {
+ // [channel] => Ok((channel.to_string(), self.device.clone())),
+ // [channel, as_device] => self
+ // .device_cache
+ // .fetch(as_device, |as_device| {
+ // self.auth
+ // .authorize_as(
+ // &self.application.metadata.name,
+ // &self.device.metadata.name,
+ // as_device,
+ // )
+ // .map_ok(|result| match result.outcome {
+ // GatewayOutcome::Pass { r#as } => Some(r#as),
+ // _ => None,
+ // })
+ // })
+ // .await
+ // .map(|r| (channel.to_string(), r)),
+ // _ => Err(PublishError::TopicNameInvalid),
+ // }
}
}
