use crate::context::Context;
use crate::schematic::conv::RawLib;
use crate::schematic::Schematic;
use scir::{Library, NetlistLibConversion};
use std::io::Write;
use std::path::Path;
use std::sync::Arc;
use substrate::schematic::schema::Schema;
pub trait ConvertibleNetlister<S: Schema + ?Sized> {
type Error: Into<substrate::error::Error>;
type Options<'a>;
fn write_scir_netlist<W: Write>(
&self,
lib: &Library<S>,
out: &mut W,
opts: Self::Options<'_>,
) -> Result<NetlistLibConversion, Self::Error>;
fn write_scir_netlist_to_file(
&self,
lib: &Library<S>,
path: impl AsRef<Path>,
opts: Self::Options<'_>,
) -> substrate::error::Result<NetlistLibConversion> {
let path = path.as_ref();
if let Some(parent) = path.parent() {
std::fs::create_dir_all(parent).map_err(Arc::new)?;
}
let mut f = std::fs::File::create(path).map_err(Arc::new)?;
let conv = self
.write_scir_netlist(lib, &mut f, opts)
.map_err(|e| e.into())?;
Ok(conv)
}
fn write_netlist<B: Schematic<S>, W: Write>(
&self,
ctx: &Context,
block: B,
out: &mut W,
opts: Self::Options<'_>,
) -> substrate::error::Result<(RawLib<S>, NetlistLibConversion)> {
let raw_lib = ctx.export_scir::<S, _>(block)?;
let conv = self
.write_scir_netlist(&raw_lib.scir, out, opts)
.map_err(|e| e.into())?;
Ok((raw_lib, conv))
}
fn write_netlist_to_file<B: Schematic<S>>(
&self,
ctx: &Context,
block: B,
path: impl AsRef<Path>,
opts: Self::Options<'_>,
) -> substrate::error::Result<(RawLib<S>, NetlistLibConversion)> {
let path = path.as_ref();
if let Some(parent) = path.parent() {
std::fs::create_dir_all(parent).map_err(Arc::new)?;
}
let mut f = std::fs::File::create(path).map_err(Arc::new)?;
self.write_netlist(ctx, block, &mut f, opts)
}
}