1use rbs::Value;
2use std::cmp::Ordering;
3pub use std::ops::Index;
4
5pub 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 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 #[must_use]
272 fn op_eq(&self, other: &Rhs) -> bool;
274
275 #[inline]
277 #[must_use]
278 fn op_ne(&self, other: &Rhs) -> bool {
280 !self.op_eq(other)
281 }
282}
283
284pub trait PartialOrd<Rhs: ?Sized = Self> {
285 #[must_use]
312 fn op_partial_cmp(&self, other: &Rhs) -> Option<Ordering>;
313
314 #[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 #[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 #[inline]
362 fn op_gt(&self, other: &Rhs) -> bool {
363 self.op_partial_cmp(other).eq(&Some(Ordering::Greater))
364 }
365
366 #[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 type Output;
390
391 #[must_use]
399 fn op_add(self, rhs: Rhs) -> Self::Output;
401}
402
403pub trait Sub<Rhs = Self> {
404 type Output;
406
407 #[must_use]
415 fn op_sub(self, rhs: Rhs) -> Self::Output;
416}
417
418pub trait Mul<Rhs = Self> {
419 type Output;
421
422 #[must_use]
430 fn op_mul(self, rhs: Rhs) -> Self::Output;
431}
432
433pub trait Div<Rhs = Self> {
434 type Output;
436
437 #[must_use]
445 fn op_div(self, rhs: Rhs) -> Self::Output;
446}
447
448pub trait Rem<Rhs = Self> {
449 type Output;
451
452 #[must_use]
460 fn op_rem(self, rhs: Rhs) -> Self::Output;
461}
462
463pub trait Not {
464 type Output;
466
467 #[must_use]
478 fn op_not(self) -> Self::Output;
479}
480
481pub trait BitAnd<Rhs = Self> {
482 type Output;
484
485 #[must_use]
496 fn op_bitand(self, rhs: Rhs) -> Self::Output;
497}
498
499pub trait BitOr<Rhs = Self> {
500 type Output;
502
503 #[must_use]
514 fn op_bitor(self, rhs: Rhs) -> Self::Output;
515}
516
517pub trait BitXor<Rhs = Self> {
518 type Output;
520
521 #[must_use]
532 fn op_bitxor(self, rhs: Rhs) -> Self::Output;
533}
534
535pub trait OpsIndex<Idx: ?Sized> {
536 type Output: ?Sized;
538
539 #[track_caller]
545 fn index(&self, index: Idx) -> &Self::Output;
546}
547
548pub trait OpsIndexMut<Idx: ?Sized>: OpsIndex<Idx> {
549 #[track_caller]
555 fn index_mut(&mut self, index: Idx) -> &mut Self::Output;
556}
557
558pub trait From<T>: Sized {
559 fn op_from(_: T) -> Self;
561}
562
563pub trait Neg {
564 type Output;
566
567 #[must_use = "this returns the result of the operation, without modifying the original"]
576 fn neg(self) -> Self::Output;
577}
578
579
580pub 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}