coap_server/app/app_builder.rs
1use std::fmt::Debug;
2use std::hash::Hash;
3
4use crate::app::app_handler::AppHandler;
5use crate::app::ResourceBuilder;
6use crate::packet_handler::IntoHandler;
7
8/// Main builder API to configure how the CoAP server should respond to requests
9pub struct AppBuilder<Endpoint: Ord + Clone> {
10 pub(crate) config: ConfigBuilder,
11 pub(crate) resources: Vec<ResourceBuilder<Endpoint>>,
12}
13
14#[derive(Debug, Default, Clone)]
15pub(crate) struct ConfigBuilder {
16 pub discoverable: Option<bool>,
17 pub block_transfer: Option<bool>,
18}
19
20impl<Endpoint: Ord + Clone> Default for AppBuilder<Endpoint> {
21 fn default() -> Self {
22 Self {
23 config: ConfigBuilder::default(),
24 resources: Vec::new(),
25 }
26 }
27}
28
29impl<Endpoint: Ord + Clone> AppBuilder<Endpoint> {
30 pub fn new() -> Self {
31 Default::default()
32 }
33
34 /// Enable resource discovery by default for all resources in the app. To disable this
35 /// on a per-resource level, see [`ResourceBuilder::not_discoverable`].
36 ///
37 /// For more information refer to [RFC 5785](https://datatracker.ietf.org/doc/html/rfc5785).
38 pub fn discoverable(mut self) -> Self {
39 self.config.discoverable = Some(true);
40 self
41 }
42
43 /// Disable resource discovery by default for all resources in the app. This can be
44 /// overridden on a per-resource level.
45 ///
46 /// See [`AppBuilder::discoverable`].
47 pub fn not_discoverable(mut self) -> Self {
48 self.config.discoverable = Some(false);
49 self
50 }
51
52 /// Enable block-wise transfer by default for all resources in the app.
53 ///
54 /// Block-wise transfer is defaulted to a transparent handler that buffers in memory large
55 /// requests or responses as they are being transferred from/to the peer, expiring after
56 /// some time if the client does not gracefully exhaust the payload (e.g. if the client
57 /// downloads only a portion of a large response then goes away).
58 ///
59 /// To disable this completely on a per-resource level, see
60 /// [`ResourceBuilder::disable_block_transfer`]. Alternatively you may implement a request
61 /// handler that responds with Block2 option values that will cause the transparent handler to
62 /// defer the handling to your custom logic.
63 ///
64 /// For more information refer to [RFC 7959](https://datatracker.ietf.org/doc/html/rfc7959).
65 pub fn block_transfer(mut self) -> Self {
66 self.config.block_transfer = Some(true);
67 self
68 }
69
70 /// Disable block-wise transfer by default for all resources in the app. This can be overriden
71 /// on a per-resource level.
72 ///
73 /// See [`AppBuilder::block_transfer`].
74 pub fn disable_block_transfer(mut self) -> Self {
75 self.config.block_transfer = Some(false);
76 self
77 }
78
79 /// Add a resource handler to the app by the configured path. See [`crate::app::resource`]
80 /// to start building one.
81 pub fn resource(mut self, resource: ResourceBuilder<Endpoint>) -> Self {
82 self.resources.push(resource);
83 self
84 }
85
86 /// Convenience method to add multiple resources at once.
87 pub fn resources(mut self, resources: Vec<ResourceBuilder<Endpoint>>) -> Self {
88 for resource in resources {
89 self = self.resource(resource);
90 }
91 self
92 }
93}
94
95impl<Endpoint: Debug + Clone + Ord + Eq + Hash + Send + 'static>
96 IntoHandler<AppHandler<Endpoint>, Endpoint> for AppBuilder<Endpoint>
97{
98 fn into_handler(self, mtu: Option<u32>) -> AppHandler<Endpoint> {
99 AppHandler::from_builder(self, mtu)
100 }
101}