bacnet_encoding/primitives/
priority_value.rs1use bacnet_types::error::{DecodeError, Error};
13use bacnet_types::primitives::{Date, Time};
14#[cfg(feature = "alloc")]
15use bytes::BytesMut;
16
17use crate::constructed::tagged::{self, misplaced_kind};
18use crate::tags::{self, app_tag};
19
20pub const PRIORITY_DATE_TIME_TAG: u8 = 1;
22
23#[cfg(feature = "alloc")]
39pub fn encode_priority_date_time(buf: &mut BytesMut, date: &Date, time: &Time) {
40 tags::encode_opening_tag(buf, PRIORITY_DATE_TIME_TAG);
41 super::encode_app_date(buf, date);
42 super::encode_app_time(buf, time);
43 tags::encode_closing_tag(buf, PRIORITY_DATE_TIME_TAG);
44}
45
46pub fn decode_priority_date_time(
53 data: &[u8],
54 offset: usize,
55) -> Result<((Date, Time), usize), Error> {
56 const WHAT: &str = "BACnetPriorityValue datetime";
57 let (tag, after) = tags::decode_tag(data, offset)?;
58 if !tag.is_opening_tag(PRIORITY_DATE_TIME_TAG) {
59 return Err(DecodeError::new(
60 misplaced_kind(data, offset, &tag, Some(PRIORITY_DATE_TIME_TAG)),
61 offset,
62 "expected opening tag 1 for a BACnetPriorityValue datetime",
63 )
64 .into());
65 }
66 let (date, date_end) = tagged::decode_app_fixed(data, after, app_tag::DATE, 4, WHAT)?;
67 let (time, time_end) = tagged::decode_app_fixed(data, date_end, app_tag::TIME, 4, WHAT)?;
68 let end = tagged::expect_closing(data, time_end, PRIORITY_DATE_TIME_TAG, WHAT)?;
69 Ok(((Date::decode(date)?, Time::decode(time)?), end))
70}
71
72#[cfg(all(test, feature = "alloc"))]
73mod tests {
74 use super::*;
75
76 fn sample() -> (Date, Time) {
77 (
78 Date {
79 year: 126,
80 month: 10,
81 day: 25,
82 day_of_week: 7,
83 },
84 Time {
85 hour: 7,
86 minute: 30,
87 second: 15,
88 hundredths: 0,
89 },
90 )
91 }
92
93 #[test]
94 fn the_datetime_choice_is_wrapped_in_context_tag_one() {
95 let (date, time) = sample();
96 let mut buf = BytesMut::new();
97 encode_priority_date_time(&mut buf, &date, &time);
98 assert_eq!(
99 &buf[..],
100 &[
101 0x1E, 0xA4, 126, 10, 25, 7, 0xB4, 7, 30, 15, 0, 0x1F, ][..]
106 );
107 }
108
109 #[test]
110 fn the_datetime_choice_round_trips() {
111 let (date, time) = sample();
112 let mut buf = BytesMut::new();
113 encode_priority_date_time(&mut buf, &date, &time);
114 buf.extend_from_slice(&[0x00]); let ((d, t), end) = decode_priority_date_time(&buf, 0).unwrap();
116 assert_eq!((d, t), (date, time));
117 assert_eq!(end, 12);
118 }
119
120 #[test]
121 fn a_bare_date_time_or_other_tag_is_not_the_datetime_choice() {
122 let (date, time) = sample();
123 let mut bare = BytesMut::new();
124 super::super::encode_app_date(&mut bare, &date);
125 super::super::encode_app_time(&mut bare, &time);
126 assert!(decode_priority_date_time(&bare, 0).is_err());
127 assert!(decode_priority_date_time(&[0x0E, 0x0F], 0).is_err());
129 let mut cut = BytesMut::new();
131 encode_priority_date_time(&mut cut, &date, &time);
132 assert!(decode_priority_date_time(&cut[..11], 0).is_err());
133 assert!(decode_priority_date_time(&cut[..4], 0).is_err());
134 }
135}