Skip to main content

surrealdb_types/traits/
surreal_value.rs

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
21/// Trait for converting between SurrealDB values and Rust types
22///
23/// This trait provides a type-safe way to convert between SurrealDB `Value` types
24/// and Rust types. It defines four main operations:
25/// - `kind_of()`: Returns the `Kind` that represents this type
26/// - `is_value()`: Checks if a `Value` can be converted to this type
27/// - `into_value()`: Converts this type into a `Value`
28/// - `from_value()`: Attempts to convert a `Value` into this type
29pub trait SurrealValue {
30	/// Returns the kind that represents this type
31	fn kind_of() -> Kind;
32	/// Checks if the given value can be converted to this type
33	fn is_value(value: &Value) -> bool {
34		value.is_kind(&Self::kind_of())
35	}
36	/// Converts this type into a SurrealDB value
37	fn into_value(self) -> Value;
38	/// Attempts to convert a SurrealDB value into this type
39	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	// Generic types
100    (
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                /// Checks if this value can be converted to the given type
129                ///
130                /// Returns `true` if the value can be converted to the type, `false` otherwise.
131                pub fn $is_fnc<$($is_generic: SurrealValue),*>(&self) -> bool {
132                    <$type>::is_value(self)
133                }
134            }
135        )?
136
137        $(
138            impl Value {
139                /// Converts the given value into a `Value`
140                pub fn $from_fnc<$($from_generic: SurrealValue),*>(value: $type) -> Value {
141                    <$type>::into_value(value)
142                }
143            }
144        )?
145
146        $(
147            impl Value {
148                /// Attempts to convert a SurrealDB value into the given type
149                ///
150                /// Returns `Ok(T)` if the conversion is successful, `Err(Error)` otherwise.
151                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				/// Returns a reference to the inner value if it matches the expected type.
160				///
161				/// Returns `Some(&T)` if the value is of the expected type, `None` otherwise.
162				pub fn $as_fnc<$($as_generic: SurrealValue),*>(&$self_as) -> Option<&$type> {
163					$as_expr
164				}
165			}
166        )?
167
168		$(
169			impl Value {
170				/// Checks if this value can be converted to the given type
171				///
172				/// Returns `true` if the value can be converted to the type, `false` otherwise.
173				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	// Concrete types
181    (
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                /// Checks if this value can be converted to the given type
210                ///
211                /// Returns `true` if the value can be converted to the type, `false` otherwise.
212                pub fn $is_fnc(&self) -> bool {
213                    <$type>::is_value(self)
214                }
215            }
216        )*
217
218        $(
219            impl Value {
220                /// Converts the given value into a `Value`
221                pub fn $from_fnc(value: $type) -> Value {
222                    <$type>::into_value(value)
223                }
224            }
225        )*
226
227        $(
228            impl Value {
229                /// Attempts to convert a SurrealDB value into the given type
230                ///
231                /// Returns `Ok(T)` if the conversion is successful, `Err(Error)` otherwise.
232                pub fn $into_fnc(self) -> Result<$type, Error> {
233                    <$type>::from_value(self)
234                }
235            }
236        )*
237
238		$(
239			impl Value {
240				$(
241					/// Returns a reference to the inner value if it matches the expected type.
242					///
243					/// Returns `Some(&T)` if the value is of the expected type, `None` otherwise.
244					pub fn $as_fnc(&$self_as) -> Option<&$type> {
245						$as_expr
246					}
247				)+
248			}
249		)?
250
251		$(
252			impl Value {
253				$(
254					/// Checks if this value can be converted to the given type
255					///
256					/// Returns `true` if the value can be converted to the type, `false` otherwise.
257					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
266// Concrete type implementations using the macro
267impl_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
332// Manual impls for true & false
333
334impl Value {
335	/// Checks if this value is specifically `true`
336	///
337	/// Returns `true` if the value is `Value::Bool(true)`, `false` otherwise.
338	pub fn is_true(&self) -> bool {
339		matches!(self, Value::Bool(true))
340	}
341
342	/// Checks if this value is specifically `false`
343	///
344	/// Returns `true` if the value is `Value::Bool(false)`, `false` otherwise.
345	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
778// NOTE: Vec<u8> is intentionally NOT implemented to force explicit usage of Bytes.
779// This prevents ambiguity: should Vec<u8> be bytes or an array of numbers?
780// Users should explicitly use:
781//   - Bytes(vec) for binary data
782//   - Vec<i64> or similar for arrays of numbers
783
784impl_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
920// Generic implementations using the macro
921impl_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
997// Geometry implementations
998impl_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
1154// Tuple implementations
1155macro_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
1212/// Non-standard numeric implementations, such as u8, u16, u32, u64, i8, i16, i32, isize, f32
1213macro_rules! impl_numeric {
1214	// Integer types that need checked conversion from i64
1215	(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				/// Checks if this value can be converted to the given type
1241				pub fn $is_fn(&self) -> bool {
1242					<$k>::is_value(self)
1243				}
1244
1245				/// Converts the given value into a `Value`
1246				pub fn $from_fn(value: $k) -> Value {
1247					<$k>::into_value(value)
1248				}
1249
1250				/// Attempts to convert a SurrealDB value into the given type
1251				pub fn $into_fn(self) -> Result<$k, Error> {
1252					<$k>::from_value(self)
1253				}
1254
1255				/// Checks if this value matches the type and passes the callback check
1256				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				/// Returns a reference-like value if it matches the expected type
1266				/// Note: For integer types, this returns `None` since the value needs conversion
1267				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 types
1279	(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				/// Checks if this value can be converted to the given type
1304				pub fn $is_fn(&self) -> bool {
1305					<$k>::is_value(self)
1306				}
1307
1308				/// Converts the given value into a `Value`
1309				pub fn $from_fn(value: $k) -> Value {
1310					<$k>::into_value(value)
1311				}
1312
1313				/// Attempts to convert a SurrealDB value into the given type
1314				pub fn $into_fn(self) -> Result<$k, Error> {
1315					<$k>::from_value(self)
1316				}
1317
1318				/// Checks if this value matches the type and passes the callback check
1319				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				/// Returns the converted value if it matches the expected type
1329				/// Note: For float types, this returns a converted value, not a reference
1330				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
1342// Non-primary integer types with conversion
1343impl_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		// i64 is implemented with the impl_surreal_value! macro
1349		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
1357// Non-primary float types with conversion
1358impl_numeric! {
1359	float:
1360		f32 => (is_f32, from_f32, into_f32, is_f32_and, as_f32),
1361		// f64 is implemented with the impl_surreal_value! macro
1362}
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					// If we can't extract as i64 or f64, try parsing as decimal
1384					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		// Header map can contain multiple values for each header.
1462		// This is handled by returning the key name first and then return multiple
1463		// values with key name = None.
1464		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				// new key, if we had accumulated a key insert it first and then update
1473				// accumulated state.
1474				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				// no new key, but this is directly after the first value, turn the header value
1483				// into an array of values.
1484				first_value = false;
1485				next_value = Value::Array(vec![next_value, v].into())
1486			} else {
1487				// Since it is not a new key and a new value it must be atleast a third header
1488				// value and `next_value` is already updated to an array.
1489				if let Value::Array(ref mut array) = next_value {
1490					array.push(v);
1491				}
1492			}
1493		}
1494
1495		// Insert final key if there is one.
1496		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		// For each kv pair in the object:
1506		//  - If the value is an array, insert each value into the header map.
1507		//  - Otherwise, insert the value into the header map.
1508		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
1727/// A wrapper struct that allows bridging between SurrealValue and types that implement Serialize
1728/// and Deserialize
1729///
1730/// # A note on parity with `SurrealValue`
1731/// Serializing and Deserializing a type does *not* behave the same as `SurrealValue` in some cases.
1732/// Notably:
1733/// - Enum variants behave differently
1734/// - The only primitives taken advantage of are String, Number, Bool, Bytes, Object, and Array
1735///
1736/// As such, it's best to use SurrealValue directly where possible. This is intended for types where
1737/// an implementation of SurrealValue isn't available or practical
1738pub 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				// TODO: `into_value` should return `Result` so we can propagate
1815				// this error instead of silently dropping it. For now we return
1816				// `Value::None` since that's the least harmful fallback.
1817				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	// static strings don't work because Value isn't zero-copy
1995	//#[case::static_str("woag!")]
1996	#[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}