coap_message_demos/
log.rs1use coap_message::{Code, MinimalWritableMessage};
17use coap_message_utils::Error;
18use coap_numbers::code;
19
20pub struct Log {
22 data: scroll_ring::Buffer<1024>,
23}
24
25impl Log {
26 pub fn new() -> Self {
27 Self {
28 data: Default::default(),
29 }
30 }
31
32 pub fn init(&'static self) -> Result<(), log::SetLoggerError> {
33 log::set_logger(self)?;
34 log::set_max_level(log::LevelFilter::Info);
35 Ok(())
36 }
37
38 pub fn start_once() -> &'static Self {
40 use static_cell::StaticCell;
41 static S: StaticCell<Log> = StaticCell::new();
42
43 let s = S.init_with(|| Self::new());
44 s.init()
45 .expect("No other log must be set before calling start_once");
46 s
47 }
48
49 pub fn handler(&self) -> coap_scroll_ring_server::BufferHandler<'_, 1024> {
54 coap_scroll_ring_server::BufferHandler::new(&self.data)
55 }
56}
57
58impl log::Log for Log {
59 fn enabled(&self, metadata: &log::Metadata) -> bool {
60 metadata.level() <= log::Level::Info
61 }
62
63 fn log(&self, record: &log::Record) {
64 if self.enabled(record.metadata()) {
65 struct WriteWrapper<'a>(&'a scroll_ring::Buffer<1024>);
69 impl<'a> core::fmt::Write for WriteWrapper<'a> {
70 fn write_str(&mut self, s: &str) -> core::fmt::Result {
71 self.0.write(s.as_bytes());
72 Ok(())
73 }
74 }
75
76 use core::fmt::Write;
77 writeln!(
78 WriteWrapper(&self.data),
79 "{} {}",
80 record.level(),
81 record.args()
82 )
83 .unwrap();
84 }
85 }
86
87 fn flush(&self) {}
88}
89
90pub struct LogMessagePostHandler {
93 level: log::Level,
94}
95
96impl LogMessagePostHandler {
97 pub fn new_info() -> Self {
98 Self {
99 level: log::Level::Info,
100 }
101 }
102
103 pub fn new_warn() -> Self {
104 Self {
105 level: log::Level::Warn,
106 }
107 }
108}
109
110impl coap_handler::Handler for LogMessagePostHandler {
111 type ExtractRequestError = Error;
112 type BuildResponseError<M: MinimalWritableMessage> = M::UnionError;
113 type RequestData = ();
114
115 fn extract_request_data<M: coap_message::ReadableMessage>(
116 &mut self,
117 request: &M,
118 ) -> Result<Self::RequestData, Error> {
119 use coap_message_utils::OptionsExt;
120
121 match request.code().into() {
122 code::POST => (),
123 _ => Err(Error::method_not_allowed())?,
124 }
125
126 request.options().ignore_elective_others()?;
127
128 let payload = core::str::from_utf8(request.payload())
129 .map_err(|e| Error::bad_request_with_rbep(e.valid_up_to()))?;
130
131 use log::log;
132 log!(self.level, "{}", payload);
133 Ok(())
134 }
135 fn estimate_length(&mut self, _: &Self::RequestData) -> usize {
136 8
137 }
138 fn build_response<M: coap_message::MutableWritableMessage>(
139 &mut self,
140 response: &mut M,
141 _request: (),
142 ) -> Result<(), M::UnionError> {
143 response.set_code(M::Code::new(code::CHANGED)?);
144 Ok(())
145 }
146}