1use std::io::Write;
4
5use chrono::{DateTime, Utc};
6use uuid::Uuid;
7
8use crate::errors::GerberResult;
9use crate::traits::PartialGerberCode;
10
11#[derive(Debug, Clone, PartialEq, Eq)]
14pub enum FileAttribute {
15 Part(Part),
16 FileFunction(FileFunction),
17 FilePolarity(FilePolarity),
18 GenerationSoftware(GenerationSoftware),
19 CreationDate(DateTime<Utc>),
20 ProjectId {
21 id: String,
22 guid: Uuid,
23 revision: String,
24 },
25 Md5(String),
26 UserDefined {
27 name: String,
28 value: Vec<String>,
29 },
30}
31
32impl<W: Write> PartialGerberCode<W> for FileAttribute {
33 fn serialize_partial(&self, writer: &mut W) -> GerberResult<()> {
34 match *self {
35 FileAttribute::Part(ref part) => {
36 write!(writer, "Part,")?;
37 part.serialize_partial(writer)?;
38 }
39 FileAttribute::FileFunction(ref function) => {
40 write!(writer, "FileFunction,")?;
41 match function {
42 FileFunction::Copper {
43 ref layer,
44 ref pos,
45 ref copper_type,
46 } => {
47 write!(writer, "Copper,L{},", layer)?;
48 pos.serialize_partial(writer)?;
49 if let Some(ref t) = *copper_type {
50 write!(writer, ",")?;
51 t.serialize_partial(writer)?;
52 }
53 }
54 FileFunction::Profile(ref plating) => {
55 write!(writer, "Profile,")?;
56 plating.serialize_partial(writer)?;
57 }
58 FileFunction::Soldermask { ref pos, ref index } => {
59 write!(writer, "Soldermask,")?;
60 pos.serialize_partial(writer)?;
61 if let Some(ref i) = index {
62 write!(writer, ",{}", *i)?;
63 }
64 }
65 FileFunction::Legend { ref pos, ref index } => {
66 write!(writer, "Legend,")?;
67 pos.serialize_partial(writer)?;
68 if let Some(ref i) = index {
69 write!(writer, ",{}", *i)?;
70 }
71 }
72 _ => unimplemented!(),
73 }
74 }
75 FileAttribute::GenerationSoftware(ref gs) => {
76 write!(writer, "GenerationSoftware,")?;
77 gs.serialize_partial(writer)?;
78 }
79 FileAttribute::FilePolarity(ref p) => {
80 write!(writer, "FilePolarity,")?;
81 p.serialize_partial(writer)?;
82 }
83 FileAttribute::Md5(ref hash) => write!(writer, "MD5,{}", hash)?,
84 _ => unimplemented!(),
85 };
86 Ok(())
87 }
88}
89
90#[derive(Debug, Clone, PartialEq)]
93pub enum ApertureAttribute {
94 ApertureFunction(ApertureFunction),
95 DrillTolerance { plus: f64, minus: f64 },
96}
97
98#[derive(Debug, Clone, PartialEq, Eq)]
101pub enum Part {
102 Single,
104 Array,
106 FabricationPanel,
108 Coupon,
110 Other(String),
112}
113
114impl<W: Write> PartialGerberCode<W> for Part {
115 fn serialize_partial(&self, writer: &mut W) -> GerberResult<()> {
116 match *self {
117 Part::Single => write!(writer, "Single")?,
118 Part::Array => write!(writer, "Array")?,
119 Part::FabricationPanel => write!(writer, "FabricationPanel")?,
120 Part::Coupon => write!(writer, "Coupon")?,
121 Part::Other(ref description) => write!(writer, "Other,{}", description)?,
122 };
123 Ok(())
124 }
125}
126
127#[derive(Debug, Clone, PartialEq, Eq)]
130pub enum Position {
131 Top,
132 Bottom,
133}
134
135impl<W: Write> PartialGerberCode<W> for Position {
136 fn serialize_partial(&self, writer: &mut W) -> GerberResult<()> {
137 match *self {
138 Position::Top => write!(writer, "Top")?,
139 Position::Bottom => write!(writer, "Bot")?,
140 };
141 Ok(())
142 }
143}
144
145#[derive(Debug, Clone, PartialEq, Eq)]
148pub enum ExtendedPosition {
149 Top,
150 Inner,
151 Bottom,
152}
153
154impl<W: Write> PartialGerberCode<W> for ExtendedPosition {
155 fn serialize_partial(&self, writer: &mut W) -> GerberResult<()> {
156 match *self {
157 ExtendedPosition::Top => write!(writer, "Top")?,
158 ExtendedPosition::Inner => write!(writer, "Inr")?,
159 ExtendedPosition::Bottom => write!(writer, "Bot")?,
160 };
161 Ok(())
162 }
163}
164
165#[derive(Debug, Clone, PartialEq, Eq)]
168pub enum CopperType {
169 Plane,
170 Signal,
171 Mixed,
172 Hatched,
173}
174
175impl<W: Write> PartialGerberCode<W> for CopperType {
176 fn serialize_partial(&self, writer: &mut W) -> GerberResult<()> {
177 match *self {
178 CopperType::Plane => write!(writer, "Plane")?,
179 CopperType::Signal => write!(writer, "Signal")?,
180 CopperType::Mixed => write!(writer, "Mixed")?,
181 CopperType::Hatched => write!(writer, "Hatched")?,
182 };
183 Ok(())
184 }
185}
186
187#[derive(Debug, Clone, PartialEq, Eq)]
190pub enum Drill {
191 ThroughHole,
192 Blind,
193 Buried,
194}
195
196#[derive(Debug, Clone, PartialEq, Eq)]
199pub enum DrillRouteType {
200 Drill,
201 Route,
202 Mixed,
203}
204
205#[derive(Debug, Clone, PartialEq, Eq)]
208pub enum Profile {
209 Plated,
210 NonPlated,
211}
212
213impl<W: Write> PartialGerberCode<W> for Profile {
214 fn serialize_partial(&self, writer: &mut W) -> GerberResult<()> {
215 match *self {
216 Profile::Plated => write!(writer, "P")?,
217 Profile::NonPlated => write!(writer, "NP")?,
218 };
219 Ok(())
220 }
221}
222
223#[derive(Debug, Clone, PartialEq, Eq)]
226pub enum FileFunction {
227 Copper {
228 layer: i32,
229 pos: ExtendedPosition,
230 copper_type: Option<CopperType>,
231 },
232 Soldermask {
233 pos: Position,
234 index: Option<i32>,
235 },
236 Legend {
237 pos: Position,
238 index: Option<i32>,
239 },
240 Goldmask {
241 pos: Position,
242 index: Option<i32>,
243 },
244 Silvermask {
245 pos: Position,
246 index: Option<i32>,
247 },
248 Tinmask {
249 pos: Position,
250 index: Option<i32>,
251 },
252 Carbonmask {
253 pos: Position,
254 index: Option<i32>,
255 },
256 Peelablesoldermask {
257 pos: Position,
258 index: Option<i32>,
259 },
260 Glue {
261 pos: Position,
262 index: Option<i32>,
263 },
264 Viatenting(Position),
265 Viafill,
266 Heatsink(Position),
267 Paste(Position),
268 KeepOut(Position),
269 Pads(Position),
270 Scoring(Position),
271 Plated {
272 from_layer: i32,
273 to_layer: i32,
274 drill: Drill,
275 label: Option<DrillRouteType>,
276 },
277 NonPlated {
278 from_layer: i32,
279 to_layer: i32,
280 drill: Drill,
281 label: Option<DrillRouteType>,
282 },
283 Profile(Profile),
284 Drillmap,
285 FabricationDrawing,
286 ArrayDrawing,
287 AssemblyDrawing(Position),
288 Drawing(String),
289 Other(String),
290}
291
292#[derive(Debug, Clone, PartialEq, Eq)]
295pub enum FilePolarity {
296 Positive,
297 Negative,
298}
299
300impl<W: Write> PartialGerberCode<W> for FilePolarity {
301 fn serialize_partial(&self, writer: &mut W) -> GerberResult<()> {
302 match *self {
303 FilePolarity::Positive => write!(writer, "Positive")?,
304 FilePolarity::Negative => write!(writer, "Negative")?,
305 };
306 Ok(())
307 }
308}
309
310#[derive(Debug, Clone, PartialEq, Eq)]
313pub struct GenerationSoftware {
314 pub vendor: String,
315 pub application: String,
316 pub version: Option<String>,
317}
318
319impl GenerationSoftware {
320 pub fn new<S: Into<String>>(vendor: S, application: S, version: Option<S>) -> Self {
321 GenerationSoftware {
322 vendor: vendor.into(),
323 application: application.into(),
324 version: version.map(|s| s.into()),
325 }
326 }
327}
328
329impl<W: Write> PartialGerberCode<W> for GenerationSoftware {
330 fn serialize_partial(&self, writer: &mut W) -> GerberResult<()> {
331 match self.version {
332 Some(ref v) => write!(writer, "{},{},{}", self.vendor, self.application, v)?,
333 None => write!(writer, "{},{}", self.vendor, self.application)?,
334 };
335 Ok(())
336 }
337}
338
339#[derive(Debug, Clone, PartialEq, Eq)]
342pub enum ApertureFunction {
343 ViaDrill,
345 BackDrill,
346 ComponentDrill {
347 press_fit: Option<bool>, },
349 CastellatedDrill,
350 MechanicalDrill {
351 function: Option<DrillFunction>,
352 },
353 Slot,
354 CutOut,
355 Cavity,
356 OtherDrill(String),
357
358 ComponentPad {
360 press_fit: Option<bool>, },
362 SmdPad(SmdPadType),
363 BgaPad(SmdPadType),
364 ConnectorPad,
365 HeatsinkPad,
366 ViaPad,
367 TestPad,
368 CastellatedPad,
369 FiducialPad(FiducialScope),
370 ThermalReliefPad,
371 WasherPad,
372 AntiPad,
373 OtherPad(String),
374 Conductor,
375 NonConductor,
376 CopperBalancing,
377 Border,
378 OtherCopper(String),
379
380 Profile,
382 NonMaterial,
383 Material,
384 Other(String),
385}
386
387#[derive(Debug, Clone, PartialEq, Eq)]
390pub enum DrillFunction {
391 BreakOut,
392 Tooling,
393 Other,
394}
395
396#[derive(Debug, Clone, PartialEq, Eq)]
399pub enum SmdPadType {
400 CopperDefined,
401 SoldermaskDefined,
402}
403
404#[derive(Debug, Clone, PartialEq, Eq)]
407pub enum FiducialScope {
408 Global,
409 Local,
410}