Skip to content

Commit

Permalink
Changed idents (core and protocol)
Browse files Browse the repository at this point in the history
  • Loading branch information
viktorlott committed Jan 16, 2023
1 parent 800db63 commit f590a44
Show file tree
Hide file tree
Showing 6 changed files with 138 additions and 124 deletions.
18 changes: 9 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

`Typed` is a procedural macro that is used for disassembling `structs`, `enums` and `fns` into their inner `type` components that are then accompanied with documentation and examples. The `Typed` structures will be wrapped into a module and reassigned with a name (default `ty`), this also goes for the `static` and `generic` fields.
`Typed` is a procedural macro that is used for disassembling `structs`, `enums` and `fns` into their inner `type` components that are then accompanied with documentation and examples. The `Typed` structures will be wrapped into a module and reassigned with a name (default `core`), this also goes for the `static` and `generic` fields.


#### *Project is still under development*
Expand Down Expand Up @@ -28,7 +28,7 @@ pub mod #name {
// Docs (/w examples) describing the original `item`.
#[doc = #docs]
// The original `ìtem`.
#struct_original // Access through `#name::ty`
#struct_original // Access through `#name::core`
}
```

Expand All @@ -48,19 +48,19 @@ struct Area(i32);
```rust
let current: Container::current = 10;
let buffer: Container::buffer = vec![current];
let another: <Container::ty<u8> as Container::proto>::another = 20;
let container: Container::ty<u8> =
Container::ty {
let another: <Container::core<u8> as Container::protocol>::another = 20;
let container: Container::core<u8> =
Container::core {
current,
buffer,
another
};
```
- It's also possible to use it as following:
```rust
trait Trait: Container::proto {
fn retrieve(&self) -> Container::proto::buffer;
fn extend(&mut self, val: Container::proto::another);
trait Trait: Container::protocol {
fn retrieve(&self) -> Container::protocol::buffer;
fn extend(&mut self, val: Container::protocol::another);
}
```

Expand All @@ -81,7 +81,7 @@ fn main() {
another: 20,
}

let y: MContainer::ty<i32> = x;
let y: MContainer::core<i32> = x;
}
```

135 changes: 35 additions & 100 deletions src/builder.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::tools::{doc_struct, doc_type, format_code, publicify_and_docify, get_generic_idents, new, ident};
use proc_macro::TokenStream;
use proc_macro2::TokenStream as TokenStream2;
use quote::{format_ident, quote, ToTokens, TokenStreamExt};
Expand All @@ -10,79 +11,6 @@ use syn::{
Attribute, Fields, Generics, Ident, Token, Type, Visibility,
};

use tools::{doc_struct, doc_type, format_code, publicify_and_docify};

#[path = "tools.rs"]
mod tools;

/// Use `new!(..)` to construct `structs`.
/// - `clone[$ident,*]` -> `$ident.clone(),*`
/// - `string[$ident,*]` -> `$ident.to_string(),*`
/// - `into[$ident,*]` -> `$ident.into(),*`
/// - `$ident($tt)` -> `$ident: $tt`
///
/// # Example
/// ```no_run
/// struct TypeStructure {
/// attrs: Vec<Attribute>,
/// vis: Visibility,
/// struct_token: Token![struct],
/// ident: Ident,
/// generics: Generics,
/// fields: Fields,
/// semi_colon: Option<Token![;]>,
/// }
///
/// let attrs = ...;
/// let generics ...;
///
/// let struct_decl = new!({
/// clone[attrs, generics],
/// vis(parse_quote!(pub)),
/// ident(format_ident!("ty", span = proc_macro2::Span::call_site())),
/// struct_token,
/// fields,
/// semi_colon,
/// }: TypeStructure);
/// ```
///
macro_rules! new {
// Invoke syntax
({ $($tail:tt)* } = $name:ident ) => { new!($name @ [] @ $($tail)*) };
({ $($tail:tt)* }: $name:ident ) => { new!($name @ [] @ $($tail)*) };
({ $($tail:tt)* } => $name:ident ) => { new!($name @ [] @ $($tail)*) };
({ $($tail:tt)* } $name:ident ) => { new!($name @ [] @ $($tail)*) };

($name:ident { $($tail:tt)* } ) => { new!($name @ [] @ $($tail)*) };
($name:ident => { $($tail:tt)* } ) => { new!($name @ [] @ $($tail)*) };
($name:ident: { $($tail:tt)* } ) => { new!($name @ [] @ $($tail)*) };
($name:ident = { $($tail:tt)* } ) => { new!($name @ [] @ $($tail)*) };

($name:ident => $($tail:tt)* ) => { new!($name @ [] @ $($tail)*) };
($name:ident: $($tail:tt)* ) => { new!($name @ [] @ $($tail)*) };
($name:ident = $($tail:tt)* ) => { new!($name @ [] @ $($tail)*) };


// Grammer
($name:ident @ [$($stored:tt)*] @ $(.)? into $(.)? [$($field:ident),*] $(, $($tail:tt)*)?) => { new!($name @ [$(, $stored)* $($field: $field.into()),*] @ $($($tail)*)? ) };
($name:ident @ [$($stored:tt)*] @ $(.)? string $(.)? [$($field:ident),*] $(, $($tail:tt)*)?) => { new!($name @ [$(, $stored)* $($field: $field.to_string()),*] @ $($($tail)*)? ) };
($name:ident @ [$($stored:tt)*] @ $(.)? str $(.)? [$($field:ident),*] $(, $($tail:tt)*)?) => { new!($name @ [$(, $stored)* $($field: $field.as_str()),*] @ $($($tail)*)? ) };


($name:ident @ [$($stored:tt)*] @ $(.)? clone $(.)? [$($field:ident),*] $(, $($tail:tt)*)?) => { new!($name @ [$(, $stored)* $($field: $field.clone()),*] @ $($($tail)*)? ) };
($name:ident @ [$($stored:tt)*] @ $field:ident: $field2:ident $(, $($tail:tt)*)?) => { new!($name @ [$($stored)*, $field: $field2] @ $($($tail)*)? ) };

($name:ident @ [$($stored:tt)*] @ $field:ident ($($sym:tt)*) $(, $($tail:tt)*)?) => { new!($name @ [$field: $($sym)*, $($stored)*] @ $($($tail)*)? ) };

($name:ident @ [$($stored:tt)*] @ $field:ident $(, $($tail:tt)*)?) => { new!($name @ [$field, $($stored)*] @ $($($tail)*)? ) };
($name:ident @ [$($stored:tt)*] @ .. $(, $($tail:tt)*)?) => { new!(@ [.., $($stored)*] @ $($($tail)*)? ) };
($name:ident @ [$($stored:tt)*] @ ) => { $name { $($stored)* } };

}

macro_rules! ident {
($name:tt) => {format_ident!($name, span = proc_macro2::Span::call_site())};
}

struct TypeModule {
attrs: Vec<Attribute>,
Expand All @@ -106,10 +34,12 @@ struct TypeAlias {
}

struct TypeGeneric {
#[allow(dead_code)]
attrs: Vec<Attribute>,
ident: Ident,
generics: Generics,
assoc_decls: Vec<TypeAlias>,
type_struct_ident: Ident,
}

struct TypeStructure {
Expand Down Expand Up @@ -149,6 +79,7 @@ impl Parse for TypeModule {
fn parse(input: ParseStream) -> syn::Result<Self> {
let code = format_code(input.to_string());


let mut attrs: Vec<Attribute> = input.call(Attribute::parse_outer)?;
let vis: Visibility = input.parse()?;
let struct_token: Token![struct] = input.parse()?;
Expand All @@ -159,26 +90,26 @@ impl Parse for TypeModule {

let mut type_decls: Vec<TypeAlias> = Vec::new();

let fields: Fields = parse_fields(input, |fields| {
let fields: Fields = parse_fields(input, |fields|
type_decls = parse_type_decls(fields, &generics, &source)
})?;
)?;

let struct_doc = doc_struct(source.name.as_str(), source.code.as_str());
attrs.push(parse_quote!(#[doc = #struct_doc]));

let struct_decl = new!({
clone[attrs, generics],
vis(parse_quote!(pub)),
ident(ident!("ty")),
ident(ident!("core")),
semi_colon(input.peek(Token![;]).then(|| input.parse().ok()).flatten()),
struct_token,
fields,
fields,
}: TypeStructure);


let generic_decl = new!({
clone[attrs],
ident(ident!("gen")),
ident(ident!("protocol")),
type_struct_ident(ident!("core")),
assoc_decls(type_decls.to_vec()),
generics,
}: TypeGeneric);
Expand Down Expand Up @@ -209,7 +140,6 @@ impl ToTokens for TypeModule {
#![allow(non_camel_case_types)]

#module_inner

}
);

Expand All @@ -219,17 +149,19 @@ impl ToTokens for TypeModule {

impl ToTokens for TypeModuleInner {
fn to_tokens(&self, tokens: &mut TokenStream2) {
let type_delcs: Vec<TypeAlias> = self
let type_decls: Vec<TypeAlias> = self
.type_decls
.iter()
.filter_map(|t| t.has_gen.then(|| t.clone()))
.collect();

let type_decls = quote!(#(#type_decls)*);

let struct_decl = &self.struct_decl;
let generic_decl = &self.generic_decl;

let inner_decls = quote!(
#(#type_delcs)*
#type_decls

#struct_decl

Expand All @@ -243,7 +175,10 @@ impl ToTokens for TypeModuleInner {
impl ToTokens for TypeAlias {
fn to_tokens(&self, tokens: &mut TokenStream2) {
let TypeAlias {
docs, ident, ty, ..
docs,
ident,
ty,
..
} = self;

tokens.append_all(quote!(#docs pub type #ident = #ty;));
Expand All @@ -252,7 +187,8 @@ impl ToTokens for TypeAlias {

impl ToTokens for TypeGeneric {
fn to_tokens(&self, tokens: &mut TokenStream2) {
let trait_ident = &self.ident;
let TypeGeneric { ident: trait_ident, type_struct_ident , .. } = self;

let (impl_generics, ty_generics, where_clause) = self.generics.split_for_impl();

let mut assoc_decls = Vec::<TokenStream2>::new();
Expand All @@ -277,13 +213,13 @@ impl ToTokens for TypeGeneric {

tokens.append_all(quote!(
pub trait #trait_ident {
type __Bind: #trait_ident #bind_generic;
type __Core: #trait_ident #bind_generic;

#(#assoc_decls)*
}

impl #impl_generics #trait_ident for ty #ty_generics #where_clause {
type __Bind = Self;
impl #impl_generics #trait_ident for #type_struct_ident #ty_generics #where_clause {
type __Core = Self;
#(#assoc_impl_decls)*
}
));
Expand All @@ -292,17 +228,19 @@ impl ToTokens for TypeGeneric {

impl ToTokens for TypeStructure {
fn to_tokens(&self, tokens: &mut TokenStream2) {
let attrs = &self.attrs;
let visibility = &self.vis;
let struct_token = &self.struct_token;
let ident = &self.ident;
let generics = &self.generics;
let fields = &self.fields;
let semi_colon = &self.semi_colon;

let TypeStructure {
attrs,
vis,
struct_token,
ident,
generics,
fields,
semi_colon
} = self;

let struct_decl = quote!(
#(#attrs)*
#visibility #struct_token #ident #generics #fields #semi_colon
#vis #struct_token #ident #generics #fields #semi_colon
);

tokens.append_all(struct_decl);
Expand Down Expand Up @@ -339,10 +277,7 @@ where
fn parse_type_decls(fields: &mut Fields, generics: &Generics, source: &Source) -> Vec<TypeAlias> {
let mut type_decls: Vec<TypeAlias> = Vec::new();

let param_generics = generics
.type_params()
.map(|tp| tp.ident.clone())
.collect::<HashSet<Ident>>();
let param_generics = get_generic_idents(generics);

for (index, field) in fields.iter_mut().enumerate() {
let field_type_generics = FieldTypeGenerics::get_idents(&field.ty);
Expand Down
6 changes: 3 additions & 3 deletions src/docs/struct.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
Use `{name}::ty` as a type.
Use `{name}::core` as a type.
```no_run
{source_code}
```
# Example
```no_run
fn get(input: {name}::ty) -> {name}::ty {{
let field: {name}::ty = input;
fn get(input: {name}::core) -> {name}::core {{
let field: {name}::core = input;
input
}}
```
9 changes: 5 additions & 4 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use proc_macro::TokenStream;

mod tools;
mod builder;

/// Use `type_it` as a proc-macro.
Expand All @@ -20,17 +21,17 @@ mod builder;
/// ```no_run
/// let current: Container::current = 10;
/// let buffer: Container::buffer = vec![current];
/// let another: <Container::ty<u8> as Container::proto>::another = 20;
/// let container: Container::ty<u8> =
/// Container::ty {
/// let another: <Container::core<u8> as Container::proto>::another = 20;
/// let container: Container::core<u8> =
/// Container::core {
/// current,
/// buffer,
/// another
/// };
/// ```
/// - It's also possible to use it as following:
/// ```no_run
/// trait Trait: Container::proto {
/// trait Trait: Container::protocol {
/// fn retrieve(&self) -> Container::proto::buffer;
/// fn extend(&mut self, val: Container::proto::another);
/// }
Expand Down

0 comments on commit f590a44

Please sign in to comment.