use std::path::{Path, PathBuf};
use ts_rs::{Dependency, ExportError, TypeVisitor, TS};
struct TypeListExporter {
out_dir: PathBuf,
dependencies: Vec<Dependency>,
}
impl TypeListExporter {
pub fn new(out_dir: impl AsRef<Path>) -> Self {
Self {
out_dir: out_dir.as_ref().to_owned(),
dependencies: Vec::new(),
}
}
pub fn into_inner(self) -> Vec<Dependency> {
self.dependencies
}
}
impl TypeVisitor for TypeListExporter {
fn visit<T: TS + 'static + ?Sized>(&mut self) {
let Some(dep) = Dependency::from_ty::<T>() else {
return;
};
if self.dependencies.contains(&dep) {
return;
}
self.dependencies.push(dep);
T::export_all_to(&self.out_dir)
.expect("type is not a primitive, so can initiate an export");
}
}
pub fn export_with_dependencies<T: 'static + TS>(
out_dir: impl AsRef<Path>,
) -> Result<Vec<Dependency>, ExportError> {
let mut exporter = TypeListExporter::new(&out_dir);
T::visit_dependencies(&mut exporter);
T::visit_generics(&mut exporter);
let mut dependencies = exporter.into_inner();
if T::output_path().is_some() {
T::export_all_to(&out_dir)?;
dependencies.push(Dependency::from_ty::<T>().expect("type is non-primitive"));
}
Ok(dependencies)
}