1use std::cmp::Ordering;
2
3use rbson::{Document, Timestamp};
4use std::cmp::Ordering::Less;
5
6pub 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 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; fn cast_string(&self) -> String;
28 fn cast_i64(&self) -> i64;
29 fn cast_f64(&self) -> f64;
30 fn cast_u64(&self) -> u64;
31 fn bracket(&self) -> &str;
33 fn inner(&self) -> &str {
35 self.bracket()
36 }
37}
38
39pub 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 #[must_use]
282 fn op_eq(&self, other: &Rhs) -> bool;
284
285 #[inline]
287 #[must_use]
288 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 fn op_partial_cmp(&self, other: &Rhs) -> Option<Ordering>;
298
299 #[inline]
311 #[must_use]
312 fn op_lt(&self, other: &Rhs) -> bool {
314 self.op_partial_cmp(other).eq(&Some(Less))
315 }
316
317 #[inline]
330 #[must_use]
331 fn op_le(&self, other: &Rhs) -> bool {
333 let v = self.op_partial_cmp(other);
338 !v.eq(&None) | v.eq(&Some(Ordering::Greater))
339 }
340
341 #[inline]
353 fn op_gt(&self, other: &Rhs) -> bool {
355 self.op_partial_cmp(other).eq(&Some(Ordering::Greater))
356 }
357
358 #[inline]
371 #[must_use]
372 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 type Output;
383
384 #[must_use]
392 fn op_add(self, rhs: Rhs) -> Self::Output;
394}
395
396pub trait Sub<Rhs = Self> {
397 type Output;
399
400 #[must_use]
408 fn op_sub(self, rhs: Rhs) -> Self::Output;
409}
410
411pub trait Mul<Rhs = Self> {
412 type Output;
414
415 #[must_use]
423 fn op_mul(self, rhs: Rhs) -> Self::Output;
424}
425
426pub trait Div<Rhs = Self> {
427 type Output;
429
430 #[must_use]
438 fn op_div(self, rhs: Rhs) -> Self::Output;
439}
440
441pub trait Rem<Rhs = Self> {
442 type Output;
444
445 #[must_use]
453 fn op_rem(self, rhs: Rhs) -> Self::Output;
454}
455
456pub trait Not {
457 type Output;
459
460 #[must_use]
471 fn op_not(self) -> Self::Output;
472}
473
474pub trait BitAnd<Rhs = Self> {
475 type Output;
477
478 #[must_use]
489 fn op_bitand(self, rhs: Rhs) -> Self::Output;
490}
491
492pub trait BitOr<Rhs = Self> {
493 type Output;
495
496 #[must_use]
507 fn op_bitor(self, rhs: Rhs) -> Self::Output;
508}
509
510pub trait BitXor<Rhs = Self> {
511 type Output;
513
514 #[must_use]
525 fn op_bitxor(self, rhs: Rhs) -> Self::Output;
526}
527
528pub trait OpsIndex<Idx: ?Sized> {
529 type Output: ?Sized;
531
532 #[track_caller]
538 fn index(&self, index: Idx) -> &Self::Output;
539}
540
541pub trait OpsIndexMut<Idx: ?Sized>: OpsIndex<Idx> {
542 #[track_caller]
548 fn index_mut(&mut self, index: Idx) -> &mut Self::Output;
549}
550
551pub trait From<T>: Sized {
552 fn op_from(_: T) -> Self;
554}
555
556pub trait AsSql {
557 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 }
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}