async_coap/option/
value.rs

1// Copyright 2019 Google LLC
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14//
15
16use super::*;
17
18/// Type describing the type of an option's value.
19#[derive(Debug, Copy, Eq, PartialEq, Hash, Clone)]
20pub enum OptionValueType {
21    /// Opaque option value.
22    Opaque,
23
24    /// Option value is determined by the presence or absence of the option.
25    Flag,
26
27    /// Integer value.
28    Integer,
29
30    /// UTF8 string value.
31    String,
32
33    /// Integer value containing a `ContentFormat`.
34    ContentFormat,
35
36    /// Integer value containing a `BlockInfo`.
37    Block,
38}
39
40#[doc(hidden)]
41#[derive(Debug)]
42pub enum OptionValue<'a> {
43    Integer(u32),
44    Bytes(&'a [u8]),
45    ETag(ETag),
46}
47
48impl<'a> From<u8> for OptionValue<'a> {
49    fn from(value: u8) -> Self {
50        OptionValue::Integer(value as u32)
51    }
52}
53
54impl<'a> From<u16> for OptionValue<'a> {
55    fn from(value: u16) -> Self {
56        OptionValue::Integer(value as u32)
57    }
58}
59
60impl<'a> From<u32> for OptionValue<'a> {
61    fn from(value: u32) -> Self {
62        OptionValue::Integer(value)
63    }
64}
65
66impl<'a> From<ContentFormat> for OptionValue<'a> {
67    fn from(value: ContentFormat) -> Self {
68        OptionValue::Integer(value.0 as u32)
69    }
70}
71
72impl<'a> From<BlockInfo> for OptionValue<'a> {
73    fn from(value: BlockInfo) -> Self {
74        OptionValue::Integer(value.0 as u32)
75    }
76}
77
78impl<'a> From<ETag> for OptionValue<'a> {
79    fn from(value: ETag) -> Self {
80        OptionValue::ETag(value)
81    }
82}
83
84impl<'a> From<&'a [u8]> for OptionValue<'a> {
85    fn from(value: &'a [u8]) -> Self {
86        OptionValue::Bytes(value)
87    }
88}
89
90impl<'a> From<&'a str> for OptionValue<'a> {
91    fn from(value: &'a str) -> Self {
92        OptionValue::Bytes(value.as_bytes())
93    }
94}
95
96impl<'a, 'b> From<&'b &'a str> for OptionValue<'a> {
97    fn from(value: &'b &'a str) -> Self {
98        OptionValue::Bytes(value.as_bytes())
99    }
100}
101
102impl<'a> From<()> for OptionValue<'a> {
103    fn from(_: ()) -> Self {
104        OptionValue::Bytes(&[])
105    }
106}
107
108#[doc(hidden)]
109pub trait TryOptionValueFrom<'a>: Sized {
110    fn try_option_value_from(buffer: &'a [u8]) -> Option<Self>;
111}
112
113impl<'a> TryOptionValueFrom<'a> for ETag {
114    fn try_option_value_from(buffer: &'a [u8]) -> Option<Self> {
115        if buffer.len() <= ETag::MAX_LEN {
116            Some(ETag::new(buffer))
117        } else {
118            None
119        }
120    }
121}
122
123impl<'a> TryOptionValueFrom<'a> for &'a [u8] {
124    fn try_option_value_from(buffer: &'a [u8]) -> Option<Self> {
125        Some(buffer)
126    }
127}
128
129impl<'a> TryOptionValueFrom<'a> for u32 {
130    fn try_option_value_from(buffer: &'a [u8]) -> Option<Self> {
131        try_decode_u32(buffer)
132    }
133}
134
135impl<'a> TryOptionValueFrom<'a> for ContentFormat {
136    fn try_option_value_from(buffer: &'a [u8]) -> Option<Self> {
137        Some(ContentFormat(try_decode_u16(buffer)?))
138    }
139}
140
141impl<'a> TryOptionValueFrom<'a> for BlockInfo {
142    fn try_option_value_from(buffer: &'a [u8]) -> Option<Self> {
143        BlockInfo(try_decode_u32(buffer)?).valid()
144    }
145}
146
147impl<'a> TryOptionValueFrom<'a> for u16 {
148    fn try_option_value_from(buffer: &'a [u8]) -> Option<Self> {
149        try_decode_u16(buffer)
150    }
151}
152
153impl<'a> TryOptionValueFrom<'a> for () {
154    fn try_option_value_from(_: &'a [u8]) -> Option<Self> {
155        Some(())
156    }
157}
158
159impl<'a> TryOptionValueFrom<'a> for &'a str {
160    fn try_option_value_from(buffer: &'a [u8]) -> Option<Self> {
161        core::str::from_utf8(buffer).ok()
162    }
163}