1use core::cmp::Ordering;
2use core::hash::Hash;
3use core::iter::FromIterator;
4use core::str::{from_utf8, Utf8Error};
5
6use toad_array::{AppendCopy, Array, Indexed};
7use toad_cursor::Cursor;
8use toad_len::Len;
9use toad_macros::rfc_7252_doc;
10
11#[allow(unused_imports)]
12use crate::TryIntoBytes;
13
14pub mod code;
16
17pub mod parse_error;
19
20pub mod id;
22
23pub mod opt;
25
26pub mod ty;
28
29pub mod token;
31
32pub mod ver;
34
35pub use code::*;
36pub use id::*;
37pub use opt::*;
38pub use parse_error::*;
39pub use token::*;
40pub use ty::*;
41pub use ver::*;
42
43use crate::from_bytes::TryConsumeBytes;
44use crate::{CacheKey, DefaultCacheKey, TryFromBytes};
45
46#[doc = rfc_7252_doc!("5.5")]
47#[derive(Default, Clone, Debug)]
48pub struct Payload<C>(pub C);
49
50impl<C> PartialOrd for Payload<C> where C: Array<Item = u8>
51{
52 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
53 self.0.iter().partial_cmp(other.0.iter())
54 }
55}
56
57impl<C> PartialEq for Payload<C> where C: Array<Item = u8>
58{
59 fn eq(&self, other: &Self) -> bool {
60 self.0.iter().eq(other.0.iter())
61 }
62}
63
64impl<C> Ord for Payload<C> where C: Array<Item = u8>
65{
66 fn cmp(&self, other: &Self) -> Ordering {
67 self.0.iter().cmp(other.0.iter())
68 }
69}
70
71impl<C> Eq for Payload<C> where C: Array<Item = u8> {}
72
73impl<C> Hash for Payload<C> where C: Array<Item = u8>
74{
75 fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
76 state.write(&self.0)
77 }
78}
79
80impl<C> Payload<C> where C: Array<Item = u8>
81{
82 pub fn as_bytes(&self) -> &[u8] {
84 &self.0
85 }
86}
87
88#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Eq, Ord)]
101pub(crate) struct Byte1 {
102 pub(crate) ver: Version,
103 pub(crate) ty: Type,
104 pub(crate) tkl: u8,
105}
106
107impl TryFrom<u8> for Byte1 {
108 type Error = MessageParseError;
109
110 fn try_from(b: u8) -> Result<Self, Self::Error> {
111 let ver = b >> 6; let ty = b >> 4 & 0b11; let tkl = b & 0b1111u8; Ok(Byte1 { ver: Version(ver),
116 ty: Type::try_from(ty)?,
117 tkl })
118 }
119}
120
121impl<PayloadBytes: Array<Item = u8>, Options: OptionMap> Len for Message<PayloadBytes, Options> {
122 const CAPACITY: Option<usize> = None;
123
124 fn len(&self) -> usize {
125 let header_size = 4;
126 let payload_marker_size = 1;
127 let payload_size = self.payload.0.len();
128 let token_size = self.token.0.len();
129 let opts_size: usize = self.opts.opt_refs().map(|o| o.len()).sum();
130
131 header_size + payload_marker_size + payload_size + token_size + opts_size
132 }
133
134 fn is_full(&self) -> bool {
135 false
136 }
137}
138
139#[doc = concat!("\n\n#", rfc_7252_doc!("2.1"))]
181#[doc = concat!("\n\n#", rfc_7252_doc!("3"))]
182#[derive(Clone, Debug)]
184pub struct Message<PayloadBytes, Options> {
185 pub id: Id,
187 pub ty: Type,
189 pub ver: Version,
191 pub token: Token,
193 pub code: Code,
195 pub opts: Options,
197 pub payload: Payload<PayloadBytes>,
199}
200
201impl<C, O> PartialOrd for Message<C, O>
202 where O: OptionMap + PartialOrd,
203 C: Array<Item = u8>
204{
205 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
206 Some(self.cmp(other))
207 }
208}
209impl<C, O> PartialEq for Message<C, O>
210 where O: OptionMap + PartialEq,
211 C: Array<Item = u8>
212{
213 fn eq(&self, other: &Self) -> bool {
214 self.id == other.id
215 && self.ver == other.ver
216 && self.code == other.code
217 && self.token == other.token
218 && self.payload == other.payload
219 && self.opts == other.opts
220 }
221}
222impl<C, O> Ord for Message<C, O>
223 where O: OptionMap + PartialOrd,
224 C: Array<Item = u8>
225{
226 fn cmp(&self, other: &Self) -> Ordering {
227 self.id
228 .cmp(&other.id)
229 .then(self.ver.cmp(&other.ver))
230 .then(self.code.cmp(&other.code))
231 .then(self.token.cmp(&other.token))
232 .then(self.payload.cmp(&other.payload))
233 .then(self.opts
234 .partial_cmp(&other.opts)
235 .unwrap_or(Ordering::Equal))
236 }
237}
238impl<C, O> Eq for Message<C, O>
239 where O: OptionMap + PartialEq,
240 C: Array<Item = u8>
241{
242}
243
244impl<C, O> Hash for Message<C, O>
245 where O: OptionMap + PartialEq + Hash,
246 C: Array<Item = u8>
247{
248 fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
249 self.id.hash(state);
250 self.code.hash(state);
251 self.token.hash(state);
252 self.ver.hash(state);
253 self.ty.hash(state);
254 self.opts.hash(state);
255 self.payload.hash(state);
256 }
257}
258
259#[allow(missing_docs)]
261#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
262pub enum SetOptionError<OV, OVs> {
263 RepeatedTooManyTimes(OV),
264 TooManyOptions(OptNumber, OVs),
265}
266
267impl<P, O> MessageOptions for Message<P, O>
268 where P: Array<Item = u8> + AppendCopy<u8>,
269 O: OptionMap
270{
271 type OptValues = O::OptValues;
272 type OptValueBytes = O::OptValue;
273 type SetError = SetOptionError<OptValue<Self::OptValueBytes>, Self::OptValues>;
274
275 fn add(&mut self, n: OptNumber, v: OptValue<Self::OptValueBytes>) -> Result<(), Self::SetError> {
276 self.add(n, v)
277 }
278
279 fn set(&mut self,
280 n: OptNumber,
281 v: OptValue<Self::OptValueBytes>)
282 -> Result<Option<Self::OptValues>, Self::SetError> {
283 self.set(n, v)
284 }
285
286 fn count(&self, n: OptNumber) -> usize {
287 self.count(n)
288 }
289
290 fn get(&self, n: OptNumber) -> Option<&Self::OptValues> {
291 self.get(n)
292 }
293
294 fn get_first(&self, n: OptNumber) -> Option<&OptValue<Self::OptValueBytes>> {
295 self.get_first(n)
296 }
297
298 fn get_str(&self, n: OptNumber) -> Result<Option<&str>, Utf8Error> {
299 self.get_str(n)
300 }
301
302 fn get_strs<'a, F>(&'a self, n: OptNumber) -> Result<F, Utf8Error>
303 where F: FromIterator<&'a str>
304 {
305 self.get_strs(n)
306 }
307
308 fn get_u8(&self, n: OptNumber) -> Option<u8> {
309 self.get_u8(n)
310 }
311
312 fn get_u16(&self, n: OptNumber) -> Option<u16> {
313 self.get_u16(n)
314 }
315
316 fn get_u32(&self, n: OptNumber) -> Option<u32> {
317 self.get_u32(n)
318 }
319
320 fn get_u64(&self, n: OptNumber) -> Option<u64> {
321 self.get_u64(n)
322 }
323
324 fn remove(&mut self, n: OptNumber) -> Option<Self::OptValues> {
325 self.remove(n)
326 }
327}
328
329pub trait MessageOptions {
331 type OptValues: Array<Item = OptValue<Self::OptValueBytes>>;
333 type OptValueBytes: Array<Item = u8> + AppendCopy<u8>;
335 type SetError;
337
338 #[doc = rfc_7252_doc!("5.4.5")]
343 fn add(&mut self, n: OptNumber, v: OptValue<Self::OptValueBytes>) -> Result<(), Self::SetError>;
344
345 fn set(&mut self,
348 n: OptNumber,
349 v: OptValue<Self::OptValueBytes>)
350 -> Result<Option<Self::OptValues>, Self::SetError>;
351
352 fn count(&self, n: OptNumber) -> usize;
354
355 fn get(&self, n: OptNumber) -> Option<&Self::OptValues>;
359
360 fn get_first(&self, n: OptNumber) -> Option<&OptValue<Self::OptValueBytes>>;
362
363 fn get_str(&self, n: OptNumber) -> Result<Option<&str>, Utf8Error>;
366
367 fn get_strs<'a, F>(&'a self, n: OptNumber) -> Result<F, Utf8Error>
369 where F: FromIterator<&'a str>;
370
371 fn get_u8(&self, n: OptNumber) -> Option<u8>;
374
375 fn get_u16(&self, n: OptNumber) -> Option<u16>;
378
379 fn get_u32(&self, n: OptNumber) -> Option<u32>;
382
383 fn get_u64(&self, n: OptNumber) -> Option<u64>;
386
387 fn remove(&mut self, n: OptNumber) -> Option<Self::OptValues>;
390
391 #[doc = rfc_7252_doc!("5.10.1")]
404 fn set_host<S>(&mut self, host: S) -> Result<(), Self::SetError>
405 where S: AsRef<str>
406 {
407 self.set(opt::known::no_repeat::HOST,
408 host.as_ref().as_bytes().iter().copied().collect())
409 .map(|_| ())
410 }
411
412 fn block1(&self) -> Option<block::Block> {
414 self.get_u32(opt::known::no_repeat::BLOCK1)
415 .map(block::Block::from)
416 }
417
418 fn set_block1(&mut self, size: u16, num: u32, more: bool) -> Result<(), Self::SetError> {
420 let block = block::Block::new(size, num, more);
421 self.set(opt::known::no_repeat::BLOCK1,
422 OptValue(u32::from(block).to_be_bytes().iter().copied().collect()))
423 .map(|_| ())
424 }
425
426 fn block2(&self) -> Option<block::Block> {
428 self.get_u32(opt::known::no_repeat::BLOCK2)
429 .map(block::Block::from)
430 }
431
432 fn set_block2(&mut self, size: u16, num: u32, more: bool) -> Result<(), Self::SetError> {
434 let block = block::Block::new(size, num, more);
435 self.set(opt::known::no_repeat::BLOCK2,
436 OptValue(u32::from(block).to_be_bytes().iter().copied().collect()))
437 .map(|_| ())
438 }
439
440 fn host(&self) -> Result<Option<&str>, Utf8Error> {
442 self.get_str(opt::known::no_repeat::HOST)
443 }
444
445 fn set_port(&mut self, port: u16) -> Result<(), Self::SetError> {
460 self.set(opt::known::no_repeat::PORT,
461 port.to_be_bytes().into_iter().collect())
462 .map(|_| ())
463 }
464
465 fn port(&self) -> Option<u16> {
467 self.get_u16(opt::known::no_repeat::PORT)
468 }
469
470 fn set_path<S>(&mut self, path: S) -> Result<(), Self::SetError>
488 where S: AsRef<str>
489 {
490 path.as_ref()
491 .split('/')
492 .try_for_each(|segment| {
493 self.add(opt::known::repeat::PATH,
494 segment.as_bytes().iter().copied().collect())
495 })
496 .map(|_| ())
497 }
498
499 fn path<'a, F>(&'a self) -> Result<F, Utf8Error>
501 where F: FromIterator<&'a str>
502 {
503 self.get_strs(opt::known::repeat::PATH)
504 }
505
506 #[cfg(feature = "std")]
508 fn path_string<'a>(&'a self) -> Result<String, Utf8Error> {
509 self.get_strs::<Vec<_>>(opt::known::repeat::PATH)
510 .map(|segs| {
511 let mut s = segs.into_iter()
512 .fold(String::new(), |s, seg| format!("{s}{seg}/"));
513 s.pop();
514 s
515 })
516 }
517
518 fn add_query<S>(&mut self, query: S) -> Result<(), Self::SetError>
521 where S: AsRef<str>
522 {
523 self.add(opt::known::repeat::QUERY,
524 query.as_ref().as_bytes().iter().copied().collect())
525 }
526
527 fn query<'a, F>(&'a self) -> Result<F, Utf8Error>
541 where F: FromIterator<&'a str>
542 {
543 self.get_strs(opt::known::repeat::QUERY)
544 }
545
546 #[doc = rfc_7252_doc!("5.10.3")]
549 fn set_content_format(&mut self, format: ContentFormat) -> Result<(), Self::SetError> {
550 self.set(opt::known::no_repeat::CONTENT_FORMAT,
551 format.into_iter().collect())
552 .map(|_| ())
553 }
554
555 fn content_format(&self) -> Option<ContentFormat> {
568 self.get_u16(opt::known::no_repeat::CONTENT_FORMAT)
569 .map(ContentFormat::from)
570 }
571
572 fn set_observe(&mut self, a: observe::Action) -> Result<(), Self::SetError> {
575 self.set(opt::known::no_repeat::OBSERVE,
576 core::iter::once(u8::from(a)).collect())
577 .map(|_| ())
578 }
579
580 fn observe(&self) -> Option<observe::Action> {
582 self.get_u8(opt::known::no_repeat::OBSERVE)
583 .and_then(observe::Action::from_byte)
584 }
585
586 #[doc = rfc_7252_doc!("5.10.4")]
589 fn set_accept(&mut self, format: ContentFormat) -> Result<(), Self::SetError> {
590 self.set(opt::known::no_repeat::ACCEPT, format.into_iter().collect())
591 .map(|_| ())
592 }
593
594 fn accept(&self) -> Option<ContentFormat> {
596 self.get_u16(opt::known::no_repeat::ACCEPT)
597 .map(ContentFormat::from)
598 }
599
600 #[doc = rfc_7252_doc!("5.10.9")]
603 fn set_size1(&mut self, size_bytes: u64) -> Result<(), Self::SetError> {
604 self.set(opt::known::no_repeat::SIZE1,
605 size_bytes.to_be_bytes().into_iter().collect())
606 .map(|_| ())
607 }
608
609 fn size1(&self) -> Option<u64> {
611 self.get_u64(opt::known::no_repeat::SIZE1)
612 }
613
614 fn set_size2(&mut self, size_bytes: u64) -> Result<(), Self::SetError> {
617 self.set(opt::known::no_repeat::SIZE2,
618 size_bytes.to_be_bytes().into_iter().collect())
619 .map(|_| ())
620 }
621
622 fn size2(&self) -> Option<u64> {
624 self.get_u64(opt::known::no_repeat::SIZE2)
625 }
626
627 #[doc = rfc_7252_doc!("5.10.8.1")]
633 fn set_if_exists(&mut self) -> Result<(), Self::SetError> {
634 self.set(opt::known::repeat::IF_MATCH, Default::default())
635 .map(|_| ())
636 }
637
638 fn if_exists_flag_enabled(&self) -> bool {
640 self.get(opt::known::repeat::IF_MATCH)
641 .map(|vs| vs.iter().any(|v| v.0.len() == 0))
642 .unwrap_or(false)
643 }
644
645 #[doc = rfc_7252_doc!("5.10.8.2")]
650 fn set_if_not_exists(&mut self) -> Result<(), Self::SetError> {
651 self.set(opt::known::no_repeat::IF_NONE_MATCH, Default::default())
652 .map(|_| ())
653 }
654
655 fn if_not_exists_flag_enabled(&self) -> bool {
657 self.get_first(opt::known::no_repeat::IF_NONE_MATCH)
658 .map(|_| true)
659 .unwrap_or(false)
660 }
661
662 #[doc = rfc_7252_doc!("5.10.5")]
665 fn set_max_age(&mut self, max_age_seconds: u32) -> Result<(), Self::SetError> {
666 self.set(opt::known::no_repeat::MAX_AGE,
667 max_age_seconds.to_be_bytes().into_iter().collect())
668 .map(|_| ())
669 }
670
671 fn max_age_seconds(&self) -> Option<u32> {
673 self.get_u32(opt::known::no_repeat::MAX_AGE)
674 }
675
676 #[doc = rfc_7252_doc!("5.10.2")]
679 fn set_proxy_uri<S>(&mut self, uri: S) -> Result<(), Self::SetError>
680 where S: AsRef<str>
681 {
682 self.set(opt::known::no_repeat::PROXY_URI,
683 uri.as_ref().as_bytes().iter().copied().collect())
684 .map(|_| ())
685 }
686
687 fn proxy_uri(&self) -> Result<Option<&str>, Utf8Error> {
689 self.get_str(opt::known::no_repeat::PROXY_URI)
690 }
691
692 fn set_proxy_scheme<S>(&mut self, scheme: S) -> Result<(), Self::SetError>
695 where S: AsRef<str>
696 {
697 self.set(opt::known::no_repeat::PROXY_SCHEME,
698 scheme.as_ref().as_bytes().iter().copied().collect())
699 .map(|_| ())
700 }
701
702 fn proxy_scheme(&self) -> Result<Option<&str>, Utf8Error> {
704 self.get_str(opt::known::no_repeat::PROXY_SCHEME)
705 }
706
707 #[doc = rfc_7252_doc!("5.10.8.1")]
710 fn add_if_match<B>(&mut self, tag: B) -> Result<(), Self::SetError>
711 where B: AsRef<[u8]>
712 {
713 if let Some(others) = self.remove(opt::known::repeat::IF_MATCH) {
714 others.into_iter()
715 .filter(|v| v.0.len() > 0)
716 .map(|v| self.add(opt::known::repeat::IF_MATCH, v))
717 .collect::<Result<(), _>>()?;
718 }
719
720 self.add(opt::known::repeat::IF_MATCH,
721 tag.as_ref().iter().copied().collect())
722 }
723
724 fn if_match(&self) -> Option<&Self::OptValues> {
726 self.get(opt::known::repeat::IF_MATCH)
727 }
728
729 #[doc = rfc_7252_doc!("5.10.7")]
732 fn add_location_path<S>(&mut self, path: S) -> Result<(), Self::SetError>
733 where S: AsRef<str>
734 {
735 self.add(opt::known::repeat::LOCATION_PATH,
736 path.as_ref().as_bytes().iter().copied().collect())
737 }
738
739 fn location_path<'a, F>(&'a self) -> Result<F, Utf8Error>
741 where F: FromIterator<&'a str>
742 {
743 self.get_strs(opt::known::repeat::LOCATION_PATH)
744 }
745
746 #[doc = rfc_7252_doc!("5.10.7")]
749 fn add_location_query<S>(&mut self, query: S) -> Result<(), Self::SetError>
750 where S: AsRef<str>
751 {
752 self.add(opt::known::repeat::LOCATION_QUERY,
753 query.as_ref().as_bytes().iter().copied().collect())
754 }
755
756 fn location_query<'a, F>(&'a self) -> Result<F, Utf8Error>
758 where F: FromIterator<&'a str>
759 {
760 self.get_strs(opt::known::repeat::LOCATION_QUERY)
761 }
762
763 #[doc = rfc_7252_doc!("5.10.7")]
766 fn add_etag<B>(&mut self, tag: B) -> Result<(), Self::SetError>
767 where B: AsRef<[u8]>
768 {
769 self.add(opt::known::repeat::ETAG,
770 tag.as_ref().iter().copied().collect())
771 }
772
773 fn etags(&self) -> Option<&Self::OptValues> {
775 self.get(opt::known::repeat::ETAG)
776 }
777}
778
779impl<PayloadBytes: Array<Item = u8> + AppendCopy<u8>, Options: OptionMap>
780 Message<PayloadBytes, Options>
781{
782 pub fn new(ty: Type, code: Code, id: Id, token: Token) -> Self {
784 Self { id,
785 token,
786 ty,
787 code,
788 ver: Version::default(),
789 payload: Payload(PayloadBytes::default()),
790 opts: Options::default() }
791 }
792
793 pub fn cache_key(&self) -> u64 {
801 DefaultCacheKey::default().cache_key(self)
802 }
803
804 pub fn payload(&self) -> &Payload<PayloadBytes> {
806 &self.payload
807 }
808
809 pub fn set_payload(&mut self, p: Payload<PayloadBytes>) -> Option<Payload<PayloadBytes>> {
811 let mut old: Payload<_> = p;
812 core::mem::swap(&mut old, &mut self.payload);
813 Some(old).filter(|old| old.0.len() > 0)
814 }
815
816 pub fn ack(&self, id: Id) -> Self {
856 Self { id,
857 token: self.token,
858 ver: Default::default(),
859 ty: Type::Ack,
860 code: Code::new(0, 0),
861 payload: Payload(Default::default()),
862 opts: Default::default() }
863 }
864
865 fn add(&mut self,
866 n: OptNumber,
867 v: OptValue<Options::OptValue>)
868 -> Result<(), SetOptionError<OptValue<Options::OptValue>, Options::OptValues>> {
869 match (self.remove(n).unwrap_or_default(), &mut self.opts) {
870 | (vals, _) if vals.is_full() => Err(SetOptionError::RepeatedTooManyTimes(v)),
871 | (vals, opts) if opts.is_full() => Err(SetOptionError::TooManyOptions(n, vals)),
872 | (mut vals, opts) => {
873 vals.append(v);
874 opts.insert(n, vals).ok();
875 Ok(())
876 },
877 }
878 }
879
880 fn set(
881 &mut self,
882 n: OptNumber,
883 v: OptValue<Options::OptValue>)
884 -> Result<Option<Options::OptValues>,
885 SetOptionError<OptValue<Options::OptValue>, Options::OptValues>> {
886 Ok(self.remove(n)).and_then(|old| self.add(n, v).map(|_| old))
887 }
888
889 fn count(&self, n: OptNumber) -> usize {
890 self.get(n).map(|a| a.len()).unwrap_or(0)
891 }
892
893 fn get(&self, n: OptNumber) -> Option<&Options::OptValues> {
894 self.opts.get(&n)
895 }
896
897 fn get_first(&self, n: OptNumber) -> Option<&OptValue<Options::OptValue>> {
898 self.get(n).and_then(|vs| vs.get(0))
899 }
900
901 fn get_str(&self, n: OptNumber) -> Result<Option<&str>, Utf8Error> {
902 match self.get_first(n) {
903 | Some(v) => from_utf8(&v.0).map(Some),
904 | _ => Ok(None),
905 }
906 }
907
908 fn get_strs<'a, F>(&'a self, n: OptNumber) -> Result<F, Utf8Error>
909 where F: FromIterator<&'a str>
910 {
911 match self.get(n) {
912 | Some(vs) if vs.len() >= 1 => vs.iter().map(|s| from_utf8(&s.0)).collect(),
913 | _ => Ok(core::iter::empty().collect()),
914 }
915 }
916
917 fn get_u8(&self, n: OptNumber) -> Option<u8> {
918 self.get_first(n)
919 .filter(|bytes| bytes.0.len() == 1)
920 .map(|bytes| bytes.0[0])
921 }
922
923 fn get_u16(&self, n: OptNumber) -> Option<u16> {
924 self.get_first(n)
925 .filter(|bytes| bytes.0.len() == 2)
926 .map(|bytes| u16::from_be_bytes([bytes.0[0], bytes.0[1]]))
927 }
928
929 fn get_u32(&self, n: OptNumber) -> Option<u32> {
930 self.get_first(n)
931 .filter(|bytes| bytes.0.len() == 4)
932 .map(|bytes| u32::from_be_bytes([bytes.0[0], bytes.0[1], bytes.0[2], bytes.0[3]]))
933 }
934
935 fn get_u64(&self, n: OptNumber) -> Option<u64> {
936 self.get_first(n)
937 .filter(|bytes| bytes.0.len() == 8)
938 .map(|bytes| {
939 u64::from_be_bytes([bytes.0[0], bytes.0[1], bytes.0[2], bytes.0[3], bytes.0[4],
940 bytes.0[5], bytes.0[6], bytes.0[7]])
941 })
942 }
943
944 fn remove(&mut self, n: OptNumber) -> Option<Options::OptValues> {
945 self.opts.remove(&n)
946 }
947}
948
949impl<Bytes: AsRef<[u8]>, PayloadBytes: Array<Item = u8> + AppendCopy<u8>, Options: OptionMap>
950 TryFromBytes<Bytes> for Message<PayloadBytes, Options>
951{
952 type Error = MessageParseError;
953
954 fn try_from_bytes(bytes: Bytes) -> Result<Self, Self::Error> {
955 let mut bytes = Cursor::new(bytes);
956
957 let Byte1 { tkl, ty, ver } = bytes.next()
958 .ok_or_else(MessageParseError::eof)?
959 .try_into()?;
960
961 if tkl > 8 {
962 return Err(Self::Error::InvalidTokenLength(tkl));
963 }
964
965 let code: Code = bytes.next().ok_or_else(MessageParseError::eof)?.into();
966 let id: Id = Id::try_consume_bytes(&mut bytes)?;
967
968 let token = bytes.take_exact(tkl as usize)
969 .ok_or_else(MessageParseError::eof)?;
970 let token = tinyvec::ArrayVec::<[u8; 8]>::try_from(token).expect("tkl was checked to be <= 8");
971 let token = Token(token);
972
973 let opts = Options::try_consume_bytes(&mut bytes).map_err(Self::Error::OptParseError)?;
974
975 let mut payload = PayloadBytes::reserve(bytes.remaining());
976 payload.append_copy(bytes.take_until_end());
977 let payload = Payload(payload);
978
979 Ok(Message { id,
980 ty,
981 ver,
982 code,
983 token,
984 opts,
985 payload })
986 }
987}
988
989#[cfg(test)]
990mod tests {
991 use super::*;
992 use crate::alloc;
993
994 #[test]
995 fn parse_msg() {
996 let (expect, msg) = crate::test_msg();
997 assert_eq!(alloc::Message::try_from_bytes(&msg).unwrap(), expect)
998 }
999
1000 #[test]
1001 fn parse_byte1() {
1002 let byte = 0b_01_10_0011u8;
1003 let byte = Byte1::try_from(byte).unwrap();
1004 assert_eq!(byte,
1005 Byte1 { ver: Version(1),
1006 ty: Type::Ack,
1007 tkl: 3 })
1008 }
1009
1010 #[test]
1011 fn parse_id() {
1012 let mut id_bytes = Cursor::new(34u16.to_be_bytes());
1013 let id = Id::try_consume_bytes(&mut id_bytes).unwrap();
1014 assert_eq!(id, Id(34));
1015 }
1016}