use crate::coordinates::{CoordinateOffset, Coordinates};
use crate::errors::GerberResult;
use crate::traits::{GerberCode, PartialGerberCode};
use crate::{attributes, CoordinateMode, Unit};
use std::io::Write;
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum DCode {
Operation(Operation),
SelectAperture(i32),
}
impl<W: Write> GerberCode<W> for DCode {
fn serialize(&self, writer: &mut W) -> GerberResult<()> {
match *self {
DCode::Operation(ref operation) => operation.serialize(writer)?,
DCode::SelectAperture(code) => writeln!(writer, "D{}*", code)?,
};
Ok(())
}
}
#[derive(Debug, Clone, PartialEq)]
pub enum GCode {
InterpolationMode(InterpolationMode),
RegionMode(bool),
QuadrantMode(QuadrantMode),
Comment(CommentContent),
Unit(Unit),
CoordinateMode(CoordinateMode),
SelectAperture,
}
impl<W: Write> GerberCode<W> for GCode {
fn serialize(&self, writer: &mut W) -> GerberResult<()> {
match *self {
GCode::InterpolationMode(ref mode) => mode.serialize(writer)?,
GCode::RegionMode(enabled) => {
if enabled {
writeln!(writer, "G36*")?;
} else {
writeln!(writer, "G37*")?;
}
}
GCode::QuadrantMode(ref mode) => mode.serialize(writer)?,
GCode::Comment(ref content) => {
write!(writer, "G04 ")?;
content.serialize_partial(writer)?;
writeln!(writer, "*")?;
}
GCode::Unit(ref unit) => match unit {
Unit::Inches => writeln!(writer, "G70*")?,
Unit::Millimeters => writeln!(writer, "G71*")?,
},
GCode::CoordinateMode(ref mode) => match mode {
CoordinateMode::Absolute => writeln!(writer, "G90*")?,
CoordinateMode::Incremental => writeln!(writer, "G91*")?,
},
GCode::SelectAperture => writeln!(writer, "G54*")?,
};
Ok(())
}
}
#[derive(Debug, Clone, PartialEq)]
pub enum CommentContent {
String(String),
Standard(StandardComment),
}
impl<W: Write> PartialGerberCode<W> for CommentContent {
fn serialize_partial(&self, writer: &mut W) -> GerberResult<()> {
match *self {
CommentContent::String(ref string) => {
write!(writer, "{}", string)?;
}
CommentContent::Standard(ref standard) => {
standard.serialize_partial(writer)?;
}
}
Ok(())
}
}
#[derive(Debug, Clone, PartialEq)]
pub enum StandardComment {
FileAttribute(attributes::FileAttribute),
ObjectAttribute(attributes::ObjectAttribute),
ApertureAttribute(attributes::ApertureAttribute),
DeleteAttribute(attributes::AttributeDeletionCriterion),
}
impl<W: Write> PartialGerberCode<W> for StandardComment {
fn serialize_partial(&self, writer: &mut W) -> GerberResult<()> {
write!(writer, "#@! ")?;
match *self {
StandardComment::FileAttribute(ref fa) => {
write!(writer, "TF")?;
fa.serialize_partial(writer)?;
}
StandardComment::ObjectAttribute(ref oa) => {
write!(writer, "TO")?;
oa.serialize_partial(writer)?;
}
StandardComment::ApertureAttribute(ref aa) => {
write!(writer, "TA")?;
aa.serialize_partial(writer)?;
}
StandardComment::DeleteAttribute(ref adc) => {
write!(writer, "TD")?;
adc.serialize_partial(writer)?;
}
}
Ok(())
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum MCode {
EndOfFile,
}
impl<W: Write> GerberCode<W> for MCode {
fn serialize(&self, writer: &mut W) -> GerberResult<()> {
match *self {
MCode::EndOfFile => writeln!(writer, "M02*")?,
};
Ok(())
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Operation {
Interpolate(Option<Coordinates>, Option<CoordinateOffset>),
Move(Option<Coordinates>),
Flash(Option<Coordinates>),
}
impl<W: Write> GerberCode<W> for Operation {
fn serialize(&self, writer: &mut W) -> GerberResult<()> {
match *self {
Operation::Interpolate(ref coords, ref offset) => {
coords.serialize_partial(writer)?;
offset.serialize_partial(writer)?;
writeln!(writer, "D01*")?;
}
Operation::Move(ref coords) => {
coords.serialize_partial(writer)?;
writeln!(writer, "D02*")?;
}
Operation::Flash(ref coords) => {
coords.serialize_partial(writer)?;
writeln!(writer, "D03*")?;
}
};
Ok(())
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum InterpolationMode {
Linear,
ClockwiseCircular,
CounterclockwiseCircular,
}
impl<W: Write> GerberCode<W> for InterpolationMode {
fn serialize(&self, writer: &mut W) -> GerberResult<()> {
match *self {
InterpolationMode::Linear => writeln!(writer, "G01*")?,
InterpolationMode::ClockwiseCircular => writeln!(writer, "G02*")?,
InterpolationMode::CounterclockwiseCircular => writeln!(writer, "G03*")?,
};
Ok(())
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum QuadrantMode {
Single,
Multi,
}
impl<W: Write> GerberCode<W> for QuadrantMode {
fn serialize(&self, writer: &mut W) -> GerberResult<()> {
match *self {
QuadrantMode::Single => writeln!(writer, "G74*")?,
QuadrantMode::Multi => writeln!(writer, "G75*")?,
};
Ok(())
}
}
#[cfg(test)]
mod test {}