Skip to main content

surrealdb_types/traits/
surreal_value.rs

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