Skip to content

Commit

Permalink
mild refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
Artem-Romanenia committed Jul 24, 2024
1 parent 1b4be6e commit c037365
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 136 deletions.
133 changes: 41 additions & 92 deletions o2o-impl/src/attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ use std::ops::Index;

use proc_macro2::{TokenStream, Span};
use quote::{quote, ToTokens};
use syn::parse::{ParseStream, Parse};
use syn::parse::{ParseStream, Parse, ParseBuffer};
use syn::punctuated::Punctuated;
use syn::spanned::Spanned;
use syn::token::{Brace, Paren};
use syn::token::{Brace, Paren, Comma};
use syn::{Attribute, Ident, Result, Token, Member, parenthesized, braced, WherePredicate, Error};

use crate::ast::SynDataTypeMember;
Expand Down Expand Up @@ -548,57 +548,44 @@ impl Parse for TraitAttrCore {
}
}

fn parse_trait_instruction_param_inner_1<T: Parse>(input: &syn::parse::ParseBuffer, condition: bool, setter: impl FnOnce(), span: impl Fn(T) -> Span, name: &str) -> Result<bool> {
let a = input.parse::<T>()?;
if input.peek(Token![,]) {
input.parse::<Token![,]>()?;
}
if condition {
Err(syn::Error::new(span(a), format!("Instruction parameter '{}' was already set.", name)))?
} else {
setter();
return Ok(true)
}
}

fn parse_trait_instruction_param_inner_2<T: Parse, U>(input: &syn::parse::ParseBuffer, parser: impl Fn(ParseBuffer) -> Result<U>, condition: bool, setter: impl FnOnce(U), span: impl Fn(T) -> Span, name: &str) -> Result<bool> {
let a = input.parse::<T>()?;
let content;
parenthesized!(content in input);
let content = parser(content)?;
if input.peek(Token![,]) {
input.parse::<Token![,]>()?;
}
if condition {
Err(syn::Error::new(span(a), format!("Instruction parameter '{}' was already set.", name)))?
} else {
setter(content);
return Ok(true)
}
}

fn parse_trait_instruction_param(input: &syn::parse::ParseBuffer, attr: &mut TraitAttrCore) -> Result<bool> {
if input.peek(kw::stop_repeat) {
let a = input.parse::<kw::stop_repeat>()?;
if input.peek(Token![,]) {
input.parse::<Token![,]>()?;
}
if attr.stop_repeat {
Err(syn::Error::new(a.span, "Instruction parameter 'stop_repeat' was already set."))?
} else {
attr.stop_repeat = true;
return Ok(true)
}
return parse_trait_instruction_param_inner_1::<kw::stop_repeat>(input, attr.stop_repeat, || attr.stop_repeat = true, |a| a.span, "stop_repeat");
} else if input.peek(kw::skip_repeat) {
let a = input.parse::<kw::skip_repeat>()?;
if input.peek(Token![,]) {
input.parse::<Token![,]>()?;
}
if attr.skip_repeat {
Err(syn::Error::new(a.span, "Instruction parameter 'skip_repeat' was already set."))?
} else {
attr.skip_repeat = true;
return Ok(true)
}
return parse_trait_instruction_param_inner_1::<kw::skip_repeat>(input, attr.skip_repeat, || attr.skip_repeat = true, |a| a.span, "skip_repeat");
} else if input.peek(kw::repeat) {
let a = input.parse::<kw::repeat>()?;
let content;
parenthesized!(content in input);
let repeat = content.parse::<TraitRepeatForWrap>()?;
if input.peek(Token![,]) {
input.parse::<Token![,]>()?;
}
if attr.repeat.is_some() {
Err(syn::Error::new(a.span, "Instruction parameter 'repeat' was already set."))?
} else {
attr.repeat = Some(repeat.0);
return Ok(true)
}
return parse_trait_instruction_param_inner_2::<kw::repeat, TraitRepeatForWrap>(input, |c| c.parse(), attr.repeat.is_some(), |x|attr.repeat = Some(x.0), |a|a.span, "repeat");
} else if input.peek(kw::vars) {
let a = input.parse::<kw::vars>()?;
let content;
parenthesized!(content in input);
let vars = Some(Punctuated::parse_separated_nonempty(&content)?);
if input.peek(Token![,]) {
input.parse::<Token![,]>()?;
}
if attr.init_data.is_some() {
Err(syn::Error::new(a.span, "Instruction parameter 'vars' was already set."))?
} else {
attr.init_data = vars;
return Ok(true)
}
return parse_trait_instruction_param_inner_2::<kw::vars, Punctuated<InitData, Comma>>(input, |c| Punctuated::parse_separated_nonempty(&c), attr.init_data.is_some(), |x|attr.init_data = Some(x), |a|a.span, "vars");
} else if input.peek(Token![..]) {
input.parse::<Token![..]>()?;
attr.update = try_parse_action(input, true)?;
Expand All @@ -612,49 +599,11 @@ fn parse_trait_instruction_param(input: &syn::parse::ParseBuffer, attr: &mut Tra
attr.default_case = try_parse_action(input, true)?;
return Ok(false)
} else if input.peek(kw::attribute) {
let a = input.parse::<kw::attribute>()?;
let content;
parenthesized!(content in input);
let attribute = content.parse::<TokenStream>()?;
if input.peek(Token![,]) {
input.parse::<Token![,]>()?;
}
if attr.attribute.is_some() {
Err(syn::Error::new(a.span, "Instruction parameter 'attribute' was already set."))?
} else {
attr.attribute = Some(quote!(#[ #attribute ]));
return Ok(true)
}
}
else if input.peek(kw::impl_attribute) {
let a = input.parse::<kw::impl_attribute>()?;
let content;
parenthesized!(content in input);
let attribute = content.parse::<TokenStream>()?;
if input.peek(Token![,]) {
input.parse::<Token![,]>()?;
}
if attr.impl_attribute.is_some() {
Err(syn::Error::new(a.span, "Instruction parameter 'impl_attribute' was already set."))?
} else {
attr.impl_attribute = Some(quote!(#[ #attribute ]));
return Ok(true)
}
}
if input.peek(kw::inner_attribute) {
let a = input.parse::<kw::inner_attribute>()?;
let content;
parenthesized!(content in input);
let attribute = content.parse::<TokenStream>()?;
if input.peek(Token![,]) {
input.parse::<Token![,]>()?;
}
if attr.inner_attribute.is_some() {
Err(syn::Error::new(a.span, "Instruction parameter 'inner_attribute' was already set."))?
} else {
attr.inner_attribute = Some(quote!(#![ #attribute ]));
return Ok(true)
}
return parse_trait_instruction_param_inner_2::<kw::attribute, TokenStream>(input, |c| c.parse(), attr.attribute.is_some(), |x|attr.attribute = Some(quote!(#[ #x ])), |a|a.span, "attribute");
} else if input.peek(kw::impl_attribute) {
return parse_trait_instruction_param_inner_2::<kw::impl_attribute, TokenStream>(input, |c| c.parse(), attr.impl_attribute.is_some(), |x|attr.impl_attribute = Some(quote!(#[ #x ])), |a|a.span, "impl_attribute");
} else if input.peek(kw::inner_attribute) {
return parse_trait_instruction_param_inner_2::<kw::inner_attribute, TokenStream>(input, |c| c.parse(), attr.inner_attribute.is_some(), |x|attr.inner_attribute = Some(quote!(#![ #x ])), |a|a.span, "inner_attribute");
}

Ok(false)
Expand Down Expand Up @@ -1413,4 +1362,4 @@ fn build_child_path_str(child_path: &Punctuated<Member, Token![.]>) -> Vec<Strin
}
});
child_path_str
}
}
83 changes: 39 additions & 44 deletions o2o-impl/src/expand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1109,29 +1109,27 @@ fn quote_try_from_trait(input: &DataType, ctx: &ImplContext, pre_init: Option<To

fn quote_into_trait(input: &DataType, ctx: &ImplContext, pre_init: Option<TokenStream>, init: TokenStream, post_init: Option<TokenStream>) -> TokenStream {
let QuoteTraitParams { attr, impl_attr, inner_attr, dst, src, gens, where_clause, r } = get_quote_trait_params(input, ctx);
match post_init {
Some(post_init) => quote!{
#impl_attr
impl #gens std::convert::Into<#dst> for #r #src #gens #where_clause {
#attr
fn into(self) -> #dst {
#inner_attr
let mut obj: #dst = Default::default();
#init
#post_init
obj
}
}

let body = match post_init {
Some(post_init) => quote! {
let mut obj: #dst = Default::default();
#init
#post_init
obj
},
None => quote! {
#impl_attr
impl #gens std::convert::Into<#dst> for #r #src #gens #where_clause {
#attr
fn into(self) -> #dst {
#inner_attr
#pre_init
#init
}
#pre_init
#init
},
};

quote!{
#impl_attr
impl #gens std::convert::Into<#dst> for #r #src #gens #where_clause {
#attr
fn into(self) -> #dst {
#inner_attr
#body
}
}
}
Expand All @@ -1140,31 +1138,28 @@ fn quote_into_trait(input: &DataType, ctx: &ImplContext, pre_init: Option<TokenS
fn quote_try_into_trait(input: &DataType, ctx: &ImplContext, pre_init: Option<TokenStream>, init: TokenStream, post_init: Option<TokenStream>) -> TokenStream {
let QuoteTraitParams { attr, impl_attr, inner_attr, dst, src, gens, where_clause, r } = get_quote_trait_params(input, ctx);
let err_ty = &ctx.struct_attr.err_ty.as_ref().unwrap().path;
match post_init {
Some(post_init) => quote!{
#impl_attr
impl #gens std::convert::TryInto<#dst> for #r #src #gens #where_clause {
type Error = #err_ty;
#attr
fn try_into(self) -> Result<#dst, #err_ty> {
#inner_attr
let mut obj: #dst = Default::default();
#init
#post_init
Ok(obj)
}
}

let body = match post_init {
Some(post_init) => quote! {
let mut obj: #dst = Default::default();
#init
#post_init
Ok(obj)
},
None => quote! {
#impl_attr
impl #gens std::convert::TryInto<#dst> for #r #src #gens #where_clause {
type Error = #err_ty;
#attr
fn try_into(self) -> Result<#dst, #err_ty> {
#inner_attr
#pre_init
#init
}
#pre_init
#init
},
};

quote! {
#impl_attr
impl #gens std::convert::TryInto<#dst> for #r #src #gens #where_clause {
type Error = #err_ty;
#attr
fn try_into(self) -> Result<#dst, #err_ty> {
#inner_attr
#body
}
}
}
Expand Down

0 comments on commit c037365

Please sign in to comment.