Skip to main content

coap_message_implementations/inmemory/
buffer_impl.rs

1//! Implementations of storage buffers for messages.
2#![cfg_attr(feature = "downcast", allow(unsafe_code))]
3
4use super::*;
5
6/// An implementation of [`MessageBuffer`] around a slice of memory.
7///
8/// As the code is not even pointer sized, it is copied in.
9#[derive(Clone, Debug)]
10#[cfg_attr(feature = "defmt", derive(defmt::Format))]
11pub struct SliceBuffer<'a> {
12    code: u8,
13    options_and_payload: &'a [u8],
14}
15
16impl<'a> SliceBuffer<'a> {
17    /// Constructs a new slice message.
18    ///
19    /// This constructor is rarely needed, as [`Message::new_from_slice()`] is a short-cut
20    /// for it.
21    #[must_use]
22    pub fn new(code: u8, options_and_payload: &'a [u8]) -> Self {
23        Self {
24            code,
25            options_and_payload,
26        }
27    }
28}
29
30impl MessageBuffer for SliceBuffer<'_> {
31    fn code(&self) -> u8 {
32        self.code
33    }
34    fn tail(&self) -> &[u8] {
35        self.options_and_payload
36    }
37
38    #[cfg(feature = "downcast")]
39    fn static_variant() -> Option<LifetimesMatterLittle<impl 'static + MessageBuffer>> {
40        // SAFETY: We don't hand out 'a slices, and we don't take any long-lived input.
41        Some(unsafe { LifetimesMatterLittle::<SliceBuffer<'static>>::new() })
42    }
43}
44
45/// The easiest implementation of [`MessageBufferMut`] that is backed by exclusive references.
46pub struct SliceBufferMut<'a> {
47    code: &'a mut u8,
48    tail: &'a mut [u8],
49}
50
51impl<'a> SliceBufferMut<'a> {
52    /// Marks an area of memory for construction of a message.
53    ///
54    /// This constructor is rarely needed, as [`MessageMut::new_in_slice()`] is a short-cut for
55    /// it.
56    pub fn new(code: &'a mut u8, tail: &'a mut [u8]) -> Self {
57        Self { code, tail }
58    }
59}
60
61impl MessageBufferMut for SliceBufferMut<'_> {
62    fn code_mut(&mut self) -> &mut u8 {
63        self.code
64    }
65
66    fn tail_mut(&mut self) -> &mut [u8] {
67        self.tail
68    }
69
70    #[cfg(feature = "downcast")]
71    fn static_mut_variant() -> Option<LifetimesMatterLittle<impl 'static + MessageBufferMut>> {
72        // SAFETY: We don't hand out 'a slices, and we don't take any long-lived input.
73        Some(unsafe { LifetimesMatterLittle::<SliceBufferMut<'static>>::new() })
74    }
75}
76
77impl MessageBuffer for SliceBufferMut<'_> {
78    fn code(&self) -> u8 {
79        *self.code
80    }
81
82    fn tail(&self) -> &[u8] {
83        self.tail
84    }
85}
86
87impl MessageBuffer for core::convert::Infallible {
88    fn code(&self) -> u8 {
89        match *self {}
90    }
91
92    fn tail(&self) -> &[u8] {
93        match *self {}
94    }
95}
96
97impl MessageBufferMut for core::convert::Infallible {
98    fn code_mut(&mut self) -> &mut u8 {
99        match *self {}
100    }
101
102    fn tail_mut(&mut self) -> &mut [u8] {
103        match *self {}
104    }
105}