Skip to content

Commit

Permalink
fix: code structure according to requested changes
Browse files Browse the repository at this point in the history
  • Loading branch information
ifiokjr committed Aug 22, 2024
1 parent 64d7304 commit 4db6097
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 64 deletions.
16 changes: 14 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -381,19 +381,31 @@ impl<T> Optional<T> for (T,) {
///
/// Handling multiple properties for `strip_option`
///
/// ```no_run
/// use typed_builder::TypedBuilder;
///
/// #[derive(TypedBuilder)]
/// struct Foo {
/// #[builder(setter(strip_option(fallback = value_opt, fallback = value_opt2)))]
/// value: Option<i32>,
/// }
/// ```
///
/// Handling alternative properties for `strip_option`
///
/// ```compile_fail
/// use typed_builder::TypedBuilder;
///
/// #[derive(TypedBuilder)]
/// struct Foo {
/// #[builder(setter(strip_option(fallback= "value_opt", fallback="value_opt2")))]
/// #[builder(setter(strip_option(type = value_opt, fallback = value_opt2)))]
/// value: Option<i32>,
/// }
/// ```
///
/// Handling empty properties for `strip_option`
///
/// ```compile_fail
/// ```no_run
/// use typed_builder::TypedBuilder;
///
/// #[derive(TypedBuilder)]
Expand Down
4 changes: 2 additions & 2 deletions tests/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ fn test_into_with_strip_option() {
fn test_strip_option_with_fallback() {
#[derive(PartialEq, TypedBuilder)]
struct Foo {
#[builder(setter(strip_option(fallback = "x_opt")))]
#[builder(setter(strip_option(fallback = x_opt)))]
x: Option<i32>,
}

Expand All @@ -159,7 +159,7 @@ fn test_strip_option_with_fallback() {
fn test_into_with_strip_option_with_fallback() {
#[derive(PartialEq, TypedBuilder)]
struct Foo {
#[builder(setter(into, strip_option(fallback = "x_opt")))]
#[builder(setter(into, strip_option(fallback = x_opt)))]
x: Option<i32>,
}

Expand Down
82 changes: 29 additions & 53 deletions typed-builder-macro/src/field_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@ use quote::quote_spanned;
use syn::{parse::Error, spanned::Spanned};

use crate::mutator::Mutator;
use crate::util::{
expr_to_lit_string, ident_to_type, path_to_single_string, strip_raw_ident_prefix, ApplyMeta, AttrArg, SubAttr,
};
use crate::util::{expr_to_lit_string, ident_to_type, path_to_single_string, strip_raw_ident_prefix, ApplyMeta, AttrArg};

#[derive(Debug)]
pub struct FieldInfo<'a> {
Expand Down Expand Up @@ -129,7 +127,7 @@ pub struct SetterSettings {
pub doc: Option<syn::Expr>,
pub skip: Option<Span>,
pub auto_into: Option<Span>,
pub strip_option: Option<StripOption>,
pub strip_option: Option<Strip>,
pub strip_bool: Option<Span>,
pub transform: Option<Transform>,
pub prefix: Option<String>,
Expand Down Expand Up @@ -197,7 +195,7 @@ impl<'a> FieldBuilderAttr<'a> {

let conflicting_transformations = [
("transform", self.setter.transform.as_ref().map(|t| &t.span)),
("strip_option", self.setter.strip_option.as_ref().map(|s| s.span())),
("strip_option", self.setter.strip_option.as_ref().map(|s| &s.span)),
("strip_bool", self.setter.strip_bool.as_ref()),
];
let mut conflicting_transformations = conflicting_transformations
Expand Down Expand Up @@ -339,21 +337,23 @@ impl ApplyMeta for SetterSettings {
"into" => expr.apply_flag_to_field(&mut self.auto_into, "calling into() on the argument"),
"strip_option" => {
let caption = "putting the argument in Some(...)";

match expr {
AttrArg::Sub(sub) => {
let span = sub.span();
let mut strip_option = Strip::new(span);

if self.strip_option.is_none() {
self.strip_option = Some(StripOption::from_args(sub)?);
strip_option.apply_sub_attr(sub)?;
self.strip_option = Some(strip_option);
Ok(())
} else {
Err(Error::new(
sub.span(),
format!("Illegal setting - field is already {caption}"),
))
Err(Error::new(span, format!("Illegal setting - field is already {caption}")))
}
}
AttrArg::Flag(flag) => {
if self.strip_option.is_none() {
self.strip_option = Some(StripOption::Span(flag.span()));
self.strip_option = Some(Strip::new(flag.span()));
Ok(())
} else {
Err(Error::new(
Expand All @@ -379,54 +379,30 @@ impl ApplyMeta for SetterSettings {
}

#[derive(Debug, Clone)]
pub enum StripOption {
Span(Span),
WithFallback(Span, String),
pub struct Strip {
pub fallback: Option<syn::Ident>,
span: Span,
}

impl StripOption {
fn span(&self) -> &Span {
match self {
StripOption::Span(span) => span,
StripOption::WithFallback(span, _) => span,
}
impl Strip {
fn new(span: Span) -> Self {
Self { fallback: None, span }
}
}

pub fn from_args(sub: SubAttr) -> Result<Self, Error> {
let name = sub.name.clone();
let mut total = 0;
let mut result: Result<Self, Error> = Err(Error::new_spanned(
&name,
format!("Parameters required {:?}", name.to_string()),
));

for arg in sub.args::<AttrArg>()? {
if total > 0 {
result = Err(Error::new_spanned(
arg.name(),
format!("Too many paramters {:?}", arg.name().to_string()),
));

continue;
}

if arg.name().to_string().as_str() != "fallback" {
result = Err(Error::new_spanned(
arg.name(),
format!("Invalid parameter used {:?}", arg.name().to_string()),
));
continue;
impl ApplyMeta for Strip {
fn apply_meta(&mut self, expr: AttrArg) -> Result<(), Error> {
match expr.name().to_string().as_str() {
"fallback" => {
let ident: syn::Ident = expr.key_value().map(|kv| kv.parse_value())??;
self.fallback = Some(ident);
Ok(())
}

let span = arg.span();
let string_expr: syn::Expr = arg.key_value().map(|kv| kv.parse_value())??;
let name: String = expr_to_lit_string(&string_expr)?;
result = Ok(Self::WithFallback(span, name));

total += 1;
_ => Err(Error::new_spanned(
expr.name(),
format!("Invalid parameter used {:?}", expr.name().to_string()),
)),
}

result
}
}

Expand Down
10 changes: 3 additions & 7 deletions typed-builder-macro/src/struct_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use quote::{format_ident, quote, quote_spanned, ToTokens};
use syn::{parse::Error, parse_quote, punctuated::Punctuated, GenericArgument, ItemFn, Token};

use crate::builder_attr::{IntoSetting, TypeBuilderAttr};
use crate::field_info::{FieldInfo, StripOption};
use crate::field_info::FieldInfo;
use crate::mutator::Mutator;
use crate::util::{
empty_type, empty_type_tuple, first_visibility, modify_types_generics_hack, phantom_data_for_generics, public_visibility,
Expand Down Expand Up @@ -284,12 +284,8 @@ impl<'a> StructInfo<'a> {
let body = &transform.body;
(quote!(#(#params),*), quote!({ #body }))
} else if let Some(ref strip_option) = field.builder_attr.setter.strip_option {
if let StripOption::WithFallback(_, fallback_name) = strip_option {
strip_option_fallback = Some((
syn::parse_str(fallback_name)?,
quote!(#field_name: #field_type),
quote!(#arg_expr),
));
if let Some(ref fallback) = strip_option.fallback {
strip_option_fallback = Some((fallback.clone(), quote!(#field_name: #field_type), quote!(#arg_expr)));
}

(quote!(#field_name: #arg_type), quote!(Some(#arg_expr)))
Expand Down

0 comments on commit 4db6097

Please sign in to comment.