Skip to content

Commit

Permalink
Close #109: Add crate_module_path
Browse files Browse the repository at this point in the history
  • Loading branch information
idanarye committed Aug 26, 2023
1 parent 628786a commit 3f78ca5
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 25 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Expand Up @@ -5,6 +5,9 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).

## [Unreleased]
### Added
- `#[builder(crate_module_path = ...)]` for overcoming cases where the derive
macro is used in another crate's macro (see issue #109)

## 0.15.2 - 2023-08-03
### Fixed
Expand Down
8 changes: 8 additions & 0 deletions src/lib.rs
Expand Up @@ -64,6 +64,14 @@ use core::ops::FnOnce;
/// but it won't be a link. If you turn this on, the builder type and its `build` method will get
/// sane defaults. The field methods on the builder will be undocumented by default.
///
/// - `crate_module_path`: This is only needed when `typed_builder` is reexported from another
/// crate - which usually happens when another macro uses it. In that case, it is the
/// reponsibility of that macro to set the `crate_module_path` to the _unquoted_ module path from
/// which the `typed_builder` crate can be accessed, so that the `TypedBuilder` macro will be
/// able to access the typed declared in it.
///
/// Defaults to `#[builder(crate_module_path=::typed_builder)]`.
///
/// - The following subsections:
/// - `builder_method(...)`: customize the builder method that creates the builder type
/// - `builder_type(...)`: customize the builder type
Expand Down
4 changes: 2 additions & 2 deletions typed-builder-macro/src/field_info.rs
Expand Up @@ -305,11 +305,11 @@ impl SetterSettings {
Ok(())
}
"prefix" => {
self.prefix = Some(expr_to_lit_string(&*assign.right)?);
self.prefix = Some(expr_to_lit_string(&assign.right)?);
Ok(())
}
"suffix" => {
self.suffix = Some(expr_to_lit_string(&*assign.right)?);
self.suffix = Some(expr_to_lit_string(&assign.right)?);
Ok(())
}
_ => Err(Error::new_spanned(&assign, format!("Unknown parameter {:?}", name))),
Expand Down
59 changes: 38 additions & 21 deletions typed-builder-macro/src/struct_info.rs
Expand Up @@ -405,25 +405,18 @@ impl<'a> StructInfo<'a> {
paren_token: None,
lifetimes: None,
modifier: syn::TraitBoundModifier::None,
path: syn::Path {
leading_colon: Some(syn::token::PathSep::default()),
segments: [
syn::PathSegment {
ident: Ident::new("typed_builder", Span::call_site()),
arguments: syn::PathArguments::None,
},
syn::PathSegment {
ident: Ident::new("Optional", Span::call_site()),
arguments: syn::PathArguments::AngleBracketed(syn::AngleBracketedGenericArguments {
colon2_token: None,
lt_token: Default::default(),
args: [syn::GenericArgument::Type(field.ty.clone())].into_iter().collect(),
gt_token: Default::default(),
}),
},
]
.into_iter()
.collect(),
path: {
let mut path = self.builder_attr.crate_module_path.clone();
path.segments.push(syn::PathSegment {
ident: Ident::new("Optional", Span::call_site()),
arguments: syn::PathArguments::AngleBracketed(syn::AngleBracketedGenericArguments {
colon2_token: None,
lt_token: Default::default(),
args: [syn::GenericArgument::Type(field.ty.clone())].into_iter().collect(),
gt_token: Default::default(),
}),
});
path
},
};
let mut generic_param: syn::TypeParam = field.generic_ident.clone().into();
Expand Down Expand Up @@ -463,7 +456,8 @@ impl<'a> StructInfo<'a> {
if field.builder_attr.setter.skip.is_some() {
quote!(let #name = #default;)
} else {
quote!(let #name = ::typed_builder::Optional::into_value(#name, || #default);)
let crate_module_path = &self.builder_attr.crate_module_path;
quote!(let #name = #crate_module_path::Optional::into_value(#name, || #default);)
}
} else {
quote!(let #name = #name.0;)
Expand Down Expand Up @@ -619,7 +613,7 @@ impl BuildMethodSettings {
}
}

#[derive(Debug, Default)]
#[derive(Debug)]
pub struct TypeBuilderAttr<'a> {
/// Whether to show docs for the `TypeBuilder` type (rather than hiding them).
pub doc: bool,
Expand All @@ -634,6 +628,21 @@ pub struct TypeBuilderAttr<'a> {
pub build_method: BuildMethodSettings,

pub field_defaults: FieldBuilderAttr<'a>,

pub crate_module_path: syn::Path,
}

impl Default for TypeBuilderAttr<'_> {
fn default() -> Self {
Self {
doc: Default::default(),
builder_method: Default::default(),
builder_type: Default::default(),
build_method: Default::default(),
field_defaults: Default::default(),
crate_module_path: syn::parse_quote!(::typed_builder),
}
}
}

impl<'a> TypeBuilderAttr<'a> {
Expand Down Expand Up @@ -678,6 +687,14 @@ impl<'a> TypeBuilderAttr<'a> {
)
};
match name.as_str() {
"crate_module_path" => {
if let syn::Expr::Path(crate_module_path) = assign.right.as_ref() {
self.crate_module_path = crate_module_path.path.clone();
Ok(())
} else {
Err(Error::new_spanned(&assign.right, "crate_module_path must be a path"))
}
}
"builder_method_doc" => Err(gen_structure_depracation_error("builder_method", "doc")),
"builder_type_doc" => Err(gen_structure_depracation_error("builder_type", "doc")),
"build_method_doc" => Err(gen_structure_depracation_error("build_method", "doc")),
Expand Down
4 changes: 2 additions & 2 deletions typed-builder-macro/src/util.rs
Expand Up @@ -120,8 +120,8 @@ pub fn expr_to_lit_string(expr: &syn::Expr) -> Result<String, Error> {
match expr {
syn::Expr::Lit(lit) => match &lit.lit {
syn::Lit::Str(str) => Ok(str.value()),
_ => return Err(Error::new_spanned(expr, "attribute only allows str values")),
_ => Err(Error::new_spanned(expr, "attribute only allows str values")),
},
_ => return Err(Error::new_spanned(expr, "attribute only allows str values")),
_ => Err(Error::new_spanned(expr, "attribute only allows str values")),
}
}

0 comments on commit 3f78ca5

Please sign in to comment.