pipebase/common/
project.rs1pub trait Project<Rhs = Self> {
3 fn project(rhs: &Rhs) -> Self;
4}
5
6impl Project<bool> for bool {
7 fn project(from: &bool) -> bool {
8 *from
9 }
10}
11
12impl Project<i8> for i8 {
13 fn project(from: &i8) -> i8 {
14 *from
15 }
16}
17
18impl Project<u8> for u8 {
19 fn project(from: &u8) -> u8 {
20 *from
21 }
22}
23
24impl Project<i16> for i16 {
25 fn project(from: &i16) -> i16 {
26 *from
27 }
28}
29
30impl Project<u16> for u16 {
31 fn project(from: &u16) -> u16 {
32 *from
33 }
34}
35
36impl Project<i32> for i32 {
37 fn project(from: &i32) -> i32 {
38 *from
39 }
40}
41
42impl Project<u32> for u32 {
43 fn project(from: &u32) -> u32 {
44 *from
45 }
46}
47
48impl Project<isize> for isize {
49 fn project(from: &isize) -> isize {
50 *from
51 }
52}
53
54impl Project<usize> for usize {
55 fn project(from: &usize) -> usize {
56 *from
57 }
58}
59
60impl Project<i64> for i64 {
61 fn project(from: &i64) -> i64 {
62 *from
63 }
64}
65
66impl Project<u64> for u64 {
67 fn project(from: &u64) -> u64 {
68 *from
69 }
70}
71
72impl Project<i128> for i128 {
73 fn project(from: &i128) -> i128 {
74 *from
75 }
76}
77
78impl Project<u128> for u128 {
79 fn project(from: &u128) -> u128 {
80 *from
81 }
82}
83
84impl Project<f32> for f32 {
85 fn project(from: &f32) -> f32 {
86 *from
87 }
88}
89
90impl Project<f64> for f64 {
91 fn project(from: &f64) -> f64 {
92 *from
93 }
94}
95
96impl Project<char> for char {
97 fn project(from: &char) -> char {
98 *from
99 }
100}
101
102impl Project<String> for String {
103 fn project(from: &String) -> String {
104 from.clone()
105 }
106}
107
108impl<T, U: Project<T>> Project<Option<T>> for Option<U> {
109 fn project(from: &Option<T>) -> Option<U> {
110 from.as_ref().map(|t| U::project(t))
111 }
112}
113
114impl<T, U, const N: usize> Project<[T; N]> for [U; N]
116where
117 U: Project<T> + Default + Copy,
118{
119 fn project(from: &[T; N]) -> [U; N] {
120 let mut to: [U; N] = [U::default(); N];
121 for i in 0..N {
122 to[i] = U::project(&from[i])
123 }
124 to
125 }
126}
127
128impl<T, U> Project<Vec<T>> for Vec<U>
130where
131 U: Project<T>,
132{
133 fn project(from: &Vec<T>) -> Vec<U> {
134 let to: Vec<U> = from.iter().map(|item| U::project(item)).collect();
135 to
136 }
137}
138
139#[cfg(test)]
140mod tests {
141
142 use crate::prelude::*;
143
144 #[derive(Debug)]
145 struct Record {
146 pub r0: i32,
147 pub r1: i32,
148 }
149
150 #[derive(Debug, Project)]
151 #[project(input = "self::Record")]
152 struct SwappedRecord {
153 #[project(from = "r1")]
154 pub r0: i32,
155 #[project(from = "r0")]
156 pub r1: i32,
157 }
158
159 #[test]
160 fn test_swap() {
161 let origin = Record { r0: 0, r1: 1 };
162 let swapped: SwappedRecord = Project::project(&origin);
163 assert_eq!(1, swapped.r0);
164 assert_eq!(0, swapped.r1);
165 }
166
167 #[derive(Debug, Project)]
168 #[project(input = "Record")]
169 struct RecordSumPlusOne {
170 #[project(alias = "r", expr = "let mut s = r.r0 + r.r1; s + 1")]
171 pub s: i32,
172 }
173
174 #[test]
175 fn test_sum_plus_one() {
176 let origin = Record { r0: 1, r1: 1 };
177 let sum = RecordSumPlusOne::project(&origin);
178 assert_eq!(3, sum.s);
179 }
180}