inline_newtype/
lib.rs

1///
2/// A rust newtype macro inspired by kotlin's inline class.
3///
4///
5/// When we use
6/// ```rust newtype!(NewTypeOne, u32);```
7/// It generate the struct
8///```
9/// #[derive(Debug, Clone)]
10///     struct UserHomeDirectory {
11///         pub v: u32,
12///     }
13///```
14/// for you.
15/// The ***v*** is the default public field.
16///
17/// ```rust
18/// use inline_newtype::newtype;
19/// use std::path::PathBuf;
20/// newtype!(UserHomeDirectory, PathBuf);
21/// newtype!(UserRuntimeDirectory, PathBuf);
22/// let user_home_directory = UserHomeDirectory { v: PathBuf::from("hello") };
23/// let user_runtime_directory= UserRuntimeDirectory {v: PathBuf::from("hello")};
24/// fn test_newtype_type_func(user_home_directory: UserHomeDirectory) -> UserHomeDirectory{
25///          user_home_directory
26/// }
27/// ```
28/// ```compile_fail
29/// test_newtype_type_func(user_runtime_directory);  // mismatch type
30/// ```
31/// You can aslo make the newtype public just adding the pub.
32/// ```rust
33/// use inline_newtype::newtype;
34/// use std::path::PathBuf;
35/// newtype!(UserHomeDirectory, PathBuf, pub);
36/// ```
37///
38/// You also can change the field name if you want.
39/// ```rust
40/// use inline_newtype::newtype;
41/// use std::path::PathBuf;
42/// newtype!(UserHomeDirectory, PathBuf, path_buf);
43/// let user_home_directory = UserHomeDirectory { path_buf: PathBuf::from("hello")};
44/// assert_eq!(user_home_directory.path_buf, PathBuf::from("hello"));
45/// ```
46/// Transform from one newtype to another
47/// ```rust
48/// use inline_newtype::newtype;
49/// use std::path::PathBuf;
50/// newtype!(UserHomeDirectory, PathBuf);
51/// newtype!(UserRuntimeDirectory, PathBuf);
52/// let user_home_directory = UserHomeDirectory { v: PathBuf::from("hello") };
53/// let user_runtime_directory = UserRuntimeDirectory { v: PathBuf::from("hello") };
54/// fn transform_user_home_to_runtime_directory(
55///     mut user_home_directory: UserHomeDirectory,
56/// ) -> UserRuntimeDirectory {
57///     let mut runtime_dir = user_home_directory.v;
58///     runtime_dir.push("runtime_dir");
59///     UserRuntimeDirectory { v: runtime_dir }
60/// }
61///
62
63/// ```
64/// You can also using curly brackets to declare the newtype.
65/// ```rust
66/// use inline_newtype::newtype;
67/// use std::path::PathBuf;
68/// newtype! {UserHomeDirectory, PathBuf, path_buf}
69/// let user_home_directory = UserHomeDirectory { path_buf: PathBuf::from("hello") };
70/// assert_eq!(user_home_directory.path_buf, PathBuf::from("hello"))
71/// ```
72///
73#[macro_export]
74macro_rules! newtype {
75    ($type_name: ident, $type: ty) => {
76        #[derive(Debug, Clone)]
77        struct $type_name {
78            pub v: $type,
79        }
80    };
81    ($type_name: ident, $type: ty, $is_pub:vis) => {
82        #[derive(Debug, Clone)]
83        pub struct $type_name {
84            pub v: $type,
85        }
86    };
87    ($type_name: ident, $type: ty, $access_name: ident) => {
88        #[derive(Debug, Clone)]
89        struct $type_name {
90            pub $access_name: $type,
91        }
92    };
93    ($type_name: ident, $type: ty, $access_name: ident, $is_pub:vis) => {
94        #[derive(Debug, Clone)]
95        $is_pub struct $type_name {
96            pub $access_name: $type,
97        }
98    };
99    {$type_name: ident, $type: ty} => {
100        #[derive(Debug, Clone)]
101        struct $type_name {
102            pub v: $type,
103        }
104    };
105    {$type_name: ident, $type: ty, $is_pub:vis} => {
106        #[derive(Debug, Clone)]
107        pub struct $type_name {
108            pub v: $type,
109        }
110    };
111    {$type_name: ident, $type: ty, $access_name: ident} => {
112        #[derive(Debug, Clone)]
113        struct $type_name {
114            pub $access_name: $type,
115        }
116    };
117    {$type_name: ident, $type: ty, $access_name: ident, $is_pub:vis} => {
118        #[derive(Debug, Clone)]
119        $is_pub struct $type_name {
120            pub $access_name: $type,
121        }
122    };
123}
124
125#[cfg(test)]
126mod tests {
127    use std::path::PathBuf;
128
129    #[test]
130    fn test_new_type() {
131        newtype!(UserHomeDirectory, PathBuf);
132        let user_home_directory = UserHomeDirectory {
133            v: PathBuf::from("hello"),
134        };
135        assert_eq!(user_home_directory.v, PathBuf::from("hello"));
136    }
137
138    #[test]
139    fn test_type_not_equal() {
140        newtype!(UserHomeDirectory, PathBuf);
141        newtype!(UserRuntimeDirectory, PathBuf);
142        let user_home_directory = UserHomeDirectory {
143            v: PathBuf::from("hello"),
144        };
145        let user_runtime_directory = UserRuntimeDirectory {
146            v: PathBuf::from("hello"),
147        };
148        fn test_newtype_type_func(user_home_directory: UserHomeDirectory) -> UserHomeDirectory {
149            user_home_directory
150        }
151    }
152
153    #[test]
154    fn test_transform_newtype() {
155        newtype!(UserHomeDirectory, PathBuf);
156        newtype!(UserRuntimeDirectory, PathBuf);
157        let user_home_directory = UserHomeDirectory {
158            v: PathBuf::from("hello"),
159        };
160        let user_runtime_directory = UserRuntimeDirectory {
161            v: PathBuf::from("hello"),
162        };
163
164        fn transform_user_home_to_runtime_directory(
165            mut user_home_directory: UserHomeDirectory,
166        ) -> UserRuntimeDirectory {
167            let mut runtime_dir = user_home_directory.v;
168            runtime_dir.push("runtime_dir");
169            UserRuntimeDirectory { v: runtime_dir }
170        }
171    }
172
173    #[test]
174    fn test_field_name() {
175        newtype!(UserHomeDirectory, PathBuf, path_buf);
176        let user_home_directory = UserHomeDirectory {
177            path_buf: PathBuf::from("hello"),
178        };
179        assert_eq!(user_home_directory.path_buf, PathBuf::from("hello"))
180    }
181
182    #[test]
183    fn test_curly_brackets_name() {
184        newtype! {UserHomeDirectory, PathBuf, path_buf}
185        let user_home_directory = UserHomeDirectory {
186            path_buf: PathBuf::from("hello"),
187        };
188        assert_eq!(user_home_directory.path_buf, PathBuf::from("hello"))
189    }
190}