rbatis_codegen/
ops.rs

1use rbs::Value;
2use std::cmp::Ordering;
3pub use std::ops::Index;
4
5/// convert Value to Value
6pub trait AsProxy {
7    fn i32(&self) -> i32;
8    fn i64(&self) -> i64;
9    fn u32(&self) -> u32;
10    fn u64(&self) -> u64;
11    fn f64(&self) -> f64;
12    fn usize(&self) -> usize;
13    fn bool(&self) -> bool;
14
15    fn string(&self) -> String;
16    fn as_binary(&self) -> Vec<u8>;
17}
18
19impl AsProxy for Value {
20    fn i32(&self) -> i32 {
21        self.as_i64().unwrap_or_default() as i32
22    }
23
24    fn i64(&self) -> i64 {
25        self.as_i64().unwrap_or_default()
26    }
27
28    fn u32(&self) -> u32 {
29        self.as_u64().unwrap_or_default() as u32
30    }
31
32    fn u64(&self) -> u64 {
33        self.as_u64().unwrap_or_default()
34    }
35
36    fn f64(&self) -> f64 {
37        self.as_f64().unwrap_or_default()
38    }
39
40    fn string(&self) -> String {
41        match self {
42            Value::String(v) => v.to_string(),
43            Value::Ext(_, ext) => ext.as_string().unwrap_or_default(),
44            _ => self.to_string(),
45        }
46    }
47
48    fn bool(&self) -> bool {
49        self.as_bool().unwrap_or_default()
50    }
51
52    fn as_binary(&self) -> Vec<u8> {
53        match self {
54            Value::Binary(s) => s.to_owned(),
55            _ => vec![],
56        }
57    }
58
59    fn usize(&self) -> usize {
60        self.as_u64().unwrap_or_default() as usize
61    }
62}
63
64impl AsProxy for bool {
65    fn i32(&self) -> i32 {
66        if *self {
67            1
68        } else {
69            0
70        }
71    }
72
73    fn i64(&self) -> i64 {
74        if *self {
75            1
76        } else {
77            0
78        }
79    }
80
81    fn u32(&self) -> u32 {
82        if *self {
83            1
84        } else {
85            0
86        }
87    }
88
89    fn u64(&self) -> u64 {
90        if *self {
91            1
92        } else {
93            0
94        }
95    }
96
97    fn usize(&self) -> usize {
98        if *self {
99            1
100        } else {
101            0
102        }
103    }
104
105    fn f64(&self) -> f64 {
106        if *self {
107            1.0
108        } else {
109            0.0
110        }
111    }
112
113    fn bool(&self) -> bool {
114        *self
115    }
116
117    fn string(&self) -> String {
118        self.to_string()
119    }
120
121    fn as_binary(&self) -> Vec<u8> {
122        if *self {
123            vec![1u8]
124        } else {
125            vec![0u8]
126        }
127    }
128}
129
130impl AsProxy for String {
131    fn i32(&self) -> i32 {
132        self.parse().unwrap_or_default()
133    }
134
135    fn i64(&self) -> i64 {
136        self.parse().unwrap_or_default()
137    }
138
139    fn u32(&self) -> u32 {
140        self.parse().unwrap_or_default()
141    }
142
143    fn u64(&self) -> u64 {
144        self.parse().unwrap_or_default()
145    }
146
147    fn usize(&self) -> usize {
148        self.parse().unwrap_or_default()
149    }
150
151    fn f64(&self) -> f64 {
152        self.parse().unwrap_or_default()
153    }
154
155    fn bool(&self) -> bool {
156        self.parse().unwrap_or_default()
157    }
158
159    fn string(&self) -> String {
160        self.to_string()
161    }
162
163    fn as_binary(&self) -> Vec<u8> {
164        self.to_string().into_bytes()
165    }
166}
167
168impl AsProxy for str {
169    fn i32(&self) -> i32 {
170        self.parse().unwrap_or_default()
171    }
172
173    fn i64(&self) -> i64 {
174        self.parse().unwrap_or_default()
175    }
176
177    fn u32(&self) -> u32 {
178        self.parse().unwrap_or_default()
179    }
180
181    fn u64(&self) -> u64 {
182        self.parse().unwrap_or_default()
183    }
184
185    fn usize(&self) -> usize {
186        self.parse().unwrap_or_default()
187    }
188
189    fn f64(&self) -> f64 {
190        self.parse().unwrap_or_default()
191    }
192
193    fn bool(&self) -> bool {
194        self.parse().unwrap_or_default()
195    }
196
197    fn string(&self) -> String {
198        self.to_string()
199    }
200
201    fn as_binary(&self) -> Vec<u8> {
202        self.to_string().into_bytes()
203    }
204}
205
206macro_rules! as_number {
207    ($ty:ty,$bool_expr:expr) => {
208        impl AsProxy for $ty {
209            fn i32(&self) -> i32 {
210                *self as i32
211            }
212
213            fn i64(&self) -> i64 {
214                *self as i64
215            }
216
217            fn u32(&self) -> u32 {
218                *self as u32
219            }
220
221            fn u64(&self) -> u64 {
222                *self as u64
223            }
224
225            fn usize(&self) -> usize {
226                *self as usize
227            }
228
229            fn f64(&self) -> f64 {
230                *self as f64
231            }
232
233            fn string(&self) -> String {
234                self.to_string()
235            }
236
237            fn bool(&self) -> bool {
238                //*self==1
239                if *self == $bool_expr {
240                    true
241                } else {
242                    false
243                }
244            }
245
246            fn as_binary(&self) -> Vec<u8> {
247                self.to_string().into_bytes()
248            }
249        }
250    };
251}
252
253as_number!(i8, 1i8);
254as_number!(i16, 1i16);
255as_number!(i32, 1i32);
256as_number!(i64, 1i64);
257as_number!(isize, 1isize);
258
259as_number!(u8, 1u8);
260as_number!(u16, 1u16);
261as_number!(u32, 1u32);
262as_number!(u64, 1u64);
263as_number!(usize, 1usize);
264
265as_number!(f32, 1.0);
266as_number!(f64, 1.0);
267
268pub trait PartialEq<Rhs: ?Sized = Self> {
269    /// This method tests for `self` and `other` values to be equal, and is used
270    /// by `==`.
271    #[must_use]
272    //#[stable(feature = "rust1", since = "1.0.0")]
273    fn op_eq(&self, other: &Rhs) -> bool;
274
275    /// This method tests for `!=`.
276    #[inline]
277    #[must_use]
278    //#[stable(feature = "rust1", since = "1.0.0")]
279    fn op_ne(&self, other: &Rhs) -> bool {
280        !self.op_eq(other)
281    }
282}
283
284pub trait PartialOrd<Rhs: ?Sized = Self> {
285    /// This method returns an ordering between `self` and `other` values if one exists.
286    ///
287    /// # Examples
288    ///
289    /// ```
290    ///
291    ///
292    /// use std::cmp::Ordering;
293    /// use rbatis_codegen::ops::PartialOrd;
294    /// let result = 1.0.op_partial_cmp(&2.0);
295    /// assert_eq!(result, Some(Ordering::Less));
296    ///
297    /// let result = 1.0.op_partial_cmp(&1.0);
298    /// assert_eq!(result, Some(Ordering::Equal));
299    ///
300    /// let result = 2.0.op_partial_cmp(&1.0);
301    /// assert_eq!(result, Some(Ordering::Greater));
302    /// ```
303    ///
304    /// When comparison is impossible:
305    ///
306    /// ```
307    /// use rbatis_codegen::ops::PartialOrd;
308    /// let result = f64::NAN.op_partial_cmp(&1.0);
309    /// assert_eq!(result, None);
310    /// ```
311    #[must_use]
312    fn op_partial_cmp(&self, other: &Rhs) -> Option<Ordering>;
313
314    /// This method tests less than (for `self` and `other`) and is used by the `<` operator.
315    ///
316    /// # Examples
317    ///
318    /// ```
319    /// let result = 1.0 < 2.0;
320    /// assert_eq!(result, true);
321    ///
322    /// let result = 2.0 < 1.0;
323    /// assert_eq!(result, false);
324    /// ```
325    #[inline]
326    #[must_use]
327    fn op_lt(&self, other: &Rhs) -> bool {
328        self.op_partial_cmp(other).eq(&Some(Ordering::Less))
329    }
330
331    /// This method tests less than or equal to (for `self` and `other`) and is used by the `<=`
332    /// operator.
333    ///
334    /// # Examples
335    ///
336    /// ```
337    /// let result = 1.0 <= 2.0;
338    /// assert_eq!(result, true);
339    ///
340    /// let result = 2.0 <= 2.0;
341    /// assert_eq!(result, true);
342    /// ```
343    #[inline]
344    #[must_use]
345    fn op_le(&self, other: &Rhs) -> bool {
346        let v = self.op_partial_cmp(other);
347        !v.eq(&None) | v.eq(&Some(Ordering::Greater))
348    }
349
350    /// This method tests greater than (for `self` and `other`) and is used by the `>` operator.
351    ///
352    /// # Examples
353    ///
354    /// ```
355    /// let result = 1.0 > 2.0;
356    /// assert_eq!(result, false);
357    ///
358    /// let result = 2.0 > 2.0;
359    /// assert_eq!(result, false);
360    /// ```
361    #[inline]
362    fn op_gt(&self, other: &Rhs) -> bool {
363        self.op_partial_cmp(other).eq(&Some(Ordering::Greater))
364    }
365
366    /// This method tests greater than or equal to (for `self` and `other`) and is used by the `>=`
367    /// operator.
368    ///
369    /// # Examples
370    ///
371    /// ```
372    /// let result = 2.0 >= 1.0;
373    /// assert_eq!(result, true);
374    ///
375    /// let result = 2.0 >= 2.0;
376    /// assert_eq!(result, true);
377    /// ```
378    #[inline]
379    #[must_use]
380    fn op_ge(&self, other: &Rhs) -> bool {
381        let v = self.op_partial_cmp(other);
382        v.eq(&Some(Ordering::Greater)) | v.eq(&Some(Ordering::Equal))
383    }
384}
385
386pub trait Add<Rhs = Self> {
387    /// The resulting type after applying the `+` operator.
388    //#[stable(feature = "rust1", since = "1.0.0")]
389    type Output;
390
391    /// Performs the `+` operation.
392    ///
393    /// # Example
394    ///
395    /// ```
396    /// assert_eq!(12 + 1, 13);
397    /// ```
398    #[must_use]
399    //#[stable(feature = "rust1", since = "1.0.0")]
400    fn op_add(self, rhs: Rhs) -> Self::Output;
401}
402
403pub trait Sub<Rhs = Self> {
404    /// The resulting type after applying the `-` operator.
405    type Output;
406
407    /// Performs the `-` operation.
408    ///
409    /// # Example
410    ///
411    /// ```
412    /// assert_eq!(12 - 1, 11);
413    /// ```
414    #[must_use]
415    fn op_sub(self, rhs: Rhs) -> Self::Output;
416}
417
418pub trait Mul<Rhs = Self> {
419    /// The resulting type after applying the `*` operator.
420    type Output;
421
422    /// Performs the `*` operation.
423    ///
424    /// # Example
425    ///
426    /// ```
427    /// assert_eq!(12 * 2, 24);
428    /// ```
429    #[must_use]
430    fn op_mul(self, rhs: Rhs) -> Self::Output;
431}
432
433pub trait Div<Rhs = Self> {
434    /// The resulting type after applying the `/` operator.
435    type Output;
436
437    /// Performs the `/` operation.
438    ///
439    /// # Example
440    ///
441    /// ```
442    /// assert_eq!(12 / 2, 6);
443    /// ```
444    #[must_use]
445    fn op_div(self, rhs: Rhs) -> Self::Output;
446}
447
448pub trait Rem<Rhs = Self> {
449    /// The resulting type after applying the `%` operator.
450    type Output;
451
452    /// Performs the `%` operation.
453    ///
454    /// # Example
455    ///
456    /// ```
457    /// assert_eq!(12 % 10, 2);
458    /// ```
459    #[must_use]
460    fn op_rem(self, rhs: Rhs) -> Self::Output;
461}
462
463pub trait Not {
464    /// The resulting type after applying the `!` operator.
465    type Output;
466
467    /// Performs the unary `!` operation.
468    ///
469    /// # Examples
470    ///
471    /// ```
472    /// assert_eq!(!true, false);
473    /// assert_eq!(!false, true);
474    /// assert_eq!(!1u8, 254);
475    /// assert_eq!(!0u8, 255);
476    /// ```
477    #[must_use]
478    fn op_not(self) -> Self::Output;
479}
480
481pub trait BitAnd<Rhs = Self> {
482    /// The resulting type after applying the `&` operator.
483    type Output;
484
485    /// Performs the `&` operation.
486    ///
487    /// # Examples
488    ///
489    /// ```
490    /// assert_eq!(true & false, false);
491    /// assert_eq!(true & true, true);
492    /// assert_eq!(5u8 & 1u8, 1);
493    /// assert_eq!(5u8 & 2u8, 0);
494    /// ```
495    #[must_use]
496    fn op_bitand(self, rhs: Rhs) -> Self::Output;
497}
498
499pub trait BitOr<Rhs = Self> {
500    /// The resulting type after applying the `|` operator.
501    type Output;
502
503    /// Performs the `|` operation.
504    ///
505    /// # Examples
506    ///
507    /// ```
508    /// assert_eq!(true | false, true);
509    /// assert_eq!(false | false, false);
510    /// assert_eq!(5u8 | 1u8, 5);
511    /// assert_eq!(5u8 | 2u8, 7);
512    /// ```
513    #[must_use]
514    fn op_bitor(self, rhs: Rhs) -> Self::Output;
515}
516
517pub trait BitXor<Rhs = Self> {
518    /// The resulting type after applying the `^` operator.
519    type Output;
520
521    /// Performs the `^` operation.
522    ///
523    /// # Examples
524    ///
525    /// ```
526    /// assert_eq!(true ^ false, true);
527    /// assert_eq!(true ^ true, false);
528    /// assert_eq!(5u8 ^ 1u8, 4);
529    /// assert_eq!(5u8 ^ 2u8, 7);
530    /// ```
531    #[must_use]
532    fn op_bitxor(self, rhs: Rhs) -> Self::Output;
533}
534
535pub trait OpsIndex<Idx: ?Sized> {
536    /// The returned type after indexing.
537    type Output: ?Sized;
538
539    /// Performs the indexing (`container[index]`) operation.
540    ///
541    /// # Panics
542    ///
543    /// May panic if the index is out of bounds.
544    #[track_caller]
545    fn index(&self, index: Idx) -> &Self::Output;
546}
547
548pub trait OpsIndexMut<Idx: ?Sized>: OpsIndex<Idx> {
549    /// Performs the mutable indexing (`container[index]`) operation.
550    ///
551    /// # Panics
552    ///
553    /// May panic if the index is out of bounds.
554    #[track_caller]
555    fn index_mut(&mut self, index: Idx) -> &mut Self::Output;
556}
557
558pub trait From<T>: Sized {
559    /// Performs the conversion.
560    fn op_from(_: T) -> Self;
561}
562
563pub trait Neg {
564    /// The resulting type after applying the `-` operator.
565    type Output;
566
567    /// Performs the unary `-` operation.
568    ///
569    /// # Example
570    ///
571    /// ```
572    /// let x: i32 = 12;
573    /// assert_eq!(-x, -12);
574    /// ```
575    #[must_use = "this returns the result of the operation, without modifying the original"]
576    fn neg(self) -> Self::Output;
577}
578
579
580/// string contains method
581pub trait StrMethods {
582    fn contains_str(self, s: &str) -> bool;
583    fn starts_with(self, other: &str) -> bool;
584    fn ends_with(self, other: &str) -> bool;
585}
586
587
588#[cfg(test)]
589mod test {
590    use crate::ops::AsProxy;
591    use rbs::{value};
592
593    #[test]
594    fn test_cast() {
595        let b = value!(u64::MAX);
596        assert_eq!(b.i64(), -1);
597        let b = value!(100u64);
598        assert_eq!(b.i64(), 100i64);
599    }
600}