use crate::GerberDoc;
use gerber_types::{
CoordinateFormat, CoordinateNumber, CoordinateOffset, Coordinates, GerberCode, GerberError,
};
use std::io::BufReader;
use std::str;
#[must_use]
pub fn gerber_to_reader(gerber_string: &str) -> BufReader<&[u8]> {
let bytes = gerber_string.as_bytes();
BufReader::new(bytes)
}
#[must_use]
pub fn gerber_doc_to_str(gerber_doc: GerberDoc) -> String {
let mut filevec = Vec::<u8>::new();
gerber_doc.into_commands().serialize(&mut filevec).unwrap();
str::from_utf8(&filevec).unwrap().to_string()
}
#[must_use]
pub fn gerber_doc_as_str(gerber_doc: &GerberDoc) -> String {
let mut filevec = Vec::<u8>::new();
gerber_doc.commands().iter().for_each(|command| {
command.serialize(&mut filevec).unwrap();
});
str::from_utf8(&filevec).unwrap().to_string()
}
pub fn coordinates_from_gerber(
mut x_as_int: i64,
mut y_as_int: i64,
fs: CoordinateFormat,
) -> Result<Option<Coordinates>, GerberError> {
let factor = (6u8 - fs.decimal) as u32;
x_as_int *= 10i64.pow(factor);
y_as_int *= 10i64.pow(factor);
Ok(Some(Coordinates::new(
CoordinateNumber::new(x_as_int).validate(&fs)?,
CoordinateNumber::new(y_as_int).validate(&fs)?,
fs,
)))
}
pub fn partial_coordinates_from_gerber(
x_as_int: Option<i64>,
y_as_int: Option<i64>,
fs: CoordinateFormat,
) -> Result<Option<Coordinates>, GerberError> {
let factor = (6u8 - fs.decimal) as u32;
let x = x_as_int
.map(|value| CoordinateNumber::new(value * 10i64.pow(factor)).validate(&fs))
.transpose()?;
let y = y_as_int
.map(|value| CoordinateNumber::new(value * 10i64.pow(factor)).validate(&fs))
.transpose()?;
let coordinates = match (x, y) {
(None, None) => None,
(x, y) => Some(Coordinates::new(x, y, fs)),
};
Ok(coordinates)
}
pub fn partial_coordinates_offset_from_gerber(
x_as_int: Option<i64>,
y_as_int: Option<i64>,
fs: CoordinateFormat,
) -> Result<Option<CoordinateOffset>, GerberError> {
let factor = (6u8 - fs.decimal) as u32;
let x = x_as_int
.map(|value| CoordinateNumber::new(value * 10i64.pow(factor)).validate(&fs))
.transpose()?;
let y = y_as_int
.map(|value| CoordinateNumber::new(value * 10i64.pow(factor)).validate(&fs))
.transpose()?;
let coordinate_offset = match (x, y) {
(None, None) => None,
(x, y) => Some(CoordinateOffset::new(x, y, fs)),
};
Ok(coordinate_offset)
}