Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Option to rename source of TS trait #274

Merged
merged 11 commits into from
Mar 20, 2024
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
# master
### Breaking
### Features
- Add `#[ts(crate = "..")]` to allow usage of `#[derive(TS)]` from other proc-macro crates ([#274](https://github.com/Aleph-Alpha/ts-rs/pull/274))
### Fixes

# v8.0.0

### Breaking

Expand Down
3 changes: 2 additions & 1 deletion e2e/workspace/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
[workspace]
members = ["crate1", "crate2", "parent"]
members = ["crate1", "crate2", "parent", "renamed"]
resolver = "2"
7 changes: 7 additions & 0 deletions e2e/workspace/renamed/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[package]
name = "renamed"
version = "0.1.0"
edition = "2021"

[dependencies]
ts-renamed = { package = "ts-rs", path = "../../../ts-rs" }
12 changes: 12 additions & 0 deletions e2e/workspace/renamed/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
use ts_renamed::TS;

#[derive(TS)]
#[ts(crate = "ts_renamed", export)]
pub struct SimpleStruct {
hello: String,
world: u32,
}

fn main() {
println!("Hello, world!");
}
24 changes: 19 additions & 5 deletions macros/src/attr/enum.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
use std::collections::HashMap;

use syn::{Attribute, Ident, Result, Type, WherePredicate};
use syn::{parse_quote, Attribute, Ident, Path, Result, Type, WherePredicate};

use super::{parse_assign_from_str, parse_bound};
use crate::{
attr::{parse_assign_inflection, parse_assign_str, parse_concrete, Inflection},
utils::{parse_attrs, parse_docs},
};

use super::parse_bound;

#[derive(Default)]
pub struct EnumAttr {
crate_rename: Option<Path>,
pub rename_all: Option<Inflection>,
pub rename_all_fields: Option<Inflection>,
pub rename: Option<String>,
Expand Down Expand Up @@ -61,9 +61,16 @@ impl EnumAttr {
Ok(result)
}

pub fn crate_rename(&self) -> Path {
self.crate_rename
.clone()
.unwrap_or_else(|| parse_quote!(::ts_rs))
}

fn merge(
&mut self,
EnumAttr {
crate_rename,
rename_all,
rename_all_fields,
rename,
Expand All @@ -77,6 +84,7 @@ impl EnumAttr {
bound,
}: EnumAttr,
) {
self.crate_rename = self.crate_rename.take().or(crate_rename);
self.rename = self.rename.take().or(rename);
self.rename_all = self.rename_all.take().or(rename_all);
self.rename_all_fields = self.rename_all_fields.take().or(rename_all_fields);
Expand All @@ -87,15 +95,21 @@ impl EnumAttr {
self.export_to = self.export_to.take().or(export_to);
self.docs = docs;
self.concrete.extend(concrete);
self.bound = self.bound
self.bound = self
.bound
.take()
.map(|b| b.into_iter().chain(bound.clone().unwrap_or_default()).collect())
.map(|b| {
b.into_iter()
.chain(bound.clone().unwrap_or_default())
.collect()
})
.or(bound);
}
}

impl_parse! {
EnumAttr(input, out) {
"crate" => out.crate_rename = Some(parse_assign_from_str(input)?),
"rename" => out.rename = Some(parse_assign_str(input)?),
"rename_all" => out.rename_all = Some(parse_assign_inflection(input)?),
"rename_all_fields" => out.rename_all_fields = Some(parse_assign_inflection(input)?),
Expand Down
7 changes: 4 additions & 3 deletions macros/src/attr/mod.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
use std::{collections::HashMap, convert::TryFrom};
use std::collections::HashMap;

pub use field::*;
pub use r#enum::*;
pub use r#struct::*;
use syn::{
parse::{Parse, ParseStream},
Error, Lit, Result, Token, WherePredicate, punctuated::Punctuated,
punctuated::Punctuated,
Error, Lit, Result, Token, WherePredicate,
};
pub use variant::*;

Expand Down Expand Up @@ -136,7 +137,7 @@ fn parse_bound(input: ParseStream) -> Result<Vec<WherePredicate>> {
let parser = Punctuated::<WherePredicate, Token![,]>::parse_terminated;

Ok(string.parse_with(parser)?.into_iter().collect())
},
}
other => Err(Error::new(other.span(), "expected string")),
}
}
54 changes: 32 additions & 22 deletions macros/src/attr/struct.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
use std::{collections::HashMap, convert::TryFrom};
use std::collections::HashMap;

use syn::{Attribute, Ident, Result, Type, WherePredicate};
use syn::{parse_quote, Attribute, Ident, Path, Result, Type, WherePredicate};

use super::{parse_assign_from_str, parse_bound, parse_concrete};
use crate::attr::EnumAttr;
use crate::{
attr::{parse_assign_str, parse_concrete, Inflection, VariantAttr},
attr::{parse_assign_str, Inflection, VariantAttr},
utils::{parse_attrs, parse_docs},
};

use super::parse_bound;

#[derive(Default, Clone)]
pub struct StructAttr {
crate_rename: Option<Path>,
pub rename_all: Option<Inflection>,
pub rename: Option<String>,
pub export_to: Option<String>,
Expand Down Expand Up @@ -38,9 +39,26 @@ impl StructAttr {
Ok(result)
}

pub fn from_variant(enum_attr: &EnumAttr, variant_attr: &VariantAttr) -> Self {
Self {
crate_rename: Some(enum_attr.crate_rename()),
rename: variant_attr.rename.clone(),
rename_all: variant_attr.rename_all,
// inline and skip are not supported on StructAttr
..Self::default()
}
}

pub fn crate_rename(&self) -> Path {
self.crate_rename
.clone()
.unwrap_or_else(|| parse_quote!(::ts_rs))
}

fn merge(
&mut self,
StructAttr {
crate_rename,
rename_all,
rename,
export,
Expand All @@ -51,37 +69,29 @@ impl StructAttr {
bound,
}: StructAttr,
) {
self.crate_rename = self.crate_rename.take().or(crate_rename);
self.rename = self.rename.take().or(rename);
self.rename_all = self.rename_all.take().or(rename_all);
self.export_to = self.export_to.take().or(export_to);
self.export = self.export || export;
self.tag = self.tag.take().or(tag);
self.docs = docs;
self.concrete.extend(concrete);
self.bound = self.bound
self.bound = self
.bound
.take()
.map(|b| b.into_iter().chain(bound.clone().unwrap_or_default()).collect())
.map(|b| {
b.into_iter()
.chain(bound.clone().unwrap_or_default())
.collect()
})
.or(bound);
}
}

impl From<VariantAttr> for StructAttr {
fn from(
VariantAttr {
rename, rename_all, ..
}: VariantAttr,
) -> Self {
Self {
rename,
rename_all,
// inline and skip are not supported on StructAttr
..Self::default()
}
}
}

impl_parse! {
StructAttr(input, out) {
"crate" => out.crate_rename = Some(parse_assign_from_str(input)?),
"rename" => out.rename = Some(parse_assign_str(input)?),
"rename_all" => out.rename_all = Some(parse_assign_str(input).and_then(Inflection::try_from)?),
"tag" => out.tag = Some(parse_assign_str(input)?),
Expand Down
20 changes: 15 additions & 5 deletions macros/src/deps.rs
Original file line number Diff line number Diff line change
@@ -1,26 +1,35 @@
use proc_macro2::TokenStream;
use quote::{quote, ToTokens};
use syn::Type;
use syn::{Path, Type};

#[derive(Default)]
pub struct Dependencies {
dependencies: Vec<TokenStream>,
crate_rename: Path,
pub types: Vec<Type>,
}

impl Dependencies {
pub fn new(crate_rename: Path) -> Self {
Self {
dependencies: Vec::default(),
crate_rename,
types: Vec::default(),
}
}
/// Adds all dependencies from the given type
pub fn append_from(&mut self, ty: &Type) {
let crate_rename = &self.crate_rename;
self.dependencies
.push(quote![.extend(<#ty as ::ts_rs::TS>::dependency_types())]);
.push(quote![.extend(<#ty as #crate_rename::TS>::dependency_types())]);
self.types.push(ty.clone());
}

/// Adds the given type.
pub fn push(&mut self, ty: &Type) {
let crate_rename = &self.crate_rename;
self.dependencies.push(quote![.push::<#ty>()]);
self.dependencies.push(quote![
.extend(<#ty as ::ts_rs::TS>::generics())
.extend(<#ty as #crate_rename::TS>::generics())
]);
self.types.push(ty.clone());
}
Expand All @@ -33,9 +42,10 @@ impl Dependencies {

impl ToTokens for Dependencies {
fn to_tokens(&self, tokens: &mut TokenStream) {
let crate_rename = &self.crate_rename;
let lines = &self.dependencies;
tokens.extend(quote![{
use ::ts_rs::typelist::TypeList;
use #crate_rename::typelist::TypeList;
()#(#lines)*
}])
}
Expand Down