1use crate::Error;
2use revision::revisioned;
3use serde::{de::DeserializeOwned, Deserialize, Serialize};
4use std::{
5 cmp::{Ordering, PartialEq, PartialOrd},
6 fmt,
7 ops::Deref,
8 str::FromStr,
9};
10use surrealdb_core::{
11 dbs::Action as CoreAction,
12 sql::{
13 Array as CoreArray, Datetime as CoreDatetime, Id as CoreId, Number as CoreNumber,
14 Thing as CoreThing, Value as CoreValue,
15 },
16 syn,
17};
18use uuid::Uuid;
19
20mod obj;
21pub use obj::{IntoIter, Iter, IterMut, Object};
22
23pub fn from_value<T: DeserializeOwned>(value: Value) -> Result<T, Error> {
24 Ok(surrealdb_core::sql::from_value(value.0)?)
25}
26
27pub fn to_value<T: Serialize + 'static>(value: T) -> Result<Value, Error> {
28 let v = surrealdb_core::sql::to_value(value)?;
29 Ok(Value(v))
30}
31
32#[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
35#[revisioned(revision = 1)]
36pub struct Bytes(Vec<u8>);
37
38impl Bytes {
39 pub fn copy_from_slice(slice: &[u8]) -> Self {
40 slice.to_vec().into()
41 }
42
43 pub fn len(&self) -> usize {
44 self.0.len()
45 }
46
47 pub fn is_empty(&self) -> bool {
48 self.0.is_empty()
49 }
50}
51
52impl PartialEq<[u8]> for Bytes {
53 fn eq(&self, other: &[u8]) -> bool {
54 self.0 == other
55 }
56}
57
58impl PartialOrd<[u8]> for Bytes {
59 fn partial_cmp(&self, other: &[u8]) -> Option<Ordering> {
60 self.0.as_slice().partial_cmp(other)
61 }
62}
63
64impl Deref for Bytes {
65 type Target = [u8];
66
67 fn deref(&self) -> &Self::Target {
68 self.0.as_slice()
69 }
70}
71
72impl From<Vec<u8>> for Bytes {
73 fn from(value: Vec<u8>) -> Self {
74 Bytes(value)
75 }
76}
77
78transparent_wrapper!(
79 #[derive( Clone, Eq, PartialEq, Ord, PartialOrd)]
80 pub struct Datetime(CoreDatetime)
81);
82
83transparent_wrapper!(
84 #[derive( Clone, PartialEq, PartialOrd)]
86 #[non_exhaustive]
87 pub struct RecordIdKey(CoreId)
88);
89
90impl From<Object> for RecordIdKey {
91 fn from(value: Object) -> Self {
92 Self::from_inner(CoreId::Object(value.into_inner()))
93 }
94}
95
96impl From<String> for RecordIdKey {
97 fn from(value: String) -> Self {
98 Self(CoreId::String(value))
99 }
100}
101
102impl From<&String> for RecordIdKey {
103 fn from(value: &String) -> Self {
104 Self(CoreId::String(value.clone()))
105 }
106}
107
108impl From<&str> for RecordIdKey {
109 fn from(value: &str) -> Self {
110 Self(CoreId::String(value.to_owned()))
111 }
112}
113
114impl From<i64> for RecordIdKey {
115 fn from(value: i64) -> Self {
116 Self(CoreId::Number(value))
117 }
118}
119
120impl From<Vec<Value>> for RecordIdKey {
121 fn from(value: Vec<Value>) -> Self {
122 let res = Value::array_to_core(value);
123 let mut array = CoreArray::default();
124 array.0 = res;
125 Self(CoreId::Array(array))
126 }
127}
128
129impl From<RecordIdKey> for Value {
130 fn from(key: RecordIdKey) -> Self {
131 match key.0 {
132 CoreId::String(x) => Value::from_inner(CoreValue::from(x)),
133 CoreId::Number(x) => Value::from_inner(CoreValue::from(x)),
134 CoreId::Object(x) => Value::from_inner(CoreValue::from(x)),
135 CoreId::Array(x) => Value::from_inner(CoreValue::from(x)),
136 _ => panic!("lib recieved generate variant of record id"),
137 }
138 }
139}
140
141impl From<RecordId> for Value {
142 fn from(key: RecordId) -> Self {
143 Value::from_inner(CoreValue::Thing(key.0))
144 }
145}
146
147impl FromStr for Value {
148 type Err = Error;
149
150 fn from_str(s: &str) -> Result<Self, Self::Err> {
151 Ok(Value::from_inner(surrealdb_core::syn::value(s)?))
152 }
153}
154
155#[derive(Debug)]
156pub struct RecordIdKeyFromValueError(());
157
158impl fmt::Display for RecordIdKeyFromValueError {
159 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
160 writeln!(f,"tried to convert a value to a record id key with a value type that is not allowed in a record id key")
161 }
162}
163
164impl TryFrom<Value> for RecordIdKey {
165 type Error = RecordIdKeyFromValueError;
166
167 fn try_from(key: Value) -> Result<Self, Self::Error> {
168 match key.0 {
169 CoreValue::Strand(x) => Ok(RecordIdKey::from_inner(CoreId::String(x.0))),
170 CoreValue::Number(CoreNumber::Int(x)) => Ok(RecordIdKey::from_inner(CoreId::Number(x))),
171 CoreValue::Object(x) => Ok(RecordIdKey::from_inner(CoreId::Object(x))),
172 CoreValue::Array(x) => Ok(RecordIdKey::from_inner(CoreId::Array(x))),
173 _ => Err(RecordIdKeyFromValueError(())),
174 }
175 }
176}
177
178transparent_wrapper!(
179 #[derive( Clone, PartialEq, PartialOrd)]
184 pub struct RecordId(CoreThing)
185);
186impl_serialize_wrapper!(RecordId);
187
188impl RecordId {
189 pub fn from_table_key<S, K>(table: S, key: K) -> Self
190 where
191 S: Into<String>,
192 K: Into<RecordIdKey>,
193 {
194 let tb = table.into();
195 let key = key.into();
196 Self(CoreThing::from((tb, key.0)))
197 }
198
199 pub fn table(&self) -> &str {
200 &self.0.tb
201 }
202
203 pub fn key(&self) -> &RecordIdKey {
204 RecordIdKey::from_inner_ref(&self.0.id)
205 }
206}
207
208impl FromStr for RecordId {
209 type Err = Error;
210
211 fn from_str(s: &str) -> Result<Self, Self::Err> {
212 syn::thing(s).map_err(crate::Error::Db).map(RecordId::from_inner)
213 }
214}
215
216impl<S, I> From<(S, I)> for RecordId
217where
218 S: Into<String>,
219 RecordIdKey: From<I>,
220{
221 fn from(value: (S, I)) -> Self {
222 Self::from_table_key(value.0, value.1)
223 }
224}
225
226transparent_wrapper!(
227 #[derive( Clone, PartialEq, PartialOrd)]
230 pub struct Number(CoreNumber)
231);
232impl_serialize_wrapper!(Number);
233
234impl Number {
235 #[doc(hidden)]
236 pub fn cource_into_i64(self) -> Option<i64> {
237 match self.0 {
238 CoreNumber::Int(x) => Some(x),
239 CoreNumber::Float(x) if x.fract() == x => Some(x as i64),
240 CoreNumber::Decimal(x) => x.try_into().ok(),
241 _ => None,
242 }
243 }
244}
245
246transparent_wrapper!(
247 #[derive( Clone, Default, PartialEq, PartialOrd)]
248 pub struct Value(pub(crate) CoreValue)
249);
250impl_serialize_wrapper!(Value);
251
252impl Value {
253 #[allow(dead_code)]
255 pub(crate) fn core_to_array(v: Vec<CoreValue>) -> Vec<Value> {
256 unsafe {
257 std::mem::transmute::<Vec<CoreValue>, Vec<Value>>(v)
260 }
261 }
262
263 #[allow(dead_code)]
264 pub(crate) fn core_to_array_ref(v: &Vec<CoreValue>) -> &Vec<Value> {
265 unsafe {
266 std::mem::transmute::<&Vec<CoreValue>, &Vec<Value>>(v)
269 }
270 }
271
272 #[allow(dead_code)]
273 pub(crate) fn core_to_array_mut(v: &mut Vec<CoreValue>) -> &mut Vec<Value> {
274 unsafe {
275 std::mem::transmute::<&mut Vec<CoreValue>, &mut Vec<Value>>(v)
278 }
279 }
280
281 #[allow(dead_code)]
282 pub(crate) fn array_to_core(v: Vec<Value>) -> Vec<CoreValue> {
283 unsafe {
284 std::mem::transmute::<Vec<Value>, Vec<CoreValue>>(v)
287 }
288 }
289
290 #[allow(dead_code)]
291 pub(crate) fn array_to_core_ref(v: &Vec<Value>) -> &Vec<CoreValue> {
292 unsafe {
293 std::mem::transmute::<&Vec<Value>, &Vec<CoreValue>>(v)
296 }
297 }
298
299 #[allow(dead_code)]
300 pub(crate) fn array_to_core_mut(v: &mut Vec<Value>) -> &mut Vec<CoreValue> {
301 unsafe {
302 std::mem::transmute::<&mut Vec<Value>, &mut Vec<CoreValue>>(v)
305 }
306 }
307}
308
309pub struct ConversionError {
310 from: &'static str,
311 expected: &'static str,
312}
313
314impl fmt::Display for ConversionError {
315 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
316 writeln!(
317 f,
318 "failed to convert into `{}` from value with type `{:?}`",
319 self.expected, self.from
320 )
321 }
322}
323
324#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
328#[non_exhaustive]
329pub enum Action {
330 Create,
331 Update,
332 Delete,
333}
334
335impl Action {
336 pub(crate) fn from_core(action: CoreAction) -> Self {
337 match action {
338 CoreAction::Create => Self::Create,
339 CoreAction::Update => Self::Update,
340 CoreAction::Delete => Self::Delete,
341 _ => panic!("unimplemented variant of action"),
342 }
343 }
344}
345
346#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
352#[non_exhaustive]
353pub struct Notification<R> {
354 pub query_id: Uuid,
355 pub action: Action,
356 pub data: R,
357}
358
359impl Notification<CoreValue> {
360 pub fn map_deserialize<R>(self) -> Result<Notification<R>, crate::error::Db>
361 where
362 R: DeserializeOwned,
363 {
364 let data = surrealdb_core::sql::from_value(self.data)?;
365 Ok(Notification {
366 query_id: self.query_id,
367 action: self.action,
368 data,
369 })
370 }
371}