smart_clone/lib.rs
1#![doc(html_root_url = "https://docs.rs/smart-clone/0.1.0")]
2
3extern crate proc_macro;
4
5use proc_macro::TokenStream;
6
7use crate::internals::smart_clone_derive;
8
9mod internals;
10
11/// # Smart Clone
12///
13/// This crate provides a custom derive macro called `SmartClone`.
14///
15/// `SmartClone` is a derive macro that replaces the standard `#[derive(Clone)]` in order to
16/// implement a custom `impl Clone`.
17/// The main difference is that `#[derive(SmartClone)]` allows you to use `#[clone(...)]` attributes
18/// to customize the clone method for each field individually.
19///
20/// This means you can implement the `Clone` trait for a Rust structure (struct, enum, etc.) even if
21/// not all fields implement `Clone`.
22///
23/// # API
24///
25/// - `#[clone]`: will perform cloning as usual for your field. Equivalent to no annotation.
26/// - `#[clone = xxx]`: will set the value `xxx` to the field when the structure is cloned
27/// - `#[clone(xxx)]`: same as above, but `xxx` can be whatever you want here, not just a literal
28/// - `#[clone(clone_with = "xxx")]`: the field will be passed by reference to a function called `xxx` and the
29/// returned value will be used when the structure is cloned.
30///
31/// # Examples
32///
33/// ```
34/// use smart_clone::SmartClone;
35///
36/// # fn main() {
37/// #[derive(SmartClone)]
38/// struct Foo {
39/// #[clone(12)]
40/// a: i32, // will always be cloned to value 12
41/// #[clone("banana".to_owned())]
42/// b: String, // this field will always clone to String `banana`
43/// #[clone(default)]
44/// c: Option<i32>, // this field will always be reset to default when Foo is cloned
45/// #[clone(clone_with = "double")]
46/// d: Vec<u32>, // uses a custom method to clone this field
47/// #[clone("banana".to_owned())]
48/// e: String,
49/// }
50///
51/// #[derive(SmartClone, Default)]
52/// enum SimpleEnum {
53/// #[default]
54/// A,
55/// B(usize, usize), // will behave as usual
56/// C { x: u8, y: u8 },
57/// #[clone(SimpleEnum::D(8, 12))]
58/// D(i32, u32),
59/// #[clone(SimpleEnum::E { x: 3, y: 4 })]
60/// E { x: u8, y: u8 },
61/// #[clone(clone_with = "double")]
62/// F { x: u8, y: u8 },
63/// #[clone(default)]
64/// G { x: u8, y: u8 },
65/// }
66/// # }
67/// ```
68#[proc_macro_derive(SmartClone, attributes(clone))]
69pub fn smart_clone_derive_macro(input: TokenStream) -> TokenStream {
70 smart_clone_derive(input.into()).into()
71}