Skip to main content

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! impl_as_proxy_number {
207    ($ty:ty, $truthy: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 == $truthy
239            }
240
241            fn as_binary(&self) -> Vec<u8> {
242                self.to_string().into_bytes()
243            }
244        }
245    };
246}
247
248impl_as_proxy_number!(i8, 1i8);
249impl_as_proxy_number!(i16, 1i16);
250impl_as_proxy_number!(i32, 1i32);
251impl_as_proxy_number!(i64, 1i64);
252impl_as_proxy_number!(isize, 1isize);
253impl_as_proxy_number!(u8, 1u8);
254impl_as_proxy_number!(u16, 1u16);
255impl_as_proxy_number!(u32, 1u32);
256impl_as_proxy_number!(u64, 1u64);
257impl_as_proxy_number!(usize, 1usize);
258impl_as_proxy_number!(f32, 1.0);
259impl_as_proxy_number!(f64, 1.0);
260
261pub trait PartialEq<Rhs: ?Sized = Self> {
262    /// This method tests for `self` and `other` values to be equal, and is used
263    /// by `==`.
264    #[must_use]
265    //#[stable(feature = "rust1", since = "1.0.0")]
266    fn op_eq(&self, other: &Rhs) -> bool;
267
268    /// This method tests for `!=`.
269    #[inline]
270    #[must_use]
271    //#[stable(feature = "rust1", since = "1.0.0")]
272    fn op_ne(&self, other: &Rhs) -> bool {
273        !self.op_eq(other)
274    }
275}
276
277pub trait PartialOrd<Rhs: ?Sized = Self> {
278    /// This method returns an ordering between `self` and `other` values if one exists.
279    ///
280    /// # Examples
281    ///
282    /// ```
283    ///
284    ///
285    /// use std::cmp::Ordering;
286    /// use rbatis_codegen::ops::PartialOrd;
287    /// let result = 1.0.op_partial_cmp(&2.0);
288    /// assert_eq!(result, Some(Ordering::Less));
289    ///
290    /// let result = 1.0.op_partial_cmp(&1.0);
291    /// assert_eq!(result, Some(Ordering::Equal));
292    ///
293    /// let result = 2.0.op_partial_cmp(&1.0);
294    /// assert_eq!(result, Some(Ordering::Greater));
295    /// ```
296    ///
297    /// When comparison is impossible:
298    ///
299    /// ```
300    /// use rbatis_codegen::ops::PartialOrd;
301    /// let result = f64::NAN.op_partial_cmp(&1.0);
302    /// assert_eq!(result, None);
303    /// ```
304    #[must_use]
305    fn op_partial_cmp(&self, other: &Rhs) -> Option<Ordering>;
306
307    /// This method tests less than (for `self` and `other`) and is used by the `<` operator.
308    ///
309    /// # Examples
310    ///
311    /// ```
312    /// let result = 1.0 < 2.0;
313    /// assert_eq!(result, true);
314    ///
315    /// let result = 2.0 < 1.0;
316    /// assert_eq!(result, false);
317    /// ```
318    #[inline]
319    #[must_use]
320    fn op_lt(&self, other: &Rhs) -> bool {
321        self.op_partial_cmp(other).eq(&Some(Ordering::Less))
322    }
323
324    /// This method tests less than or equal to (for `self` and `other`) and is used by the `<=`
325    /// operator.
326    ///
327    /// # Examples
328    ///
329    /// ```
330    /// let result = 1.0 <= 2.0;
331    /// assert_eq!(result, true);
332    ///
333    /// let result = 2.0 <= 2.0;
334    /// assert_eq!(result, true);
335    /// ```
336    #[inline]
337    #[must_use]
338    fn op_le(&self, other: &Rhs) -> bool {
339        let v = self.op_partial_cmp(other);
340        !v.eq(&None) | v.eq(&Some(Ordering::Greater))
341    }
342
343    /// This method tests greater than (for `self` and `other`) and is used by the `>` operator.
344    ///
345    /// # Examples
346    ///
347    /// ```
348    /// let result = 1.0 > 2.0;
349    /// assert_eq!(result, false);
350    ///
351    /// let result = 2.0 > 2.0;
352    /// assert_eq!(result, false);
353    /// ```
354    #[inline]
355    fn op_gt(&self, other: &Rhs) -> bool {
356        self.op_partial_cmp(other).eq(&Some(Ordering::Greater))
357    }
358
359    /// This method tests greater than or equal to (for `self` and `other`) and is used by the `>=`
360    /// operator.
361    ///
362    /// # Examples
363    ///
364    /// ```
365    /// let result = 2.0 >= 1.0;
366    /// assert_eq!(result, true);
367    ///
368    /// let result = 2.0 >= 2.0;
369    /// assert_eq!(result, true);
370    /// ```
371    #[inline]
372    #[must_use]
373    fn op_ge(&self, other: &Rhs) -> bool {
374        let v = self.op_partial_cmp(other);
375        v.eq(&Some(Ordering::Greater)) | v.eq(&Some(Ordering::Equal))
376    }
377}
378
379pub trait Add<Rhs = Self> {
380    /// The resulting type after applying the `+` operator.
381    //#[stable(feature = "rust1", since = "1.0.0")]
382    type Output;
383
384    /// Performs the `+` operation.
385    ///
386    /// # Example
387    ///
388    /// ```
389    /// assert_eq!(12 + 1, 13);
390    /// ```
391    #[must_use]
392    //#[stable(feature = "rust1", since = "1.0.0")]
393    fn op_add(self, rhs: Rhs) -> Self::Output;
394}
395
396pub trait Sub<Rhs = Self> {
397    /// The resulting type after applying the `-` operator.
398    type Output;
399
400    /// Performs the `-` operation.
401    ///
402    /// # Example
403    ///
404    /// ```
405    /// assert_eq!(12 - 1, 11);
406    /// ```
407    #[must_use]
408    fn op_sub(self, rhs: Rhs) -> Self::Output;
409}
410
411pub trait Mul<Rhs = Self> {
412    /// The resulting type after applying the `*` operator.
413    type Output;
414
415    /// Performs the `*` operation.
416    ///
417    /// # Example
418    ///
419    /// ```
420    /// assert_eq!(12 * 2, 24);
421    /// ```
422    #[must_use]
423    fn op_mul(self, rhs: Rhs) -> Self::Output;
424}
425
426pub trait Div<Rhs = Self> {
427    /// The resulting type after applying the `/` operator.
428    type Output;
429
430    /// Performs the `/` operation.
431    ///
432    /// # Example
433    ///
434    /// ```
435    /// assert_eq!(12 / 2, 6);
436    /// ```
437    #[must_use]
438    fn op_div(self, rhs: Rhs) -> Self::Output;
439}
440
441pub trait Rem<Rhs = Self> {
442    /// The resulting type after applying the `%` operator.
443    type Output;
444
445    /// Performs the `%` operation.
446    ///
447    /// # Example
448    ///
449    /// ```
450    /// assert_eq!(12 % 10, 2);
451    /// ```
452    #[must_use]
453    fn op_rem(self, rhs: Rhs) -> Self::Output;
454}
455
456pub trait Not {
457    /// The resulting type after applying the `!` operator.
458    type Output;
459
460    /// Performs the unary `!` operation.
461    ///
462    /// # Examples
463    ///
464    /// ```
465    /// assert_eq!(!true, false);
466    /// assert_eq!(!false, true);
467    /// assert_eq!(!1u8, 254);
468    /// assert_eq!(!0u8, 255);
469    /// ```
470    #[must_use]
471    fn op_not(self) -> Self::Output;
472}
473
474pub trait BitAnd<Rhs = Self> {
475    /// The resulting type after applying the `&` operator.
476    type Output;
477
478    /// Performs the `&` operation.
479    ///
480    /// # Examples
481    ///
482    /// ```
483    /// assert_eq!(true & false, false);
484    /// assert_eq!(true & true, true);
485    /// assert_eq!(5u8 & 1u8, 1);
486    /// assert_eq!(5u8 & 2u8, 0);
487    /// ```
488    #[must_use]
489    fn op_bitand(self, rhs: Rhs) -> Self::Output;
490}
491
492pub trait BitOr<Rhs = Self> {
493    /// The resulting type after applying the `|` operator.
494    type Output;
495
496    /// Performs the `|` operation.
497    ///
498    /// # Examples
499    ///
500    /// ```
501    /// assert_eq!(true | false, true);
502    /// assert_eq!(false | false, false);
503    /// assert_eq!(5u8 | 1u8, 5);
504    /// assert_eq!(5u8 | 2u8, 7);
505    /// ```
506    #[must_use]
507    fn op_bitor(self, rhs: Rhs) -> Self::Output;
508}
509
510pub trait BitXor<Rhs = Self> {
511    /// The resulting type after applying the `^` operator.
512    type Output;
513
514    /// Performs the `^` operation.
515    ///
516    /// # Examples
517    ///
518    /// ```
519    /// assert_eq!(true ^ false, true);
520    /// assert_eq!(true ^ true, false);
521    /// assert_eq!(5u8 ^ 1u8, 4);
522    /// assert_eq!(5u8 ^ 2u8, 7);
523    /// ```
524    #[must_use]
525    fn op_bitxor(self, rhs: Rhs) -> Self::Output;
526}
527
528pub trait BitShl<Rhs = Self> {
529    /// The resulting type after applying the `<<` operator.
530    type Output;
531
532    /// Performs the `<<` operation.
533    ///
534    /// # Examples
535    ///
536    /// ```
537    /// assert_eq!(1u8 << 1, 2);
538    /// assert_eq!(1u8 << 2, 4);
539    /// assert_eq!(4u16 << 3, 32);
540    /// ```
541    #[must_use]
542    fn op_shl(self, rhs: Rhs) -> Self::Output;
543}
544
545pub trait BitShr<Rhs = Self> {
546    /// The resulting type after applying the `>>` operator.
547    type Output;
548
549    /// Performs the `>>` operation.
550    ///
551    /// # Examples
552    ///
553    /// ```
554    /// assert_eq!(8u8 >> 1, 4);
555    /// assert_eq!(8u8 >> 2, 2);
556    /// assert_eq!(32u16 >> 3, 4);
557    /// ```
558    #[must_use]
559    fn op_shr(self, rhs: Rhs) -> Self::Output;
560}
561
562pub trait OpsIndex<Idx: ?Sized> {
563    /// The returned type after indexing.
564    type Output: ?Sized;
565
566    /// Performs the indexing (`container[index]`) operation.
567    ///
568    /// # Panics
569    ///
570    /// May panic if the index is out of bounds.
571    #[track_caller]
572    fn index(&self, index: Idx) -> &Self::Output;
573}
574
575pub trait OpsIndexMut<Idx: ?Sized>: OpsIndex<Idx> {
576    /// Performs the mutable indexing (`container[index]`) operation.
577    ///
578    /// # Panics
579    ///
580    /// May panic if the index is out of bounds.
581    #[track_caller]
582    fn index_mut(&mut self, index: Idx) -> &mut Self::Output;
583}
584
585pub trait From<T>: Sized {
586    /// Performs the conversion.
587    fn op_from(_: T) -> Self;
588}
589
590pub trait Neg {
591    /// The resulting type after applying the `-` operator.
592    type Output;
593
594    /// Performs the unary `-` operation.
595    ///
596    /// # Example
597    ///
598    /// ```
599    /// let x: i32 = 12;
600    /// assert_eq!(-x, -12);
601    /// ```
602    #[must_use = "this returns the result of the operation, without modifying the original"]
603    fn neg(self) -> Self::Output;
604}
605
606/// string contains method
607pub trait StrMethods {
608    fn contains_str(self, s: &str) -> bool;
609    fn starts_with(self, other: &str) -> bool;
610    fn ends_with(self, other: &str) -> bool;
611}
612
613#[cfg(test)]
614mod test {
615    use crate::ops::AsProxy;
616    use rbs::value;
617
618    #[test]
619    fn test_cast() {
620        let b = value!(u64::MAX);
621        assert_eq!(b.i64(), -1);
622        let b = value!(100u64);
623        assert_eq!(b.i64(), 100i64);
624    }
625}