mybatis_sql/
ops.rs

1use std::cmp::Ordering;
2
3use rbson::{Document, Timestamp};
4use std::cmp::Ordering::Less;
5
6/// convert Value to Value
7pub trait AsProxy {
8    fn i32(&self) -> i32;
9    fn i64(&self) -> i64;
10    fn u32(&self) -> u32;
11    fn u64(&self) -> u64;
12    fn f64(&self) -> f64;
13    fn str(&self) -> &str;
14    fn string(&self) -> String;
15    fn bool(&self) -> bool;
16    fn array(&self) -> Option<&rbson::Array>;
17    fn object(&self) -> Option<&Document>;
18
19    //is
20    fn is_empty(&self) -> bool;
21    fn is_null(&self) -> bool;
22    fn is_array(&self) -> bool;
23    fn is_document(&self) -> bool;
24    fn is_object(&self) -> bool; // is_document = is_object
25
26    //try to any string
27    fn cast_string(&self) -> String;
28    fn cast_i64(&self) -> i64;
29    fn cast_f64(&self) -> f64;
30    fn cast_u64(&self) -> u64;
31    /// bracket(xxxx) inner data
32    fn bracket(&self) -> &str;
33    /// bracket(xxxx) inner data
34    fn inner(&self) -> &str {
35        self.bracket()
36    }
37}
38
39/// proxy rbson::Document struct,support Deserializer, Serializer
40/// use Cow Optimize unnecessary clones
41/// This structure has a certain amount of computing power
42pub type Value = rbson::Bson;
43
44pub fn as_timestamp(arg: &Timestamp) -> i64 {
45    let upper = (arg.time.to_le() as u64) << 32;
46    let lower = arg.increment.to_le() as u64;
47    (upper | lower) as i64
48}
49
50impl AsProxy for Value {
51    fn i32(&self) -> i32 {
52        return match self {
53            Value::Double(v) => *v as i32,
54            Value::UInt32(v) => *v as i32,
55            Value::UInt64(v) => *v as i32,
56            Value::Int32(v) => *v,
57            Value::Int64(v) => *v as i32,
58            _ => 0,
59        };
60    }
61
62    fn i64(&self) -> i64 {
63        return match self {
64            Value::Double(v) => *v as i64,
65            Value::UInt32(v) => *v as i64,
66            Value::UInt64(v) => *v as i64,
67            Value::Int32(v) => *v as i64,
68            Value::Int64(v) => *v,
69            _ => 0,
70        };
71    }
72
73    fn u32(&self) -> u32 {
74        return match self {
75            Value::Double(v) => *v as u32,
76            Value::Int32(v) => *v as u32,
77            Value::Int64(v) => *v as u32,
78            Value::UInt32(v) => *v,
79            Value::UInt64(v) => *v as u32,
80            _ => 0,
81        };
82    }
83
84    fn u64(&self) -> u64 {
85        return match self {
86            Value::Double(v) => *v as u64,
87            Value::Int32(v) => *v as u64,
88            Value::Int64(v) => *v as u64,
89            Value::UInt32(v) => *v as u64,
90            Value::UInt64(v) => *v,
91            _ => 0,
92        };
93    }
94
95    fn f64(&self) -> f64 {
96        return match self {
97            Value::Double(v) => *v,
98            Value::Int32(v) => *v as f64,
99            Value::Int64(v) => *v as f64,
100            Value::UInt32(v) => *v as f64,
101            Value::UInt64(v) => *v as f64,
102            _ => 0.0,
103        };
104    }
105
106    fn str(&self) -> &str {
107        self.as_str().unwrap_or_default()
108    }
109
110    fn string(&self) -> String {
111        self.str().to_string()
112    }
113
114    fn cast_string(&self) -> String {
115        match self {
116            Value::Binary(b) => String::from_utf8(b.bytes.clone()).unwrap_or_default(),
117            Value::Double(d) => d.to_string(),
118            Value::String(d) => d.to_string(),
119            Value::Boolean(d) => d.to_string(),
120            Value::Null => "".to_string(),
121            Value::Int32(i) => i.to_string(),
122            Value::Int64(d) => d.to_string(),
123            Value::Timestamp(d) => as_timestamp(d).to_string(),
124            Value::DateTime(d) => d.to_string(),
125            Value::Decimal128(d) => d.to_string(),
126            _ => String::new(),
127        }
128    }
129
130    fn cast_i64(&self) -> i64 {
131        match self {
132            Value::Binary(b) => String::from_utf8(b.bytes.clone())
133                .unwrap_or_default()
134                .parse()
135                .unwrap_or_default(),
136            Value::Double(d) => *d as i64,
137            Value::String(d) => d.to_string().parse().unwrap_or_default(),
138            Value::Boolean(d) => {
139                if *d == true {
140                    return 1;
141                } else {
142                    return 0;
143                }
144            }
145            Value::Null => 0,
146            Value::UInt32(i) => *i as i64,
147            Value::UInt64(d) => *d as i64,
148            Value::Int32(i) => *i as i64,
149            Value::Int64(d) => *d,
150            Value::Timestamp(d) => as_timestamp(d),
151            Value::DateTime(d) => d.timestamp_millis(),
152            Value::Decimal128(d) => d.to_string().parse().unwrap_or_default(),
153            _ => 0,
154        }
155    }
156
157    fn cast_u64(&self) -> u64 {
158        match self {
159            Value::Binary(b) => String::from_utf8(b.bytes.clone())
160                .unwrap_or_default()
161                .parse()
162                .unwrap_or_default(),
163            Value::Double(d) => *d as u64,
164            Value::String(d) => d.to_string().parse().unwrap_or_default(),
165            Value::Boolean(d) => {
166                if *d == true {
167                    return 1;
168                } else {
169                    return 0;
170                }
171            }
172            Value::Null => 0,
173            Value::Int32(i) => *i as u64,
174            Value::Int64(d) => *d as u64,
175            Value::UInt32(i) => *i as u64,
176            Value::UInt64(d) => *d,
177            Value::Timestamp(d) => as_timestamp(d) as u64,
178            Value::DateTime(d) => d.timestamp_millis() as u64,
179            Value::Decimal128(d) => d.to_string().parse().unwrap_or_default(),
180            _ => 0,
181        }
182    }
183
184    fn cast_f64(&self) -> f64 {
185        match self {
186            Value::Binary(b) => String::from_utf8(b.bytes.clone())
187                .unwrap_or_default()
188                .parse()
189                .unwrap_or_default(),
190            Value::Double(d) => *d as f64,
191            Value::String(d) => d.to_string().parse().unwrap_or_default(),
192            Value::Boolean(d) => {
193                if *d == true {
194                    return 1.0;
195                } else {
196                    return 0.0;
197                }
198            }
199            Value::Null => 0.0,
200            Value::Int32(i) => *i as f64,
201            Value::Int64(d) => *d as f64,
202            Value::Timestamp(d) => as_timestamp(d) as f64,
203            Value::DateTime(d) => d.timestamp_millis() as f64,
204            Value::Decimal128(d) => d.to_string().parse().unwrap_or_default(),
205            _ => 0.0,
206        }
207    }
208
209    fn bool(&self) -> bool {
210        self.as_bool().unwrap_or_default()
211    }
212    fn is_empty(&self) -> bool {
213        return match self {
214            Value::Null => true,
215            Value::String(s) => s.is_empty(),
216            Value::Array(arr) => arr.is_empty(),
217            Value::Document(m) => m.is_empty(),
218            _ => {
219                return false;
220            }
221        };
222    }
223
224    fn is_null(&self) -> bool {
225        return match self {
226            Value::Null => true,
227            _ => false,
228        };
229    }
230
231    fn is_array(&self) -> bool {
232        return match self {
233            Value::Array(_) => true,
234            _ => false,
235        };
236    }
237
238    fn array(&self) -> Option<&rbson::Array> {
239        return match self {
240            Value::Array(arr) => Some(arr),
241            _ => None,
242        };
243    }
244
245    fn is_document(&self) -> bool {
246        return match self {
247            Value::Document(_) => true,
248            _ => false,
249        };
250    }
251
252    fn is_object(&self) -> bool {
253        return self.is_document();
254    }
255
256    fn object(&self) -> Option<&Document> {
257        return match self {
258            Value::Document(d) => Some(d),
259            _ => None,
260        };
261    }
262
263    fn bracket(&self) -> &str {
264        let bracket = self.as_str().unwrap_or_default();
265        let start = bracket.find("(");
266        let end = bracket.find(")");
267        if let Some(start) = start {
268            if let Some(end) = end {
269                if end > (start + 1) {
270                    return &bracket[start + 1..end];
271                }
272            }
273        }
274        return bracket;
275    }
276}
277
278pub trait PartialEq<Rhs: ?Sized = Self> {
279    /// This method tests for `self` and `other` values to be equal, and is used
280    /// by `==`.
281    #[must_use]
282    //#[stable(feature = "rust1", since = "1.0.0")]
283    fn op_eq(&self, other: &Rhs) -> bool;
284
285    /// This method tests for `!=`.
286    #[inline]
287    #[must_use]
288    //#[stable(feature = "rust1", since = "1.0.0")]
289    fn op_ne(&self, other: &Rhs) -> bool {
290        !self.op_eq(other)
291    }
292}
293
294pub trait PartialOrd<Rhs: ?Sized = Self> {
295    #[must_use]
296    // #[stable(feature = "rust1", since = "1.0.0")]
297    fn op_partial_cmp(&self, other: &Rhs) -> Option<Ordering>;
298
299    /// This method tests less than (for `self` and `other`) and is used by the `<` operator.
300    ///
301    /// # Examples
302    ///
303    /// ```
304    /// let result = 1.0 < 2.0;
305    /// assert_eq!(result, true);
306    ///
307    /// let result = 2.0 < 1.0;
308    /// assert_eq!(result, false);
309    /// ```
310    #[inline]
311    #[must_use]
312    // #[stable(feature = "rust1", since = "1.0.0")]
313    fn op_lt(&self, other: &Rhs) -> bool {
314        self.op_partial_cmp(other).eq(&Some(Less))
315    }
316
317    /// This method tests less than or equal to (for `self` and `other`) and is used by the `<=`
318    /// operator.
319    ///
320    /// # Examples
321    ///
322    /// ```
323    /// let result = 1.0 <= 2.0;
324    /// assert_eq!(result, true);
325    ///
326    /// let result = 2.0 <= 2.0;
327    /// assert_eq!(result, true);
328    /// ```
329    #[inline]
330    #[must_use]
331    // #[stable(feature = "rust1", since = "1.0.0")]
332    fn op_le(&self, other: &Rhs) -> bool {
333        // Pattern `Some(Less | Eq)` optimizes worse than negating `None | Some(Greater)`.
334        // FIXME: The root cause was fixed upstream in LLVM with:
335        // https://github.com/llvm/llvm-project/commit/9bad7de9a3fb844f1ca2965f35d0c2a3d1e11775
336        // Revert this workaround once support for LLVM 12 gets dropped.
337        let v = self.op_partial_cmp(other);
338        !v.eq(&None) | v.eq(&Some(Ordering::Greater))
339    }
340
341    /// This method tests greater than (for `self` and `other`) and is used by the `>` operator.
342    ///
343    /// # Examples
344    ///
345    /// ```
346    /// let result = 1.0 > 2.0;
347    /// assert_eq!(result, false);
348    ///
349    /// let result = 2.0 > 2.0;
350    /// assert_eq!(result, false);
351    /// ```
352    #[inline]
353    // #[stable(feature = "rust1", since = "1.0.0")]
354    fn op_gt(&self, other: &Rhs) -> bool {
355        self.op_partial_cmp(other).eq(&Some(Ordering::Greater))
356    }
357
358    /// This method tests greater than or equal to (for `self` and `other`) and is used by the `>=`
359    /// operator.
360    ///
361    /// # Examples
362    ///
363    /// ```
364    /// let result = 2.0 >= 1.0;
365    /// assert_eq!(result, true);
366    ///
367    /// let result = 2.0 >= 2.0;
368    /// assert_eq!(result, true);
369    /// ```
370    #[inline]
371    #[must_use]
372    // #[stable(feature = "rust1", since = "1.0.0")]
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 OpsIndex<Idx: ?Sized> {
529    /// The returned type after indexing.
530    type Output: ?Sized;
531
532    /// Performs the indexing (`container[index]`) operation.
533    ///
534    /// # Panics
535    ///
536    /// May panic if the index is out of bounds.
537    #[track_caller]
538    fn index(&self, index: Idx) -> &Self::Output;
539}
540
541pub trait OpsIndexMut<Idx: ?Sized>: OpsIndex<Idx> {
542    /// Performs the mutable indexing (`container[index]`) operation.
543    ///
544    /// # Panics
545    ///
546    /// May panic if the index is out of bounds.
547    #[track_caller]
548    fn index_mut(&mut self, index: Idx) -> &mut Self::Output;
549}
550
551pub trait From<T>: Sized {
552    /// Performs the conversion.
553    fn op_from(_: T) -> Self;
554}
555
556pub trait AsSql {
557    /// Performs the conversion.
558    fn as_sql(&self) -> String;
559}
560
561#[cfg(test)]
562mod test {
563    use crate::ops::AsProxy;
564    use rbson::spec::BinarySubtype;
565    use rbson::{bson, Bson};
566
567    #[test]
568    fn test_string() {
569        let b = Bson::Binary(rbson::Binary {
570            subtype: BinarySubtype::Generic,
571            bytes: "s".as_bytes().to_owned(),
572        });
573        println!("{:?}", b.string());
574        //assert_eq!("s", b.string());
575    }
576
577    #[test]
578    fn test_cast() {
579        let b = bson!(u64::MAX);
580        assert_eq!(b.cast_i64(), -1);
581        let b = bson!(100u64);
582        assert_eq!(b.cast_i64(), 100i64);
583    }
584}