coap_server/app/
resource_builder.rs1use std::collections::HashMap;
2use std::fmt::Debug;
3use std::hash::Hash;
4use std::sync::Arc;
5
6use coap_lite::link_format::LINK_ATTR_OBSERVABLE;
7use coap_lite::RequestType;
8use tokio::sync::Mutex;
9
10use crate::app::app_builder::ConfigBuilder;
11use crate::app::block_handler_util::new_block_handler;
12use crate::app::core_link::{CoreLink, LinkAttributeValue};
13use crate::app::observable_resource::ObservableResource;
14use crate::app::observe_handler::ObserveHandler;
15use crate::app::request_handler::RequestHandler;
16use crate::app::request_type_key::RequestTypeKey;
17use crate::app::resource_handler::ResourceHandler;
18use crate::app::retransmission_manager::RetransmissionManager;
19
20pub struct ResourceBuilder<Endpoint: Ord + Clone> {
22 path: String,
23 config: ConfigBuilder,
24 attributes: CoreLink,
25 handlers: HashMap<RequestTypeKey, Box<dyn RequestHandler<Endpoint> + Send + Sync>>,
26 observable: Option<Box<dyn ObservableResource + Send + Sync>>,
27}
28
29impl<Endpoint: Debug + Clone + Eq + Hash + Ord + Send + 'static> ResourceBuilder<Endpoint> {
30 pub fn new(path: &str) -> Self {
31 Self {
32 path: path.to_string(),
33 config: ConfigBuilder::default(),
34 attributes: CoreLink::new(path),
35 handlers: HashMap::new(),
36 observable: None,
37 }
38 }
39
40 pub fn not_discoverable(mut self) -> Self {
42 self.config.discoverable = Some(false);
43 self
44 }
45
46 pub fn disable_block_transfer(mut self) -> Self {
48 self.config.block_transfer = Some(false);
49 self
50 }
51
52 pub fn link_attr(
56 mut self,
57 attr_name: &'static str,
58 value: impl LinkAttributeValue<String> + 'static,
59 ) -> Self {
60 self.attributes.attr(attr_name, value);
61 self
62 }
63
64 pub fn default_handler(self, handler: impl RequestHandler<Endpoint> + Send + Sync) -> Self {
68 self.handler(RequestTypeKey::new_match_all(), handler)
69 }
70
71 pub fn get(self, handler: impl RequestHandler<Endpoint> + Send + Sync) -> Self {
73 self.handler(RequestType::Get.into(), handler)
74 }
75
76 pub fn post(self, handler: impl RequestHandler<Endpoint> + Send + Sync) -> Self {
78 self.handler(RequestType::Post.into(), handler)
79 }
80
81 pub fn put(self, handler: impl RequestHandler<Endpoint> + Send + Sync) -> Self {
83 self.handler(RequestType::Put.into(), handler)
84 }
85
86 pub fn delete(self, handler: impl RequestHandler<Endpoint> + Send + Sync) -> Self {
88 self.handler(RequestType::Delete.into(), handler)
89 }
90
91 pub fn fetch(self, handler: impl RequestHandler<Endpoint> + Send + Sync) -> Self {
93 self.handler(RequestType::Fetch.into(), handler)
94 }
95
96 pub fn patch(self, handler: impl RequestHandler<Endpoint> + Send + Sync) -> Self {
98 self.handler(RequestType::Patch.into(), handler)
99 }
100
101 pub fn ipatch(self, handler: impl RequestHandler<Endpoint> + Send + Sync) -> Self {
103 self.handler(RequestType::IPatch.into(), handler)
104 }
105
106 pub fn method_handler(
110 self,
111 request_type: RequestType,
112 handler: impl RequestHandler<Endpoint> + Send + Sync,
113 ) -> Self {
114 self.handler(request_type.into(), handler)
115 }
116
117 fn handler(
118 mut self,
119 key: RequestTypeKey,
120 handler: impl RequestHandler<Endpoint> + Send + Sync,
121 ) -> Self {
122 self.handlers.insert(key, Box::new(handler));
123 self
124 }
125
126 pub fn observable(mut self, observable: impl ObservableResource + Send + Sync) -> Self {
133 self.observable = Some(Box::new(observable));
134 self.link_attr(LINK_ATTR_OBSERVABLE, ())
135 }
136
137 pub(crate) fn build(self, params: BuildParameters<Endpoint>) -> Resource<Endpoint> {
138 let discoverable = if self.config.discoverable.unwrap_or(true) {
139 Some(DiscoverableResource::from(self.attributes))
140 } else {
141 None
142 };
143
144 let observe_handler = self
145 .observable
146 .map(|x| Arc::new(Mutex::new(ObserveHandler::new(self.path.clone(), x))));
147
148 let block_transfer = self
149 .config
150 .block_transfer
151 .unwrap_or(crate::app::app_handler::DEFAULT_BLOCK_TRANSFER);
152 let block_handler = if block_transfer {
153 Some(Arc::new(Mutex::new(new_block_handler(params.mtu))))
154 } else {
155 None
156 };
157
158 let handler = ResourceHandler {
159 handlers: self.handlers,
160 observe_handler,
161 block_handler,
162 retransmission_manager: params.retransmission_manager,
163 };
164 Resource {
165 path: self.path,
166 discoverable,
167 handler,
168 }
169 }
170}
171
172#[derive(Clone)]
173pub(crate) struct BuildParameters<Endpoint: Debug + Clone + Eq + Hash> {
174 pub mtu: Option<u32>,
175 pub retransmission_manager: Arc<Mutex<RetransmissionManager<Endpoint>>>,
176}
177
178#[derive(Clone)]
179pub(crate) struct DiscoverableResource {
180 pub link_str: String,
184
185 pub attributes_as_string: HashMap<&'static str, String>,
188}
189
190pub(crate) struct Resource<Endpoint: Debug + Clone + Ord + Eq + Hash> {
191 pub path: String,
192 pub discoverable: Option<DiscoverableResource>,
193 pub handler: ResourceHandler<Endpoint>,
194}