use layout21utils::SerializationFormat;
use std::error::Error;
pub struct ConvOptions {
pub gds: String,
pub fmt: String,
pub out: String,
pub verbose: bool,
}
fn parse_format(format: &str) -> Result<SerializationFormat, Box<dyn Error>> {
match format {
"json" => Ok(SerializationFormat::Json),
"yaml" => Ok(SerializationFormat::Yaml),
"toml" => Err(format!(
"TOML is not yet supported, see https://github.com/dan-fritchman/Layout21/issues/33"
)
.into()),
_ => Err(format!(
"Invalid format: {}. Must be one of (json, yaml, toml).",
format
)
.into()),
}
}
pub fn convert(options: &ConvOptions) -> Result<(), Box<dyn Error>> {
let gds_library = match gds21::GdsLibrary::load(&options.gds) {
Err(err) => panic!("Couldn't interpret GDS data: {}", err),
Ok(lib) => lib,
};
if options.verbose {
let gds_stats = gds_library.stats();
println!("{:?}", gds_stats);
}
let fmt: SerializationFormat = parse_format(&options.fmt)?;
match fmt.save(&gds_library, &options.out) {
Err(err) => panic!("Could not save output file: {}", err),
Ok(_) => {}
};
if options.verbose {
println!("wrote {:?}", &options.out);
}
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
fn test_fmt(fmtstr: &str) {
let output_path = scratch(&format!("sky130_fd_sc_hd__dfxtp_1.test_output.{}", fmtstr));
let golden_output_path =
resource(&format!("sky130_fd_sc_hd__dfxtp_1.golden.gds.{}", fmtstr));
let options = ConvOptions {
gds: resource("sky130_fd_sc_hd__dfxtp_1.gds"),
out: output_path.clone(),
fmt: fmtstr.to_string(),
verbose: true,
};
let result = convert(&options);
assert!(result.is_ok());
let bytes = std::fs::read(&output_path).unwrap();
let golden_bytes = std::fs::read(&golden_output_path).unwrap();
assert_eq!(golden_bytes, bytes);
}
#[test]
fn golden_json() {
test_fmt("json");
}
#[test]
fn golden_yaml() {
test_fmt("yaml");
}
#[test]
#[ignore] fn golden_toml() {
test_fmt("toml");
}
fn resource(rname: &str) -> String {
format!("{}/resources/{}", env!("CARGO_MANIFEST_DIR"), rname)
}
fn scratch(rname: &str) -> String {
format!("{}/scratch/{}", env!("CARGO_MANIFEST_DIR"), rname)
}
}