neodes_codec/line/id/
block_id.rs1use crate::line::id::short_block_id::{ShortBlockId, ShortBlockIdParsingError};
2use crate::line::id::short_group_id::{ShortGroupId, ShortGroupIdParsingError};
3use crate::line::id::short_struc_id::{ShortStrucId, ShortStrucIdParsingError};
4use serde_with::{DeserializeFromStr, SerializeDisplay};
5use std::error::Error;
6use std::fmt::{Display, Formatter};
7use std::str::FromStr;
8
9#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, DeserializeFromStr, SerializeDisplay)]
12pub struct BlockId {
13 short_struc_id: ShortStrucId,
14 short_group_id: ShortGroupId,
15 short_block_id: ShortBlockId,
16}
17
18impl BlockId {
19 #[inline]
21 pub const fn new(
22 short_struc_id: ShortStrucId,
23 short_group_id: ShortGroupId,
24 short_block_id: ShortBlockId,
25 ) -> BlockId {
26 BlockId {
27 short_struc_id,
28 short_group_id,
29 short_block_id,
30 }
31 }
32
33 #[inline]
50 pub fn short_struc_id(&self) -> ShortStrucId {
51 self.short_struc_id
52 }
53
54 #[inline]
69 pub fn short_group_id(&self) -> ShortGroupId {
70 self.short_group_id
71 }
72
73 #[inline]
87 pub fn short_block_id(&self) -> ShortBlockId {
88 self.short_block_id
89 }
90}
91
92impl Display for BlockId {
93 #[inline]
94 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
95 f.write_fmt(format_args!(
96 "{}.{}.{}",
97 self.short_struc_id, self.short_group_id, self.short_block_id
98 ))
99 }
100}
101
102impl FromStr for BlockId {
103 type Err = BlockIdParseError;
104
105 #[inline]
125 fn from_str(s: &str) -> Result<Self, Self::Err> {
126 let mut split_n = s.splitn(3, '.');
127
128 let next_split = split_n.next().ok_or(BlockIdParseError::Format)?;
129 let short_struc_id = ShortStrucId::from_str(next_split)?;
130
131 let next_split = split_n.next().ok_or(BlockIdParseError::Format)?;
132 let short_group_id = ShortGroupId::from_str(next_split)?;
133
134 let next_split = split_n.next().ok_or(BlockIdParseError::Format)?;
135 let short_block_id = ShortBlockId::from_str(next_split)?;
136
137 Ok(BlockId {
138 short_struc_id,
139 short_group_id,
140 short_block_id,
141 })
142 }
143}
144
145#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
147pub enum BlockIdParseError {
148 Format,
150
151 Structure,
153
154 Group,
156
157 Block,
159}
160
161impl Error for BlockIdParseError {}
162
163impl From<ShortStrucIdParsingError> for BlockIdParseError {
164 #[inline]
165 fn from(_: ShortStrucIdParsingError) -> Self {
166 BlockIdParseError::Structure
167 }
168}
169
170impl From<ShortGroupIdParsingError> for BlockIdParseError {
171 #[inline]
172 fn from(_: ShortGroupIdParsingError) -> Self {
173 BlockIdParseError::Group
174 }
175}
176
177impl From<ShortBlockIdParsingError> for BlockIdParseError {
178 #[inline]
179 fn from(_: ShortBlockIdParsingError) -> Self {
180 BlockIdParseError::Block
181 }
182}
183
184impl Display for BlockIdParseError {
185 #[inline]
186 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
187 match self {
188 BlockIdParseError::Format => {
189 write!(f, "Wrong Field ID format")
190 }
191 BlockIdParseError::Structure => {
192 write!(f, "Cannot parse structure ID")
193 }
194 BlockIdParseError::Group => {
195 write!(f, "Cannot parse group ID")
196 }
197 BlockIdParseError::Block => {
198 write!(f, "Cannot parse block ID")
199 }
200 }
201 }
202}
203
204#[cfg(test)]
205mod tests {
206 use crate::line::{BlockId, ShortBlockId, ShortGroupId, ShortStrucId};
207 use parameterized::parameterized;
208 use std::str::FromStr;
209
210 #[parameterized(input = {
211 "S215G00.00",
212 "S21.G00|00",
213 "S2X.G00.00",
214 "S21.G0X.00",
215 "S21.G00.0X",
216 "S21.G00.00.",
217 "S21.G00.00.001"
218 })]
219 fn returns_parsing_errors(input: &str) {
220 assert!(BlockId::from_str(input).is_err());
221 }
222
223 #[test]
224 fn can_parse_string() {
225 assert_eq!(
226 BlockId::from_str("S21.G00.00"),
227 Ok(BlockId {
228 short_struc_id: ShortStrucId::from_u8_lossy(21),
229 short_group_id: ShortGroupId::from_u8_lossy(0),
230 short_block_id: ShortBlockId::from_u8_lossy(0),
231 })
232 );
233 }
234}