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}