From c281d3497ec02ae85cab6205aefe1c15694704ff Mon Sep 17 00:00:00 2001 From: Cecile Tonglet Date: Sun, 5 Nov 2023 17:50:49 +0100 Subject: [PATCH 01/12] Impl ImplicitClone for arrays and ref arrays --- src/lib.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index 6f397de..ea204f6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -78,6 +78,8 @@ impl_implicit_clone!( (), ); +impl ImplicitClone for [T; N] {} + macro_rules! impl_implicit_clone_for_tuple { ($($param:ident),+ $(,)?) => { impl<$($param: ImplicitClone),+> ImplicitClone for ($($param,)+) {} @@ -174,6 +176,19 @@ mod test { bool, usize, isize, char, (), + [u8; 4], + &[u8], + ); + + macro_rules! test_all_with_value { + ($($t:ty => $v:expr),* $(,)?) => { + $(host_library!($v);)* + }; + } + + #[rustfmt::skip] + test_all_with_value!( + &[u8; 4] => &[0, 1, 2, 3], ); } From 295877f0db295fffb086d0a7725a680670adf9f7 Mon Sep 17 00:00:00 2001 From: Cecile Tonglet Date: Sun, 5 Nov 2023 18:07:19 +0100 Subject: [PATCH 02/12] Improve the test to make sure we impl ImplicitClone on Copy types --- src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index ea204f6..a6ddf8c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -138,7 +138,7 @@ macro_rules! imap_deconstruct { mod test { use super::*; - fn host_library(value: &T) -> T { + fn host_library(value: &T) -> T { value.clone() } @@ -152,7 +152,7 @@ mod test { #[test] fn custom() { - #[derive(Clone)] + #[derive(Clone, Copy)] struct ImplicitCloneType; impl ImplicitClone for ImplicitCloneType {} From ddb351ce556972d5edeaf0c0e7bdd54b033b1d83 Mon Sep 17 00:00:00 2001 From: Cecile Tonglet Date: Sun, 5 Nov 2023 18:09:36 +0100 Subject: [PATCH 03/12] shut up clippy --- src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index a6ddf8c..643aeb3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -139,7 +139,7 @@ mod test { use super::*; fn host_library(value: &T) -> T { - value.clone() + *value } macro_rules! host_library { From c79fbc02f9c312e3c1f0ef0b7b9650c0370fda43 Mon Sep 17 00:00:00 2001 From: Cecile Tonglet Date: Sun, 5 Nov 2023 18:13:31 +0100 Subject: [PATCH 04/12] Proper naming for type assertions --- src/lib.rs | 62 ++++++++++++++++++++++++++++++++---------------------- 1 file changed, 37 insertions(+), 25 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 643aeb3..a378105 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -138,13 +138,23 @@ macro_rules! imap_deconstruct { mod test { use super::*; - fn host_library(value: &T) -> T { + fn assert_implicit_clone(value: &T) -> T { + value.clone() + } + + fn assert_copy(value: &T) -> T { *value } - macro_rules! host_library { + macro_rules! assert_implicit_clone { + ($a:expr) => { + assert_implicit_clone(&$a) + }; + } + + macro_rules! assert_copy { ($a:expr) => { - host_library(&$a) + assert_copy(&$a) }; } @@ -152,19 +162,20 @@ mod test { #[test] fn custom() { - #[derive(Clone, Copy)] + #[derive(Clone)] struct ImplicitCloneType; impl ImplicitClone for ImplicitCloneType {} - host_library!(ImplicitCloneType); + assert_implicit_clone!(ImplicitCloneType); } #[test] fn copy_types() { macro_rules! test_all { ($($t:ty),* $(,)?) => { - $(host_library!(<$t>::default());)* + $(assert_implicit_clone!(<$t>::default());)* + $(assert_copy!(<$t>::default());)* }; } @@ -182,7 +193,8 @@ mod test { macro_rules! test_all_with_value { ($($t:ty => $v:expr),* $(,)?) => { - $(host_library!($v);)* + $(assert_implicit_clone!($v);)* + $(assert_copy!($v);)* }; } @@ -194,31 +206,31 @@ mod test { #[test] fn ref_type() { - host_library!(&NonImplicitCloneType); - // `host_library!(NonImplicitCloneType)` doesn't compile + assert_implicit_clone!(&NonImplicitCloneType); + // `assert_implicit_clone!(NonImplicitCloneType)` doesn't compile } #[test] fn option() { - host_library!(Some("foo")); - // `host_library!(Some(NonImplicitCloneType));` doesn't compile + assert_implicit_clone!(Some("foo")); + // `assert_implicit_clone!(Some(NonImplicitCloneType));` doesn't compile } #[test] fn tuples() { - host_library!((1,)); - host_library!((1, 2)); - host_library!((1, 2, 3)); - host_library!((1, 2, 3, 4)); - host_library!((1, 2, 3, 4, 5)); - host_library!((1, 2, 3, 4, 5, 6)); - host_library!((1, 2, 3, 4, 5, 6, 7)); - host_library!((1, 2, 3, 4, 5, 6, 7, 8)); - host_library!((1, 2, 3, 4, 5, 6, 7, 8, 9)); - host_library!((1, 2, 3, 4, 5, 6, 7, 8, 9, 10)); - host_library!((1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)); - host_library!((1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)); - // `host_library!((1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13));` doesn't compile - // `host_library!((NonImplicitCloneType,));` doesn't compile + assert_implicit_clone!((1,)); + assert_implicit_clone!((1, 2)); + assert_implicit_clone!((1, 2, 3)); + assert_implicit_clone!((1, 2, 3, 4)); + assert_implicit_clone!((1, 2, 3, 4, 5)); + assert_implicit_clone!((1, 2, 3, 4, 5, 6)); + assert_implicit_clone!((1, 2, 3, 4, 5, 6, 7)); + assert_implicit_clone!((1, 2, 3, 4, 5, 6, 7, 8)); + assert_implicit_clone!((1, 2, 3, 4, 5, 6, 7, 8, 9)); + assert_implicit_clone!((1, 2, 3, 4, 5, 6, 7, 8, 9, 10)); + assert_implicit_clone!((1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)); + assert_implicit_clone!((1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)); + // `assert_implicit_clone!((1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13));` doesn't compile + // `assert_implicit_clone!((NonImplicitCloneType,));` doesn't compile } } From 6789a802a14e5107120b111d1b248dae363b872d Mon Sep 17 00:00:00 2001 From: Cecile Tonglet Date: Sun, 5 Nov 2023 18:20:12 +0100 Subject: [PATCH 05/12] Remove unnecessary usage comments in tests --- src/lib.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index a378105..d41190d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -213,7 +213,6 @@ mod test { #[test] fn option() { assert_implicit_clone!(Some("foo")); - // `assert_implicit_clone!(Some(NonImplicitCloneType));` doesn't compile } #[test] @@ -231,6 +230,5 @@ mod test { assert_implicit_clone!((1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)); assert_implicit_clone!((1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)); // `assert_implicit_clone!((1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13));` doesn't compile - // `assert_implicit_clone!((NonImplicitCloneType,));` doesn't compile } } From 3e44e8a892c91d4702e38845e58e569cb804b63e Mon Sep 17 00:00:00 2001 From: Cecile Tonglet Date: Sun, 5 Nov 2023 18:27:39 +0100 Subject: [PATCH 06/12] Do not test Copy per se --- src/lib.rs | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index d41190d..976ef16 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -138,11 +138,7 @@ macro_rules! imap_deconstruct { mod test { use super::*; - fn assert_implicit_clone(value: &T) -> T { - value.clone() - } - - fn assert_copy(value: &T) -> T { + fn assert_implicit_clone(value: &T) -> T { *value } @@ -152,12 +148,6 @@ mod test { }; } - macro_rules! assert_copy { - ($a:expr) => { - assert_copy(&$a) - }; - } - struct NonImplicitCloneType; #[test] @@ -167,7 +157,9 @@ mod test { impl ImplicitClone for ImplicitCloneType {} - assert_implicit_clone!(ImplicitCloneType); + fn assert_implicit_clone(value: &T) -> T { + value.clone() + } } #[test] @@ -175,7 +167,6 @@ mod test { macro_rules! test_all { ($($t:ty),* $(,)?) => { $(assert_implicit_clone!(<$t>::default());)* - $(assert_copy!(<$t>::default());)* }; } @@ -194,7 +185,6 @@ mod test { macro_rules! test_all_with_value { ($($t:ty => $v:expr),* $(,)?) => { $(assert_implicit_clone!($v);)* - $(assert_copy!($v);)* }; } From 0d9355e7333650e52e473303d527f72b6c671949 Mon Sep 17 00:00:00 2001 From: Cecile Tonglet Date: Sun, 5 Nov 2023 19:09:25 +0100 Subject: [PATCH 07/12] Add example to documentation --- src/lib.rs | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index 976ef16..3ef23c8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -40,6 +40,79 @@ //! particularity: iterating on these types yields clones of the items and not references.** This //! can be particularly handy when using a React-like framework. //! +//! ## Example +//! +//! As an example, here is an implementation of a macro called `html_input! {}` which allows its +//! user to build an `` HTML node: +//! +//! ``` +//! // In the host library source code: +//! +//! use implicit_clone::ImplicitClone; +//! use implicit_clone::unsync::IString; +//! +//! macro_rules! html_input { +//! () => {{ +//! let mut input = Input::new(); +//! $(input.set_type($ty);)* +//! $(input.set_name($name);)* +//! $(input.set_value($value);)* +//! input +//! }} +//! } +//! +//! #[derive(Clone)] +//! pub struct Input { +//! ty: IString, +//! name: Option, +//! value: Option, +//! } +//! +//! impl ImplicitClone for Input {} +//! +//! impl Input { +//! pub fn new() -> Self { +//! Self { +//! ty: IString::Static("text"), +//! name: None, +//! value: None, +//! } +//! } +//! +//! pub fn set_type(&mut self, ty: impl Into) { +//! self.ty = ty.into(); +//! } +//! +//! pub fn set_name(&mut self, name: impl Into) { +//! self.name.replace(name.into()); +//! } +//! +//! pub fn set_value(&mut self, value: impl Into) { +//! self.value.replace(value.into()); +//! } +//! } +//! +//! impl std::fmt::Display for Input { +//! fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +//! write!(f, "") +//! } +//! } +//! +//! // In the user's source code: +//! +//! let age = IString::from(20.to_string()); +//! let input = html_input!(); +//! +//! assert_eq!(input.to_string(), r#""#); +//! ``` +//! //! [std::marker::Copy]: https://doc.rust-lang.org/std/marker/trait.Copy.html //! [std::clone::Clone]: https://doc.rust-lang.org/std/clone/trait.Clone.html //! [std::rc::Rc]: https://doc.rust-lang.org/std/rc/struct.Rc.html From ac67764ff7a02f6f448a2e69be43a0be775debe0 Mon Sep 17 00:00:00 2001 From: Cecile Tonglet Date: Sun, 5 Nov 2023 19:09:40 +0100 Subject: [PATCH 08/12] Fix wrong assertion --- src/lib.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 3ef23c8..9191068 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -230,8 +230,12 @@ mod test { impl ImplicitClone for ImplicitCloneType {} - fn assert_implicit_clone(value: &T) -> T { - value.clone() + #[allow(dead_code)] + fn assert_ok() { + fn assert_implicit_clone(value: &T) -> T { + unreachable!() + } + assert_implicit_clone(&ImplicitCloneType); } } From 95de8ac60d2185e13a21dc015994a6053be84db2 Mon Sep 17 00:00:00 2001 From: Cecile Tonglet Date: Sun, 5 Nov 2023 19:31:22 +0100 Subject: [PATCH 09/12] Improve example --- src/lib.rs | 25 ++++++++----------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 9191068..aba5649 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -54,9 +54,9 @@ //! macro_rules! html_input { //! () => {{ //! let mut input = Input::new(); -//! $(input.set_type($ty);)* -//! $(input.set_name($name);)* -//! $(input.set_value($value);)* +//! $(input.type = $ty.clone().into();)* +//! $(input.name.replace($name.clone().into());)* +//! $(input.value.replace($value.clone().into());)* //! input //! }} //! } @@ -78,18 +78,6 @@ //! value: None, //! } //! } -//! -//! pub fn set_type(&mut self, ty: impl Into) { -//! self.ty = ty.into(); -//! } -//! -//! pub fn set_name(&mut self, name: impl Into) { -//! self.name.replace(name.into()); -//! } -//! -//! pub fn set_value(&mut self, value: impl Into) { -//! self.value.replace(value.into()); -//! } //! } //! //! impl std::fmt::Display for Input { @@ -108,9 +96,12 @@ //! // In the user's source code: //! //! let age = IString::from(20.to_string()); -//! let input = html_input!(); +//! // `age` is implicitly cloned to the 2 different inputs +//! let input1 = html_input!(); +//! let input2 = html_input!(); //! -//! assert_eq!(input.to_string(), r#""#); +//! assert_eq!(input1.to_string(), r#""#); +//! assert_eq!(input2.to_string(), r#""#); //! ``` //! //! [std::marker::Copy]: https://doc.rust-lang.org/std/marker/trait.Copy.html From 15804b6ff131a92878aab1be45fad78e1778a659 Mon Sep 17 00:00:00 2001 From: Cecile Tonglet Date: Sun, 5 Nov 2023 19:31:31 +0100 Subject: [PATCH 10/12] clippy --- src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index aba5649..40d8f7e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -223,7 +223,7 @@ mod test { #[allow(dead_code)] fn assert_ok() { - fn assert_implicit_clone(value: &T) -> T { + fn assert_implicit_clone(_value: &T) -> T { unreachable!() } assert_implicit_clone(&ImplicitCloneType); From 2a39bcda0ef19e988b07dfcf0dba5d54ddeb5b71 Mon Sep 17 00:00:00 2001 From: Cecile Tonglet Date: Sun, 5 Nov 2023 19:37:28 +0100 Subject: [PATCH 11/12] meh --- src/lib.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 40d8f7e..973f14a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -95,10 +95,11 @@ //! //! // In the user's source code: //! +//! let name = IString::Static("age"); //! let age = IString::from(20.to_string()); -//! // `age` is implicitly cloned to the 2 different inputs -//! let input1 = html_input!(); -//! let input2 = html_input!(); +//! // `name` and `age` are implicitly cloned to the 2 different inputs +//! let input1 = html_input!(); +//! let input2 = html_input!(); //! //! assert_eq!(input1.to_string(), r#""#); //! assert_eq!(input2.to_string(), r#""#); From b129b62d915a040de7ee33b0a7c0e1cebf5c249d Mon Sep 17 00:00:00 2001 From: Cecile Tonglet Date: Thu, 9 Nov 2023 11:23:09 +0100 Subject: [PATCH 12/12] Revert re-documentation process to focus on PR change --- src/lib.rs | 133 +++++++++++------------------------------------------ 1 file changed, 27 insertions(+), 106 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 973f14a..6ea77e1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -40,71 +40,6 @@ //! particularity: iterating on these types yields clones of the items and not references.** This //! can be particularly handy when using a React-like framework. //! -//! ## Example -//! -//! As an example, here is an implementation of a macro called `html_input! {}` which allows its -//! user to build an `` HTML node: -//! -//! ``` -//! // In the host library source code: -//! -//! use implicit_clone::ImplicitClone; -//! use implicit_clone::unsync::IString; -//! -//! macro_rules! html_input { -//! () => {{ -//! let mut input = Input::new(); -//! $(input.type = $ty.clone().into();)* -//! $(input.name.replace($name.clone().into());)* -//! $(input.value.replace($value.clone().into());)* -//! input -//! }} -//! } -//! -//! #[derive(Clone)] -//! pub struct Input { -//! ty: IString, -//! name: Option, -//! value: Option, -//! } -//! -//! impl ImplicitClone for Input {} -//! -//! impl Input { -//! pub fn new() -> Self { -//! Self { -//! ty: IString::Static("text"), -//! name: None, -//! value: None, -//! } -//! } -//! } -//! -//! impl std::fmt::Display for Input { -//! fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { -//! write!(f, "") -//! } -//! } -//! -//! // In the user's source code: -//! -//! let name = IString::Static("age"); -//! let age = IString::from(20.to_string()); -//! // `name` and `age` are implicitly cloned to the 2 different inputs -//! let input1 = html_input!(); -//! let input2 = html_input!(); -//! -//! assert_eq!(input1.to_string(), r#""#); -//! assert_eq!(input2.to_string(), r#""#); -//! ``` -//! //! [std::marker::Copy]: https://doc.rust-lang.org/std/marker/trait.Copy.html //! [std::clone::Clone]: https://doc.rust-lang.org/std/clone/trait.Clone.html //! [std::rc::Rc]: https://doc.rust-lang.org/std/rc/struct.Rc.html @@ -203,13 +138,13 @@ macro_rules! imap_deconstruct { mod test { use super::*; - fn assert_implicit_clone(value: &T) -> T { - *value + fn host_library(value: &T) -> T { + value.clone() } - macro_rules! assert_implicit_clone { + macro_rules! host_library { ($a:expr) => { - assert_implicit_clone(&$a) + host_library(&$a) }; } @@ -222,20 +157,17 @@ mod test { impl ImplicitClone for ImplicitCloneType {} - #[allow(dead_code)] - fn assert_ok() { - fn assert_implicit_clone(_value: &T) -> T { - unreachable!() - } - assert_implicit_clone(&ImplicitCloneType); - } + host_library!(ImplicitCloneType); } #[test] fn copy_types() { + fn assert_copy(_: T) {} + macro_rules! test_all { ($($t:ty),* $(,)?) => { - $(assert_implicit_clone!(<$t>::default());)* + $(host_library!(<$t>::default());)* + $(assert_copy(<$t>::default());)* }; } @@ -247,47 +179,36 @@ mod test { bool, usize, isize, char, (), - [u8; 4], - &[u8], - ); - - macro_rules! test_all_with_value { - ($($t:ty => $v:expr),* $(,)?) => { - $(assert_implicit_clone!($v);)* - }; - } - - #[rustfmt::skip] - test_all_with_value!( - &[u8; 4] => &[0, 1, 2, 3], ); } #[test] fn ref_type() { - assert_implicit_clone!(&NonImplicitCloneType); - // `assert_implicit_clone!(NonImplicitCloneType)` doesn't compile + host_library!(&NonImplicitCloneType); + // `host_library!(NonImplicitCloneType)` doesn't compile } #[test] fn option() { - assert_implicit_clone!(Some("foo")); + host_library!(Some("foo")); + // `host_library!(Some(NonImplicitCloneType));` doesn't compile } #[test] fn tuples() { - assert_implicit_clone!((1,)); - assert_implicit_clone!((1, 2)); - assert_implicit_clone!((1, 2, 3)); - assert_implicit_clone!((1, 2, 3, 4)); - assert_implicit_clone!((1, 2, 3, 4, 5)); - assert_implicit_clone!((1, 2, 3, 4, 5, 6)); - assert_implicit_clone!((1, 2, 3, 4, 5, 6, 7)); - assert_implicit_clone!((1, 2, 3, 4, 5, 6, 7, 8)); - assert_implicit_clone!((1, 2, 3, 4, 5, 6, 7, 8, 9)); - assert_implicit_clone!((1, 2, 3, 4, 5, 6, 7, 8, 9, 10)); - assert_implicit_clone!((1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)); - assert_implicit_clone!((1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)); - // `assert_implicit_clone!((1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13));` doesn't compile + host_library!((1,)); + host_library!((1, 2)); + host_library!((1, 2, 3)); + host_library!((1, 2, 3, 4)); + host_library!((1, 2, 3, 4, 5)); + host_library!((1, 2, 3, 4, 5, 6)); + host_library!((1, 2, 3, 4, 5, 6, 7)); + host_library!((1, 2, 3, 4, 5, 6, 7, 8)); + host_library!((1, 2, 3, 4, 5, 6, 7, 8, 9)); + host_library!((1, 2, 3, 4, 5, 6, 7, 8, 9, 10)); + host_library!((1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)); + host_library!((1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)); + // `host_library!((1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13));` doesn't compile + // `host_library!((NonImplicitCloneType,));` doesn't compile } }