Skip to content

Commit

Permalink
feat(struct): take
Browse files Browse the repository at this point in the history
  • Loading branch information
makcandrov committed Sep 29, 2024
1 parent 5a077cf commit 5ec1a18
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 5 deletions.
3 changes: 3 additions & 0 deletions src/components/structs/methods/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,8 @@ pub use into::struct_method_into;
mod set;
pub use set::struct_method_set;

mod take;
pub use take::struct_method_take;

mod with;
pub use with::struct_method_with;
41 changes: 41 additions & 0 deletions src/components/structs/methods/take.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
use proc_macro2::TokenStream;
use quote::quote;

use crate::attributes::{Attribute, MethodAttribute};
use crate::config::{build_config, build_enum_doc, build_enum_name};
use crate::expand::Context;
use crate::tokens::IndexedField;

build_enum_name! { ConfigName, "take_{}" }
build_enum_doc! {
ConfigDoc,
"Replaces the field `{1}` of [`{0}`] with its default value.",
}

build_config! {
Config,
(name, ConfigName, true),
(doc, ConfigDoc, false),
}

pub fn struct_method_take(
context: &Context,
indexed_field: &IndexedField,
attribute: &Attribute,
method_attr: &MethodAttribute,
) -> syn::Result<TokenStream> {
let config = Config::new(context, attribute, indexed_field)?;

let doc = &config.doc;
let keywords = method_attr.keywords();
let ty = &indexed_field.ty;
let method_ident = &config.name;
let field_ident = indexed_field.as_token();

Ok(quote! {
#[doc = #doc]
#keywords fn #method_ident (&mut self) -> #ty where #ty: ::std::default::Default {
::core::mem::take(&mut self.#field_ident)
}
})
}
8 changes: 7 additions & 1 deletion src/components/structs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use syn::DataStruct;
use crate::attributes::{AttributeType, Attributes};
use crate::expand::{Context, Implems};
use crate::idents::methods::{
METHOD_GET, METHOD_GET_CLONE, METHOD_GET_MUT, METHOD_INTO, METHOD_SET, METHOD_WITH,
METHOD_GET, METHOD_GET_CLONE, METHOD_GET_MUT, METHOD_INTO, METHOD_SET, METHOD_TAKE, METHOD_WITH,
};
use crate::idents::traits::{TRAIT_AS_MUT, TRAIT_AS_REF, TRAIT_DEREF, TRAIT_DEREF_MUT, TRAIT_INTO};
use crate::tokens::to_indexed_field_iter;
Expand Down Expand Up @@ -53,6 +53,12 @@ pub fn struct_impl(
attribute,
method_attr,
)?,
METHOD_TAKE => methods::struct_method_take(
context,
&indexed_field,
attribute,
method_attr,
)?,
METHOD_WITH => methods::struct_method_with(
context,
&indexed_field,
Expand Down
1 change: 1 addition & 0 deletions src/idents.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ pub mod methods {
pub const METHOD_INTO: &str = "into";
pub const METHOD_IS: &str = "is";
pub const METHOD_SET: &str = "set";
pub const METHOD_TAKE: &str = "take";
pub const METHOD_TRY_INTO: &str = "try_into";
pub const METHOD_WITH: &str = "with";
}
Expand Down
12 changes: 8 additions & 4 deletions tests/test_struct.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use quick_impl::QuickImpl;
fn test_struct_single_named() {
#[derive(QuickImpl)]
struct Test {
#[quick_impl(pub const get = "{}", pub get_clone, get_mut, const into, pub(crate) set, pub(crate) const with, impl Deref, impl DerefMut, impl Into, impl AsRef, impl AsMut)]
#[quick_impl(pub const get = "{}", pub get_clone, get_mut, const into, pub(crate) set, pub take, pub(crate) const with, impl Deref, impl DerefMut, impl Into, impl AsRef, impl AsMut)]
a: usize,
}

Expand All @@ -24,14 +24,16 @@ fn test_struct_single_named() {
assert_eq!(*a.get_a_mut(), 13);

*a.get_a_mut() = 14;
assert_eq!(Into::<usize>::into(a), 14)
assert_eq!(Into::<usize>::into(a.clone()), 14);

assert_eq!(a.take_a(), 14);
}

#[test]
fn test_struct_single_unnamed() {
#[derive(QuickImpl)]
struct Test(
#[quick_impl(pub const get, get_mut, const into, pub(crate) set, pub(crate) const with, impl Deref, impl DerefMut, impl Into, impl AsRef, impl AsMut)]
#[quick_impl(pub const get, get_mut, const into, pub(crate) set, take, pub(crate) const with, impl Deref, impl DerefMut, impl Into, impl AsRef, impl AsMut)]
usize,
);

Expand All @@ -49,5 +51,7 @@ fn test_struct_single_unnamed() {
assert_eq!(*a.get_0_mut(), 13);

*a.get_0_mut() = 14;
assert_eq!(Into::<usize>::into(a), 14)
assert_eq!(Into::<usize>::into(a.clone()), 14);

assert_eq!(a.take_0(), 14);
}

0 comments on commit 5ec1a18

Please sign in to comment.