1use std::borrow::Cow;
2use std::collections::{BTreeMap, HashMap, HashSet, LinkedList};
3use std::hash::Hash;
4use std::rc::Rc;
5use std::sync::Arc;
6
7use rust_decimal::Decimal;
8
9use crate as surrealdb_types;
10use crate::error::{ConversionError, LengthMismatchError, OutOfRangeError};
11use crate::{
12 Array, Bytes, Datetime, Duration, Error, File, Geometry, Kind, Number, Object, Range, RecordId,
13 Set, SurrealNone, SurrealNull, Table, Uuid, Value, kind,
14};
15
16pub trait SurrealValue {
25 fn kind_of() -> Kind;
27 fn is_value(value: &Value) -> bool {
29 value.is_kind(&Self::kind_of())
30 }
31 fn into_value(self) -> Value;
33 fn from_value(value: Value) -> Result<Self, Error>
35 where
36 Self: Sized;
37}
38
39impl<T: SurrealValue> SurrealValue for Box<T> {
40 fn kind_of() -> Kind {
41 T::kind_of()
42 }
43
44 fn is_value(value: &Value) -> bool {
45 T::is_value(value)
46 }
47
48 fn into_value(self) -> Value {
49 T::into_value(*self)
50 }
51
52 fn from_value(value: Value) -> Result<Self, Error> {
53 T::from_value(value).map(Box::new)
54 }
55}
56
57impl<T: SurrealValue + Clone> SurrealValue for Arc<T> {
58 fn kind_of() -> Kind {
59 T::kind_of()
60 }
61
62 fn is_value(value: &Value) -> bool {
63 T::is_value(value)
64 }
65
66 fn into_value(self) -> Value {
67 T::into_value(self.as_ref().clone())
68 }
69
70 fn from_value(value: Value) -> Result<Self, Error> {
71 T::from_value(value).map(Arc::new)
72 }
73}
74
75impl<T: SurrealValue + Clone> SurrealValue for Rc<T> {
76 fn kind_of() -> Kind {
77 T::kind_of()
78 }
79
80 fn is_value(value: &Value) -> bool {
81 T::is_value(value)
82 }
83
84 fn into_value(self) -> Value {
85 T::into_value(self.as_ref().clone())
86 }
87
88 fn from_value(value: Value) -> Result<Self, Error> {
89 T::from_value(value).map(Rc::new)
90 }
91}
92
93macro_rules! impl_surreal_value {
94 (
96 <$($generic:ident),*> $type:ty as $kind:expr,
97 $($is_fnc:ident<$($is_generic:ident),*>)? ($value_is:ident) => $is:expr,
98 $($from_fnc:ident<$($from_generic:ident),*>)? ($self:ident) => $into:expr,
99 $($into_fnc:ident<$($into_generic:ident),*>)? ($value_into:ident) => $from:expr
100 $(, as_ty => $as_fnc:ident<$($as_generic:ident),*> ($self_as:ident) => $as_expr:expr)?
101 $(, is_ty_and => $is_and_fnc:ident<$($is_and_generic:ident),*> ($self_is_and:ident, $is_and_callback:ident) => $is_and:expr)?
102 ) => {
103 impl<$($generic: SurrealValue),*> SurrealValue for $type {
104 fn kind_of() -> Kind {
105 $kind
106 }
107
108 fn is_value($value_is: &Value) -> bool {
109 $is
110 }
111
112 fn into_value($self) -> Value {
113 $into
114 }
115
116 fn from_value($value_into: Value) -> Result<Self, Error> {
117 $from
118 }
119 }
120
121 $(
122 impl Value {
123 pub fn $is_fnc<$($is_generic: SurrealValue),*>(&self) -> bool {
127 <$type>::is_value(self)
128 }
129 }
130 )?
131
132 $(
133 impl Value {
134 pub fn $from_fnc<$($from_generic: SurrealValue),*>(value: $type) -> Value {
136 <$type>::into_value(value)
137 }
138 }
139 )?
140
141 $(
142 impl Value {
143 pub fn $into_fnc<$($into_generic: SurrealValue),*>(self) -> Result<$type, Error> {
147 <$type>::from_value(self)
148 }
149 }
150 )?
151
152 $(
153 impl Value {
154 pub fn $as_fnc<$($as_generic: SurrealValue),*>(&$self_as) -> Option<&$type> {
158 $as_expr
159 }
160 }
161 )?
162
163 $(
164 impl Value {
165 pub fn $is_and_fnc<$($is_and_generic: SurrealValue),*>(&$self_is_and, $is_and_callback: impl FnOnce(&$type) -> bool) -> bool {
169 $is_and
170 }
171 }
172 )?
173 };
174
175 (
177 $type:ty as $kind:expr,
178 $($is_fnc:ident),* ($value_is:ident) => $is:expr,
179 $($from_fnc:ident),* ($self:ident) => $into:expr,
180 $($into_fnc:ident),* ($value_into:ident) => $from:expr
181 $(, as_ty => $($as_fnc:ident),+ ($self_as:ident) => $as_expr:expr)?
182 $(, is_ty_and => $($is_and_fnc:ident),+($self_is_and:ident, $is_and_callback:ident) => $is_and:expr)?
183 ) => {
184 impl SurrealValue for $type {
185 fn kind_of() -> Kind {
186 $kind
187 }
188
189 fn is_value($value_is: &Value) -> bool {
190 $is
191 }
192
193 fn into_value($self) -> Value {
194 $into
195 }
196
197 fn from_value($value_into: Value) -> Result<Self, Error> {
198 $from
199 }
200 }
201
202 $(
203 impl Value {
204 pub fn $is_fnc(&self) -> bool {
208 <$type>::is_value(self)
209 }
210 }
211 )*
212
213 $(
214 impl Value {
215 pub fn $from_fnc(value: $type) -> Value {
217 <$type>::into_value(value)
218 }
219 }
220 )*
221
222 $(
223 impl Value {
224 pub fn $into_fnc(self) -> Result<$type, Error> {
228 <$type>::from_value(self)
229 }
230 }
231 )*
232
233 $(
234 impl Value {
235 $(
236 pub fn $as_fnc(&$self_as) -> Option<&$type> {
240 $as_expr
241 }
242 )+
243 }
244 )?
245
246 $(
247 impl Value {
248 $(
249 pub fn $is_and_fnc(&$self_is_and, $is_and_callback: impl FnOnce(&$type) -> bool) -> bool {
253 $is_and
254 }
255 )+
256 }
257 )?
258 };
259}
260
261impl_surreal_value!(
263 Value as kind!(any),
264 (_value) => true,
265 (self) => self,
266 (value) => Ok(value)
267);
268
269impl_surreal_value!(
270 () as kind!(none),
271 (value) => matches!(value, Value::None),
272 (self) => Value::None,
273 (value) => {
274 if value == Value::None {
275 Ok(())
276 } else {
277 Err(ConversionError::from_value(Self::kind_of(), &value).into())
278 }
279 }
280);
281
282impl_surreal_value!(
283 SurrealNone as kind!(none),
284 is_none(value) => matches!(value, Value::None),
285 (self) => Value::None,
286 (value) => {
287 if value == Value::None {
288 Ok(SurrealNone)
289 } else {
290 Err(ConversionError::from_value(Self::kind_of(), &value).into())
291 }
292 }
293);
294
295impl_surreal_value!(
296 SurrealNull as kind!(null),
297 is_null(value) => matches!(value, Value::Null),
298 (self) => Value::Null,
299 (value) => {
300 if value == Value::Null {
301 Ok(SurrealNull)
302 } else {
303 Err(ConversionError::from_value(Self::kind_of(), &value).into())
304 }
305 }
306);
307
308impl_surreal_value!(
309 bool as kind!(bool),
310 is_bool(value) => matches!(value, Value::Bool(_)),
311 from_bool(self) => Value::Bool(self),
312 into_bool(value) => {
313 let Value::Bool(b) = value else {
314 return Err(ConversionError::from_value(Self::kind_of(), &value).into());
315 };
316 Ok(b)
317 },
318 as_ty => as_bool(self) => {
319 if let Value::Bool(b) = self {
320 Some(b)
321 } else {
322 None
323 }
324 }
325);
326
327impl Value {
330 pub fn is_true(&self) -> bool {
334 matches!(self, Value::Bool(true))
335 }
336
337 pub fn is_false(&self) -> bool {
341 matches!(self, Value::Bool(false))
342 }
343}
344
345impl_surreal_value!(
346 Number as kind!(number),
347 is_number(value) => matches!(value, Value::Number(_)),
348 from_number(self) => Value::Number(self),
349 into_number(value) => {
350 let Value::Number(n) = value else {
351 return Err(ConversionError::from_value(Self::kind_of(), &value).into());
352 };
353 Ok(n)
354 },
355 as_ty => as_number(self) => {
356 if let Value::Number(n) = self {
357 Some(n)
358 } else {
359 None
360 }
361 },
362 is_ty_and => is_number_and(self, callback) => {
363 if let Value::Number(n) = self {
364 callback(n)
365 } else {
366 false
367 }
368 }
369);
370
371impl_surreal_value!(
372 i64 as kind!(int),
373 is_int, is_i64(value) => matches!(value, Value::Number(Number::Int(_))),
374 from_int, from_i64(self) => Value::Number(Number::Int(self)),
375 into_int, into_i64(value) => {
376 let Value::Number(Number::Int(n)) = value else {
377 return Err(ConversionError::from_value(Self::kind_of(), &value).into());
378 };
379 Ok(n)
380 },
381 as_ty => as_int, as_i64(self) => {
382 if let Value::Number(Number::Int(n)) = self {
383 Some(n)
384 } else {
385 None
386 }
387 },
388 is_ty_and => is_int_and, is_i64_and(self, callback) => {
389 if let Value::Number(Number::Int(n)) = self {
390 callback(n)
391 } else {
392 false
393 }
394 }
395);
396
397impl_surreal_value!(
398 f64 as kind!(float),
399 is_float, is_f64(value) => matches!(value, Value::Number(Number::Float(_))),
400 from_float, from_f64(self) => Value::Number(Number::Float(self)),
401 into_float, into_f64(value) => {
402 let Value::Number(Number::Float(n)) = value else {
403 return Err(ConversionError::from_value(Self::kind_of(), &value).into());
404 };
405 Ok(n)
406 },
407 as_ty => as_float, as_f64(self) => {
408 if let Value::Number(Number::Float(n)) = self {
409 Some(n)
410 } else {
411 None
412 }
413 },
414 is_ty_and => is_float_and, is_f64_and(self, callback) => {
415 if let Value::Number(Number::Float(n)) = self {
416 callback(n)
417 } else {
418 false
419 }
420 }
421);
422
423impl_surreal_value!(
424 Decimal as kind!(decimal),
425 is_decimal(value) => matches!(value, Value::Number(Number::Decimal(_))),
426 from_decimal(self) => Value::Number(Number::Decimal(self)),
427 into_decimal(value) => {
428 let Value::Number(Number::Decimal(n)) = value else {
429 return Err(ConversionError::from_value(Self::kind_of(), &value).into());
430 };
431 Ok(n)
432 },
433 as_ty => as_decimal(self) => {
434 if let Value::Number(Number::Decimal(n)) = self {
435 Some(n)
436 } else {
437 None
438 }
439 },
440 is_ty_and => is_decimal_and(self, callback) => {
441 if let Value::Number(Number::Decimal(n)) = self {
442 callback(n)
443 } else {
444 false
445 }
446 }
447);
448
449impl_surreal_value!(
450 String as kind!(string),
451 is_string(value) => matches!(value, Value::String(_)),
452 from_string(self) => Value::String(self),
453 into_string(value) => {
454 let Value::String(s) = value else {
455 return Err(ConversionError::from_value(Self::kind_of(), &value).into());
456 };
457 Ok(s)
458 },
459 as_ty => as_string(self) => {
460 if let Value::String(s) = self {
461 Some(s)
462 } else {
463 None
464 }
465 },
466 is_ty_and => is_string_and(self, callback) => {
467 if let Value::String(s) = self {
468 callback(s)
469 } else {
470 false
471 }
472 }
473);
474
475impl SurrealValue for Cow<'static, str> {
476 fn kind_of() -> Kind {
477 kind!(string)
478 }
479
480 fn is_value(value: &Value) -> bool {
481 matches!(value, Value::String(_))
482 }
483
484 fn into_value(self) -> Value {
485 Value::String(self.to_string())
486 }
487
488 fn from_value(value: Value) -> Result<Self, Error> {
489 let Value::String(s) = value else {
490 return Err(ConversionError::from_value(Self::kind_of(), &value).into());
491 };
492 Ok(Cow::Owned(s))
493 }
494}
495
496impl SurrealValue for &'static str {
497 fn kind_of() -> Kind {
498 kind!(string)
499 }
500
501 fn is_value(value: &Value) -> bool {
502 matches!(value, Value::String(_))
503 }
504
505 fn into_value(self) -> Value {
506 Value::String(self.to_string())
507 }
508
509 fn from_value(_value: Value) -> Result<Self, Error> {
510 Err(Error::internal(
511 "Cannot deserialize &'static str from value: static string references cannot be created from runtime values".to_string(),
512 ))
513 }
514}
515
516impl_surreal_value!(
517 Duration as kind!(duration),
518 is_duration(value) => matches!(value, Value::Duration(_)),
519 from_duration(self) => Value::Duration(self),
520 into_duration(value) => {
521 let Value::Duration(d) = value else {
522 return Err(ConversionError::from_value(Self::kind_of(), &value).into());
523 };
524 Ok(d)
525 },
526 as_ty => as_duration(self) => {
527 if let Value::Duration(d) = self {
528 Some(d)
529 } else {
530 None
531 }
532 },
533 is_ty_and => is_duration_and(self, callback) => {
534 if let Value::Duration(d) = self {
535 callback(d)
536 } else {
537 false
538 }
539 }
540);
541
542impl_surreal_value!(
543 std::time::Duration as kind!(duration),
544 (value) => matches!(value, Value::Duration(_)),
545 (self) => Value::Duration(Duration(self)),
546 (value) => {
547 let Value::Duration(Duration(d)) = value else {
548 return Err(ConversionError::from_value(Self::kind_of(), &value).into());
549 };
550 Ok(d)
551 }
552);
553
554impl_surreal_value!(
555 Datetime as kind!(datetime),
556 is_datetime(value) => matches!(value, Value::Datetime(_)),
557 from_datetime(self) => Value::Datetime(self),
558 into_datetime(value) => {
559 let Value::Datetime(d) = value else {
560 return Err(ConversionError::from_value(Self::kind_of(), &value).into());
561 };
562 Ok(d)
563 },
564 as_ty => as_datetime(self) => {
565 if let Value::Datetime(d) = self {
566 Some(d)
567 } else {
568 None
569 }
570 },
571 is_ty_and => is_datetime_and(self, callback) => {
572 if let Value::Datetime(d) = self {
573 callback(d)
574 } else {
575 false
576 }
577 }
578);
579
580impl_surreal_value!(
581 chrono::DateTime<chrono::Utc> as kind!(datetime),
582 (value) => matches!(value, Value::Datetime(_)),
583 (self) => Value::Datetime(Datetime(self)),
584 (value) => {
585 let Value::Datetime(Datetime(d)) = value else {
586 return Err(ConversionError::from_value(Self::kind_of(), &value).into());
587 };
588 Ok(d)
589 }
590);
591
592impl_surreal_value!(
593 chrono::NaiveDate as kind!(datetime),
594 (value) => matches!(value, Value::Datetime(_)),
595 (self) => Value::Datetime(Datetime(chrono::DateTime::from_naive_utc_and_offset(self.and_time(chrono::NaiveTime::MIN), chrono::Utc))),
596 (value) => {
597 let Value::Datetime(Datetime(d)) = value else {
598 return Err(ConversionError::from_value(Self::kind_of(), &value).into());
599 };
600 Ok(d.date_naive())
601 }
602);
603
604impl_surreal_value!(
605 Uuid as kind!(uuid),
606 is_uuid(value) => matches!(value, Value::Uuid(_)),
607 from_uuid(self) => Value::Uuid(self),
608 into_uuid(value) => {
609 let Value::Uuid(u) = value else {
610 return Err(ConversionError::from_value(Self::kind_of(), &value).into());
611 };
612 Ok(u)
613 },
614 as_ty => as_uuid(self) => {
615 if let Value::Uuid(u) = self {
616 Some(u)
617 } else {
618 None
619 }
620 },
621 is_ty_and => is_uuid_and(self, callback) => {
622 if let Value::Uuid(u) = self {
623 callback(u)
624 } else {
625 false
626 }
627 }
628);
629
630impl_surreal_value!(
631 uuid::Uuid as kind!(uuid),
632 (value) => matches!(value, Value::Uuid(_)),
633 (self) => Value::Uuid(Uuid(self)),
634 (value) => {
635 let Value::Uuid(Uuid(u)) = value else {
636 return Err(ConversionError::from_value(<Uuid>::kind_of(), &value).into());
637 };
638 Ok(u)
639 }
640);
641
642impl_surreal_value!(
643 Array as kind!(array),
644 is_array(value) => matches!(value, Value::Array(_)),
645 from_array(self) => Value::Array(self),
646 into_array(value) => {
647 let Value::Array(a) = value else {
648 return Err(ConversionError::from_value(Self::kind_of(), &value).into());
649 };
650 Ok(a)
651 },
652 as_ty => as_array(self) => {
653 if let Value::Array(a) = self {
654 Some(a)
655 } else {
656 None
657 }
658 },
659 is_ty_and => is_array_and(self, callback) => {
660 if let Value::Array(a) = self {
661 callback(a)
662 } else {
663 false
664 }
665 }
666);
667
668impl_surreal_value!(
669 Set as kind!(set),
670 is_set(value) => matches!(value, Value::Set(_)),
671 from_set(self) => Value::Set(self),
672 into_set(value) => {
673 let Value::Set(s) = value else {
674 return Err(ConversionError::from_value(Self::kind_of(), &value).into());
675 };
676 Ok(s)
677 },
678 as_ty => as_set(self) => {
679 if let Value::Set(s) = self {
680 Some(s)
681 } else {
682 None
683 }
684 },
685 is_ty_and => is_set_and(self, callback) => {
686 if let Value::Set(s) = self {
687 callback(s)
688 } else {
689 false
690 }
691 }
692);
693
694impl_surreal_value!(
695 Object as kind!(object),
696 is_object(value) => matches!(value, Value::Object(_)),
697 from_object(self) => Value::Object(self),
698 into_object(value) => {
699 let Value::Object(o) = value else {
700 return Err(ConversionError::from_value(Self::kind_of(), &value).into());
701 };
702 Ok(o)
703 },
704 as_ty => as_object(self) => {
705 if let Value::Object(o) = self {
706 Some(o)
707 } else {
708 None
709 }
710 },
711 is_ty_and => is_object_and(self, callback) => {
712 if let Value::Object(o) = self {
713 callback(o)
714 } else {
715 false
716 }
717 }
718);
719
720impl_surreal_value!(
721 Geometry as kind!(geometry),
722 is_geometry(value) => matches!(value, Value::Geometry(_)),
723 from_geometry(self) => Value::Geometry(self),
724 into_geometry(value) => {
725 let Value::Geometry(g) = value else {
726 return Err(ConversionError::from_value(Self::kind_of(), &value).into());
727 };
728 Ok(g)
729 },
730 as_ty => as_geometry(self) => {
731 if let Value::Geometry(g) = self {
732 Some(g)
733 } else {
734 None
735 }
736 },
737 is_ty_and => is_geometry_and(self, callback) => {
738 if let Value::Geometry(g) = self {
739 callback(g)
740 } else {
741 false
742 }
743 }
744);
745
746impl_surreal_value!(
747 Bytes as kind!(bytes),
748 is_bytes(value) => matches!(value, Value::Bytes(_)),
749 from_bytes(self) => Value::Bytes(self),
750 into_bytes(value) => {
751 let Value::Bytes(b) = value else {
752 return Err(ConversionError::from_value(Self::kind_of(), &value).into());
753 };
754 Ok(b)
755 },
756 as_ty => as_bytes(self) => {
757 if let Value::Bytes(b) = self {
758 Some(b)
759 } else {
760 None
761 }
762 },
763 is_ty_and => is_bytes_and(self, callback) => {
764 if let Value::Bytes(b) = self {
765 callback(b)
766 } else {
767 false
768 }
769 }
770);
771
772impl_surreal_value!(
779 bytes::Bytes as kind!(bytes),
780 (value) => matches!(value, Value::Bytes(_)),
781 (self) => Value::Bytes(Bytes(self)),
782 (value) => {
783 let Value::Bytes(Bytes(b)) = value else {
784 return Err(ConversionError::from_value(Self::kind_of(), &value).into());
785 };
786 Ok(b)
787 }
788);
789
790impl_surreal_value!(
791 Table as kind!(table),
792 is_table(value) => {
793 matches!(value, Value::Table(_))
794 },
795 from_table(self) => Value::Table(self),
796 into_table(value) => {
797 match value {
798 Value::Table(t) => Ok(t),
799 _ => Err(ConversionError::from_value(Self::kind_of(), &value).into()),
800 }
801 },
802 as_ty => as_table(self) => {
803 if let Value::Table(t) = self {
804 Some(t)
805 } else {
806 None
807 }
808 },
809 is_ty_and => is_table_and(self, callback) => {
810 if let Value::Table(t) = self {
811 callback(t)
812 } else {
813 false
814 }
815 }
816);
817
818impl_surreal_value!(
819 RecordId as kind!(record),
820 is_record(value) => {
821 match value {
822 Value::RecordId(_) => true,
823 Value::String(s) => Self::parse_simple(s).is_ok(),
824 Value::Object(o) => {
825 o.get("id").is_some()
826 }
827 _ => false,
828 }
829 },
830 from_record(self) => Value::RecordId(self),
831 into_record(value) => {
832 match value {
833 Value::RecordId(r) => Ok(r),
834 Value::String(s) => Self::parse_simple(&s).map_err(|e| Error::internal(e.to_string())),
835 Value::Object(o) => {
836 let v = o.get("id").ok_or_else(|| Error::internal("Invalid record id".to_string()))?;
837 v.clone().into_record()
838 }
839 Value::Array(a) => {
840 let first = a.first().ok_or_else(|| Error::internal("Invalid record id: array is empty".to_string()))?;
841 first.clone().into_record()
842 }
843 _ => Err(ConversionError::from_value(Self::kind_of(), &value).into()),
844 }
845 },
846 as_ty => as_record(self) => {
847 if let Value::RecordId(r) = self {
848 Some(r)
849 } else {
850 None
851 }
852 },
853 is_ty_and => is_record_and(self, callback) => {
854 if let Value::RecordId(r) = self {
855 callback(r)
856 } else {
857 false
858 }
859 }
860);
861
862impl_surreal_value!(
863 File as kind!(file),
864 is_file(value) => matches!(value, Value::File(_)),
865 from_file(self) => Value::File(self),
866 into_file(value) => {
867 let Value::File(f) = value else {
868 return Err(ConversionError::from_value(Self::kind_of(), &value).into());
869 };
870 Ok(f)
871 },
872 as_ty => as_file(self) => {
873 if let Value::File(f) = self {
874 Some(f)
875 } else {
876 None
877 }
878 },
879 is_ty_and => is_file_and(self, callback) => {
880 if let Value::File(f) = self {
881 callback(f)
882 } else {
883 false
884 }
885 }
886);
887
888impl_surreal_value!(
889 Range as kind!(range),
890 is_range(value) => matches!(value, Value::Range(_)),
891 from_range(self) => Value::Range(Box::new(self)),
892 into_range(value) => {
893 let Value::Range(r) = value else {
894 return Err(ConversionError::from_value(Self::kind_of(), &value).into());
895 };
896 Ok(*r)
897 },
898 as_ty => as_range(self) => {
899 if let Value::Range(r) = self {
900 Some(r)
901 } else {
902 None
903 }
904 },
905 is_ty_and => is_range_and(self, callback) => {
906 if let Value::Range(r) = self {
907 callback(r)
908 } else {
909 false
910 }
911 }
912);
913
914impl_surreal_value!(
916 <T> Vec<T> as kind!(array<(T::kind_of())>),
917 is_vec<T>(value) => {
918 if let Value::Array(Array(a)) = value {
919 a.iter().all(T::is_value)
920 } else {
921 false
922 }
923 },
924 from_vec<T>(self) => Value::Array(Array(self.into_iter().map(SurrealValue::into_value).collect())),
925 into_vec<T>(value) => {
926 let Value::Array(Array(a)) = value else {
927 return Err(ConversionError::from_value(Self::kind_of(), &value).into());
928 };
929 a
930 .into_iter()
931 .map(|v| T::from_value(v))
932 .collect::<Result<Vec<T>, Error>>()
933 .map_err(|e| Error::internal(format!("Failed to convert to {}: {}", Self::kind_of(), e)))
934 }
935);
936
937impl_surreal_value!(
938 <T> Option<T> as kind!(none | (T::kind_of())),
939 is_option<T>(value) => matches!(value, Value::None) || T::is_value(value),
940 from_option<T>(self) => self.map(T::into_value).unwrap_or(Value::None),
941 into_option<T>(value) => match value{
942 Value::None => Ok(None),
943 x => T::from_value(x).map(Some).map_err(|e| Error::internal(format!("Failed to convert to {}: {}", Self::kind_of(), e))),
944 }
945);
946
947impl_surreal_value!(
948 <V> BTreeMap<String, V> as kind!(object),
949 (value) => {
950 if let Value::Object(Object(o)) = value {
951 o.iter().all(|(_, v)| V::is_value(v))
952 } else {
953 false
954 }
955 },
956 from_btreemap<V>(self) => Value::Object(Object(self.into_iter().map(|(k, v)| (k, v.into_value())).collect())),
957 into_btreemap<V>(value) => {
958 let Value::Object(Object(o)) = value else {
959 return Err(ConversionError::from_value(Self::kind_of(), &value).into());
960 };
961 o
962 .into_iter()
963 .map(|(k, v)| V::from_value(v).map(|v| (k, v)))
964 .collect::<Result<BTreeMap<String, V>, Error>>()
965 .map_err(|e| Error::internal(format!("Failed to convert to {}: {}", Self::kind_of(), e)))
966 }
967);
968
969impl_surreal_value!(
970 <V> HashMap<String, V> as kind!(object),
971 (value) => {
972 if let Value::Object(Object(o)) = value {
973 o.iter().all(|(_, v)| V::is_value(v))
974 } else {
975 false
976 }
977 },
978 from_hashmap<V>(self) => Value::Object(Object(self.into_iter().map(|(k, v)| (k, v.into_value())).collect())),
979 into_hashmap<V>(value) => {
980 let Value::Object(Object(o)) = value else {
981 return Err(ConversionError::from_value(Self::kind_of(), &value).into());
982 };
983 o
984 .into_iter()
985 .map(|(k, v)| V::from_value(v).map(|v| (k, v)))
986 .collect::<Result<HashMap<String, V>, Error>>()
987 .map_err(|e| Error::internal(format!("Failed to convert to {}: {}", Self::kind_of(), e)))
988 }
989);
990
991impl_surreal_value!(
993 geo::Point as kind!(geometry<point>),
994 is_point(value) => matches!(value, Value::Geometry(Geometry::Point(_))),
995 from_point(self) => Value::Geometry(Geometry::Point(self)),
996 into_point(value) => {
997 let Value::Geometry(Geometry::Point(p)) = value else {
998 return Err(ConversionError::from_value(Self::kind_of(), &value).into());
999 };
1000 Ok(p)
1001 },
1002 as_ty => as_point(self) => {
1003 if let Value::Geometry(Geometry::Point(p)) = self {
1004 Some(p)
1005 } else {
1006 None
1007 }
1008 },
1009 is_ty_and => is_point_and(self, callback) => {
1010 if let Value::Geometry(Geometry::Point(p)) = self {
1011 callback(p)
1012 } else {
1013 false
1014 }
1015 }
1016);
1017
1018impl_surreal_value!(
1019 geo::LineString as kind!(geometry<line>),
1020 is_line(value) => matches!(value, Value::Geometry(Geometry::Line(_))),
1021 from_line(self) => Value::Geometry(Geometry::Line(self)),
1022 into_line(value) => {
1023 let Value::Geometry(Geometry::Line(l)) = value else {
1024 return Err(ConversionError::from_value(Self::kind_of(), &value).into());
1025 };
1026 Ok(l)
1027 },
1028 as_ty => as_line(self) => {
1029 if let Value::Geometry(Geometry::Line(l)) = self {
1030 Some(l)
1031 } else {
1032 None
1033 }
1034 },
1035 is_ty_and => is_line_and(self, callback) => {
1036 if let Value::Geometry(Geometry::Line(l)) = self {
1037 callback(l)
1038 } else {
1039 false
1040 }
1041 }
1042);
1043
1044impl_surreal_value!(
1045 geo::Polygon as kind!(geometry<polygon>),
1046 is_polygon(value) => matches!(value, Value::Geometry(Geometry::Polygon(_))),
1047 from_polygon(self) => Value::Geometry(Geometry::Polygon(self)),
1048 into_polygon(value) => {
1049 let Value::Geometry(Geometry::Polygon(p)) = value else {
1050 return Err(ConversionError::from_value(Self::kind_of(), &value).into());
1051 };
1052 Ok(p)
1053 },
1054 as_ty => as_polygon(self) => {
1055 if let Value::Geometry(Geometry::Polygon(p)) = self {
1056 Some(p)
1057 } else {
1058 None
1059 }
1060 },
1061 is_ty_and => is_polygon_and(self, callback) => {
1062 if let Value::Geometry(Geometry::Polygon(p)) = self {
1063 callback(p)
1064 } else {
1065 false
1066 }
1067 }
1068);
1069
1070impl_surreal_value!(
1071 geo::MultiPoint as kind!(geometry<multipoint>),
1072 is_multipoint(value) => matches!(value, Value::Geometry(Geometry::MultiPoint(_))),
1073 from_multipoint(self) => Value::Geometry(Geometry::MultiPoint(self)),
1074 into_multipoint(value) => {
1075 let Value::Geometry(Geometry::MultiPoint(m)) = value else {
1076 return Err(ConversionError::from_value(Self::kind_of(), &value).into());
1077 };
1078 Ok(m)
1079 },
1080 as_ty => as_multipoint(self) => {
1081 if let Value::Geometry(Geometry::MultiPoint(m)) = self {
1082 Some(m)
1083 } else {
1084 None
1085 }
1086 },
1087 is_ty_and => is_multipoint_and(self, callback) => {
1088 if let Value::Geometry(Geometry::MultiPoint(m)) = self {
1089 callback(m)
1090 } else {
1091 false
1092 }
1093 }
1094);
1095
1096impl_surreal_value!(
1097 geo::MultiLineString as kind!(geometry<multiline>),
1098 is_multiline(value) => matches!(value, Value::Geometry(Geometry::MultiLine(_))),
1099 from_multiline(self) => Value::Geometry(Geometry::MultiLine(self)),
1100 into_multiline(value) => {
1101 let Value::Geometry(Geometry::MultiLine(m)) = value else {
1102 return Err(ConversionError::from_value(Self::kind_of(), &value).into());
1103 };
1104 Ok(m)
1105 },
1106 as_ty => as_multiline(self) => {
1107 if let Value::Geometry(Geometry::MultiLine(m)) = self {
1108 Some(m)
1109 } else {
1110 None
1111 }
1112 },
1113 is_ty_and => is_multiline_and(self, callback) => {
1114 if let Value::Geometry(Geometry::MultiLine(m)) = self {
1115 callback(m)
1116 } else {
1117 false
1118 }
1119 }
1120);
1121
1122impl_surreal_value!(
1123 geo::MultiPolygon as kind!(geometry<multipolygon>),
1124 is_multipolygon(value) => matches!(value, Value::Geometry(Geometry::MultiPolygon(_))),
1125 from_multipolygon(self) => Value::Geometry(Geometry::MultiPolygon(self)),
1126 into_multipolygon(value) => {
1127 let Value::Geometry(Geometry::MultiPolygon(m)) = value else {
1128 return Err(ConversionError::from_value(Self::kind_of(), &value).into());
1129 };
1130 Ok(m)
1131 },
1132 as_ty => as_multipolygon(self) => {
1133 if let Value::Geometry(Geometry::MultiPolygon(m)) = self {
1134 Some(m)
1135 } else {
1136 None
1137 }
1138 },
1139 is_ty_and => is_multipolygon_and(self, callback) => {
1140 if let Value::Geometry(Geometry::MultiPolygon(m)) = self {
1141 callback(m)
1142 } else {
1143 false
1144 }
1145 }
1146);
1147
1148macro_rules! impl_tuples {
1150 ($($n:expr => ($($t:ident),+)),+ $(,)?) => {
1151 $(
1152 impl<$($t: SurrealValue),+> SurrealValue for ($($t,)+) {
1153 fn kind_of() -> Kind {
1154 kind!([$(($t::kind_of())),+])
1155 }
1156
1157 fn is_value(value: &Value) -> bool {
1158 if let Value::Array(Array(a)) = value {
1159 a.len() == $n && {
1160 let mut iter = a.iter();
1161 $(
1162 iter.next().map_or(false, |v| $t::is_value(v))
1163 )&&*
1164 }
1165 } else {
1166 false
1167 }
1168 }
1169
1170 fn into_value(self) -> Value {
1171 #[allow(non_snake_case)]
1172 let ($($t,)+) = self;
1173 Value::Array(Array(vec![$($t.into_value()),+]))
1174 }
1175
1176 fn from_value(value: Value) -> Result<Self, Error> {
1177 let Value::Array(Array(mut a)) = value else {
1178 return Err(ConversionError::from_value(Self::kind_of(), &value).into());
1179 };
1180
1181 if a.len() != $n {
1182 return Err(LengthMismatchError::new($n, a.len(), std::any::type_name::<Self>()).into());
1183 }
1184
1185 $(#[allow(non_snake_case)] let $t = $t::from_value(a.remove(0)).map_err(|e| Error::internal(format!("Failed to convert to {}: {}", Self::kind_of(), e)))?;)+
1186 Ok(($($t,)+))
1187 }
1188 }
1189 )+
1190 }
1191}
1192
1193impl_tuples! {
1194 1 => (A),
1195 2 => (A, B),
1196 3 => (A, B, C),
1197 4 => (A, B, C, D),
1198 5 => (A, B, C, D, E),
1199 6 => (A, B, C, D, E, F),
1200 7 => (A, B, C, D, E, F, G),
1201 8 => (A, B, C, D, E, F, G, H),
1202 9 => (A, B, C, D, E, F, G, H, I),
1203 10 => (A, B, C, D, E, F, G, H, I, J)
1204}
1205
1206macro_rules! impl_numeric {
1208 (int: $($k:ty => ($is_fn:ident, $from_fn:ident, $into_fn:ident, $is_and_fn:ident, $as_fn:ident)),+ $(,)?) => {
1210 $(
1211 impl SurrealValue for $k {
1212 fn kind_of() -> Kind {
1213 kind!(number)
1214 }
1215
1216 fn is_value(value: &Value) -> bool {
1217 matches!(value, Value::Number(_))
1218 }
1219
1220 fn into_value(self) -> Value {
1221 Value::Number(Number::Int(self as i64))
1222 }
1223
1224 fn from_value(value: Value) -> Result<Self, Error> {
1225 let Value::Number(Number::Int(n)) = value else {
1226 return Err(ConversionError::from_value(Self::kind_of(), &value).into());
1227 };
1228 <$k>::try_from(n)
1229 .map_err(|_| OutOfRangeError::new(n, std::any::type_name::<$k>()).into())
1230 }
1231 }
1232
1233 impl Value {
1234 pub fn $is_fn(&self) -> bool {
1236 <$k>::is_value(self)
1237 }
1238
1239 pub fn $from_fn(value: $k) -> Value {
1241 <$k>::into_value(value)
1242 }
1243
1244 pub fn $into_fn(self) -> Result<$k, Error> {
1246 <$k>::from_value(self)
1247 }
1248
1249 pub fn $is_and_fn(&self, callback: impl FnOnce(&$k) -> bool) -> bool {
1251 if let Value::Number(Number::Int(n)) = self {
1252 if let Ok(v) = <$k>::try_from(*n) {
1253 return callback(&v);
1254 }
1255 }
1256 false
1257 }
1258
1259 pub fn $as_fn(&self) -> Option<$k> {
1262 if let Value::Number(Number::Int(n)) = self {
1263 <$k>::try_from(*n).ok()
1264 } else {
1265 None
1266 }
1267 }
1268 }
1269 )+
1270 };
1271
1272 (float: $($k:ty => ($is_fn:ident, $from_fn:ident, $into_fn:ident, $is_and_fn:ident, $as_fn:ident)),+ $(,)?) => {
1274 $(
1275 impl SurrealValue for $k {
1276 fn kind_of() -> Kind {
1277 kind!(number)
1278 }
1279
1280 fn is_value(value: &Value) -> bool {
1281 matches!(value, Value::Number(_))
1282 }
1283
1284 fn into_value(self) -> Value {
1285 Value::Number(Number::Float(self as f64))
1286 }
1287
1288 fn from_value(value: Value) -> Result<Self, Error> {
1289 let Value::Number(Number::Float(n)) = value else {
1290 return Err(ConversionError::from_value(Self::kind_of(), &value).into());
1291 };
1292 Ok(n as $k)
1293 }
1294 }
1295
1296 impl Value {
1297 pub fn $is_fn(&self) -> bool {
1299 <$k>::is_value(self)
1300 }
1301
1302 pub fn $from_fn(value: $k) -> Value {
1304 <$k>::into_value(value)
1305 }
1306
1307 pub fn $into_fn(self) -> Result<$k, Error> {
1309 <$k>::from_value(self)
1310 }
1311
1312 pub fn $is_and_fn(&self, callback: impl FnOnce(&$k) -> bool) -> bool {
1314 if let Value::Number(Number::Float(n)) = self {
1315 let v = *n as $k;
1316 callback(&v)
1317 } else {
1318 false
1319 }
1320 }
1321
1322 pub fn $as_fn(&self) -> Option<$k> {
1325 if let Value::Number(Number::Float(n)) = self {
1326 Some(*n as $k)
1327 } else {
1328 None
1329 }
1330 }
1331 }
1332 )+
1333 };
1334}
1335
1336impl_numeric! {
1338 int:
1339 i8 => (is_i8, from_i8, into_i8, is_i8_and, as_i8),
1340 i16 => (is_i16, from_i16, into_i16, is_i16_and, as_i16),
1341 i32 => (is_i32, from_i32, into_i32, is_i32_and, as_i32),
1342 isize => (is_isize, from_isize, into_isize, is_isize_and, as_isize),
1344 u8 => (is_u8, from_u8, into_u8, is_u8_and, as_u8),
1345 u16 => (is_u16, from_u16, into_u16, is_u16_and, as_u16),
1346 u32 => (is_u32, from_u32, into_u32, is_u32_and, as_u32),
1347 u64 => (is_u64, from_u64, into_u64, is_u64_and, as_u64),
1348 usize => (is_usize, from_usize, into_usize, is_usize_and, as_usize),
1349}
1350
1351impl_numeric! {
1353 float:
1354 f32 => (is_f32, from_f32, into_f32, is_f32_and, as_f32),
1355 }
1357
1358impl SurrealValue for serde_json::Value {
1359 fn kind_of() -> Kind {
1360 kind!(any)
1361 }
1362
1363 fn is_value(_value: &Value) -> bool {
1364 true
1365 }
1366
1367 fn into_value(self) -> Value {
1368 match self {
1369 serde_json::Value::Null => Value::Null,
1370 serde_json::Value::Bool(b) => Value::Bool(b),
1371 serde_json::Value::Number(n) => {
1372 if let Some(i) = n.as_i64() {
1373 Value::Number(Number::Int(i))
1374 } else if let Some(f) = n.as_f64() {
1375 Value::Number(Number::Float(f))
1376 } else {
1377 Value::String(n.to_string())
1379 }
1380 }
1381 serde_json::Value::String(s) => Value::String(s),
1382 serde_json::Value::Object(o) => {
1383 let mut obj = Object::new();
1384 for (k, v) in o {
1385 obj.insert(k, serde_json::Value::into_value(v));
1386 }
1387 Value::Object(obj)
1388 }
1389 serde_json::Value::Array(a) => {
1390 Value::Array(Array(a.into_iter().map(serde_json::Value::into_value).collect()))
1391 }
1392 }
1393 }
1394
1395 fn from_value(value: Value) -> Result<Self, Error> {
1396 Ok(value.into_json_value())
1397 }
1398}
1399
1400macro_rules! impl_slice {
1401 ($($n:expr),+ $(,)?) => {
1402 $(
1403 impl<T: SurrealValue> SurrealValue for [T; $n] {
1404 fn kind_of() -> Kind {
1405 kind!(array<(T::kind_of()), $n>)
1406 }
1407
1408 fn is_value(value: &Value) -> bool {
1409 matches!(value, Value::Array(_))
1410 }
1411
1412 fn into_value(self) -> Value {
1413 Value::Array(Array(self.into_iter().map(T::into_value).collect()))
1414 }
1415
1416 fn from_value(value: Value) -> Result<Self, Error> {
1417 let Value::Array(Array(a)) = value else {
1418 return Err(ConversionError::from_value(Self::kind_of(), &value).into());
1419 };
1420 if a.len() != $n {
1421 return Err(LengthMismatchError::new($n, a.len(), std::any::type_name::<Self>()).into());
1422 }
1423 let mut result = Vec::with_capacity($n);
1424 for v in a {
1425 result.push(T::from_value(v)?);
1426 }
1427 result.try_into()
1428 .map_err(|v: Vec<_>| Error::internal(format!("Failed to convert vec of length {} to array of size {}", v.len(), $n)))
1429 }
1430 }
1431 )+
1432 }
1433}
1434
1435impl_slice!(
1436 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
1437 27, 28, 29, 30, 31, 32
1438);
1439
1440impl SurrealValue for http::HeaderMap {
1441 fn kind_of() -> Kind {
1442 kind!(object)
1443 }
1444
1445 fn is_value(value: &Value) -> bool {
1446 matches!(value, Value::Object(_))
1447 }
1448
1449 fn into_value(self) -> Value {
1450 let mut next_key = None;
1451 let mut next_value = Value::None;
1452 let mut first_value = true;
1453 let mut res = BTreeMap::new();
1454
1455 for (k, v) in self {
1459 let v = match v.to_str() {
1460 Ok(v) => Value::String(v.to_owned()),
1461 Err(_) => continue,
1462 };
1463
1464 if let Some(k) = k {
1465 let k = k.as_str().to_owned();
1466 if let Some(k) = next_key.take() {
1469 let v = std::mem::replace(&mut next_value, Value::None);
1470 res.insert(k, v);
1471 }
1472 next_key = Some(k);
1473 next_value = v;
1474 first_value = true;
1475 } else if first_value {
1476 first_value = false;
1479 next_value = Value::Array(vec![next_value, v].into())
1480 } else {
1481 if let Value::Array(ref mut array) = next_value {
1484 array.push(v);
1485 }
1486 }
1487 }
1488
1489 if let Some(x) = next_key {
1491 let v = std::mem::replace(&mut next_value, Value::None);
1492 res.insert(x, v);
1493 }
1494
1495 Value::Object(Object::from(res))
1496 }
1497
1498 fn from_value(value: Value) -> Result<Self, Error> {
1499 let Value::Object(Object(o)) = value else {
1503 return Err(ConversionError::from_value(Self::kind_of(), &value).into());
1504 };
1505 let mut res = http::HeaderMap::new();
1506 for (k, v) in o {
1507 let k = k.parse::<http::HeaderName>().map_err(|e| Error::internal(e.to_string()))?;
1508 match v {
1509 Value::Array(Array(a)) => {
1510 for v in a {
1511 let v = v
1512 .into_string()
1513 .map_err(|e| Error::internal(e.to_string()))?
1514 .parse::<http::HeaderValue>()
1515 .map_err(|e: http::header::InvalidHeaderValue| {
1516 Error::internal(e.to_string())
1517 })?;
1518 res.insert(k.clone(), v);
1519 }
1520 }
1521 Value::String(v) => {
1522 res.insert(
1523 k,
1524 v.parse::<http::HeaderValue>().map_err(
1525 |e: http::header::InvalidHeaderValue| Error::internal(e.to_string()),
1526 )?,
1527 );
1528 }
1529 unexpected => {
1530 return Err(ConversionError::from_value(Self::kind_of(), &unexpected).into());
1531 }
1532 }
1533 }
1534 Ok(res)
1535 }
1536}
1537
1538impl SurrealValue for http::StatusCode {
1539 fn kind_of() -> Kind {
1540 kind!(number)
1541 }
1542
1543 fn is_value(value: &Value) -> bool {
1544 matches!(value, Value::Number(_))
1545 }
1546
1547 fn into_value(self) -> Value {
1548 Value::Number(Number::Int(self.as_u16() as i64))
1549 }
1550
1551 fn from_value(value: Value) -> Result<Self, Error> {
1552 let Value::Number(Number::Int(n)) = value else {
1553 return Err(ConversionError::from_value(Self::kind_of(), &value).into());
1554 };
1555 http::StatusCode::from_u16(n as u16)
1556 .map_err(|_| Error::internal("Failed to convert status code".to_string()))
1557 }
1558}
1559
1560impl<T: SurrealValue> SurrealValue for LinkedList<T> {
1561 fn kind_of() -> Kind {
1562 kind!(array<(T::kind_of())>)
1563 }
1564
1565 fn is_value(value: &Value) -> bool {
1566 {
1567 if let Value::Array(Array(a)) = value {
1568 a.iter().all(T::is_value)
1569 } else {
1570 false
1571 }
1572 }
1573 }
1574
1575 fn into_value(self) -> Value {
1576 Value::Array(Array(self.into_iter().map(SurrealValue::into_value).collect()))
1577 }
1578
1579 fn from_value(value: Value) -> Result<Self, Error> {
1580 let Value::Array(Array(a)) = value else {
1581 return Err(ConversionError::from_value(Self::kind_of(), &value).into());
1582 };
1583
1584 a.into_iter().map(|v| T::from_value(v)).collect::<Result<LinkedList<T>, Error>>().map_err(
1585 |e| Error::internal(format!("Failed to convert to {}: {}", Self::kind_of(), e)),
1586 )
1587 }
1588}
1589
1590impl<T: SurrealValue + Hash + Eq> SurrealValue for HashSet<T> {
1591 fn kind_of() -> Kind {
1592 kind!(array<(T::kind_of())>)
1593 }
1594
1595 fn is_value(value: &Value) -> bool {
1596 {
1597 if let Value::Array(Array(a)) = value {
1598 a.iter().all(T::is_value)
1599 } else {
1600 false
1601 }
1602 }
1603 }
1604
1605 fn into_value(self) -> Value {
1606 Value::Array(Array(self.into_iter().map(SurrealValue::into_value).collect()))
1607 }
1608
1609 fn from_value(value: Value) -> Result<Self, Error> {
1610 let Value::Array(Array(a)) = value else {
1611 return Err(ConversionError::from_value(Self::kind_of(), &value).into());
1612 };
1613
1614 a.into_iter().map(|v| T::from_value(v)).collect::<Result<HashSet<T>, Error>>().map_err(
1615 |e| Error::internal(format!("Failed to convert to {}: {}", Self::kind_of(), e)),
1616 )
1617 }
1618}