Skip to content

Commit 590f821

Browse files
wip: massive macro refactor
1 parent f391c08 commit 590f821

File tree

12 files changed

+594
-630
lines changed

12 files changed

+594
-630
lines changed

specta-macros/src/specta.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ pub fn attribute(item: proc_macro::TokenStream) -> syn::Result<proc_macro::Token
8888
let arg_signatures = function.sig.inputs.iter().map(|_| quote!(_));
8989

9090
let mut attrs = parse_attrs(&function.attrs)?;
91-
let common = crate::r#type::attr::CommonAttr::from_attrs(&mut attrs)?;
91+
let common = crate::r#type::attr::RustCAttr::from_attrs(&mut attrs)?;
9292

9393
let deprecated = common.deprecated_as_tokens();
9494
let docs = common.doc;

specta-macros/src/type/attr/common.rs

Lines changed: 0 additions & 121 deletions
This file was deleted.

specta-macros/src/type/attr/container.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,18 @@ use syn::Result;
44

55
use crate::utils::{Attribute, Inflection, impl_parse};
66

7-
use super::CommonAttr;
7+
use super::RustCAttr;
88

99
#[derive(Default, Clone)]
1010
pub struct ContainerAttr {
11-
pub rename_all: Option<Inflection>,
12-
pub rename: Option<TokenStream>,
13-
pub tag: Option<String>,
11+
// pub rename_all: Option<Inflection>,
12+
// pub rename: Option<TokenStream>,
13+
// pub tag: Option<String>,
1414
pub crate_name: Option<TokenStream>,
1515
pub inline: bool,
1616
pub remote: Option<TokenStream>,
1717
pub collect: Option<bool>,
18-
pub common: CommonAttr,
18+
pub common: RustCAttr,
1919

2020
// Struct only (we pass it anyway so enums get nice errors)
2121
pub transparent: bool,
@@ -51,7 +51,7 @@ impl_parse! {
5151
impl ContainerAttr {
5252
pub fn from_attrs(attrs: &mut Vec<Attribute>) -> Result<Self> {
5353
let mut result = Self::default();
54-
result.common = CommonAttr::from_attrs(attrs)?;
54+
result.common = RustCAttr::from_attrs(attrs)?;
5555
Self::try_from_attrs("specta", attrs, &mut result)?;
5656
Self::try_from_attrs("serde", attrs, &mut result)?;
5757
Self::try_from_attrs("repr", attrs, &mut result)?; // To handle `#[repr(transparent)]`

specta-macros/src/type/attr/field.rs

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,45 +2,44 @@ use proc_macro2::TokenStream;
22
use quote::ToTokens;
33
use syn::{Result, Type, TypePath};
44

5-
use crate::utils::{impl_parse, Attribute};
5+
use crate::utils::{Attribute, impl_parse};
66

7-
use super::CommonAttr;
7+
use super::RustCAttr;
88

99
#[derive(Default)]
1010
pub struct FieldAttr {
11-
pub rename: Option<TokenStream>,
1211
pub r#type: Option<Type>,
1312
pub inline: bool,
1413
pub skip: bool,
1514
pub optional: bool,
1615
pub flatten: bool,
17-
pub common: CommonAttr,
16+
pub common: RustCAttr,
1817
}
1918

2019
impl_parse! {
2120
FieldAttr(attr, out) {
22-
"rename" => {
23-
let attr = attr.parse_string()?;
24-
out.rename = out.rename.take().or_else(|| Some(
25-
attr.to_token_stream()
26-
))
27-
},
28-
"rename_from_path" => {
29-
let attr = attr.parse_path()?;
30-
out.rename = out.rename.take().or_else(|| Some({
31-
let expr = attr.to_token_stream();
32-
quote::quote!( #expr )
33-
}))
34-
},
21+
// "rename" => {
22+
// let attr = attr.parse_string()?;
23+
// out.rename = out.rename.take().or_else(|| Some(
24+
// attr.to_token_stream()
25+
// ))
26+
// },
27+
// "rename_from_path" => {
28+
// let attr = attr.parse_path()?;
29+
// out.rename = out.rename.take().or_else(|| Some({
30+
// let expr = attr.to_token_stream();
31+
// quote::quote!( #expr )
32+
// }))
33+
// },
3534
"type" => out.r#type = out.r#type.take().or(Some(Type::Path(TypePath {
3635
qself: None,
3736
path: attr.parse_path()?,
3837
}))),
3938
"inline" => out.inline = attr.parse_bool().unwrap_or(true),
4039
"skip" => out.skip = attr.parse_bool().unwrap_or(true),
41-
"skip_serializing" => out.skip = true,
42-
"skip_deserializing" => out.skip = true,
43-
"skip_serializing_if" => out.optional = true,
40+
// "skip_serializing" => out.skip = true,
41+
// "skip_deserializing" => out.skip = true,
42+
// "skip_serializing_if" => out.optional = true,
4443
// Specta only attribute
4544
"optional" => out.optional = attr.parse_bool().unwrap_or(true),
4645
"default" => out.optional = attr.parse_bool().unwrap_or(true),
@@ -51,7 +50,7 @@ impl_parse! {
5150
impl FieldAttr {
5251
pub fn from_attrs(attrs: &mut Vec<Attribute>) -> Result<Self> {
5352
let mut result = Self::default();
54-
result.common = CommonAttr::from_attrs(attrs)?;
53+
result.common = RustCAttr::from_attrs(attrs)?;
5554
Self::try_from_attrs("specta", attrs, &mut result)?;
5655
Self::try_from_attrs("serde", attrs, &mut result)?;
5756
Ok(result)

specta-macros/src/type/attr/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
pub use common::*;
21
pub use container::*;
3-
pub use field::*;
42
pub use r#enum::*;
3+
pub use field::*;
4+
pub use rustc::*;
55
pub use variant::*;
66

7-
mod common;
87
mod container;
98
mod r#enum;
109
mod field;
10+
mod rustc;
1111
mod variant;
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
use std::borrow::Cow;
2+
3+
use quote::quote;
4+
use syn::{Lit, Result};
5+
6+
use crate::utils::{Attribute, AttributeValue};
7+
8+
#[derive(Clone)]
9+
pub enum DeprecatedType {
10+
Deprecated,
11+
DeprecatedWithSince {
12+
since: Option<Cow<'static, str>>,
13+
note: Cow<'static, str>,
14+
},
15+
}
16+
17+
#[derive(Default, Clone)]
18+
pub struct RustCAttr {
19+
pub doc: String,
20+
pub deprecated: Option<DeprecatedType>,
21+
}
22+
23+
impl RustCAttr {
24+
pub fn from_attrs(attrs: &mut Vec<Attribute>) -> Result<Self> {
25+
let doc = attrs.extract_if(.., |attr| attr.key == "doc").try_fold(
26+
String::new(),
27+
|mut s, doc| {
28+
let doc = doc.parse_string()?;
29+
if !s.is_empty() {
30+
s.push_str("\n");
31+
}
32+
s.push_str(&doc);
33+
Ok(s) as syn::Result<_>
34+
},
35+
)?;
36+
37+
let mut deprecated = None;
38+
// if let Some(attr_value) = attrs.iter().filter(|attr| attr.key == "deprecated").next() {
39+
// match &attr_value.value {
40+
// Some(AttributeValue::Lit(lit)) => {
41+
// deprecated = Some(DeprecatedType::DeprecatedWithSince {
42+
// since: None,
43+
// note: match lit {
44+
// Lit::Str(s) => s.value().into(),
45+
// _ => return Err(syn::Error::new_spanned(lit, "expected string")),
46+
// },
47+
// });
48+
// }
49+
// Some(AttributeValue::Path(_)) => {
50+
// unreachable!("deprecated attribute can't be a path!")
51+
// }
52+
// Some(AttributeValue::Attribute { attr, .. }) => {
53+
// let since = attr
54+
// .iter()
55+
// .filter(|attr| attr.key == "since")
56+
// .next()
57+
// .and_then(|v| v.value.as_ref())
58+
// .and_then(|v| match v {
59+
// AttributeValue::Lit(lit) => Some(lit),
60+
// _ => None, // TODO: This should probs be an error
61+
// })
62+
// .and_then(|lit| match lit {
63+
// syn::Lit::Str(s) => Some(s.value()),
64+
// _ => None, // TODO: This should probs be an error
65+
// });
66+
67+
// let note = attr
68+
// .iter()
69+
// .filter(|attr| attr.key == "note")
70+
// .next()
71+
// .and_then(|v| match v.value.as_ref() {
72+
// Some(AttributeValue::Lit(lit)) => Some(lit),
73+
// _ => None, // TODO: This should probs be an error
74+
// })
75+
// .and_then(|lit| match lit {
76+
// syn::Lit::Str(s) => Some(s.value()),
77+
// _ => None, // TODO: This should probs be an error
78+
// })
79+
// .unwrap_or_default();
80+
81+
// deprecated = Some(DeprecatedType::DeprecatedWithSince {
82+
// // TODO: Use Cow's earlier rather than later
83+
// since: since.map(Into::into),
84+
// note: note.into(),
85+
// });
86+
// }
87+
// None => deprecated = Some(DeprecatedType::Deprecated),
88+
// }
89+
// };
90+
91+
Ok(RustCAttr { doc, deprecated })
92+
}
93+
94+
pub fn deprecated_as_tokens(&self) -> proc_macro2::TokenStream {
95+
match &self.deprecated {
96+
Some(DeprecatedType::Deprecated) => {
97+
quote!(Some(datatype::DeprecatedType::Deprecated))
98+
}
99+
Some(DeprecatedType::DeprecatedWithSince { since, note }) => {
100+
let since = since
101+
.as_ref()
102+
.map(|v| quote!(#v.into()))
103+
.unwrap_or(quote!(None));
104+
105+
quote!(Some(datatype::DeprecatedType::DeprecatedWithSince {
106+
since: #since,
107+
note: #note.into(),
108+
}))
109+
}
110+
None => quote!(None),
111+
}
112+
}
113+
}

specta-macros/src/type/attr/variant.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,17 @@ use proc_macro2::TokenStream;
22
use quote::ToTokens;
33
use syn::Result;
44

5-
use crate::utils::{impl_parse, Attribute, Inflection};
5+
use crate::utils::{Attribute, Inflection, impl_parse};
66

7-
use super::CommonAttr;
7+
use super::RustCAttr;
88

99
#[derive(Default)]
1010
pub struct VariantAttr {
1111
pub rename_all: Option<Inflection>,
1212
pub rename: Option<TokenStream>,
1313
pub skip: bool,
1414
pub inline: bool,
15-
pub common: CommonAttr,
15+
pub common: RustCAttr,
1616
}
1717

1818
impl_parse! {
@@ -29,7 +29,7 @@ impl_parse! {
2929
impl VariantAttr {
3030
pub fn from_attrs(attrs: &mut Vec<Attribute>) -> Result<Self> {
3131
let mut result = Self::default();
32-
result.common = CommonAttr::from_attrs(attrs)?;
32+
result.common = RustCAttr::from_attrs(attrs)?;
3333
Self::try_from_attrs("specta", attrs, &mut result)?;
3434
Self::try_from_attrs("serde", attrs, &mut result)?;
3535
Ok(result)

0 commit comments

Comments
 (0)