1use std::convert::From;
8
9use crate::attributes;
10use crate::coordinates;
11use crate::extended_codes;
12use crate::function_codes;
13use crate::macros;
14
15macro_rules! impl_from {
18 ($from:ty, $target:ty, $variant:expr) => {
19 impl From<$from> for $target {
20 fn from(val: $from) -> Self {
21 $variant(val)
22 }
23 }
24 };
25}
26
27#[derive(Debug, Clone, PartialEq)]
30pub enum Command {
31 FunctionCode(FunctionCode),
32 ExtendedCode(ExtendedCode),
33}
34
35impl_from!(FunctionCode, Command, Command::FunctionCode);
36impl_from!(ExtendedCode, Command, Command::ExtendedCode);
37
38macro_rules! impl_command_fromfrom {
39 ($from:ty, $inner:path) => {
40 impl From<$from> for Command {
41 fn from(val: $from) -> Self {
42 Command::from($inner(val))
43 }
44 }
45 };
46}
47
48#[derive(Debug, Clone, PartialEq, Eq)]
51pub enum FunctionCode {
52 DCode(function_codes::DCode),
53 GCode(function_codes::GCode),
54 MCode(function_codes::MCode),
55}
56
57impl_from!(function_codes::DCode, FunctionCode, FunctionCode::DCode);
58impl_from!(function_codes::GCode, FunctionCode, FunctionCode::GCode);
59impl_from!(function_codes::MCode, FunctionCode, FunctionCode::MCode);
60
61impl_command_fromfrom!(function_codes::DCode, FunctionCode::from);
62impl_command_fromfrom!(function_codes::GCode, FunctionCode::from);
63impl_command_fromfrom!(function_codes::MCode, FunctionCode::from);
64
65#[derive(Debug, Clone, PartialEq)]
66pub enum ExtendedCode {
67 CoordinateFormat(coordinates::CoordinateFormat),
69 Unit(extended_codes::Unit),
71 ApertureDefinition(extended_codes::ApertureDefinition),
73 ApertureMacro(macros::ApertureMacro),
75 LoadPolarity(extended_codes::Polarity),
77 StepAndRepeat(extended_codes::StepAndRepeat),
79 FileAttribute(attributes::FileAttribute),
81 ApertureAttribute(attributes::ApertureAttribute),
83 DeleteAttribute(String),
85}
86
87impl_from!(
88 coordinates::CoordinateFormat,
89 ExtendedCode,
90 ExtendedCode::CoordinateFormat
91);
92impl_from!(extended_codes::Unit, ExtendedCode, ExtendedCode::Unit);
93impl_from!(
94 extended_codes::ApertureDefinition,
95 ExtendedCode,
96 ExtendedCode::ApertureDefinition
97);
98impl_from!(
99 macros::ApertureMacro,
100 ExtendedCode,
101 ExtendedCode::ApertureMacro
102);
103impl_from!(
104 extended_codes::Polarity,
105 ExtendedCode,
106 ExtendedCode::LoadPolarity
107);
108impl_from!(
109 extended_codes::StepAndRepeat,
110 ExtendedCode,
111 ExtendedCode::StepAndRepeat
112);
113impl_from!(
114 attributes::FileAttribute,
115 ExtendedCode,
116 ExtendedCode::FileAttribute
117);
118impl_from!(
119 attributes::ApertureAttribute,
120 ExtendedCode,
121 ExtendedCode::ApertureAttribute
122);
123
124impl_command_fromfrom!(coordinates::CoordinateFormat, ExtendedCode::from);
125impl_command_fromfrom!(extended_codes::Unit, ExtendedCode::from);
126impl_command_fromfrom!(extended_codes::ApertureDefinition, ExtendedCode::from);
127impl_command_fromfrom!(macros::ApertureMacro, ExtendedCode::from);
128impl_command_fromfrom!(extended_codes::Polarity, ExtendedCode::from);
129impl_command_fromfrom!(extended_codes::StepAndRepeat, ExtendedCode::from);
130impl_command_fromfrom!(attributes::FileAttribute, ExtendedCode::from);
131impl_command_fromfrom!(attributes::ApertureAttribute, ExtendedCode::from);
132
133#[cfg(test)]
134mod test {
135 use super::*;
136
137 use std::io::BufWriter;
138
139 use crate::extended_codes::Polarity;
140 use crate::function_codes::GCode;
141 use crate::traits::GerberCode;
142
143 #[test]
144 fn test_debug() {
145 let c = Command::FunctionCode(FunctionCode::GCode(GCode::Comment("test".to_string())));
147 let debug = format!("{:?}", c);
148 assert_eq!(debug, "FunctionCode(GCode(Comment(\"test\")))");
149 }
150
151 #[test]
152 fn test_function_code_serialize() {
153 let c = FunctionCode::GCode(GCode::Comment("comment".to_string()));
155 assert_code!(c, "G04 comment*\n");
156 }
157
158 #[test]
159 fn test_function_code_from_gcode() {
160 let comment = GCode::Comment("hello".into());
161 let f1: FunctionCode = FunctionCode::GCode(comment.clone());
162 let f2: FunctionCode = comment.into();
163 assert_eq!(f1, f2);
164 }
165
166 #[test]
167 fn test_command_from_function_code() {
168 let comment = FunctionCode::GCode(GCode::Comment("hello".into()));
169 let c1: Command = Command::FunctionCode(comment.clone());
170 let c2: Command = comment.into();
171 assert_eq!(c1, c2);
172 }
173
174 #[test]
175 fn test_command_from_extended_code() {
176 let delete_attr = ExtendedCode::DeleteAttribute("hello".into());
177 let c1: Command = Command::ExtendedCode(delete_attr.clone());
178 let c2: Command = delete_attr.into();
179 assert_eq!(c1, c2);
180 }
181
182 #[test]
183 fn test_extended_code_from_polarity() {
184 let e1: ExtendedCode = ExtendedCode::LoadPolarity(Polarity::Dark);
185 let e2: ExtendedCode = Polarity::Dark.into();
186 assert_eq!(e1, e2);
187 }
188}