Skip to content

Commit

Permalink
fixes #144 & #116
Browse files Browse the repository at this point in the history
  • Loading branch information
oscartbeaumont committed Sep 22, 2023
1 parent 44e4020 commit 70b834d
Show file tree
Hide file tree
Showing 22 changed files with 346 additions and 127 deletions.
6 changes: 3 additions & 3 deletions macros/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@ documentation = "https://docs.rs/specta/latest/specta"
keywords = ["async", "specta", "rspc", "typescript", "typesafe"]
categories = ["web-programming", "asynchronous"]

[lib]
proc-macro = true

[features]
serde = []
functions = []
export = []

[lib]
proc-macro = true

[dependencies]
Inflector = { version = "0.11.4", default-features = false }
itertools = "0.10.5"
Expand Down
1 change: 1 addition & 0 deletions macros/src/data_type_from/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ pub fn derive(input: proc_macro::TokenStream) -> syn::Result<proc_macro::TokenSt
#skip,
false,
false,
std::borrow::Cow::Borrowed(""),
t.#ident.into(),
)))
});
Expand Down
8 changes: 6 additions & 2 deletions macros/src/type/attr/container.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ pub struct ContainerAttr {
pub inline: bool,
pub remote: Option<TokenStream>,
pub export: Option<bool>,
pub doc: Vec<String>,
pub doc: String,
pub deprecated: Option<String>,

// Struct ony (we pass it anyway so enums get nice errors)
Expand Down Expand Up @@ -45,7 +45,11 @@ impl_parse! {
"export" => out.export = out.export.take().or(Some(attr.parse_bool().unwrap_or(true))),
"doc" => {
if attr.key == "doc" {
out.doc.push(attr.parse_string()?);
if !out.doc.is_empty() {
out.doc.push_str("\n");
}

out.doc.push_str(&attr.parse_string()?);
}
},
// TODO: Finish implementing by supporting the official `#[deprecated]` attribute: https://github.com/oscartbeaumont/specta/issues/32
Expand Down
13 changes: 12 additions & 1 deletion macros/src/type/attr/field.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ pub struct FieldAttr {
pub skip: bool,
pub optional: bool,
pub flatten: bool,
pub doc: String,
}

impl_parse! {
Expand Down Expand Up @@ -41,7 +42,16 @@ impl_parse! {
// Specta only attribute
"optional" => out.optional = attr.parse_bool().unwrap_or(true),
"default" => out.optional = attr.parse_bool().unwrap_or(true),
"flatten" => out.flatten = attr.parse_bool().unwrap_or(true)
"flatten" => out.flatten = attr.parse_bool().unwrap_or(true),
"doc" => {
if attr.key == "doc" {
if !out.doc.is_empty() {
out.doc.push_str("\n");
}

out.doc.push_str(&attr.parse_string()?);
}
},
}
}

Expand All @@ -51,6 +61,7 @@ impl FieldAttr {
Self::try_from_attrs("specta", attrs, &mut result)?;
#[cfg(feature = "serde")]
Self::try_from_attrs("serde", attrs, &mut result)?;
Self::try_from_attrs("doc", attrs, &mut result)?;
Ok(result)
}
}
11 changes: 11 additions & 0 deletions macros/src/type/attr/variant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ pub struct VariantAttr {
pub rename: Option<TokenStream>,
pub skip: bool,
pub inline: bool,
pub doc: String,
}

impl_parse! {
Expand All @@ -20,6 +21,15 @@ impl_parse! {
"skip_serializing" => out.skip = true,
"skip_deserializing" => out.skip = true,
"inline" => out.inline = attr.parse_bool().unwrap_or(true),
"doc" => {
if attr.key == "doc" {
if !out.doc.is_empty() {
out.doc.push_str("\n");
}

out.doc.push_str(&attr.parse_string()?);
}
},
}
}

Expand All @@ -29,6 +39,7 @@ impl VariantAttr {
Self::try_from_attrs("specta", attrs, &mut result)?;
#[cfg(feature = "serde")]
Self::try_from_attrs("serde", attrs, &mut result)?;
Self::try_from_attrs("doc", attrs, &mut result)?;
Ok(result)
}
}
7 changes: 6 additions & 1 deletion macros/src/type/enum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ pub fn parse_enum(
let skip = field_attrs.skip;
let optional = field_attrs.optional;
let flatten = field_attrs.flatten;
let doc = field_attrs.doc;

let generic_vars = construct_datatype(
format_ident!("gen"),
Expand All @@ -115,6 +116,7 @@ pub fn parse_enum(
#skip,
#optional,
#flatten,
#doc.into(),
{
#generic_vars

Expand Down Expand Up @@ -159,11 +161,13 @@ pub fn parse_enum(
let skip = field_attrs.skip;
let optional = field_attrs.optional;
let flatten = field_attrs.flatten;
let doc = field_attrs.doc;

Ok(quote!((#field_name.into(), #crate_ref::internal::construct::field(
#skip,
#optional,
#flatten,
#doc.into(),
{
#generic_vars

Expand All @@ -178,7 +182,8 @@ pub fn parse_enum(
};

let skip = attrs.skip;
Ok(quote!((#variant_name_str.into(), #crate_ref::internal::construct::enum_variant(#skip, #inner))))
let doc = attrs.doc;
Ok(quote!((#variant_name_str.into(), #crate_ref::internal::construct::enum_variant(#skip, #doc.into(), #inner))))
})
.collect::<syn::Result<Vec<_>>>()?;

Expand Down
7 changes: 2 additions & 5 deletions macros/src/type/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,10 +109,7 @@ pub fn derive(input: proc_macro::TokenStream) -> syn::Result<proc_macro::TokenSt
}
});

let comments = {
let comments = &container_attrs.doc;
quote!(vec![#(#comments.into()),*])
};
let comments = &container_attrs.doc;
let should_export = match container_attrs.export {
Some(export) => quote!(Some(#export)),
None => quote!(None),
Expand Down Expand Up @@ -153,7 +150,7 @@ pub fn derive(input: proc_macro::TokenStream) -> syn::Result<proc_macro::TokenSt
fn named_data_type(opts: #crate_ref::DefOpts, generics: &[#crate_ref::DataType]) -> #crate_ref::NamedDataType {
#crate_ref::internal::construct::named_data_type(
#name.into(),
#comments,
#comments.into(),
#deprecated,
SID,
IMPL_LOCATION,
Expand Down
5 changes: 4 additions & 1 deletion macros/src/type/struct.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ pub fn parse_struct(
let optional = field_attrs.optional;
let flatten = field_attrs.flatten;
let skip = field_attrs.skip;
let doc = field_attrs.doc;

let parent_inline = container_attrs
.inline
Expand Down Expand Up @@ -164,6 +165,7 @@ pub fn parse_struct(
#skip,
#optional,
#flatten,
#doc.into(),
{
#ty
}
Expand Down Expand Up @@ -197,10 +199,11 @@ pub fn parse_struct(
let optional = field_attrs.optional;
let flatten = field_attrs.flatten;
let skip = field_attrs.skip;
let doc = field_attrs.doc;
Ok(quote!({
#generic_vars

#crate_ref::internal::construct::field(#skip, #optional, #flatten, gen)
#crate_ref::internal::construct::field(#skip, #optional, #flatten, #doc.into(), gen)
}))
})
.collect::<syn::Result<Vec<TokenStream>>>()?;
Expand Down
8 changes: 7 additions & 1 deletion src/datatype/enum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ impl EnumType {
pub fn to_named(self, name: impl Into<Cow<'static, str>>) -> NamedDataType {
NamedDataType {
name: name.into(),
comments: vec![],
docs: Cow::Borrowed(""),
deprecated: None,
ext: None,
inner: DataType::Enum(self),
Expand Down Expand Up @@ -79,6 +79,8 @@ pub struct EnumVariant {
/// You might think, well why not apply this in the macro and just not emit the variant?
/// Well in Serde `A(String)` and `A(#[serde(skip)] (), String)` export as different Typescript types so the exporter needs runtime knowledge of this.
pub(crate) skip: bool,
/// Documentation comments for the field.
pub(crate) docs: Cow<'static, str>,
/// The type of the variant.
pub(crate) inner: EnumVariants,
}
Expand All @@ -88,6 +90,10 @@ impl EnumVariant {
self.skip
}

pub fn docs(&self) -> &Cow<'static, str> {
&self.docs
}

pub fn inner(&self) -> &EnumVariants {
&self.inner
}
Expand Down
10 changes: 10 additions & 0 deletions src/datatype/fields.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,16 @@ pub struct Field {
pub(crate) optional: bool,
/// Did the user apply a `#[serde(flatten)]` or `#[specta(flatten)]` attribute.
pub(crate) flatten: bool,
/// Documentation comments for the field.
pub(crate) docs: Cow<'static, str>,
pub(crate) ty: DataType,
}

impl Field {
pub fn skip(&self) -> bool {
self.skip
}

pub fn optional(&self) -> bool {
self.optional
}
Expand All @@ -27,6 +33,10 @@ impl Field {
self.flatten
}

pub fn docs(&self) -> &Cow<'static, str> {
&self.docs
}

pub fn ty(&self) -> &DataType {
&self.ty
}
Expand Down
4 changes: 3 additions & 1 deletion src/datatype/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ impl DataType {
pub fn to_named(self, name: impl Into<Cow<'static, str>>) -> NamedDataType {
NamedDataType {
name: name.into(),
comments: vec![],
docs: Cow::Borrowed(""),
deprecated: None,
ext: None,
inner: self,
Expand Down Expand Up @@ -163,11 +163,13 @@ impl<T: Into<DataType> + 'static> From<Vec<T>> for DataType {
},
EnumVariant {
skip: false,
docs: Cow::Borrowed(""),
inner: EnumVariants::Unnamed(UnnamedFields {
fields: vec![Field {
skip: false,
optional: false,
flatten: false,
docs: Cow::Borrowed(""),
ty,
}],
}),
Expand Down
6 changes: 3 additions & 3 deletions src/datatype/named.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ pub struct NamedDataType {
/// The name of the type
pub(crate) name: Cow<'static, str>,
/// Rust documentation comments on the type
pub(crate) comments: Vec<Cow<'static, str>>,
pub(crate) docs: Cow<'static, str>,
/// The Rust deprecated comment if the type is deprecated.
pub(crate) deprecated: Option<Cow<'static, str>>,
/// Extra information that comes from a real Rust type (using the `Type` macro).
Expand All @@ -51,8 +51,8 @@ impl NamedDataType {
&self.name
}

pub fn comments(&self) -> &Vec<Cow<'static, str>> {
&self.comments
pub fn docs(&self) -> &Cow<'static, str> {
&self.docs
}

pub fn deprecated(&self) -> Option<&Cow<'static, str>> {
Expand Down
2 changes: 1 addition & 1 deletion src/datatype/struct.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ impl StructType {
pub fn to_named(self, name: impl Into<Cow<'static, str>>) -> NamedDataType {
NamedDataType {
name: name.into(),
comments: vec![],
docs: Cow::Borrowed(""),
deprecated: None,
ext: None,
inner: DataType::Struct(self),
Expand Down
2 changes: 1 addition & 1 deletion src/datatype/tuple.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ impl TupleType {
pub fn to_named(self, name: impl Into<Cow<'static, str>>) -> NamedDataType {
NamedDataType {
name: name.into(),
comments: vec![],
docs: Cow::Borrowed(""),
deprecated: None,
ext: None,
inner: DataType::Tuple(self),
Expand Down
21 changes: 16 additions & 5 deletions src/internal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,18 @@ pub mod construct {

use crate::{datatype::*, ImplLocation, SpectaID};

pub const fn field(skip: bool, optional: bool, flatten: bool, ty: DataType) -> Field {
pub const fn field(
skip: bool,
optional: bool,
flatten: bool,
docs: Cow<'static, str>,
ty: DataType,
) -> Field {
Field {
skip,
optional,
flatten,
docs,
ty,
}
}
Expand Down Expand Up @@ -68,8 +75,12 @@ pub mod construct {
}
}

pub const fn enum_variant(skip: bool, inner: EnumVariants) -> EnumVariant {
EnumVariant { skip, inner }
pub const fn enum_variant(
skip: bool,
docs: Cow<'static, str>,
inner: EnumVariants,
) -> EnumVariant {
EnumVariant { skip, docs, inner }
}

pub const fn enum_variant_unit() -> EnumVariants {
Expand All @@ -89,7 +100,7 @@ pub mod construct {

pub const fn named_data_type(
name: Cow<'static, str>,
comments: Vec<Cow<'static, str>>,
docs: Cow<'static, str>,
deprecated: Option<Cow<'static, str>>,
sid: SpectaID,
impl_location: ImplLocation,
Expand All @@ -98,7 +109,7 @@ pub mod construct {
) -> NamedDataType {
NamedDataType {
name,
comments,
docs,
deprecated,
ext: Some(NamedDataTypeExt {
sid,
Expand Down
Loading

0 comments on commit 70b834d

Please sign in to comment.