1pub trait AsCopy<T> {
2 #[allow(clippy::wrong_self_convention)]
3 fn as_copy(self) -> T;
4}
5
6impl<T: Copy> AsCopy<T> for T {
7 fn as_copy(self) -> T {
8 self
9 }
10}
11
12impl<T: Copy + AsCopy<T>> AsCopy<T> for &T {
13 fn as_copy(self) -> T {
14 (*self).as_copy()
15 }
16}
17
18#[cfg(test)]
19mod tests {
20 use std::{
21 fmt::Debug,
22 net::{IpAddr, Ipv4Addr},
23 };
24
25 use super::*;
26
27 #[derive(Debug, PartialEq, Default)]
28 struct MyStruct(usize);
29
30 impl Clone for MyStruct {
31 #[allow(clippy::non_canonical_clone_impl)]
32 fn clone(&self) -> Self {
33 Self(self.0 + 1)
34 }
35 }
36
37 impl Copy for MyStruct {}
38
39 #[test]
40 fn as_copy_should_call_copy_on_a_reference() {
41 let source = MyStruct::default();
42 let copied = source;
43
44 fn takes_impl<T>(arg: impl AsCopy<T>) -> T {
45 arg.as_copy()
46 }
47
48 assert_eq!(
49 copied,
50 takes_impl(
51 #[allow(clippy::needless_borrows_for_generic_args)]
52 &source
53 )
54 );
55 }
56
57 #[test]
58 fn as_copy_should_return_an_owned_value_unchanged() {
59 let source = MyStruct::default();
60 let equal = MyStruct::default();
61
62 fn takes_impl<T>(arg: impl AsCopy<T>) -> T {
63 arg.as_copy()
64 }
65
66 assert_eq!(equal, takes_impl(source));
67 }
68
69 #[test]
70 fn as_copy_should_work_with_any_copyable_type() {
71 fn case(value: impl Copy + Debug + PartialEq) {
72 assert_eq!(value, value.as_copy());
73 }
74
75 case("Hello, world!");
76 case(123);
77 case(IpAddr::V4(Ipv4Addr::new(192, 168, 0, 1)));
78 }
79}