fix44_forge_helpers/
errors.rs1#[derive(Debug)]
11#[allow(dead_code)]
12pub enum ReadError {
13 MissingRequiredFields {
17 missing_mask: u64,
19 meta: &'static [(&'static str, u16, u8)],
21 },
22 InvalidValue {
24 name: &'static str,
26 tag: u16,
28 msg: &'static str,
30 },
31}
32
33impl core::fmt::Display for ReadError {
34 fn fmt(
35 &self,
36 f: &mut core::fmt::Formatter<'_>,
37 ) -> core::fmt::Result {
38 match self {
39 ReadError::MissingRequiredFields { missing_mask, meta } => {
40 if *missing_mask == 0 {
41 return write!(
42 f,
43 "No required members are missing"
44 );
45 }
46 write!(
47 f,
48 "Missing required members (mask=0x{missing_mask:0X}): "
49 )?;
50 let mut first = true;
51 for (i, (name, tag, kind)) in meta.iter().enumerate() {
52 if (missing_mask >> i) & 1 == 1 {
53 if !first {
54 write!(f, ", ")?;
55 }
56 first = false;
57 let kind_str = match kind {
58 0 => "field",
59 1 => "component",
60 _ => "group",
61 };
62 if *kind == 2 {
63 write!(
65 f,
66 "{kind_str} {name}(countTag={tag})"
67 )?;
68 } else {
69 write!(
70 f,
71 "{kind_str} {name}(tag={tag})"
72 )?;
73 }
74 }
75 }
76 Ok(())
77 }
78 ReadError::InvalidValue { name, tag, msg } => {
79 write!(
80 f,
81 "Invalid value for {name} (tag={tag}): {msg}"
82 )
83 }
84 }
85 }
86}
87
88impl std::error::Error for ReadError {}
89
90impl ReadError {
91 #[allow(dead_code)]
97 pub fn missing_member_names(&self) -> Option<Vec<&'static str>> {
98 match self {
99 ReadError::MissingRequiredFields { missing_mask, meta } => {
100 let mut v = Vec::new();
101 if *missing_mask != 0 {
102 for (i, (name, _tag, _kind)) in meta.iter().enumerate() {
103 if (missing_mask >> i) & 1 == 1 {
104 v.push(*name);
105 }
106 }
107 }
108 Some(v)
109 }
110 _ => None,
111 }
112 }
113}
114
115#[cfg(test)]
116mod tests {
117 use super::*;
118
119 #[test]
120 fn test_read_error_display_no_missing_fields() {
121 let error = ReadError::MissingRequiredFields {
122 missing_mask: 0,
123 meta: &[("TestField", 1, 0)],
124 };
125 assert_eq!(
126 error.to_string(),
127 "No required members are missing"
128 );
129 }
130
131 #[test]
132 fn test_read_error_display_missing_fields() {
133 let meta = &[("Field1", 1, 0), ("Component1", 2, 1), ("Group1", 3, 2)];
134 let error = ReadError::MissingRequiredFields {
135 missing_mask: 0b101, meta,
137 };
138 let error_str = error.to_string();
139 assert!(error_str.contains("Missing required members"));
140 assert!(error_str.contains("field Field1(tag=1)"));
141 assert!(error_str.contains("group Group1(countTag=3)"));
142 }
143
144 #[test]
145 fn test_read_error_display_invalid_value() {
146 let error = ReadError::InvalidValue {
147 name: "TestField",
148 tag: 42,
149 msg: "Expected numeric value",
150 };
151 assert_eq!(
152 error.to_string(),
153 "Invalid value for TestField (tag=42): Expected numeric value"
154 );
155 }
156
157 #[test]
158 fn test_missing_member_names() {
159 let meta = &[("Field1", 1, 0), ("Field2", 2, 0), ("Field3", 3, 0)];
160
161 let error = ReadError::MissingRequiredFields {
163 missing_mask: 0b101, meta,
165 };
166 let names = error
167 .missing_member_names()
168 .unwrap();
169 assert_eq!(
170 names,
171 vec!["Field1", "Field3"]
172 );
173
174 let error = ReadError::MissingRequiredFields {
176 missing_mask: 0,
177 meta,
178 };
179 let names = error
180 .missing_member_names()
181 .unwrap();
182 assert!(names.is_empty());
183
184 let error = ReadError::InvalidValue {
186 name: "TestField",
187 tag: 42,
188 msg: "Test message",
189 };
190 assert!(error
191 .missing_member_names()
192 .is_none());
193 }
194}