gerber_types/
codegen.rs

1//! Generic code generation, e.g. implementations of `PartialGerberCode` for
2//! bool or Vec<G: GerberCode>.
3
4use std::io::Write;
5
6use crate::errors::GerberResult;
7use crate::traits::{GerberCode, PartialGerberCode};
8use crate::types::*;
9use crate::{CoordinateMode, ZeroOmission};
10
11/// Implement `PartialGerberCode` for booleans
12impl<W: Write> PartialGerberCode<W> for bool {
13    fn serialize_partial(&self, writer: &mut W) -> GerberResult<()> {
14        if *self {
15            write!(writer, "1")?;
16        } else {
17            write!(writer, "0")?;
18        };
19        Ok(())
20    }
21}
22
23/// Implement `GerberCode` for Vectors of types that are `GerberCode`.
24impl<W: Write, G: GerberCode<W>> GerberCode<W> for Vec<G> {
25    fn serialize(&self, writer: &mut W) -> GerberResult<()> {
26        for item in self.iter() {
27            item.serialize(writer)?;
28        }
29        Ok(())
30    }
31}
32
33/// Implement `PartialGerberCode` for `Option<T: PartialGerberCode>`
34impl<T: PartialGerberCode<W>, W: Write> PartialGerberCode<W> for Option<T> {
35    fn serialize_partial(&self, writer: &mut W) -> GerberResult<()> {
36        if let Some(ref val) = *self {
37            val.serialize_partial(writer)?;
38        }
39        Ok(())
40    }
41}
42
43impl<W: Write> GerberCode<W> for Command {
44    fn serialize(&self, writer: &mut W) -> GerberResult<()> {
45        match *self {
46            Command::FunctionCode(ref code) => code.serialize(writer)?,
47            Command::ExtendedCode(ref code) => code.serialize(writer)?,
48        };
49        Ok(())
50    }
51}
52
53impl<W: Write> GerberCode<W> for FunctionCode {
54    fn serialize(&self, writer: &mut W) -> GerberResult<()> {
55        match *self {
56            FunctionCode::DCode(ref code) => code.serialize(writer)?,
57            FunctionCode::GCode(ref code) => code.serialize(writer)?,
58            FunctionCode::MCode(ref code) => code.serialize(writer)?,
59        };
60        Ok(())
61    }
62}
63
64impl<W: Write> GerberCode<W> for ExtendedCode {
65    fn serialize(&self, writer: &mut W) -> GerberResult<()> {
66        match *self {
67            ExtendedCode::CoordinateFormat(ref cf) => {
68                let zero_omission = match &cf.zero_omission {
69                    ZeroOmission::Leading => 'L',
70                    ZeroOmission::Trailing => 'T',
71                };
72                let mode = match &cf.coordinate_mode {
73                    CoordinateMode::Absolute => 'A',
74                    CoordinateMode::Incremental => 'I',
75                };
76                writeln!(
77                    writer,
78                    "%FS{2}{3}X{0}{1}Y{0}{1}*%",
79                    cf.integer, cf.decimal, zero_omission, mode
80                )?;
81            }
82            ExtendedCode::Unit(ref unit) => {
83                write!(writer, "%MO")?;
84                unit.serialize_partial(writer)?;
85                writeln!(writer, "*%")?;
86            }
87            ExtendedCode::ApertureDefinition(ref def) => {
88                write!(writer, "%ADD")?;
89                def.serialize_partial(writer)?;
90                writeln!(writer, "*%")?;
91            }
92            ExtendedCode::ApertureMacro(ref am) => {
93                write!(writer, "%")?;
94                am.serialize_partial(writer)?;
95                writeln!(writer, "%")?;
96            }
97            ExtendedCode::LoadPolarity(ref polarity) => {
98                write!(writer, "%LP")?;
99                polarity.serialize_partial(writer)?;
100                writeln!(writer, "*%")?;
101            }
102            ExtendedCode::LoadMirroring(ref mirroring) => {
103                write!(writer, "%LM")?;
104                mirroring.serialize_partial(writer)?;
105                writeln!(writer, "*%")?;
106            }
107            ExtendedCode::LoadRotation(ref rotation) => {
108                write!(writer, "%LR")?;
109                rotation.serialize_partial(writer)?;
110                writeln!(writer, "*%")?;
111            }
112            ExtendedCode::LoadScaling(ref scaling) => {
113                write!(writer, "%LS")?;
114                scaling.serialize_partial(writer)?;
115                writeln!(writer, "*%")?;
116            }
117            ExtendedCode::StepAndRepeat(ref sar) => {
118                write!(writer, "%SR")?;
119                sar.serialize_partial(writer)?;
120                writeln!(writer, "*%")?;
121            }
122            ExtendedCode::FileAttribute(ref attr) => {
123                write!(writer, "%TF")?;
124                attr.serialize_partial(writer)?;
125                writeln!(writer, "*%")?;
126            }
127            ExtendedCode::DeleteAttribute(ref attr) => {
128                write!(writer, "%TD")?;
129                attr.serialize_partial(writer)?;
130                writeln!(writer, "*%")?;
131            }
132            ExtendedCode::ApertureBlock(ref ab) => {
133                write!(writer, "%AB")?;
134                ab.serialize_partial(writer)?;
135                writeln!(writer, "*%")?;
136            }
137            ExtendedCode::ApertureAttribute(ref aa) => {
138                write!(writer, "%TA")?;
139                aa.serialize_partial(writer)?;
140                writeln!(writer, "*%")?;
141            }
142            ExtendedCode::ObjectAttribute(ref oa) => {
143                write!(writer, "%TO")?;
144                oa.serialize_partial(writer)?;
145                writeln!(writer, "*%")?;
146            }
147            ExtendedCode::MirrorImage(ref mi) => {
148                write!(writer, "%MI")?;
149                mi.serialize_partial(writer)?;
150                writeln!(writer, "*%")?;
151            }
152            ExtendedCode::OffsetImage(ref of) => {
153                write!(writer, "%OF")?;
154                of.serialize_partial(writer)?;
155                writeln!(writer, "*%")?;
156            }
157            ExtendedCode::ScaleImage(ref sf) => {
158                write!(writer, "%SF")?;
159                sf.serialize_partial(writer)?;
160                writeln!(writer, "*%")?;
161            }
162            ExtendedCode::RotateImage(ref ir) => {
163                write!(writer, "%IR")?;
164                ir.serialize_partial(writer)?;
165                writeln!(writer, "*%")?;
166            }
167            ExtendedCode::ImagePolarity(ref ip) => {
168                write!(writer, "%IP")?;
169                ip.serialize_partial(writer)?;
170                writeln!(writer, "*%")?;
171            }
172            ExtendedCode::AxisSelect(ref r#as) => {
173                write!(writer, "%AS")?;
174                r#as.serialize_partial(writer)?;
175                writeln!(writer, "*%")?;
176            }
177            ExtendedCode::ImageName(ref r#in) => {
178                write!(writer, "%IN")?;
179                r#in.serialize_partial(writer)?;
180                writeln!(writer, "*%")?;
181            }
182        };
183        Ok(())
184    }
185}