embedded_bacnet/common/
daily_schedule.rs

1use core::fmt::Debug;
2
3use super::{
4    error::Error,
5    helper::{encode_closing_tag, encode_opening_tag, get_tagged_body},
6    io::{Reader, Writer},
7    time_value::TimeValue,
8};
9
10// note that Debug is implemented manually here because of the reader in time value iter
11#[derive(Debug, Clone)]
12#[cfg_attr(feature = "defmt", derive(defmt::Format))]
13pub struct WeeklySchedule<'a> {
14    pub monday: TimeValueList<'a>,
15    pub tuesday: TimeValueList<'a>,
16    pub wednesday: TimeValueList<'a>,
17    pub thursday: TimeValueList<'a>,
18    pub friday: TimeValueList<'a>,
19    pub saturday: TimeValueList<'a>,
20    pub sunday: TimeValueList<'a>,
21}
22
23impl<'a> WeeklySchedule<'a> {
24    pub fn new(
25        monday: &'a [TimeValue],
26        tuesday: &'a [TimeValue],
27        wednesday: &'a [TimeValue],
28        thursday: &'a [TimeValue],
29        friday: &'a [TimeValue],
30        saturday: &'a [TimeValue],
31        sunday: &'a [TimeValue],
32    ) -> Self {
33        Self {
34            monday: TimeValueList::new(monday),
35            tuesday: TimeValueList::new(tuesday),
36            wednesday: TimeValueList::new(wednesday),
37            thursday: TimeValueList::new(thursday),
38            friday: TimeValueList::new(friday),
39            saturday: TimeValueList::new(saturday),
40            sunday: TimeValueList::new(sunday),
41        }
42    }
43
44    pub fn encode(&self, writer: &mut Writer) {
45        self.monday.encode(writer);
46        self.tuesday.encode(writer);
47        self.wednesday.encode(writer);
48        self.thursday.encode(writer);
49        self.friday.encode(writer);
50        self.saturday.encode(writer);
51        self.sunday.encode(writer);
52    }
53
54    // due to the fact that WeeklySchedule contains an arbitrary number of TimeValue pairs we need to return an iterator
55    // because we cannot use an allocator
56    pub fn decode(reader: &mut Reader, buf: &'a [u8]) -> Result<Self, Error> {
57        let monday = TimeValueList::decode(reader, buf)?;
58        let tuesday = TimeValueList::decode(reader, buf)?;
59        let wednesday = TimeValueList::decode(reader, buf)?;
60        let thursday = TimeValueList::decode(reader, buf)?;
61        let friday = TimeValueList::decode(reader, buf)?;
62        let saturday = TimeValueList::decode(reader, buf)?;
63        let sunday = TimeValueList::decode(reader, buf)?;
64
65        Ok(Self {
66            monday,
67            tuesday,
68            wednesday,
69            thursday,
70            friday,
71            saturday,
72            sunday,
73        })
74    }
75}
76
77// note that Debug is not implemented here because if does not add value
78#[derive(Debug, Clone)]
79#[cfg_attr(feature = "defmt", derive(defmt::Format))]
80pub struct TimeValueList<'a> {
81    pub time_values: &'a [TimeValue],
82    buf: &'a [u8],
83}
84
85impl<'a> TimeValueList<'a> {
86    pub fn new(time_values: &'a [TimeValue]) -> Self {
87        Self {
88            time_values,
89            buf: &[],
90        }
91    }
92
93    pub fn new_from_buf(buf: &'a [u8]) -> Self {
94        Self {
95            time_values: &[],
96            buf,
97        }
98    }
99
100    pub fn encode(&self, writer: &mut Writer) {
101        encode_opening_tag(writer, 0);
102        for time_value in self.time_values {
103            time_value.encode(writer)
104        }
105        encode_closing_tag(writer, 0);
106    }
107
108    pub fn decode(reader: &mut Reader, buf: &'a [u8]) -> Result<Self, Error> {
109        let (body_buf, _tag_num) = get_tagged_body(reader, buf)?;
110        Ok(TimeValueList::new_from_buf(body_buf))
111    }
112}
113
114impl<'a> IntoIterator for &'_ TimeValueList<'a> {
115    type Item = Result<TimeValue, Error>;
116    type IntoIter = TimeValueIter<'a>;
117
118    fn into_iter(self) -> Self::IntoIter {
119        TimeValueIter {
120            buf: self.buf,
121            reader: Reader::new_with_len(self.buf.len()),
122        }
123    }
124}
125
126pub struct TimeValueIter<'a> {
127    reader: Reader,
128    buf: &'a [u8],
129}
130
131impl<'a> Iterator for TimeValueIter<'a> {
132    type Item = Result<TimeValue, Error>;
133
134    fn next(&mut self) -> Option<Self::Item> {
135        if self.reader.eof() {
136            return None;
137        }
138
139        Some(TimeValue::decode(&mut self.reader, self.buf))
140    }
141}