Skip to content

Commit

Permalink
Option to rename source of TS trait (#274)
Browse files Browse the repository at this point in the history
Add #[ts(crate = ..)] attribute 

---------

Co-authored-by: Gustavo <gustavo.shigueo@proton.me>
Co-authored-by: Moritz Bischof <moritz.bischof1@gmail.com>
  • Loading branch information
3 people authored Mar 20, 2024
1 parent a2feac5 commit 77f224e
Show file tree
Hide file tree
Showing 16 changed files with 201 additions and 84 deletions.
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
Loading

0 comments on commit 77f224e

Please sign in to comment.