1use std::cmp::{Ordering, PartialEq, PartialOrd};
2use std::fmt;
3use std::ops::{Deref, Index};
4use std::str::FromStr;
5
6use chrono::{DateTime, Utc};
7use revision::revisioned;
8use serde::de::DeserializeOwned;
9use serde::{Deserialize, Serialize};
10use uuid::Uuid;
11
12use crate::Result;
13use crate::core::dbs::Action as CoreAction;
14use crate::core::{syn, val};
15use crate::error::Api as ApiError;
16
17mod convert;
18pub(crate) use convert::{from_value as from_core_value, to_value as to_core_value};
19mod obj;
20pub use obj::{IntoIter, Iter, IterMut, Object};
21
22pub fn from_value<T: DeserializeOwned>(value: Value) -> Result<T> {
23 convert::from_value(value.0)
24}
25
26pub fn to_value<T: Serialize + 'static>(value: T) -> Result<Value> {
27 convert::to_value(value).map(Value)
28}
29
30#[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
33#[revisioned(revision = 1)]
34pub struct Bytes(Vec<u8>);
35
36impl Bytes {
37 pub fn copy_from_slice(slice: &[u8]) -> Self {
38 slice.to_vec().into()
39 }
40
41 pub fn len(&self) -> usize {
42 self.0.len()
43 }
44
45 pub fn is_empty(&self) -> bool {
46 self.0.is_empty()
47 }
48}
49
50impl PartialEq<[u8]> for Bytes {
51 fn eq(&self, other: &[u8]) -> bool {
52 self.0 == other
53 }
54}
55
56impl PartialOrd<[u8]> for Bytes {
57 fn partial_cmp(&self, other: &[u8]) -> Option<Ordering> {
58 self.0.as_slice().partial_cmp(other)
59 }
60}
61
62impl Deref for Bytes {
63 type Target = [u8];
64
65 fn deref(&self) -> &Self::Target {
66 self.0.as_slice()
67 }
68}
69
70impl From<Vec<u8>> for Bytes {
71 fn from(value: Vec<u8>) -> Self {
72 Bytes(value)
73 }
74}
75
76transparent_wrapper!(
77 #[derive(Clone, Default, Eq, PartialEq, Ord, PartialOrd, Hash)]
78 pub struct Datetime(val::Datetime)
79);
80impl_serialize_wrapper!(Datetime);
81
82impl From<DateTime<Utc>> for Datetime {
83 fn from(v: DateTime<Utc>) -> Self {
84 Self(v.into())
85 }
86}
87
88transparent_wrapper!(
89 #[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
91 #[non_exhaustive]
92 pub struct RecordIdKey(val::RecordIdKey)
93);
94impl_serialize_wrapper!(RecordIdKey);
95
96impl From<Object> for RecordIdKey {
97 fn from(value: Object) -> Self {
98 Self::from_inner(val::RecordIdKey::Object(value.into_inner()))
99 }
100}
101
102impl TryFrom<RecordIdKey> for Object {
103 type Error = anyhow::Error;
104
105 fn try_from(value: RecordIdKey) -> Result<Self> {
106 if let val::RecordIdKey::Object(x) = value.0 {
107 Ok(Object::from_inner(x))
108 } else {
109 Err(anyhow::Error::new(ApiError::FromValue {
110 value: value.into(),
111 error: String::from("inner value is not an object"),
112 }))
113 }
114 }
115}
116
117impl From<String> for RecordIdKey {
119 fn from(value: String) -> Self {
120 Self(val::RecordIdKey::String(value))
121 }
122}
123
124impl TryFrom<RecordIdKey> for String {
125 type Error = anyhow::Error;
126
127 fn try_from(value: RecordIdKey) -> Result<Self> {
128 if let val::RecordIdKey::String(x) = value.0 {
129 Ok(x)
130 } else {
131 Err(anyhow::Error::new(ApiError::FromValue {
132 value: value.into(),
133 error: String::from("inner value is not a string"),
134 }))
135 }
136 }
137}
138
139impl From<&String> for RecordIdKey {
140 fn from(value: &String) -> Self {
141 Self(val::RecordIdKey::String(value.clone()))
142 }
143}
144
145impl From<&str> for RecordIdKey {
146 fn from(value: &str) -> Self {
147 Self(val::RecordIdKey::String(value.to_owned()))
148 }
149}
150
151impl From<i64> for RecordIdKey {
152 fn from(value: i64) -> Self {
153 Self(val::RecordIdKey::Number(value))
154 }
155}
156
157impl TryFrom<RecordIdKey> for i64 {
158 type Error = anyhow::Error;
159
160 fn try_from(value: RecordIdKey) -> Result<Self> {
161 if let val::RecordIdKey::Number(x) = value.0 {
162 Ok(x)
163 } else {
164 Err(anyhow::Error::new(ApiError::FromValue {
165 value: value.into(),
166 error: String::from("inner value is not a number"),
167 }))
168 }
169 }
170}
171
172impl From<Uuid> for RecordIdKey {
173 fn from(value: Uuid) -> Self {
174 Self(val::RecordIdKey::Uuid(value.into()))
175 }
176}
177
178impl TryFrom<RecordIdKey> for Uuid {
179 type Error = anyhow::Error;
180
181 fn try_from(value: RecordIdKey) -> Result<Self> {
182 if let val::RecordIdKey::Uuid(x) = value.0 {
183 Ok(*x)
184 } else {
185 Err(anyhow::Error::new(ApiError::FromValue {
186 value: value.into(),
187 error: String::from("inner value is not a UUID"),
188 }))
189 }
190 }
191}
192
193impl From<Vec<Value>> for RecordIdKey {
194 fn from(value: Vec<Value>) -> Self {
195 let res = Value::array_to_core(value);
196 Self(val::RecordIdKey::Array(val::Array(res)))
197 }
198}
199
200#[expect(clippy::fallible_impl_from)]
201impl From<RecordIdKey> for Value {
202 fn from(key: RecordIdKey) -> Self {
203 match key.0 {
204 val::RecordIdKey::String(x) => Value::from_inner(val::Value::from(x)),
205 val::RecordIdKey::Number(x) => Value::from_inner(val::Value::from(x)),
206 val::RecordIdKey::Object(x) => Value::from_inner(val::Value::from(x)),
207 val::RecordIdKey::Array(x) => Value::from_inner(val::Value::from(x)),
208 val::RecordIdKey::Uuid(x) => Value::from_inner(val::Value::from(x)),
209 _ => panic!("lib recieved generate variant of record id"),
210 }
211 }
212}
213
214impl From<RecordId> for Value {
215 fn from(key: RecordId) -> Self {
216 Value::from_inner(val::Value::RecordId(key.0))
217 }
218}
219
220impl FromStr for Value {
221 type Err = anyhow::Error;
222
223 fn from_str(s: &str) -> Result<Self> {
224 Ok(Value::from_inner(crate::core::syn::value(s)?))
225 }
226}
227
228#[derive(Debug)]
229pub struct RecordIdKeyFromValueError(());
230
231impl fmt::Display for RecordIdKeyFromValueError {
232 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
233 writeln!(
234 f,
235 "tried to convert a value to a record id key with a value type that is not allowed in a record id key"
236 )
237 }
238}
239
240impl TryFrom<Value> for RecordIdKey {
241 type Error = RecordIdKeyFromValueError;
242
243 fn try_from(key: Value) -> std::result::Result<Self, Self::Error> {
244 match key.0 {
245 val::Value::Strand(x) => {
246 Ok(RecordIdKey::from_inner(val::RecordIdKey::String(x.into_string())))
247 }
248 val::Value::Number(val::Number::Int(x)) => {
249 Ok(RecordIdKey::from_inner(val::RecordIdKey::Number(x)))
250 }
251 val::Value::Object(x) => Ok(RecordIdKey::from_inner(val::RecordIdKey::Object(x))),
252 val::Value::Array(x) => Ok(RecordIdKey::from_inner(val::RecordIdKey::Array(x))),
253 _ => Err(RecordIdKeyFromValueError(())),
254 }
255 }
256}
257
258transparent_wrapper!(
259 #[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
264 pub struct RecordId(val::RecordId)
265);
266impl_serialize_wrapper!(RecordId);
267
268impl RecordId {
269 pub fn from_table_key<S, K>(table: S, key: K) -> Self
270 where
271 S: Into<String>,
272 K: Into<RecordIdKey>,
273 {
274 let tb = table.into();
275 let key = key.into();
276 Self(val::RecordId::new(tb, key.0))
277 }
278
279 pub fn table(&self) -> &str {
280 &self.0.table
281 }
282
283 pub fn key(&self) -> &RecordIdKey {
284 RecordIdKey::from_inner_ref(&self.0.key)
285 }
286}
287
288impl FromStr for RecordId {
289 type Err = anyhow::Error;
290
291 fn from_str(s: &str) -> Result<Self> {
292 syn::record_id(s).map(RecordId::from_inner)
293 }
294}
295
296impl<S, I> From<(S, I)> for RecordId
297where
298 S: Into<String>,
299 RecordIdKey: From<I>,
300{
301 fn from(value: (S, I)) -> Self {
302 Self::from_table_key(value.0, value.1)
303 }
304}
305
306transparent_wrapper!(
307 #[derive( Clone, PartialEq, PartialOrd)]
310 pub struct Number(val::Number)
311);
312impl_serialize_wrapper!(Number);
313
314transparent_wrapper!(
315 #[derive(Clone, Default, Eq, PartialEq, Ord, PartialOrd, Hash)]
316 pub struct Value(pub(crate) val::Value)
317);
318impl_serialize_wrapper!(Value);
319
320impl Value {
321 #[expect(dead_code)]
322 pub(crate) fn core_to_array(v: Vec<val::Value>) -> Vec<Value> {
323 unsafe {
324 std::mem::transmute::<Vec<val::Value>, Vec<Value>>(v)
327 }
328 }
329
330 #[expect(dead_code)]
331 pub(crate) fn core_to_array_ref(v: &Vec<val::Value>) -> &Vec<Value> {
332 unsafe {
333 std::mem::transmute::<&Vec<val::Value>, &Vec<Value>>(v)
336 }
337 }
338
339 #[expect(dead_code)]
340 pub(crate) fn core_to_array_mut(v: &mut Vec<val::Value>) -> &mut Vec<Value> {
341 unsafe {
342 std::mem::transmute::<&mut Vec<val::Value>, &mut Vec<Value>>(v)
345 }
346 }
347
348 pub(crate) fn array_to_core(v: Vec<Value>) -> Vec<val::Value> {
349 unsafe {
350 std::mem::transmute::<Vec<Value>, Vec<val::Value>>(v)
353 }
354 }
355
356 #[expect(dead_code)]
357 pub(crate) fn array_to_core_ref(v: &Vec<Value>) -> &Vec<val::Value> {
358 unsafe {
359 std::mem::transmute::<&Vec<Value>, &Vec<val::Value>>(v)
362 }
363 }
364
365 #[expect(dead_code)]
366 pub(crate) fn array_to_core_mut(v: &mut Vec<Value>) -> &mut Vec<val::Value> {
367 unsafe {
368 std::mem::transmute::<&mut Vec<Value>, &mut Vec<val::Value>>(v)
371 }
372 }
373}
374
375impl Index<usize> for Value {
376 type Output = Self;
377
378 fn index(&self, index: usize) -> &Self::Output {
379 match &self.0 {
380 val::Value::Array(map) => {
381 map.0.get(index).map(Self::from_inner_ref).unwrap_or(&Value(val::Value::None))
382 }
383 _ => &Value(val::Value::None),
384 }
385 }
386}
387
388impl Index<&str> for Value {
389 type Output = Self;
390
391 fn index(&self, index: &str) -> &Self::Output {
392 match &self.0 {
393 val::Value::Object(map) => {
394 map.0.get(index).map(Self::from_inner_ref).unwrap_or(&Value(val::Value::None))
395 }
396 _ => &Value(val::Value::None),
397 }
398 }
399}
400
401impl Value {
402 pub fn get<Idx>(&self, index: Idx) -> &Value
409 where
410 Value: Index<Idx, Output = Value>,
411 {
412 self.index(index)
413 }
414
415 pub fn into_option(&self) -> Option<&Value> {
418 match self {
419 Value(val::Value::None) => None,
420 v => Some(v),
421 }
422 }
423
424 pub fn is_none(&self) -> bool {
426 matches!(&self, Value(val::Value::None))
427 }
428}
429
430pub struct ConversionError {
431 from: &'static str,
432 expected: &'static str,
433}
434
435impl fmt::Display for ConversionError {
436 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
437 writeln!(
438 f,
439 "failed to convert into `{}` from value with type `{:?}`",
440 self.expected, self.from
441 )
442 }
443}
444
445#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
449#[non_exhaustive]
450pub enum Action {
451 Create,
452 Update,
453 Delete,
454}
455
456impl Action {
457 #[allow(dead_code, reason = "Used by other engines except the HTTP one")]
458 pub(crate) fn from_core(action: CoreAction) -> Self {
459 match action {
460 CoreAction::Create => Self::Create,
461 CoreAction::Update => Self::Update,
462 CoreAction::Delete => Self::Delete,
463 _ => panic!("unimplemented variant of action"),
464 }
465 }
466}
467
468#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
476#[non_exhaustive]
477pub struct Notification<R> {
478 pub query_id: Uuid,
479 pub action: Action,
480 pub data: R,
481}