bacnet_objects/color/
mod.rs1use std::ops::RangeInclusive;
19use std::time::Duration;
20
21use bacnet_types::constructed::BACnetXyColor;
22use bacnet_types::enums::ColorTransition;
23use bacnet_types::error::Error;
24use bacnet_types::primitives::PropertyValue;
25
26use crate::audit::ObjectAuditPolicy;
27use crate::common;
28
29mod command;
30mod engine;
31mod metadata;
32mod temperature;
33mod xy;
34
35pub use temperature::ColorTemperatureObject;
36pub use xy::ColorObject;
37
38#[cfg(test)]
39mod command_tests;
40#[cfg(test)]
41mod engine_tests;
42#[cfg(test)]
43mod metadata_tests;
44#[cfg(test)]
45mod rows_tests;
46#[cfg(test)]
47mod value_source_tests;
48
49fn xy_value(color: BACnetXyColor) -> PropertyValue {
52 PropertyValue::List(vec![
53 PropertyValue::Real(color.x),
54 PropertyValue::Real(color.y),
55 ])
56}
57
58fn written_xy(value: PropertyValue) -> Result<BACnetXyColor, Error> {
62 let PropertyValue::List(items) = value else {
63 return Err(common::invalid_data_type_error());
64 };
65 let [PropertyValue::Real(x), PropertyValue::Real(y)] = items.as_slice() else {
66 return Err(common::invalid_data_type_error());
67 };
68 let color = BACnetXyColor::new(*x, *y);
69 if command::xy_in_range(color) {
70 Ok(color)
71 } else {
72 Err(common::value_out_of_range_error())
73 }
74}
75
76fn written_unsigned(value: PropertyValue, range: RangeInclusive<u32>) -> Result<u32, Error> {
79 let PropertyValue::Unsigned(value) = value else {
80 return Err(common::invalid_data_type_error());
81 };
82 u32::try_from(value)
83 .ok()
84 .filter(|value| range.contains(value))
85 .ok_or_else(common::value_out_of_range_error)
86}
87
88fn written_transition(
92 value: PropertyValue,
93 last: ColorTransition,
94) -> Result<ColorTransition, Error> {
95 let PropertyValue::Enumerated(raw) = value else {
96 return Err(common::invalid_data_type_error());
97 };
98 if raw > last.to_raw() {
99 return Err(common::value_out_of_range_error());
100 }
101 Ok(ColorTransition::from_raw(raw))
102}
103
104fn noncommandable_audit_policy(policy: ObjectAuditPolicy) -> ObjectAuditPolicy {
107 ObjectAuditPolicy {
108 priority_filter: None,
109 ..policy
110 }
111}
112
113fn milliseconds(fade_time: u32) -> Duration {
115 Duration::from_millis(u64::from(fade_time))
116}