1use std::borrow::Cow;
2use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, LinkedList, VecDeque};
3use std::hash::Hash;
4use std::marker::PhantomData;
5use std::rc::Rc;
6use std::sync::Arc;
7
8use castaway::{cast, match_type};
9use rust_decimal::Decimal;
10use serde::Serialize;
11use serde::de::DeserializeOwned;
12
13use crate as surrealdb_types;
14use crate::error::{ConversionError, LengthMismatchError, OutOfRangeError, SerializationError};
15use crate::traits::ser::Serializer;
16use crate::{
17 Array, Bytes, Datetime, Duration, Error, File, Geometry, Kind, Number, Object, Range, RecordId,
18 Set, SurrealNone, SurrealNull, Table, Uuid, Value, kind,
19};
20
21pub trait SurrealValue {
30 fn kind_of() -> Kind;
32 fn is_value(value: &Value) -> bool {
34 value.is_kind(&Self::kind_of())
35 }
36 fn into_value(self) -> Value;
38 fn from_value(value: Value) -> Result<Self, Error>
40 where
41 Self: Sized;
42}
43
44impl<T: SurrealValue> SurrealValue for Box<T> {
45 fn kind_of() -> Kind {
46 T::kind_of()
47 }
48
49 fn is_value(value: &Value) -> bool {
50 T::is_value(value)
51 }
52
53 fn into_value(self) -> Value {
54 T::into_value(*self)
55 }
56
57 fn from_value(value: Value) -> Result<Self, Error> {
58 T::from_value(value).map(Box::new)
59 }
60}
61
62impl<T: SurrealValue + Clone> SurrealValue for Arc<T> {
63 fn kind_of() -> Kind {
64 T::kind_of()
65 }
66
67 fn is_value(value: &Value) -> bool {
68 T::is_value(value)
69 }
70
71 fn into_value(self) -> Value {
72 T::into_value(self.as_ref().clone())
73 }
74
75 fn from_value(value: Value) -> Result<Self, Error> {
76 T::from_value(value).map(Arc::new)
77 }
78}
79
80impl<T: SurrealValue + Clone> SurrealValue for Rc<T> {
81 fn kind_of() -> Kind {
82 T::kind_of()
83 }
84
85 fn is_value(value: &Value) -> bool {
86 T::is_value(value)
87 }
88
89 fn into_value(self) -> Value {
90 T::into_value(self.as_ref().clone())
91 }
92
93 fn from_value(value: Value) -> Result<Self, Error> {
94 T::from_value(value).map(Rc::new)
95 }
96}
97
98macro_rules! impl_surreal_value {
99 (
101 <$($generic:ident),*> $type:ty as $kind:expr,
102 $($is_fnc:ident<$($is_generic:ident),*>)? ($value_is:ident) => $is:expr,
103 $($from_fnc:ident<$($from_generic:ident),*>)? ($self:ident) => $into:expr,
104 $($into_fnc:ident<$($into_generic:ident),*>)? ($value_into:ident) => $from:expr
105 $(, as_ty => $as_fnc:ident<$($as_generic:ident),*> ($self_as:ident) => $as_expr:expr)?
106 $(, is_ty_and => $is_and_fnc:ident<$($is_and_generic:ident),*> ($self_is_and:ident, $is_and_callback:ident) => $is_and:expr)?
107 ) => {
108 impl<$($generic: SurrealValue),*> SurrealValue for $type {
109 fn kind_of() -> Kind {
110 $kind
111 }
112
113 fn is_value($value_is: &Value) -> bool {
114 $is
115 }
116
117 fn into_value($self) -> Value {
118 $into
119 }
120
121 fn from_value($value_into: Value) -> Result<Self, Error> {
122 $from
123 }
124 }
125
126 $(
127 impl Value {
128 pub fn $is_fnc<$($is_generic: SurrealValue),*>(&self) -> bool {
132 <$type>::is_value(self)
133 }
134 }
135 )?
136
137 $(
138 impl Value {
139 pub fn $from_fnc<$($from_generic: SurrealValue),*>(value: $type) -> Value {
141 <$type>::into_value(value)
142 }
143 }
144 )?
145
146 $(
147 impl Value {
148 pub fn $into_fnc<$($into_generic: SurrealValue),*>(self) -> Result<$type, Error> {
152 <$type>::from_value(self)
153 }
154 }
155 )?
156
157 $(
158 impl Value {
159 pub fn $as_fnc<$($as_generic: SurrealValue),*>(&$self_as) -> Option<&$type> {
163 $as_expr
164 }
165 }
166 )?
167
168 $(
169 impl Value {
170 pub fn $is_and_fnc<$($is_and_generic: SurrealValue),*>(&$self_is_and, $is_and_callback: impl FnOnce(&$type) -> bool) -> bool {
174 $is_and
175 }
176 }
177 )?
178 };
179
180 (
182 $type:ty as $kind:expr,
183 $($is_fnc:ident),* ($value_is:ident) => $is:expr,
184 $($from_fnc:ident),* ($self:ident) => $into:expr,
185 $($into_fnc:ident),* ($value_into:ident) => $from:expr
186 $(, as_ty => $($as_fnc:ident),+ ($self_as:ident) => $as_expr:expr)?
187 $(, is_ty_and => $($is_and_fnc:ident),+($self_is_and:ident, $is_and_callback:ident) => $is_and:expr)?
188 ) => {
189 impl SurrealValue for $type {
190 fn kind_of() -> Kind {
191 $kind
192 }
193
194 fn is_value($value_is: &Value) -> bool {
195 $is
196 }
197
198 fn into_value($self) -> Value {
199 $into
200 }
201
202 fn from_value($value_into: Value) -> Result<Self, Error> {
203 $from
204 }
205 }
206
207 $(
208 impl Value {
209 pub fn $is_fnc(&self) -> bool {
213 <$type>::is_value(self)
214 }
215 }
216 )*
217
218 $(
219 impl Value {
220 pub fn $from_fnc(value: $type) -> Value {
222 <$type>::into_value(value)
223 }
224 }
225 )*
226
227 $(
228 impl Value {
229 pub fn $into_fnc(self) -> Result<$type, Error> {
233 <$type>::from_value(self)
234 }
235 }
236 )*
237
238 $(
239 impl Value {
240 $(
241 pub fn $as_fnc(&$self_as) -> Option<&$type> {
245 $as_expr
246 }
247 )+
248 }
249 )?
250
251 $(
252 impl Value {
253 $(
254 pub fn $is_and_fnc(&$self_is_and, $is_and_callback: impl FnOnce(&$type) -> bool) -> bool {
258 $is_and
259 }
260 )+
261 }
262 )?
263 };
264}
265
266impl_surreal_value!(
268 Value as kind!(any),
269 (_value) => true,
270 (self) => self,
271 (value) => Ok(value)
272);
273
274impl_surreal_value!(
275 () as kind!(none),
276 (value) => matches!(value, Value::None),
277 (self) => Value::None,
278 (value) => {
279 if value == Value::None {
280 Ok(())
281 } else {
282 Err(ConversionError::from_value(Self::kind_of(), &value).into())
283 }
284 }
285);
286
287impl_surreal_value!(
288 SurrealNone as kind!(none),
289 is_none(value) => matches!(value, Value::None),
290 (self) => Value::None,
291 (value) => {
292 if value == Value::None {
293 Ok(SurrealNone)
294 } else {
295 Err(ConversionError::from_value(Self::kind_of(), &value).into())
296 }
297 }
298);
299
300impl_surreal_value!(
301 SurrealNull as kind!(null),
302 is_null(value) => matches!(value, Value::Null),
303 (self) => Value::Null,
304 (value) => {
305 if value == Value::Null {
306 Ok(SurrealNull)
307 } else {
308 Err(ConversionError::from_value(Self::kind_of(), &value).into())
309 }
310 }
311);
312
313impl_surreal_value!(
314 bool as kind!(bool),
315 is_bool(value) => matches!(value, Value::Bool(_)),
316 from_bool(self) => Value::Bool(self),
317 into_bool(value) => {
318 let Value::Bool(b) = value else {
319 return Err(ConversionError::from_value(Self::kind_of(), &value).into());
320 };
321 Ok(b)
322 },
323 as_ty => as_bool(self) => {
324 if let Value::Bool(b) = self {
325 Some(b)
326 } else {
327 None
328 }
329 }
330);
331
332impl Value {
335 pub fn is_true(&self) -> bool {
339 matches!(self, Value::Bool(true))
340 }
341
342 pub fn is_false(&self) -> bool {
346 matches!(self, Value::Bool(false))
347 }
348}
349
350impl_surreal_value!(
351 Number as kind!(number),
352 is_number(value) => matches!(value, Value::Number(_)),
353 from_number(self) => Value::Number(self),
354 into_number(value) => {
355 let Value::Number(n) = value else {
356 return Err(ConversionError::from_value(Self::kind_of(), &value).into());
357 };
358 Ok(n)
359 },
360 as_ty => as_number(self) => {
361 if let Value::Number(n) = self {
362 Some(n)
363 } else {
364 None
365 }
366 },
367 is_ty_and => is_number_and(self, callback) => {
368 if let Value::Number(n) = self {
369 callback(n)
370 } else {
371 false
372 }
373 }
374);
375
376impl_surreal_value!(
377 i64 as kind!(int),
378 is_int, is_i64(value) => matches!(value, Value::Number(Number::Int(_))),
379 from_int, from_i64(self) => Value::Number(Number::Int(self)),
380 into_int, into_i64(value) => {
381 let Value::Number(Number::Int(n)) = value else {
382 return Err(ConversionError::from_value(Self::kind_of(), &value).into());
383 };
384 Ok(n)
385 },
386 as_ty => as_int, as_i64(self) => {
387 if let Value::Number(Number::Int(n)) = self {
388 Some(n)
389 } else {
390 None
391 }
392 },
393 is_ty_and => is_int_and, is_i64_and(self, callback) => {
394 if let Value::Number(Number::Int(n)) = self {
395 callback(n)
396 } else {
397 false
398 }
399 }
400);
401
402impl_surreal_value!(
403 f64 as kind!(float),
404 is_float, is_f64(value) => matches!(value, Value::Number(Number::Float(_))),
405 from_float, from_f64(self) => Value::Number(Number::Float(self)),
406 into_float, into_f64(value) => {
407 let Value::Number(Number::Float(n)) = value else {
408 return Err(ConversionError::from_value(Self::kind_of(), &value).into());
409 };
410 Ok(n)
411 },
412 as_ty => as_float, as_f64(self) => {
413 if let Value::Number(Number::Float(n)) = self {
414 Some(n)
415 } else {
416 None
417 }
418 },
419 is_ty_and => is_float_and, is_f64_and(self, callback) => {
420 if let Value::Number(Number::Float(n)) = self {
421 callback(n)
422 } else {
423 false
424 }
425 }
426);
427
428impl_surreal_value!(
429 Decimal as kind!(decimal),
430 is_decimal(value) => matches!(value, Value::Number(Number::Decimal(_))),
431 from_decimal(self) => Value::Number(Number::Decimal(self)),
432 into_decimal(value) => {
433 let Value::Number(Number::Decimal(n)) = value else {
434 return Err(ConversionError::from_value(Self::kind_of(), &value).into());
435 };
436 Ok(n)
437 },
438 as_ty => as_decimal(self) => {
439 if let Value::Number(Number::Decimal(n)) = self {
440 Some(n)
441 } else {
442 None
443 }
444 },
445 is_ty_and => is_decimal_and(self, callback) => {
446 if let Value::Number(Number::Decimal(n)) = self {
447 callback(n)
448 } else {
449 false
450 }
451 }
452);
453
454impl_surreal_value!(
455 String as kind!(string),
456 is_string(value) => matches!(value, Value::String(_)),
457 from_string(self) => Value::String(self),
458 into_string(value) => {
459 let Value::String(s) = value else {
460 return Err(ConversionError::from_value(Self::kind_of(), &value).into());
461 };
462 Ok(s)
463 },
464 as_ty => as_string(self) => {
465 if let Value::String(s) = self {
466 Some(s)
467 } else {
468 None
469 }
470 },
471 is_ty_and => is_string_and(self, callback) => {
472 if let Value::String(s) = self {
473 callback(s)
474 } else {
475 false
476 }
477 }
478);
479
480impl<T: ToOwned + ?Sized> SurrealValue for Cow<'_, T>
481where
482 T::Owned: SurrealValue,
483{
484 fn kind_of() -> Kind {
485 <T::Owned>::kind_of()
486 }
487
488 fn is_value(value: &Value) -> bool {
489 <T::Owned>::is_value(value)
490 }
491
492 fn into_value(self) -> Value {
493 <T::Owned>::into_value(self.into_owned())
494 }
495
496 fn from_value(value: Value) -> Result<Self, Error> {
497 <T::Owned>::from_value(value).map(Cow::Owned)
498 }
499}
500
501impl SurrealValue for &str {
502 fn kind_of() -> Kind {
503 kind!(string)
504 }
505
506 fn is_value(value: &Value) -> bool {
507 matches!(value, Value::String(_))
508 }
509
510 fn into_value(self) -> Value {
511 Value::String(self.to_string())
512 }
513
514 fn from_value(_: Value) -> Result<Self, Error> {
515 Err(Error::serialization(
516 "Cannot convert to &str because the value would be dropped and the reference would dangle. Use String or Cow<'_, str> instead".to_owned(),
517 SerializationError::Deserialization,
518 ))
519 }
520}
521
522impl_surreal_value!(
523 Duration as kind!(duration),
524 is_duration(value) => matches!(value, Value::Duration(_)),
525 from_duration(self) => Value::Duration(self),
526 into_duration(value) => {
527 let Value::Duration(d) = value else {
528 return Err(ConversionError::from_value(Self::kind_of(), &value).into());
529 };
530 Ok(d)
531 },
532 as_ty => as_duration(self) => {
533 if let Value::Duration(d) = self {
534 Some(d)
535 } else {
536 None
537 }
538 },
539 is_ty_and => is_duration_and(self, callback) => {
540 if let Value::Duration(d) = self {
541 callback(d)
542 } else {
543 false
544 }
545 }
546);
547
548impl_surreal_value!(
549 std::time::Duration as kind!(duration),
550 (value) => matches!(value, Value::Duration(_)),
551 (self) => Value::Duration(Duration(self)),
552 (value) => {
553 let Value::Duration(Duration(d)) = value else {
554 return Err(ConversionError::from_value(Self::kind_of(), &value).into());
555 };
556 Ok(d)
557 }
558);
559
560impl_surreal_value!(
561 Datetime as kind!(datetime),
562 is_datetime(value) => matches!(value, Value::Datetime(_)),
563 from_datetime(self) => Value::Datetime(self),
564 into_datetime(value) => {
565 let Value::Datetime(d) = value else {
566 return Err(ConversionError::from_value(Self::kind_of(), &value).into());
567 };
568 Ok(d)
569 },
570 as_ty => as_datetime(self) => {
571 if let Value::Datetime(d) = self {
572 Some(d)
573 } else {
574 None
575 }
576 },
577 is_ty_and => is_datetime_and(self, callback) => {
578 if let Value::Datetime(d) = self {
579 callback(d)
580 } else {
581 false
582 }
583 }
584);
585
586impl_surreal_value!(
587 chrono::DateTime<chrono::Utc> as kind!(datetime),
588 (value) => matches!(value, Value::Datetime(_)),
589 (self) => Value::Datetime(Datetime(self)),
590 (value) => {
591 let Value::Datetime(Datetime(d)) = value else {
592 return Err(ConversionError::from_value(Self::kind_of(), &value).into());
593 };
594 Ok(d)
595 }
596);
597
598impl_surreal_value!(
599 chrono::NaiveDate as kind!(datetime),
600 (value) => matches!(value, Value::Datetime(_)),
601 (self) => Value::Datetime(Datetime(chrono::DateTime::from_naive_utc_and_offset(self.and_time(chrono::NaiveTime::MIN), chrono::Utc))),
602 (value) => {
603 let Value::Datetime(Datetime(d)) = value else {
604 return Err(ConversionError::from_value(Self::kind_of(), &value).into());
605 };
606 Ok(d.date_naive())
607 }
608);
609
610impl_surreal_value!(
611 Uuid as kind!(uuid),
612 is_uuid(value) => matches!(value, Value::Uuid(_)),
613 from_uuid(self) => Value::Uuid(self),
614 into_uuid(value) => {
615 let Value::Uuid(u) = value else {
616 return Err(ConversionError::from_value(Self::kind_of(), &value).into());
617 };
618 Ok(u)
619 },
620 as_ty => as_uuid(self) => {
621 if let Value::Uuid(u) = self {
622 Some(u)
623 } else {
624 None
625 }
626 },
627 is_ty_and => is_uuid_and(self, callback) => {
628 if let Value::Uuid(u) = self {
629 callback(u)
630 } else {
631 false
632 }
633 }
634);
635
636impl_surreal_value!(
637 uuid::Uuid as kind!(uuid),
638 (value) => matches!(value, Value::Uuid(_)),
639 (self) => Value::Uuid(Uuid(self)),
640 (value) => {
641 let Value::Uuid(Uuid(u)) = value else {
642 return Err(ConversionError::from_value(<Uuid>::kind_of(), &value).into());
643 };
644 Ok(u)
645 }
646);
647
648impl_surreal_value!(
649 Array as kind!(array),
650 is_array(value) => matches!(value, Value::Array(_)),
651 from_array(self) => Value::Array(self),
652 into_array(value) => {
653 let Value::Array(a) = value else {
654 return Err(ConversionError::from_value(Self::kind_of(), &value).into());
655 };
656 Ok(a)
657 },
658 as_ty => as_array(self) => {
659 if let Value::Array(a) = self {
660 Some(a)
661 } else {
662 None
663 }
664 },
665 is_ty_and => is_array_and(self, callback) => {
666 if let Value::Array(a) = self {
667 callback(a)
668 } else {
669 false
670 }
671 }
672);
673
674impl_surreal_value!(
675 Set as kind!(set),
676 is_set(value) => matches!(value, Value::Set(_)),
677 from_set(self) => Value::Set(self),
678 into_set(value) => {
679 let Value::Set(s) = value else {
680 return Err(ConversionError::from_value(Self::kind_of(), &value).into());
681 };
682 Ok(s)
683 },
684 as_ty => as_set(self) => {
685 if let Value::Set(s) = self {
686 Some(s)
687 } else {
688 None
689 }
690 },
691 is_ty_and => is_set_and(self, callback) => {
692 if let Value::Set(s) = self {
693 callback(s)
694 } else {
695 false
696 }
697 }
698);
699
700impl_surreal_value!(
701 Object as kind!(object),
702 is_object(value) => matches!(value, Value::Object(_)),
703 from_object(self) => Value::Object(self),
704 into_object(value) => {
705 let Value::Object(o) = value else {
706 return Err(ConversionError::from_value(Self::kind_of(), &value).into());
707 };
708 Ok(o)
709 },
710 as_ty => as_object(self) => {
711 if let Value::Object(o) = self {
712 Some(o)
713 } else {
714 None
715 }
716 },
717 is_ty_and => is_object_and(self, callback) => {
718 if let Value::Object(o) = self {
719 callback(o)
720 } else {
721 false
722 }
723 }
724);
725
726impl_surreal_value!(
727 Geometry as kind!(geometry),
728 is_geometry(value) => matches!(value, Value::Geometry(_)),
729 from_geometry(self) => Value::Geometry(self),
730 into_geometry(value) => {
731 let Value::Geometry(g) = value else {
732 return Err(ConversionError::from_value(Self::kind_of(), &value).into());
733 };
734 Ok(g)
735 },
736 as_ty => as_geometry(self) => {
737 if let Value::Geometry(g) = self {
738 Some(g)
739 } else {
740 None
741 }
742 },
743 is_ty_and => is_geometry_and(self, callback) => {
744 if let Value::Geometry(g) = self {
745 callback(g)
746 } else {
747 false
748 }
749 }
750);
751
752impl_surreal_value!(
753 Bytes as kind!(bytes),
754 is_bytes(value) => matches!(value, Value::Bytes(_)),
755 from_bytes(self) => Value::Bytes(self),
756 into_bytes(value) => {
757 let Value::Bytes(b) = value else {
758 return Err(ConversionError::from_value(Self::kind_of(), &value).into());
759 };
760 Ok(b)
761 },
762 as_ty => as_bytes(self) => {
763 if let Value::Bytes(b) = self {
764 Some(b)
765 } else {
766 None
767 }
768 },
769 is_ty_and => is_bytes_and(self, callback) => {
770 if let Value::Bytes(b) = self {
771 callback(b)
772 } else {
773 false
774 }
775 }
776);
777
778impl_surreal_value!(
785 bytes::Bytes as kind!(bytes),
786 (value) => matches!(value, Value::Bytes(_)),
787 (self) => Value::Bytes(Bytes(self)),
788 (value) => {
789 let Value::Bytes(Bytes(b)) = value else {
790 return Err(ConversionError::from_value(Self::kind_of(), &value).into());
791 };
792 Ok(b)
793 }
794);
795
796impl_surreal_value!(
797 Table as kind!(table),
798 is_table(value) => {
799 matches!(value, Value::Table(_))
800 },
801 from_table(self) => Value::Table(self),
802 into_table(value) => {
803 match value {
804 Value::Table(t) => Ok(t),
805 _ => Err(ConversionError::from_value(Self::kind_of(), &value).into()),
806 }
807 },
808 as_ty => as_table(self) => {
809 if let Value::Table(t) = self {
810 Some(t)
811 } else {
812 None
813 }
814 },
815 is_ty_and => is_table_and(self, callback) => {
816 if let Value::Table(t) = self {
817 callback(t)
818 } else {
819 false
820 }
821 }
822);
823
824impl_surreal_value!(
825 RecordId as kind!(record),
826 is_record(value) => {
827 match value {
828 Value::RecordId(_) => true,
829 Value::String(s) => Self::parse_simple(s).is_ok(),
830 Value::Object(o) => {
831 o.get("id").is_some()
832 }
833 _ => false,
834 }
835 },
836 from_record(self) => Value::RecordId(self),
837 into_record(value) => {
838 match value {
839 Value::RecordId(r) => Ok(r),
840 Value::String(s) => Self::parse_simple(&s).map_err(|e| Error::internal(e.to_string())),
841 Value::Object(o) => {
842 let v = o.get("id").ok_or_else(|| Error::internal("Invalid record id".to_string()))?;
843 v.clone().into_record()
844 }
845 Value::Array(a) => {
846 let first = a.first().ok_or_else(|| Error::internal("Invalid record id: array is empty".to_string()))?;
847 first.clone().into_record()
848 }
849 _ => Err(ConversionError::from_value(Self::kind_of(), &value).into()),
850 }
851 },
852 as_ty => as_record(self) => {
853 if let Value::RecordId(r) = self {
854 Some(r)
855 } else {
856 None
857 }
858 },
859 is_ty_and => is_record_and(self, callback) => {
860 if let Value::RecordId(r) = self {
861 callback(r)
862 } else {
863 false
864 }
865 }
866);
867
868impl_surreal_value!(
869 File as kind!(file),
870 is_file(value) => matches!(value, Value::File(_)),
871 from_file(self) => Value::File(self),
872 into_file(value) => {
873 let Value::File(f) = value else {
874 return Err(ConversionError::from_value(Self::kind_of(), &value).into());
875 };
876 Ok(f)
877 },
878 as_ty => as_file(self) => {
879 if let Value::File(f) = self {
880 Some(f)
881 } else {
882 None
883 }
884 },
885 is_ty_and => is_file_and(self, callback) => {
886 if let Value::File(f) = self {
887 callback(f)
888 } else {
889 false
890 }
891 }
892);
893
894impl_surreal_value!(
895 Range as kind!(range),
896 is_range(value) => matches!(value, Value::Range(_)),
897 from_range(self) => Value::Range(Box::new(self)),
898 into_range(value) => {
899 let Value::Range(r) = value else {
900 return Err(ConversionError::from_value(Self::kind_of(), &value).into());
901 };
902 Ok(*r)
903 },
904 as_ty => as_range(self) => {
905 if let Value::Range(r) = self {
906 Some(r)
907 } else {
908 None
909 }
910 },
911 is_ty_and => is_range_and(self, callback) => {
912 if let Value::Range(r) = self {
913 callback(r)
914 } else {
915 false
916 }
917 }
918);
919
920impl_surreal_value!(
922 <T> Vec<T> as kind!(array<(T::kind_of())>),
923 is_vec<T>(value) => {
924 if let Value::Array(Array(a)) = value {
925 a.iter().all(T::is_value)
926 } else {
927 false
928 }
929 },
930 from_vec<T>(self) => Value::Array(Array(self.into_iter().map(SurrealValue::into_value).collect())),
931 into_vec<T>(value) => {
932 let Value::Array(Array(a)) = value else {
933 return Err(ConversionError::from_value(Self::kind_of(), &value).into());
934 };
935 a
936 .into_iter()
937 .map(|v| T::from_value(v))
938 .collect::<Result<Vec<T>, Error>>()
939 .map_err(|e| Error::internal(format!("Failed to convert to {}: {}", Self::kind_of(), e)))
940 }
941);
942
943impl_surreal_value!(
944 <T> Option<T> as kind!(none | (T::kind_of())),
945 is_option<T>(value) => matches!(value, Value::None) || T::is_value(value),
946 from_option<T>(self) => self.map(T::into_value).unwrap_or(Value::None),
947 into_option<T>(value) => match value{
948 Value::None => Ok(None),
949 x => T::from_value(x).map(Some).map_err(|e| Error::internal(format!("Failed to convert to {}: {}", Self::kind_of(), e))),
950 }
951);
952
953impl_surreal_value!(
954 <V> BTreeMap<String, V> as kind!(object),
955 (value) => {
956 if let Value::Object(Object(o)) = value {
957 o.iter().all(|(_, v)| V::is_value(v))
958 } else {
959 false
960 }
961 },
962 from_btreemap<V>(self) => Value::Object(Object(self.into_iter().map(|(k, v)| (k, v.into_value())).collect())),
963 into_btreemap<V>(value) => {
964 let Value::Object(Object(o)) = value else {
965 return Err(ConversionError::from_value(Self::kind_of(), &value).into());
966 };
967 o
968 .into_iter()
969 .map(|(k, v)| V::from_value(v).map(|v| (k, v)))
970 .collect::<Result<BTreeMap<String, V>, Error>>()
971 .map_err(|e| Error::internal(format!("Failed to convert to {}: {}", Self::kind_of(), e)))
972 }
973);
974
975impl_surreal_value!(
976 <V> HashMap<String, V> as kind!(object),
977 (value) => {
978 if let Value::Object(Object(o)) = value {
979 o.iter().all(|(_, v)| V::is_value(v))
980 } else {
981 false
982 }
983 },
984 from_hashmap<V>(self) => Value::Object(Object(self.into_iter().map(|(k, v)| (k, v.into_value())).collect())),
985 into_hashmap<V>(value) => {
986 let Value::Object(Object(o)) = value else {
987 return Err(ConversionError::from_value(Self::kind_of(), &value).into());
988 };
989 o
990 .into_iter()
991 .map(|(k, v)| V::from_value(v).map(|v| (k, v)))
992 .collect::<Result<HashMap<String, V>, Error>>()
993 .map_err(|e| Error::internal(format!("Failed to convert to {}: {}", Self::kind_of(), e)))
994 }
995);
996
997impl_surreal_value!(
999 geo::Point as kind!(geometry<point>),
1000 is_point(value) => matches!(value, Value::Geometry(Geometry::Point(_))),
1001 from_point(self) => Value::Geometry(Geometry::Point(self)),
1002 into_point(value) => {
1003 let Value::Geometry(Geometry::Point(p)) = value else {
1004 return Err(ConversionError::from_value(Self::kind_of(), &value).into());
1005 };
1006 Ok(p)
1007 },
1008 as_ty => as_point(self) => {
1009 if let Value::Geometry(Geometry::Point(p)) = self {
1010 Some(p)
1011 } else {
1012 None
1013 }
1014 },
1015 is_ty_and => is_point_and(self, callback) => {
1016 if let Value::Geometry(Geometry::Point(p)) = self {
1017 callback(p)
1018 } else {
1019 false
1020 }
1021 }
1022);
1023
1024impl_surreal_value!(
1025 geo::LineString as kind!(geometry<line>),
1026 is_line(value) => matches!(value, Value::Geometry(Geometry::Line(_))),
1027 from_line(self) => Value::Geometry(Geometry::Line(self)),
1028 into_line(value) => {
1029 let Value::Geometry(Geometry::Line(l)) = value else {
1030 return Err(ConversionError::from_value(Self::kind_of(), &value).into());
1031 };
1032 Ok(l)
1033 },
1034 as_ty => as_line(self) => {
1035 if let Value::Geometry(Geometry::Line(l)) = self {
1036 Some(l)
1037 } else {
1038 None
1039 }
1040 },
1041 is_ty_and => is_line_and(self, callback) => {
1042 if let Value::Geometry(Geometry::Line(l)) = self {
1043 callback(l)
1044 } else {
1045 false
1046 }
1047 }
1048);
1049
1050impl_surreal_value!(
1051 geo::Polygon as kind!(geometry<polygon>),
1052 is_polygon(value) => matches!(value, Value::Geometry(Geometry::Polygon(_))),
1053 from_polygon(self) => Value::Geometry(Geometry::Polygon(self)),
1054 into_polygon(value) => {
1055 let Value::Geometry(Geometry::Polygon(p)) = value else {
1056 return Err(ConversionError::from_value(Self::kind_of(), &value).into());
1057 };
1058 Ok(p)
1059 },
1060 as_ty => as_polygon(self) => {
1061 if let Value::Geometry(Geometry::Polygon(p)) = self {
1062 Some(p)
1063 } else {
1064 None
1065 }
1066 },
1067 is_ty_and => is_polygon_and(self, callback) => {
1068 if let Value::Geometry(Geometry::Polygon(p)) = self {
1069 callback(p)
1070 } else {
1071 false
1072 }
1073 }
1074);
1075
1076impl_surreal_value!(
1077 geo::MultiPoint as kind!(geometry<multipoint>),
1078 is_multipoint(value) => matches!(value, Value::Geometry(Geometry::MultiPoint(_))),
1079 from_multipoint(self) => Value::Geometry(Geometry::MultiPoint(self)),
1080 into_multipoint(value) => {
1081 let Value::Geometry(Geometry::MultiPoint(m)) = value else {
1082 return Err(ConversionError::from_value(Self::kind_of(), &value).into());
1083 };
1084 Ok(m)
1085 },
1086 as_ty => as_multipoint(self) => {
1087 if let Value::Geometry(Geometry::MultiPoint(m)) = self {
1088 Some(m)
1089 } else {
1090 None
1091 }
1092 },
1093 is_ty_and => is_multipoint_and(self, callback) => {
1094 if let Value::Geometry(Geometry::MultiPoint(m)) = self {
1095 callback(m)
1096 } else {
1097 false
1098 }
1099 }
1100);
1101
1102impl_surreal_value!(
1103 geo::MultiLineString as kind!(geometry<multiline>),
1104 is_multiline(value) => matches!(value, Value::Geometry(Geometry::MultiLine(_))),
1105 from_multiline(self) => Value::Geometry(Geometry::MultiLine(self)),
1106 into_multiline(value) => {
1107 let Value::Geometry(Geometry::MultiLine(m)) = value else {
1108 return Err(ConversionError::from_value(Self::kind_of(), &value).into());
1109 };
1110 Ok(m)
1111 },
1112 as_ty => as_multiline(self) => {
1113 if let Value::Geometry(Geometry::MultiLine(m)) = self {
1114 Some(m)
1115 } else {
1116 None
1117 }
1118 },
1119 is_ty_and => is_multiline_and(self, callback) => {
1120 if let Value::Geometry(Geometry::MultiLine(m)) = self {
1121 callback(m)
1122 } else {
1123 false
1124 }
1125 }
1126);
1127
1128impl_surreal_value!(
1129 geo::MultiPolygon as kind!(geometry<multipolygon>),
1130 is_multipolygon(value) => matches!(value, Value::Geometry(Geometry::MultiPolygon(_))),
1131 from_multipolygon(self) => Value::Geometry(Geometry::MultiPolygon(self)),
1132 into_multipolygon(value) => {
1133 let Value::Geometry(Geometry::MultiPolygon(m)) = value else {
1134 return Err(ConversionError::from_value(Self::kind_of(), &value).into());
1135 };
1136 Ok(m)
1137 },
1138 as_ty => as_multipolygon(self) => {
1139 if let Value::Geometry(Geometry::MultiPolygon(m)) = self {
1140 Some(m)
1141 } else {
1142 None
1143 }
1144 },
1145 is_ty_and => is_multipolygon_and(self, callback) => {
1146 if let Value::Geometry(Geometry::MultiPolygon(m)) = self {
1147 callback(m)
1148 } else {
1149 false
1150 }
1151 }
1152);
1153
1154macro_rules! impl_tuples {
1156 ($($n:expr => ($($t:ident),+)),+ $(,)?) => {
1157 $(
1158 impl<$($t: SurrealValue),+> SurrealValue for ($($t,)+) {
1159 fn kind_of() -> Kind {
1160 kind!([$(($t::kind_of())),+])
1161 }
1162
1163 fn is_value(value: &Value) -> bool {
1164 if let Value::Array(Array(a)) = value {
1165 a.len() == $n && {
1166 let mut iter = a.iter();
1167 $(
1168 iter.next().map_or(false, |v| $t::is_value(v))
1169 )&&*
1170 }
1171 } else {
1172 false
1173 }
1174 }
1175
1176 fn into_value(self) -> Value {
1177 #[allow(non_snake_case)]
1178 let ($($t,)+) = self;
1179 Value::Array(Array(vec![$($t.into_value()),+]))
1180 }
1181
1182 fn from_value(value: Value) -> Result<Self, Error> {
1183 let Value::Array(Array(mut a)) = value else {
1184 return Err(ConversionError::from_value(Self::kind_of(), &value).into());
1185 };
1186
1187 if a.len() != $n {
1188 return Err(LengthMismatchError::new($n, a.len(), std::any::type_name::<Self>()).into());
1189 }
1190
1191 $(#[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)))?;)+
1192 Ok(($($t,)+))
1193 }
1194 }
1195 )+
1196 }
1197}
1198
1199impl_tuples! {
1200 1 => (A),
1201 2 => (A, B),
1202 3 => (A, B, C),
1203 4 => (A, B, C, D),
1204 5 => (A, B, C, D, E),
1205 6 => (A, B, C, D, E, F),
1206 7 => (A, B, C, D, E, F, G),
1207 8 => (A, B, C, D, E, F, G, H),
1208 9 => (A, B, C, D, E, F, G, H, I),
1209 10 => (A, B, C, D, E, F, G, H, I, J)
1210}
1211
1212macro_rules! impl_numeric {
1214 (int: $($k:ty => ($is_fn:ident, $from_fn:ident, $into_fn:ident, $is_and_fn:ident, $as_fn:ident)),+ $(,)?) => {
1216 $(
1217 impl SurrealValue for $k {
1218 fn kind_of() -> Kind {
1219 kind!(number)
1220 }
1221
1222 fn is_value(value: &Value) -> bool {
1223 matches!(value, Value::Number(_))
1224 }
1225
1226 fn into_value(self) -> Value {
1227 Value::Number(Number::Int(self as i64))
1228 }
1229
1230 fn from_value(value: Value) -> Result<Self, Error> {
1231 let Value::Number(Number::Int(n)) = value else {
1232 return Err(ConversionError::from_value(Self::kind_of(), &value).into());
1233 };
1234 <$k>::try_from(n)
1235 .map_err(|_| OutOfRangeError::new(n, std::any::type_name::<$k>()).into())
1236 }
1237 }
1238
1239 impl Value {
1240 pub fn $is_fn(&self) -> bool {
1242 <$k>::is_value(self)
1243 }
1244
1245 pub fn $from_fn(value: $k) -> Value {
1247 <$k>::into_value(value)
1248 }
1249
1250 pub fn $into_fn(self) -> Result<$k, Error> {
1252 <$k>::from_value(self)
1253 }
1254
1255 pub fn $is_and_fn(&self, callback: impl FnOnce(&$k) -> bool) -> bool {
1257 if let Value::Number(Number::Int(n)) = self {
1258 if let Ok(v) = <$k>::try_from(*n) {
1259 return callback(&v);
1260 }
1261 }
1262 false
1263 }
1264
1265 pub fn $as_fn(&self) -> Option<$k> {
1268 if let Value::Number(Number::Int(n)) = self {
1269 <$k>::try_from(*n).ok()
1270 } else {
1271 None
1272 }
1273 }
1274 }
1275 )+
1276 };
1277
1278 (float: $($k:ty => ($is_fn:ident, $from_fn:ident, $into_fn:ident, $is_and_fn:ident, $as_fn:ident)),+ $(,)?) => {
1280 $(
1281 impl SurrealValue for $k {
1282 fn kind_of() -> Kind {
1283 kind!(number)
1284 }
1285
1286 fn is_value(value: &Value) -> bool {
1287 matches!(value, Value::Number(_))
1288 }
1289
1290 fn into_value(self) -> Value {
1291 Value::Number(Number::Float(self as f64))
1292 }
1293
1294 fn from_value(value: Value) -> Result<Self, Error> {
1295 let Value::Number(Number::Float(n)) = value else {
1296 return Err(ConversionError::from_value(Self::kind_of(), &value).into());
1297 };
1298 Ok(n as $k)
1299 }
1300 }
1301
1302 impl Value {
1303 pub fn $is_fn(&self) -> bool {
1305 <$k>::is_value(self)
1306 }
1307
1308 pub fn $from_fn(value: $k) -> Value {
1310 <$k>::into_value(value)
1311 }
1312
1313 pub fn $into_fn(self) -> Result<$k, Error> {
1315 <$k>::from_value(self)
1316 }
1317
1318 pub fn $is_and_fn(&self, callback: impl FnOnce(&$k) -> bool) -> bool {
1320 if let Value::Number(Number::Float(n)) = self {
1321 let v = *n as $k;
1322 callback(&v)
1323 } else {
1324 false
1325 }
1326 }
1327
1328 pub fn $as_fn(&self) -> Option<$k> {
1331 if let Value::Number(Number::Float(n)) = self {
1332 Some(*n as $k)
1333 } else {
1334 None
1335 }
1336 }
1337 }
1338 )+
1339 };
1340}
1341
1342impl_numeric! {
1344 int:
1345 i8 => (is_i8, from_i8, into_i8, is_i8_and, as_i8),
1346 i16 => (is_i16, from_i16, into_i16, is_i16_and, as_i16),
1347 i32 => (is_i32, from_i32, into_i32, is_i32_and, as_i32),
1348 isize => (is_isize, from_isize, into_isize, is_isize_and, as_isize),
1350 u8 => (is_u8, from_u8, into_u8, is_u8_and, as_u8),
1351 u16 => (is_u16, from_u16, into_u16, is_u16_and, as_u16),
1352 u32 => (is_u32, from_u32, into_u32, is_u32_and, as_u32),
1353 u64 => (is_u64, from_u64, into_u64, is_u64_and, as_u64),
1354 usize => (is_usize, from_usize, into_usize, is_usize_and, as_usize),
1355}
1356
1357impl_numeric! {
1359 float:
1360 f32 => (is_f32, from_f32, into_f32, is_f32_and, as_f32),
1361 }
1363
1364impl SurrealValue for serde_json::Value {
1365 fn kind_of() -> Kind {
1366 kind!(any)
1367 }
1368
1369 fn is_value(_value: &Value) -> bool {
1370 true
1371 }
1372
1373 fn into_value(self) -> Value {
1374 match self {
1375 serde_json::Value::Null => Value::Null,
1376 serde_json::Value::Bool(b) => Value::Bool(b),
1377 serde_json::Value::Number(n) => {
1378 if let Some(i) = n.as_i64() {
1379 Value::Number(Number::Int(i))
1380 } else if let Some(f) = n.as_f64() {
1381 Value::Number(Number::Float(f))
1382 } else {
1383 Value::String(n.to_string())
1385 }
1386 }
1387 serde_json::Value::String(s) => Value::String(s),
1388 serde_json::Value::Object(o) => {
1389 let mut obj = Object::new();
1390 for (k, v) in o {
1391 obj.insert(k, serde_json::Value::into_value(v));
1392 }
1393 Value::Object(obj)
1394 }
1395 serde_json::Value::Array(a) => {
1396 Value::Array(Array(a.into_iter().map(serde_json::Value::into_value).collect()))
1397 }
1398 }
1399 }
1400
1401 fn from_value(value: Value) -> Result<Self, Error> {
1402 Ok(value.into_json_value())
1403 }
1404}
1405
1406macro_rules! impl_slice {
1407 ($($n:expr),+ $(,)?) => {
1408 $(
1409 impl<T: SurrealValue> SurrealValue for [T; $n] {
1410 fn kind_of() -> Kind {
1411 kind!(array<(T::kind_of()), $n>)
1412 }
1413
1414 fn is_value(value: &Value) -> bool {
1415 matches!(value, Value::Array(_))
1416 }
1417
1418 fn into_value(self) -> Value {
1419 Value::Array(Array(self.into_iter().map(T::into_value).collect()))
1420 }
1421
1422 fn from_value(value: Value) -> Result<Self, Error> {
1423 let Value::Array(Array(a)) = value else {
1424 return Err(ConversionError::from_value(Self::kind_of(), &value).into());
1425 };
1426 if a.len() != $n {
1427 return Err(LengthMismatchError::new($n, a.len(), std::any::type_name::<Self>()).into());
1428 }
1429 let mut result = Vec::with_capacity($n);
1430 for v in a {
1431 result.push(T::from_value(v)?);
1432 }
1433 result.try_into()
1434 .map_err(|v: Vec<_>| Error::internal(format!("Failed to convert vec of length {} to array of size {}", v.len(), $n)))
1435 }
1436 }
1437 )+
1438 }
1439}
1440
1441impl_slice!(
1442 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,
1443 27, 28, 29, 30, 31, 32
1444);
1445
1446impl SurrealValue for http::HeaderMap {
1447 fn kind_of() -> Kind {
1448 kind!(object)
1449 }
1450
1451 fn is_value(value: &Value) -> bool {
1452 matches!(value, Value::Object(_))
1453 }
1454
1455 fn into_value(self) -> Value {
1456 let mut next_key = None;
1457 let mut next_value = Value::None;
1458 let mut first_value = true;
1459 let mut res = BTreeMap::new();
1460
1461 for (k, v) in self {
1465 let v = match v.to_str() {
1466 Ok(v) => Value::String(v.to_owned()),
1467 Err(_) => continue,
1468 };
1469
1470 if let Some(k) = k {
1471 let k = k.as_str().to_owned();
1472 if let Some(k) = next_key.take() {
1475 let v = std::mem::replace(&mut next_value, Value::None);
1476 res.insert(k, v);
1477 }
1478 next_key = Some(k);
1479 next_value = v;
1480 first_value = true;
1481 } else if first_value {
1482 first_value = false;
1485 next_value = Value::Array(vec![next_value, v].into())
1486 } else {
1487 if let Value::Array(ref mut array) = next_value {
1490 array.push(v);
1491 }
1492 }
1493 }
1494
1495 if let Some(x) = next_key {
1497 let v = std::mem::replace(&mut next_value, Value::None);
1498 res.insert(x, v);
1499 }
1500
1501 Value::Object(Object::from(res))
1502 }
1503
1504 fn from_value(value: Value) -> Result<Self, Error> {
1505 let Value::Object(Object(o)) = value else {
1509 return Err(ConversionError::from_value(Self::kind_of(), &value).into());
1510 };
1511 let mut res = http::HeaderMap::new();
1512 for (k, v) in o {
1513 let k = k.parse::<http::HeaderName>().map_err(|e| Error::internal(e.to_string()))?;
1514 match v {
1515 Value::Array(Array(a)) => {
1516 for v in a {
1517 let v = v
1518 .into_string()
1519 .map_err(|e| Error::internal(e.to_string()))?
1520 .parse::<http::HeaderValue>()
1521 .map_err(|e: http::header::InvalidHeaderValue| {
1522 Error::internal(e.to_string())
1523 })?;
1524 res.insert(k.clone(), v);
1525 }
1526 }
1527 Value::String(v) => {
1528 res.insert(
1529 k,
1530 v.parse::<http::HeaderValue>().map_err(
1531 |e: http::header::InvalidHeaderValue| Error::internal(e.to_string()),
1532 )?,
1533 );
1534 }
1535 unexpected => {
1536 return Err(ConversionError::from_value(Self::kind_of(), &unexpected).into());
1537 }
1538 }
1539 }
1540 Ok(res)
1541 }
1542}
1543
1544impl SurrealValue for http::StatusCode {
1545 fn kind_of() -> Kind {
1546 kind!(number)
1547 }
1548
1549 fn is_value(value: &Value) -> bool {
1550 matches!(value, Value::Number(_))
1551 }
1552
1553 fn into_value(self) -> Value {
1554 Value::Number(Number::Int(self.as_u16() as i64))
1555 }
1556
1557 fn from_value(value: Value) -> Result<Self, Error> {
1558 let Value::Number(Number::Int(n)) = value else {
1559 return Err(ConversionError::from_value(Self::kind_of(), &value).into());
1560 };
1561 http::StatusCode::from_u16(n as u16)
1562 .map_err(|_| Error::internal("Failed to convert status code".to_string()))
1563 }
1564}
1565
1566impl<T: SurrealValue> SurrealValue for LinkedList<T> {
1567 fn kind_of() -> Kind {
1568 kind!(array<(T::kind_of())>)
1569 }
1570
1571 fn is_value(value: &Value) -> bool {
1572 {
1573 if let Value::Array(Array(a)) = value {
1574 a.iter().all(T::is_value)
1575 } else {
1576 false
1577 }
1578 }
1579 }
1580
1581 fn into_value(self) -> Value {
1582 Value::Array(Array(self.into_iter().map(SurrealValue::into_value).collect()))
1583 }
1584
1585 fn from_value(value: Value) -> Result<Self, Error> {
1586 let Value::Array(Array(a)) = value else {
1587 return Err(ConversionError::from_value(Self::kind_of(), &value).into());
1588 };
1589
1590 a.into_iter().map(|v| T::from_value(v)).collect::<Result<LinkedList<T>, Error>>().map_err(
1591 |e| Error::internal(format!("Failed to convert to {}: {}", Self::kind_of(), e)),
1592 )
1593 }
1594}
1595
1596impl<T: SurrealValue + Hash + Eq> SurrealValue for HashSet<T> {
1597 fn kind_of() -> Kind {
1598 kind!(array<(T::kind_of())>)
1599 }
1600
1601 fn is_value(value: &Value) -> bool {
1602 {
1603 if let Value::Array(Array(a)) = value {
1604 a.iter().all(T::is_value)
1605 } else {
1606 false
1607 }
1608 }
1609 }
1610
1611 fn into_value(self) -> Value {
1612 Value::Array(Array(self.into_iter().map(SurrealValue::into_value).collect()))
1613 }
1614
1615 fn from_value(value: Value) -> Result<Self, Error> {
1616 let Value::Array(Array(a)) = value else {
1617 return Err(ConversionError::from_value(Self::kind_of(), &value).into());
1618 };
1619
1620 a.into_iter().map(|v| T::from_value(v)).collect::<Result<HashSet<T>, Error>>().map_err(
1621 |e| Error::internal(format!("Failed to convert to {}: {}", Self::kind_of(), e)),
1622 )
1623 }
1624}
1625
1626impl<T: SurrealValue + Ord> SurrealValue for BTreeSet<T> {
1627 fn kind_of() -> Kind {
1628 kind!(array<(T::kind_of())>)
1629 }
1630
1631 fn is_value(value: &Value) -> bool {
1632 if let Value::Array(Array(array)) = value {
1633 array.iter().all(T::is_value)
1634 } else {
1635 false
1636 }
1637 }
1638
1639 fn into_value(self) -> Value {
1640 Value::Array(Array(self.into_iter().map(SurrealValue::into_value).collect()))
1641 }
1642
1643 fn from_value(value: Value) -> Result<Self, Error> {
1644 let Value::Array(Array(array)) = value else {
1645 return Err(ConversionError::from_value(Self::kind_of(), &value).into());
1646 };
1647
1648 array.into_iter().map(|v| T::from_value(v)).collect::<Result<BTreeSet<T>, Error>>().map_err(
1649 |error| {
1650 Error::serialization(
1651 format!("Failed to convert to {}: {error}", Self::kind_of()),
1652 SerializationError::Deserialization,
1653 )
1654 },
1655 )
1656 }
1657}
1658
1659impl<T: SurrealValue> SurrealValue for VecDeque<T> {
1660 fn kind_of() -> Kind {
1661 kind!(array<(T::kind_of())>)
1662 }
1663
1664 fn is_value(value: &Value) -> bool {
1665 if let Value::Array(Array(array)) = value {
1666 array.iter().all(T::is_value)
1667 } else {
1668 false
1669 }
1670 }
1671
1672 fn into_value(self) -> Value {
1673 Value::Array(Array(self.into_iter().map(SurrealValue::into_value).collect()))
1674 }
1675
1676 fn from_value(value: Value) -> Result<Self, Error> {
1677 let Value::Array(Array(array)) = value else {
1678 return Err(ConversionError::from_value(Self::kind_of(), &value).into());
1679 };
1680
1681 array.into_iter().map(|v| T::from_value(v)).collect::<Result<VecDeque<T>, Error>>().map_err(
1682 |error| {
1683 Error::serialization(
1684 format!("Failed to convert to {}: {error}", Self::kind_of()),
1685 SerializationError::Deserialization,
1686 )
1687 },
1688 )
1689 }
1690}
1691
1692impl<T: SurrealValue + Ord> SurrealValue for BinaryHeap<T> {
1693 fn kind_of() -> Kind {
1694 kind!(array<(T::kind_of())>)
1695 }
1696
1697 fn is_value(value: &Value) -> bool {
1698 if let Value::Array(Array(array)) = value {
1699 array.iter().all(T::is_value)
1700 } else {
1701 false
1702 }
1703 }
1704
1705 fn into_value(self) -> Value {
1706 Value::Array(Array(self.into_iter().map(SurrealValue::into_value).collect()))
1707 }
1708
1709 fn from_value(value: Value) -> Result<Self, Error> {
1710 let Value::Array(Array(array)) = value else {
1711 return Err(ConversionError::from_value(Self::kind_of(), &value).into());
1712 };
1713
1714 array
1715 .into_iter()
1716 .map(|v| T::from_value(v))
1717 .collect::<Result<BinaryHeap<T>, Error>>()
1718 .map_err(|error| {
1719 Error::serialization(
1720 format!("Failed to convert to {}: {error}", Self::kind_of()),
1721 SerializationError::Deserialization,
1722 )
1723 })
1724 }
1725}
1726
1727pub struct SerdeWrapper<T: Serialize + DeserializeOwned + 'static>(pub T);
1739
1740impl<T: Serialize + DeserializeOwned + 'static> SurrealValue for SerdeWrapper<T> {
1741 fn kind_of() -> Kind {
1742 Kind::Any
1743 }
1744
1745 fn into_value(self) -> Value {
1746 match_type!(self.0, {
1747 uuid::Uuid as uuid => Value::Uuid(Uuid::from(uuid)),
1748 chrono::DateTime<chrono::Utc> as datetime => Value::Datetime(Datetime::from(datetime)),
1749 std::time::Duration as duration => Value::Duration(Duration::from(duration)),
1750 Vec<uuid::Uuid> as uuids => Value::Array(Array(
1751 uuids.into_iter().map(|uuid| Value::Uuid(Uuid::from(uuid))).collect(),
1752 )),
1753 Vec<chrono::DateTime<chrono::Utc>> as datetimes => Value::Array(Array(
1754 datetimes
1755 .into_iter()
1756 .map(|datetime| Value::Datetime(Datetime::from(datetime)))
1757 .collect(),
1758 )),
1759 Vec<std::time::Duration> as durations => Value::Array(Array(
1760 durations
1761 .into_iter()
1762 .map(|duration| Value::Duration(Duration::from(duration)))
1763 .collect(),
1764 )),
1765 Option<uuid::Uuid> as uuid => uuid.map(|uuid| Value::Uuid(Uuid::from(uuid))).unwrap_or(Value::None),
1766 Option<chrono::DateTime<chrono::Utc>> as datetime => datetime
1767 .map(|datetime| Value::Datetime(Datetime::from(datetime)))
1768 .unwrap_or(Value::None),
1769 Option<std::time::Duration> as duration => duration
1770 .map(|duration| Value::Duration(Duration::from(duration)))
1771 .unwrap_or(Value::None),
1772 BTreeMap<String, uuid::Uuid> as map => Value::Object(Object(
1773 map
1774 .into_iter()
1775 .map(|(key, uuid)| (key, Value::Uuid(Uuid::from(uuid))))
1776 .collect(),
1777 )),
1778 BTreeMap<String, chrono::DateTime<chrono::Utc>> as map => Value::Object(Object(
1779 map
1780 .into_iter()
1781 .map(|(key, datetime)| (key, Value::Datetime(Datetime::from(datetime))))
1782 .collect(),
1783 )),
1784 BTreeMap<String, std::time::Duration> as map => Value::Object(Object(
1785 map
1786 .into_iter()
1787 .map(|(key, duration)| (key, Value::Duration(Duration::from(duration))))
1788 .collect(),
1789 )),
1790 HashMap<String, uuid::Uuid> as map => Value::Object(Object(
1791 map
1792 .into_iter()
1793 .map(|(key, uuid)| (key, Value::Uuid(Uuid::from(uuid))))
1794 .collect(),
1795 )),
1796 HashMap<String, chrono::DateTime<chrono::Utc>> as map => Value::Object(Object(
1797 map
1798 .into_iter()
1799 .map(|(key, datetime)| (key, Value::Datetime(Datetime::from(datetime))))
1800 .collect(),
1801 )),
1802 HashMap<String, std::time::Duration> as map => Value::Object(Object(
1803 map
1804 .into_iter()
1805 .map(|(key, duration)| (key, Value::Duration(Duration::from(duration))))
1806 .collect(),
1807 )),
1808 value => match value.serialize(Serializer) {
1809 Ok(value) => value,
1810 Err(err) => {
1811 let error = format!("SerdeWrapper serialization to value failed: {err}");
1812 debug_assert!(false, "{error}");
1813 tracing::warn!("{error}");
1814 Value::None
1818 }
1819 },
1820 })
1821 }
1822
1823 fn from_value(value: Value) -> Result<Self, Error>
1824 where
1825 Self: Sized,
1826 {
1827 let cast_error = |target: &str| {
1828 Error::serialization(
1829 format!("failed to cast {target} wrapper type"),
1830 SerializationError::Deserialization,
1831 )
1832 };
1833
1834 match_type!(PhantomData::<T>, {
1835 PhantomData<uuid::Uuid> as _ => {
1836 let uuid = uuid::Uuid::from_value(value)?;
1837 let typed = cast!(uuid, T).map_err(|_| cast_error("uuid"))?;
1838 Ok(Self(typed))
1839 },
1840 PhantomData<chrono::DateTime<chrono::Utc>> as _ => {
1841 let datetime = chrono::DateTime::<chrono::Utc>::from_value(value)?;
1842 let typed = cast!(datetime, T).map_err(|_| cast_error("datetime"))?;
1843 Ok(Self(typed))
1844 },
1845 PhantomData<std::time::Duration> as _ => {
1846 let duration = std::time::Duration::from_value(value)?;
1847 let typed = cast!(duration, T).map_err(|_| cast_error("duration"))?;
1848 Ok(Self(typed))
1849 },
1850 PhantomData<Vec<uuid::Uuid>> as _ => {
1851 let uuids = Vec::<Uuid>::from_value(value)?
1852 .into_iter()
1853 .map(Uuid::into_inner)
1854 .collect::<Vec<_>>();
1855 let typed = cast!(uuids, T).map_err(|_| cast_error("uuid vec"))?;
1856 Ok(Self(typed))
1857 },
1858 PhantomData<Vec<chrono::DateTime<chrono::Utc>>> as _ => {
1859 let datetimes = Vec::<Datetime>::from_value(value)?
1860 .into_iter()
1861 .map(Datetime::into_inner)
1862 .collect::<Vec<_>>();
1863 let typed = cast!(datetimes, T).map_err(|_| cast_error("datetime vec"))?;
1864 Ok(Self(typed))
1865 },
1866 PhantomData<Vec<std::time::Duration>> as _ => {
1867 let durations = Vec::<Duration>::from_value(value)?
1868 .into_iter()
1869 .map(Duration::into_inner)
1870 .collect::<Vec<_>>();
1871 let typed = cast!(durations, T).map_err(|_| cast_error("duration vec"))?;
1872 Ok(Self(typed))
1873 },
1874 PhantomData<Option<uuid::Uuid>> as _ => {
1875 let uuid = Option::<Uuid>::from_value(value)?.map(Uuid::into_inner);
1876 let typed = cast!(uuid, T).map_err(|_| cast_error("uuid option"))?;
1877 Ok(Self(typed))
1878 },
1879 PhantomData<Option<chrono::DateTime<chrono::Utc>>> as _ => {
1880 let datetime = Option::<Datetime>::from_value(value)?.map(Datetime::into_inner);
1881 let typed = cast!(datetime, T).map_err(|_| cast_error("datetime option"))?;
1882 Ok(Self(typed))
1883 },
1884 PhantomData<Option<std::time::Duration>> as _ => {
1885 let duration = Option::<Duration>::from_value(value)?.map(Duration::into_inner);
1886 let typed = cast!(duration, T).map_err(|_| cast_error("duration option"))?;
1887 Ok(Self(typed))
1888 },
1889 PhantomData<BTreeMap<String, uuid::Uuid>> as _ => {
1890 let map = BTreeMap::<String, Uuid>::from_value(value)?
1891 .into_iter()
1892 .map(|(key, uuid)| (key, uuid.into_inner()))
1893 .collect::<BTreeMap<_, _>>();
1894 let typed = cast!(map, T).map_err(|_| cast_error("uuid map"))?;
1895 Ok(Self(typed))
1896 },
1897 PhantomData<BTreeMap<String, chrono::DateTime<chrono::Utc>>> as _ => {
1898 let map = BTreeMap::<String, Datetime>::from_value(value)?
1899 .into_iter()
1900 .map(|(key, datetime)| (key, datetime.into_inner()))
1901 .collect::<BTreeMap<_, _>>();
1902 let typed = cast!(map, T).map_err(|_| cast_error("datetime map"))?;
1903 Ok(Self(typed))
1904 },
1905 PhantomData<BTreeMap<String, std::time::Duration>> as _ => {
1906 let map = BTreeMap::<String, Duration>::from_value(value)?
1907 .into_iter()
1908 .map(|(key, duration)| (key, duration.into_inner()))
1909 .collect::<BTreeMap<_, _>>();
1910 let typed = cast!(map, T).map_err(|_| cast_error("duration map"))?;
1911 Ok(Self(typed))
1912 },
1913 PhantomData<HashMap<String, uuid::Uuid>> as _ => {
1914 let map = HashMap::<String, Uuid>::from_value(value)?
1915 .into_iter()
1916 .map(|(key, uuid)| (key, uuid.into_inner()))
1917 .collect::<HashMap<_, _>>();
1918 let typed = cast!(map, T).map_err(|_| cast_error("uuid hashmap"))?;
1919 Ok(Self(typed))
1920 },
1921 PhantomData<HashMap<String, chrono::DateTime<chrono::Utc>>> as _ => {
1922 let map = HashMap::<String, Datetime>::from_value(value)?
1923 .into_iter()
1924 .map(|(key, datetime)| (key, datetime.into_inner()))
1925 .collect::<HashMap<_, _>>();
1926 let typed = cast!(map, T).map_err(|_| cast_error("datetime hashmap"))?;
1927 Ok(Self(typed))
1928 },
1929 PhantomData<HashMap<String, std::time::Duration>> as _ => {
1930 let map = HashMap::<String, Duration>::from_value(value)?
1931 .into_iter()
1932 .map(|(key, duration)| (key, duration.into_inner()))
1933 .collect::<HashMap<_, _>>();
1934 let typed = cast!(map, T).map_err(|_| cast_error("duration hashmap"))?;
1935 Ok(Self(typed))
1936 },
1937 _ => Ok(Self(T::deserialize(value)?)),
1938 })
1939 }
1940}
1941
1942#[cfg(test)]
1943mod test {
1944 use std::fmt::Debug;
1945
1946 use rstest::rstest;
1947 use serde::{Deserialize, Serialize};
1948
1949 use super::*;
1950 use crate::RecordIdKey;
1951
1952 #[derive(Serialize, Deserialize, PartialEq, Debug)]
1953 enum Test {
1954 A,
1955 B(u8),
1956 C {
1957 hi: String,
1958 },
1959 }
1960
1961 #[derive(Serialize, Deserialize, PartialEq, Debug)]
1962 struct Test2 {
1963 is_goober: bool,
1964 sneaky_and_evil: (),
1965 also_sneaky_and_evil: Gerald,
1966 }
1967
1968 #[derive(Serialize, Deserialize, PartialEq, Debug)]
1969 struct Gerald;
1970
1971 #[derive(Clone, Serialize, Deserialize, PartialEq, Debug)]
1972 struct SpecialPayload {
1973 uuid: Uuid,
1974 datetime: Datetime,
1975 duration: Duration,
1976 record_id: RecordId,
1977 }
1978
1979 #[rstest]
1980 #[case::u8(64_u8)]
1981 #[case::u16(64_u16)]
1982 #[case::u32(64_u32)]
1983 #[case::u64(64_u64)]
1984 #[case::i8(64_i8)]
1985 #[case::i16(64_i16)]
1986 #[case::i32(64_i32)]
1987 #[case::i64(64_i64)]
1988 #[case::f32(64.0_f32)]
1989 #[case::f64(64.0_f64)]
1990 #[case::bool(true)]
1991 #[case::zst_unit(())]
1992 #[case::zst_arr([(); 0])]
1993 #[case::zst_struct(Gerald)]
1994 #[case::string("woag!".to_string())]
1997 #[case::unit_enum(Test::A)]
1998 #[case::newtype_enum(Test::B(64))]
1999 #[case::struct_enum(Test::C{hi: "woag!".to_string()})]
2000 #[case::_struct(Test2 {
2001 is_goober: true,
2002 sneaky_and_evil: (),
2003 also_sneaky_and_evil: Gerald
2004 })]
2005 #[allow(non_snake_case)]
2006 fn wrapper_roundtrip<'a>(#[case] value: impl Serialize + Deserialize<'a> + PartialEq + Debug) {
2007 let serialized_value = value.serialize(Serializer).expect("this should work!");
2008 let deserialized_value =
2009 <_ as Deserialize>::deserialize(serialized_value).expect("this should work!");
2010 assert_eq!(value, deserialized_value);
2011 }
2012
2013 #[test]
2014 fn wrapper_roundtrip_special_surreal_types_uses_native_variants() {
2015 let datetime =
2016 Datetime::from_timestamp(1_706_660_400, 123_000_000).expect("valid datetime");
2017 let uuid = Uuid::new_v4();
2018 let duration = Duration::new(42, 7);
2019 let record_id = RecordId::new("person", RecordIdKey::Uuid(Uuid::new_v4()));
2020
2021 assert_eq!(SerdeWrapper(datetime).into_value(), datetime.into_value());
2022 assert_eq!(SerdeWrapper(uuid).into_value(), uuid.into_value());
2023 assert_eq!(SerdeWrapper(duration).into_value(), duration.into_value());
2024 assert_eq!(SerdeWrapper(record_id.clone()).into_value(), record_id.clone().into_value());
2025
2026 assert_eq!(
2027 SerdeWrapper::<Datetime>::from_value(datetime.into_value())
2028 .expect("roundtrip Datetime")
2029 .0,
2030 datetime
2031 );
2032 assert_eq!(
2033 SerdeWrapper::<Uuid>::from_value(uuid.into_value()).expect("roundtrip Uuid").0,
2034 uuid
2035 );
2036 assert_eq!(
2037 SerdeWrapper::<Duration>::from_value(duration.into_value())
2038 .expect("roundtrip Duration")
2039 .0,
2040 duration
2041 );
2042 assert_eq!(
2043 SerdeWrapper::<RecordId>::from_value(record_id.clone().into_value())
2044 .expect("roundtrip RecordId")
2045 .0,
2046 record_id
2047 );
2048 }
2049
2050 #[test]
2051 fn wrapper_roundtrip_nested_payload_keeps_surreal_types() {
2052 let payload = SpecialPayload {
2053 uuid: Uuid::new_v4(),
2054 datetime: Datetime::from_timestamp(1_706_660_400, 0).expect("valid datetime"),
2055 duration: Duration::new(3600, 500),
2056 record_id: RecordId::new("person", "alice"),
2057 };
2058
2059 let value = SerdeWrapper(payload.clone()).into_value();
2060 let Value::Object(object) = &value else {
2061 panic!("payload should serialize to object");
2062 };
2063 assert!(matches!(object.get("uuid"), Some(Value::Uuid(_))));
2064 assert!(matches!(object.get("datetime"), Some(Value::Datetime(_))));
2065 assert!(matches!(object.get("duration"), Some(Value::Duration(_))));
2066 assert!(matches!(object.get("record_id"), Some(Value::RecordId(_))));
2067
2068 let roundtrip = SerdeWrapper::<SpecialPayload>::from_value(value)
2069 .expect("payload should deserialize from value")
2070 .0;
2071 assert_eq!(roundtrip, payload);
2072 }
2073
2074 #[test]
2075 fn deserializing_none_into_non_option_is_an_error_not_a_panic() {
2076 let result = std::panic::catch_unwind(|| i64::deserialize(Value::None));
2077 assert!(result.is_ok(), "deserializing Value::None should not panic");
2078 assert!(result.expect("no panic").is_err());
2079 }
2080
2081 #[test]
2082 fn cow_str_roundtrip() {
2083 let original: Cow<'_, str> = Cow::Borrowed("hello");
2084 let value = original.clone().into_value();
2085 assert!(matches!(value, Value::String(ref s) if s == "hello"));
2086 let recovered = Cow::<'_, str>::from_value(value).unwrap();
2087 assert_eq!(recovered, "hello");
2088
2089 let owned: Cow<'_, str> = Cow::Owned("world".to_string());
2090 let value = owned.into_value();
2091 let recovered = Cow::<'_, str>::from_value(value).unwrap();
2092 assert_eq!(recovered, "world");
2093 }
2094
2095 #[test]
2096 fn cow_str_kind_of() {
2097 assert_eq!(Cow::<'_, str>::kind_of(), kind!(string));
2098 }
2099
2100 #[test]
2101 fn cow_str_is_value() {
2102 assert!(Cow::<'_, str>::is_value(&Value::String("test".to_string())));
2103 assert!(!Cow::<'_, str>::is_value(&Value::Number(Number::Int(42))));
2104 }
2105
2106 #[test]
2107 fn cow_clone_type_roundtrip() {
2108 let original: Cow<'_, str> = Cow::Owned("hello".to_string());
2109 let value = original.into_value();
2110 assert!(matches!(value, Value::String(ref s) if s == "hello"));
2111 let recovered = Cow::<'_, str>::from_value(value).unwrap();
2112 assert_eq!(recovered.into_owned(), "hello");
2113
2114 let original: Cow<'_, i64> = Cow::Owned(42);
2115 let value = original.into_value();
2116 let recovered = Cow::<'_, i64>::from_value(value).unwrap();
2117 assert_eq!(recovered.into_owned(), 42);
2118
2119 let original: Cow<'_, bool> = Cow::Owned(true);
2120 let value = original.into_value();
2121 let recovered = Cow::<'_, bool>::from_value(value).unwrap();
2122 assert!(recovered.into_owned());
2123 }
2124
2125 #[test]
2126 fn cow_from_value_type_mismatch() {
2127 let value = Value::Number(Number::Int(42));
2128 let result = Cow::<'_, str>::from_value(value);
2129 assert!(result.is_err());
2130 }
2131}