coap_server/app/
coap_utils.rs1use std::collections::HashMap;
2
3use coap_lite::error::IncompatibleOptionValueFormat;
4use coap_lite::option_value::OptionValueType;
5use coap_lite::{CoapOption, CoapRequest, MessageClass, MessageType, Packet};
6
7use crate::app::CoapError;
8
9pub fn new_pong_message(ping: &Packet) -> Packet {
10 let mut pong = Packet::new();
11
12 pong.header.set_type(MessageType::Reset);
13 pong.header.code = MessageClass::Empty;
14 pong.header.message_id = ping.header.message_id;
15 pong
16}
17
18pub fn request_get_queries<Endpoint>(request: &CoapRequest<Endpoint>) -> HashMap<String, String> {
19 request
20 .message
21 .get_options_as::<OptionValueQuery>(CoapOption::UriQuery)
22 .map_or_else(
23 || HashMap::new(),
24 |options| {
25 options
26 .into_iter()
27 .filter_map(Result::ok)
28 .map(|query| (query.key, query.value))
29 .collect::<HashMap<_, _>>()
30 },
31 )
32}
33
34pub struct OptionValueQuery {
35 key: String,
36 value: String,
37}
38
39impl From<OptionValueQuery> for Vec<u8> {
40 fn from(option_value: OptionValueQuery) -> Self {
41 format!("{}={}", option_value.key, option_value.value).into_bytes()
42 }
43}
44
45impl TryFrom<Vec<u8>> for OptionValueQuery {
46 type Error = IncompatibleOptionValueFormat;
47
48 fn try_from(value: Vec<u8>) -> Result<Self, Self::Error> {
49 Self::do_try_from(value).map_err(|e| IncompatibleOptionValueFormat {
50 message: e.to_string(),
51 })
52 }
53}
54
55impl OptionValueType for OptionValueQuery {}
56
57impl OptionValueQuery {
58 fn do_try_from(value: Vec<u8>) -> Result<Self, CoapError> {
59 let mut key_value_iter = value.split(|&c| c == b'=');
60 let key_vec = key_value_iter.next().unwrap().to_vec();
61 let value_vec = key_value_iter
62 .next()
63 .ok_or_else(|| CoapError::bad_request("Missing '=', not a valid query string"))?
64 .to_vec();
65 let key = String::from_utf8(key_vec)
66 .map_err(|e| CoapError::bad_request(format!("Key is not UTF-8: {e}")))?;
67 let value = String::from_utf8(value_vec)
68 .map_err(|e| CoapError::bad_request(format!("Value is not UTF-8: {e}")))?;
69
70 Ok(OptionValueQuery { key, value })
71 }
72}