use crate::ts::{ExportConfiguration, TsExportError};
use crate::*;
use once_cell::sync::Lazy;
use std::collections::{BTreeMap, BTreeSet};
use std::sync::Mutex;
pub static TYPES: Lazy<Mutex<(TypeDefs, BTreeSet<ExportError>)>> = Lazy::new(Default::default);
pub fn ts(path: &str) -> Result<(), TsExportError> {
ts_with_cfg(path, &ExportConfiguration::default())
}
pub fn ts_with_cfg(path: &str, conf: &ExportConfiguration) -> Result<(), TsExportError> {
let mut out = "// This file has been generated by Specta. DO NOT EDIT.\n\n".to_string();
let export_by_default = conf.export_by_default.unwrap_or(true);
let types = TYPES.lock().expect("Failed to acquire lock on 'TYPES'");
if let Some(err) = types.1.iter().next() {
return Err(err.clone().into());
}
let types = types
.0
.clone()
.into_iter()
.filter(|(_, v)| match v {
Some(v) => v.export.unwrap_or(export_by_default),
None => {
unreachable!("Placeholder type should never be returned from the Specta functions!")
}
})
.collect::<BTreeMap<_, _>>();
let mut map = BTreeMap::new();
for (sid, dt) in &types {
match dt {
Some(dt) => {
if let Some((existing_sid, existing_impl_location)) =
map.insert(dt.name, (sid, dt.impl_location))
{
if existing_sid != sid {
return Err(TsExportError::DuplicateTypeName(
dt.name,
dt.impl_location,
existing_impl_location,
));
}
}
}
None => unreachable!(),
}
}
for (_, typ) in types {
out += &ts::export_datatype(
conf,
&match typ {
Some(v) => v,
None => unreachable!(),
},
)?;
out += "\n\n";
}
std::fs::write(path, out).map_err(Into::into)
}