Skip to main content

rbatis_codegen/
ops_add.rs

1use crate::ops::{Add, AsProxy};
2use crate::ops_macros::{impl_numeric_binary_op, impl_same_type_binary_op, impl_value_binary_op};
3use rbs::Value;
4
5fn op_add_u64(value: &Value, other: u64) -> u64 {
6    value.u64() + other
7}
8
9fn op_add_i64(value: &Value, other: i64) -> i64 {
10    value.i64() + other
11}
12
13fn op_add_f64(value: &Value, other: f64) -> f64 {
14    value.f64() + other
15}
16
17fn op_add_value(left: Value, rhs: Value) -> Value {
18    match left {
19        Value::String(s) => Value::String(s + rhs.as_str().unwrap_or("")),
20        Value::I32(s) => Value::I32(s + rhs.i32()),
21        Value::I64(s) => Value::I64(s + rhs.i64()),
22        Value::U32(s) => Value::U32(s + rhs.u32()),
23        Value::U64(s) => Value::U64(s + rhs.u64()),
24        Value::F64(s) => Value::F64(s + rhs.f64()),
25        Value::F32(v) => Value::F32(v + rhs.f64() as f32),
26        Value::Ext(_, e) => op_add_value(*e, rhs),
27        _ => Value::Null,
28    }
29}
30
31impl_value_binary_op!(Add, op_add, op_add_value);
32impl_numeric_binary_op!(
33    Add,
34    op_add,
35    op_add_u64,
36    op_add_u64,
37    [u8, u16, u32, u64],
38    u64
39);
40impl_numeric_binary_op!(
41    Add,
42    op_add,
43    op_add_i64,
44    op_add_i64,
45    [i8, i16, i32, i64, isize, usize],
46    i64
47);
48impl_numeric_binary_op!(Add, op_add, op_add_f64, op_add_f64, [f32, f64], f64);
49impl_same_type_binary_op!(
50    Add,
51    op_add,
52    +,
53    [
54        u8, u16, u32, u64, i8, i16, i32, i64, isize, usize, f32, f64
55    ]
56);
57
58macro_rules! impl_value_string_add {
59    ($($rhs:ty),* $(,)?) => {
60        $(
61            impl Add<$rhs> for Value {
62                type Output = Value;
63
64                fn op_add(self, rhs: $rhs) -> Self::Output {
65                    Value::String(self.string() + &rhs.to_string())
66                }
67            }
68
69            impl Add<$rhs> for &Value {
70                type Output = Value;
71
72                fn op_add(self, rhs: $rhs) -> Self::Output {
73                    Value::String(self.string() + &rhs.to_string())
74                }
75            }
76
77            impl Add<$rhs> for &&Value {
78                type Output = Value;
79
80                fn op_add(self, rhs: $rhs) -> Self::Output {
81                    Value::String(self.string() + &rhs.to_string())
82                }
83            }
84        )*
85    };
86}
87
88impl_value_string_add!(&str, &&str, String, &String, &&String);
89
90macro_rules! impl_string_value_add {
91    ($($lhs:ty),* $(,)?) => {
92        $(
93            impl Add<Value> for $lhs {
94                type Output = String;
95
96                fn op_add(self, rhs: Value) -> Self::Output {
97                    self.to_string() + &rhs.string()
98                }
99            }
100
101            impl Add<&Value> for $lhs {
102                type Output = String;
103
104                fn op_add(self, rhs: &Value) -> Self::Output {
105                    self.to_string() + &rhs.string()
106                }
107            }
108
109            impl Add<&&Value> for $lhs {
110                type Output = String;
111
112                fn op_add(self, rhs: &&Value) -> Self::Output {
113                    self.to_string() + &rhs.string()
114                }
115            }
116        )*
117    };
118}
119
120impl_string_value_add!(&str, &&str, String, &String, &&String);
121
122impl Add<&str> for String {
123    type Output = String;
124
125    fn op_add(self, rhs: &str) -> Self::Output {
126        self + rhs
127    }
128}
129
130impl Add<&&str> for String {
131    type Output = String;
132
133    fn op_add(self, rhs: &&str) -> Self::Output {
134        self + *rhs
135    }
136}
137
138impl Add<String> for String {
139    type Output = String;
140
141    fn op_add(self, rhs: String) -> Self::Output {
142        self + &rhs
143    }
144}
145
146impl Add<&String> for String {
147    type Output = String;
148
149    fn op_add(self, rhs: &String) -> Self::Output {
150        self + rhs.as_str()
151    }
152}
153
154impl Add<&&String> for String {
155    type Output = String;
156
157    fn op_add(self, rhs: &&String) -> Self::Output {
158        self + rhs.as_str()
159    }
160}
161
162impl Add<String> for &str {
163    type Output = String;
164
165    fn op_add(self, rhs: String) -> Self::Output {
166        self.to_string() + &rhs
167    }
168}
169
170impl Add<&String> for &str {
171    type Output = String;
172
173    fn op_add(self, rhs: &String) -> Self::Output {
174        self.to_string() + rhs.as_str()
175    }
176}
177
178impl Add<&&String> for &str {
179    type Output = String;
180
181    fn op_add(self, rhs: &&String) -> Self::Output {
182        self.to_string() + rhs.as_str()
183    }
184}
185
186impl Add<&str> for &str {
187    type Output = String;
188
189    fn op_add(self, rhs: &str) -> Self::Output {
190        self.to_string() + rhs
191    }
192}
193
194impl Add<&&str> for &str {
195    type Output = String;
196
197    fn op_add(self, rhs: &&str) -> Self::Output {
198        self.to_string() + rhs
199    }
200}
201
202impl Add<&str> for &&str {
203    type Output = String;
204
205    fn op_add(self, rhs: &str) -> Self::Output {
206        self.to_string() + rhs
207    }
208}
209
210impl Add<&&str> for &&str {
211    type Output = String;
212
213    fn op_add(self, rhs: &&str) -> Self::Output {
214        self.to_string() + rhs
215    }
216}
217
218#[cfg(test)]
219mod test {
220    use crate::ops::Add;
221    use rbs::{value, Value};
222
223    #[test]
224    fn test_add() {
225        let i: i64 = 1;
226        let v = value!(1);
227        assert_eq!((&v).op_add(&i), 2i64);
228        assert_eq!(v.op_add(&i), 2i64);
229        assert_eq!(Value::I32(1).op_add(&&Value::I32(2)), Value::I32(3));
230    }
231
232    #[test]
233    fn test_string_reference_matrix() {
234        let value = Value::String("left".to_string());
235        assert_eq!(
236            value.op_add("right"),
237            Value::String("leftright".to_string())
238        );
239        assert_eq!(
240            (&Value::String("left".to_string())).op_add("right"),
241            Value::String("leftright".to_string())
242        );
243        assert_eq!(
244            "left".op_add(&Value::String("right".to_string())),
245            "leftright"
246        );
247    }
248}