This commit is contained in:
Moritz Bischof
2020-12-19 03:58:35 +01:00
parent 48e805177f
commit e52c81470c
10 changed files with 41 additions and 46 deletions

View File

@@ -1,7 +1,7 @@
#![allow(dead_code)]
use serde::Serialize;
use ts_rs::{TS, export};
use ts_rs::{export, TS};
#[derive(Serialize, TS)]
#[ts(rename_all = "lowercase")]
@@ -44,9 +44,9 @@ mod export_ts {
}
}
// this will export [Role] to `role.ts` and [User] to `user.ts`.
// this will export [Role] to `role.ts` and [User] to `user.ts`.
// `export!` will also take care of including imports in typescript files.
export! {
Role => "role.ts",
User => "user.ts",
}
}

View File

@@ -30,7 +30,11 @@ pub(crate) fn r#enum(s: &ItemEnum) -> Result<DerivedTS> {
})
}
fn format_variant(formatted_variants: &mut Vec<String>, rename_all: &Option<Inflection>, variant: &Variant) -> Result<()> {
fn format_variant(
formatted_variants: &mut Vec<String>,
rename_all: &Option<Inflection>,
variant: &Variant,
) -> Result<()> {
let FieldAttr {
type_override,
rename,
@@ -38,7 +42,7 @@ fn format_variant(formatted_variants: &mut Vec<String>, rename_all: &Option<Infl
skip,
flatten,
} = FieldAttr::from_attrs(&variant.attrs)?;
match (skip, &type_override, inline, flatten) {
(true, ..) => return Ok(()),
(_, Some(_), ..) => syn_err!("`type_override` is not applicable to enum variants"),
@@ -52,7 +56,7 @@ fn format_variant(formatted_variants: &mut Vec<String>, rename_all: &Option<Infl
(None, None) => variant.ident.to_string(),
(None, Some(rn)) => rn.apply(&variant.ident.to_string()),
};
formatted_variants.push(format!("{:?}", name));
Ok(())
}
}

View File

@@ -17,7 +17,7 @@ struct DerivedTS {
inline: TokenStream,
decl: TokenStream,
inline_flattened: Option<TokenStream>,
dependencies: TokenStream
dependencies: TokenStream,
}
impl DerivedTS {
@@ -27,7 +27,7 @@ impl DerivedTS {
inline,
decl,
inline_flattened,
dependencies
dependencies,
} = self;
let inline_flattened = inline_flattened
.map(|t| {
@@ -48,7 +48,7 @@ impl DerivedTS {
#name.to_owned()
}
fn inline(indent: usize) -> String {
#inline
#inline
}
#inline_flattened
fn dependencies() -> Vec<(std::any::TypeId, String)> {

View File

@@ -42,11 +42,11 @@ pub(crate) fn newtype(s: &ItemStruct, i: &FieldsUnnamed) -> Result<DerivedTS> {
name,
dependencies: match inline {
true => quote! {
<#inner_ty as ts_rs::TS>::dependencies()
<#inner_ty as ts_rs::TS>::dependencies()
},
false => quote!{
false => quote! {
vec![(std::any::TypeId::of::<#inner_ty>(), <#inner_ty as ts_rs::TS>::name())]
}
}
},
},
})
}

View File

@@ -12,13 +12,13 @@ pub(crate) fn tuple(s: &ItemStruct, i: &FieldsUnnamed) -> Result<DerivedTS> {
}
let name = rename.unwrap_or_else(|| s.ident.to_string());
let mut formatted_fields = Vec::new();
let mut dependenciees = Vec::new();
for field in &i.unnamed {
format_field(&mut formatted_fields, &mut dependenciees, field)?;
}
Ok(DerivedTS {
inline: quote! {
format!(
@@ -72,16 +72,15 @@ fn format_field(
None if inline => quote!(<#ty as ts_rs::TS>::inline(0)),
None => quote!(<#ty as ts_rs::TS>::name()),
});
dependencies.push(match inline {
false => quote!{
false => quote! {
dependencies.push((std::any::TypeId::of::<#ty>(), <#ty as ts_rs::TS>::name()));
},
true => quote!{
true => quote! {
dependencies.append(&mut (<#ty as ts_rs::TS>::dependencies()));
}
},
});
Ok(())
}

View File

@@ -16,6 +16,6 @@ pub(crate) fn unit(s: &ItemStruct) -> Result<DerivedTS> {
decl: quote!(format!("export type {} = null;", #name)),
inline_flattened: None,
name,
dependencies: quote!(vec![])
dependencies: quote!(vec![]),
})
}

View File

@@ -4,9 +4,9 @@ use std::path::{Component, Path, PathBuf};
use crate::TS;
/// Expands to a test function which exports typescript bindings to one or multiple files when
/// Expands to a test function which exports typescript bindings to one or multiple files when
/// running `cargo test`.
/// If a type depends on an other type which is exported to a different file, an appropriate import
/// If a type depends on an other type which is exported to a different file, an appropriate import
/// will be included.
/// If a file already exists, it will be overriden.
/// Missing parent directories of the file(s) will be created.
@@ -34,8 +34,8 @@ macro_rules! export {
let manifest_var = std::env::var("CARGO_MANIFEST_DIR").unwrap();
let manifest_dir = std::path::Path::new(&manifest_var);
// {TypeId} -> {PathBuf}
// {TypeId} -> {PathBuf}
let mut files = std::collections::HashMap::new();
$(
let path = manifest_dir.join($l);
@@ -81,15 +81,15 @@ pub fn write_imports<T: TS, W: std::fmt::Write>(
.for_each(|(path, name)| {
imports.entry(path).or_insert_with(Vec::new).push(name);
});
for (path, types) in imports {
writeln!(out, "import {{{}}} from {:?};", types.join(", "), path).unwrap();
}
}
fn import_path(from: &Path, import: &Path) -> String {
let rel_path = diff_paths(import, from.parent().unwrap())
.expect("failed to calculate import path");
let rel_path =
diff_paths(import, from.parent().unwrap()).expect("failed to calculate import path");
match rel_path.components().next() {
Some(Component::Normal(_)) => format!("./{}", rel_path.to_string_lossy()),
_ => rel_path.to_string_lossy().into(),
@@ -111,9 +111,9 @@ fn import_path(from: &Path, import: &Path) -> String {
// Adapted from rustc's path_relative_from
// https://github.com/rust-lang/rust/blob/e1d0de82cc40b666b88d4a6d2c9dcbc81d7ed27f/src/librustc_back/rpath.rs#L116-L158
fn diff_paths<P, B>(path: P, base: B) -> Option<PathBuf>
where
P: AsRef<Path>,
B: AsRef<Path>,
where
P: AsRef<Path>,
B: AsRef<Path>,
{
let path = path.as_ref();
let base = base.as_ref();

View File

@@ -22,8 +22,8 @@ use std::fs::OpenOptions;
use std::io::{BufWriter, Write};
use std::path::Path;
pub use ts_rs_macros::TS;
use std::any::TypeId;
pub use ts_rs_macros::TS;
#[doc(hidden)]
pub mod export;
@@ -120,11 +120,10 @@ pub trait TS: 'static {
fn inline_flattened(#[allow(unused_variables)] indent: usize) -> String {
panic!("{} cannot be flattened", Self::name())
}
/// All type ids and typescript names of the types this type depends on.
/// This is used for resolving imports when using the `export!` macro.
fn dependencies() -> Vec<(TypeId, String)>;
/// Dumps the declaration of this type to a file.
/// If the file does not exist, it will be created.
@@ -146,7 +145,6 @@ pub trait TS: 'static {
}
}
macro_rules! impl_primitives {
($($($ty:ty),* => $l:literal),*) => { $($(
impl TS for $ty {

View File

@@ -5,10 +5,7 @@ use ts_rs::TS;
#[test]
fn test_tuple() {
type Tuple = (String, i32, (i32, i32));
assert_eq!(
"[string, number, [number, number]]",
Tuple::name()
);
assert_eq!("[string, number, [number, number]]", Tuple::name());
}
#[test]

View File

@@ -5,8 +5,5 @@ struct Unit;
#[test]
fn test() {
assert_eq!(
"export type Unit = null;",
Unit::decl()
)
}
assert_eq!("export type Unit = null;", Unit::decl())
}