bnr_xfs/status/
position_status.rs

1use std::{cmp, fmt};
2
3use crate::{MaxSize, Size};
4
5use super::{CdrPosition, ContentStatus, HardwareStatus, ShutterStatus};
6
7pub const POS_STATUS_LIST_LEN: usize = 2;
8
9/// Status of a CDR stacker.
10#[repr(C)]
11#[derive(Clone, Copy, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)]
12pub struct PositionStatus {
13    pub position: CdrPosition,
14    pub content_status: ContentStatus,
15    pub shutter_status: ShutterStatus,
16}
17
18impl PositionStatus {
19    /// Creates a new [PositionStatus].
20    pub const fn new() -> Self {
21        Self {
22            position: CdrPosition::new(),
23            content_status: ContentStatus::new(),
24            shutter_status: ShutterStatus::new(),
25        }
26    }
27}
28
29impl From<PositionStatus> for HardwareStatus {
30    fn from(val: PositionStatus) -> Self {
31        [
32            Self::from(val.content_status),
33            Self::from(val.shutter_status),
34        ]
35        .into()
36    }
37}
38
39impl fmt::Display for PositionStatus {
40    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
41        write!(f, "{{")?;
42        write!(f, r#""position": {}, "#, self.position)?;
43        write!(f, r#""content_status": {}, "#, self.content_status)?;
44        write!(f, r#""shutter_status": {}"#, self.shutter_status)?;
45        write!(f, "}}")
46    }
47}
48
49impl_xfs_struct!(
50    PositionStatus,
51    "positionStatus",
52    [
53        position: CdrPosition,
54        content_status: ContentStatus,
55        shutter_status: ShutterStatus
56    ]
57);
58
59/// List of CDR stacker status by position.
60#[repr(C)]
61#[derive(Clone, Copy, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)]
62pub struct CdrPositionStatusList {
63    max_size: MaxSize,
64    size: Size,
65    items: [PositionStatus; POS_STATUS_LIST_LEN],
66}
67
68impl CdrPositionStatusList {
69    /// Creates a new [CdrPositionStatusList].
70    pub const fn new() -> Self {
71        Self {
72            max_size: MaxSize::create(POS_STATUS_LIST_LEN as u32),
73            size: Size::new(),
74            items: [PositionStatus::new(); POS_STATUS_LIST_LEN],
75        }
76    }
77
78    /// Creates a new [XfsCdrPositionStatusList] from the provided parameter.
79    pub const fn create(items: [PositionStatus; POS_STATUS_LIST_LEN]) -> Self {
80        Self {
81            max_size: MaxSize::create(POS_STATUS_LIST_LEN as u32),
82            size: Size::create(POS_STATUS_LIST_LEN as u32),
83            items,
84        }
85    }
86
87    /// Gets the max size.
88    pub const fn max_size() -> usize {
89        POS_STATUS_LIST_LEN
90    }
91
92    /// Gets the populated size of the [PositionStatus] list.
93    pub const fn size(&self) -> usize {
94        self.size.inner() as usize
95    }
96
97    /// Sets the populated size of the [PositionStatus] list.
98    ///
99    /// **NOTE** `size` must be less-than-or-equal to `POS_STATUS_LIST_LEN`.
100    pub fn set_size(&mut self, size: u32) {
101        if size as usize <= POS_STATUS_LIST_LEN {
102            self.size.set_inner(size);
103        }
104    }
105
106    /// Builder function that sets the populated size of the [PositionStatus] list.
107    ///
108    /// **NOTE** `size` must be less-than-or-equal to `POS_STATUS_LIST_LEN`.
109    pub fn with_size(mut self, size: u32) -> Self {
110        self.set_size(size);
111        self
112    }
113
114    /// Gets a reference to the [PositionStatus] list.
115    pub fn items(&self) -> &[PositionStatus] {
116        let len = self.size();
117        if len <= Self::max_size() {
118            self.items[..len].as_ref()
119        } else {
120            self.items.as_ref()
121        }
122    }
123
124    /// Gets a mutable reference to the [PositionStatus] list.
125    pub fn items_mut(&mut self) -> &mut [PositionStatus] {
126        let len = self.size();
127        if len <= Self::max_size() {
128            self.items[..len].as_mut()
129        } else {
130            self.items.as_mut()
131        }
132    }
133
134    /// Sets the [PositionStatus] list.
135    ///
136    /// **NOTE** sets at most `POS_STATUS_LIST_LEN` items.
137    pub fn set_items(&mut self, items: &[PositionStatus]) {
138        let len = cmp::min(items.len(), Self::max_size());
139        self.items[..len].copy_from_slice(&items[..len]);
140        self.size.set_inner(len as u32);
141    }
142
143    /// Builder function that sets the [PositionStatus] list.
144    ///
145    /// **NOTE** sets at most `POS_STATUS_LIST_LEN` items.
146    pub fn with_items(mut self, items: &[PositionStatus]) -> Self {
147        self.set_items(items);
148        self
149    }
150}
151
152impl From<CdrPositionStatusList> for HardwareStatus {
153    fn from(val: CdrPositionStatusList) -> Self {
154        val.items.map(Self::from).into()
155    }
156}
157
158impl fmt::Display for CdrPositionStatusList {
159    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
160        write!(f, "{{")?;
161        write!(f, r#""max_size": {}, "#, self.max_size)?;
162        write!(f, r#""size": {}, "#, self.size)?;
163        write!(f, r#""items": ["#)?;
164
165        for (i, item) in self.items().iter().enumerate() {
166            if i != 0 {
167                write!(f, ", ")?;
168            }
169            write!(f, "{item}")?;
170        }
171
172        write!(f, "]}}")
173    }
174}
175
176impl_xfs_array!(CdrPositionStatusList, "positionStatusList");