1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
//! `FromSimilar` automatically implements [`From`] between two structs that are "similar".
//!
//! Specifically for structs where the *fields have the same names*.
//! Or tuple structs with similar positional arguments.
//!
//! This macro is mainly useful to generate predicable `From` implementations for:
//! - Structs that are *mostly* identical, except for a few attributes like `#[serde]` exceptions for serializing BSON.
//! - Structs with a subset of fields from the more complete one.
//!
//! ### Struct attributes
//!
//! `#[from(InputType)]` a **required attribute** to specify the input type.<br>
//! Will generate `impl From<InputType> for T`.
//!
//! `#[from(.., bidirectional = true)]` optional attribute to implement both directions.<br>
//! Will generate `impl From<InputType> for T` and `impl From<T> for InputType`.
//!
//! ### Field attributes
//!
//! `#[use_into]` is an optional *field attribute* to use `.into()` when converting this field.
//!
//! `#[use_into_option]` for `Option<T>` types that need a `.map(Into::into)` when converting this field.
//!
//! `#[use_into_collection]` for `impl IntoIterator<T>` types that should map each item and collect.
//!
//! ## Example with database models
//!
//! A bidirectional FromSimilar that can be used for MongoDB.
//!
//! ```rust
//! use from_similar::FromSimilar;
//!
//! #[derive(Default)]
//! struct NormalModel {
//! id: String,
//! date: chrono::DateTime<chrono::Utc>,
//! date_option: Option<chrono::DateTime<chrono::Utc>>,
//! date_list: Vec<chrono::DateTime<chrono::Utc>>,
//! }
//!
//! #[derive(FromSimilar, serde::Serialize, serde::Deserialize)]
//! #[from(NormalModel, bidirectional = true)]
//! struct DatabaseModel {
//! #[serde(rename = "_id")]
//! id: String,
//!
//! #[use_into]
//! date: bson::DateTime,
//!
//! #[use_into_option]
//! date_option: Option<bson::DateTime>,
//!
//! #[use_into_collection]
//! date_list: Vec<bson::DateTime>,
//! }
//!
//! let normal = NormalModel::default();
//! let db: DatabaseModel = normal.into();
//! let _: NormalModel = db.into();
//! ```
//!
//! ### Example with views
//!
//! Note: `#[from(.., bidirectional = true)]` would break here, because it's a lossy conversion.
//!
//! ```rust
//! use from_similar::FromSimilar;
//!
//! #[derive(Default)]
//! struct FullModel {
//! id: String,
//! pretty_name: String,
//! secret: String,
//! }
//!
//! #[derive(FromSimilar)]
//! #[from(FullModel)]
//! struct PublicView {
//! id: String,
//! pretty_name: String,
//! // ... omits `secret` field
//! }
//!
//! let full = FullModel::default();
//! let _: PublicView = full.into();
//! ```
//!
//! ### Example with tuple struct
//!
//! ```rust
//! use from_similar::FromSimilar;
//!
//! #[derive(Default)]
//! struct Data(pub String, pub usize);
//!
//! #[derive(FromSimilar)]
//! #[from(Data)]
//! struct SealedData(#[use_into] std::sync::Arc<str>, usize);
//!
//! let mut data = Data::default();
//! data.0 += "Pushing ";
//! data.0 += "some text";
//! data.1 = 42;
//! let data: SealedData = data.into();
//! ```
extern crate proc_macro;
use TokenStream;
use ;
/// [`FromSimilar`] derive macro.
///
/// Typical usage means adding the Derive macro, setting the source with
/// `#[from(SourceType)]` and using field macros as needed.
///
/// - `#[use_into]` for types that need direct `into` calls.
/// - `#[use_into_option]` for `Option<T>` types that need a map-into.
/// - `#[use_into_collection]` for `impl IntoIterator<T>` types that should map each item and collect.