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}