awdl_frame_parser/tlvs/sync_elect/channel_sequence_tlv/
channel_sequence.rs1use core::fmt::Debug;
2use scroll::{
3 ctx::{MeasureWith, TryFromCtx, TryIntoCtx},
4 Pread, Pwrite,
5};
6
7use super::channel::*;
8
9#[derive(Clone, PartialEq, Eq)]
10pub enum ChannelSequence {
12 Simple([u8; 16]),
14 Legacy([(LegacyFlags, u8); 16]),
16 OpClass([(u8, u8); 16]),
18}
19impl ChannelSequence {
20 #[inline]
21 pub const fn channel_encoding(&self) -> ChannelEncoding {
23 match self {
24 Self::Simple(_) => ChannelEncoding::Simple,
25 Self::Legacy(_) => ChannelEncoding::Legacy,
26 Self::OpClass(_) => ChannelEncoding::OpClass,
27 }
28 }
29 #[inline]
30 pub const fn fixed_channel_sequence(channel: Channel) -> Self {
32 match channel {
33 Channel::Simple { channel } => ChannelSequence::Simple([channel; 16]),
34 Channel::Legacy { flags, channel } => ChannelSequence::Legacy([(flags, channel); 16]),
35 Channel::OpClass { channel, opclass } => {
36 ChannelSequence::OpClass([(channel, opclass); 16])
37 }
38 }
39 }
40}
41impl Default for ChannelSequence {
42 fn default() -> Self {
43 ChannelSequence::Simple(Default::default())
44 }
45}
46impl Debug for ChannelSequence {
47 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
48 match self {
49 ChannelSequence::Simple(channels) => f.debug_list().entries(channels.iter()).finish(),
50 ChannelSequence::Legacy(channels) => f
51 .debug_list()
52 .entries(channels.iter().map(|(_, channel)| channel))
53 .finish(),
54 ChannelSequence::OpClass(channels) => f
55 .debug_list()
56 .entries(channels.iter().map(|(channel, _)| channel))
57 .finish(),
58 }
59 }
60}
61impl MeasureWith<()> for ChannelSequence {
62 fn measure_with(&self, _ctx: &()) -> usize {
63 16 * match self {
64 ChannelSequence::Legacy(_) | ChannelSequence::OpClass(_) => 2,
65 _ => 1,
66 }
67 }
68}
69impl<'a> TryFromCtx<'a, ChannelEncoding> for ChannelSequence {
70 type Error = scroll::Error;
71 fn try_from_ctx(
72 from: &'a [u8],
73 encoding: ChannelEncoding,
74 ) -> Result<(Self, usize), Self::Error> {
75 let mut offset = 0;
76 Ok((
77 match encoding {
78 ChannelEncoding::Simple => {
79 ChannelSequence::Simple(from.gread::<[u8; 16]>(&mut offset)?)
80 }
81 ChannelEncoding::Legacy => ChannelSequence::Legacy({
82 let mut array = [(LegacyFlags::default(), 0); 16];
83 for (i, bytes) in from.gread::<[u8; 32]>(&mut offset)?.chunks(2).enumerate() {
84 array[i] = (LegacyFlags::from_bits(bytes[0]), bytes[1]);
85 }
86 array
87 }),
88 ChannelEncoding::OpClass => ChannelSequence::OpClass({
89 let mut array = [(0, 0); 16];
90 for (i, bytes) in from.gread::<[u8; 32]>(&mut offset)?.chunks(2).enumerate() {
91 array[i] = (bytes[0], bytes[1]);
92 }
93 array
94 }),
95 ChannelEncoding::Unknown(_) => {
96 return Err(scroll::Error::BadInput {
97 size: offset,
98 msg: "Unknown encoding.",
99 })
100 }
101 },
102 offset,
103 ))
104 }
105}
106impl TryIntoCtx for ChannelSequence {
107 type Error = scroll::Error;
108 fn try_into_ctx(self, buf: &mut [u8], _ctx: ()) -> Result<usize, Self::Error> {
109 match self {
110 ChannelSequence::Simple(channels) => buf.pwrite::<&[u8]>(channels.as_ref(), 0),
111 ChannelSequence::Legacy(channels) => {
112 let mut offset = 0;
113 for (flags, channel) in channels.iter() {
114 buf.gwrite(flags.into_bits(), &mut offset)?;
115 buf.gwrite(channel, &mut offset)?;
116 }
117 Ok(offset)
118 }
119 ChannelSequence::OpClass(channels) => {
120 let mut offset = 0;
121 for (channel, opclass) in channels.iter() {
122 buf.gwrite(channel, &mut offset)?;
123 buf.gwrite(opclass, &mut offset)?;
124 }
125 Ok(offset)
126 }
127 }
128 }
129}