Skip to main content

surrealdb_expr/expr/record_id/
key.rs

1use std::ops::Bound;
2
3use surrealdb_strand::Strand;
4use surrealdb_types::{SqlFormat, ToSql};
5
6use crate::expr::literal::ObjectEntry;
7use crate::expr::{Expr, Kind, KindLiteral, RecordIdKeyRangeLit};
8use crate::val::{RecordIdKey, Uuid};
9
10#[derive(Clone, Debug, Eq, PartialEq, Hash)]
11pub enum RecordIdKeyGen {
12	Rand,
13	Ulid,
14	Uuid,
15}
16
17impl RecordIdKeyGen {
18	pub fn compute(&self) -> RecordIdKey {
19		match self {
20			RecordIdKeyGen::Rand => RecordIdKey::rand(),
21			RecordIdKeyGen::Ulid => RecordIdKey::ulid(),
22			RecordIdKeyGen::Uuid => RecordIdKey::uuid(),
23		}
24	}
25}
26
27#[derive(Clone, Debug, Eq, PartialEq, Hash)]
28pub enum RecordIdKeyLit {
29	Number(i64),
30	String(Strand),
31	Uuid(Uuid),
32	Array(Vec<Expr>),
33	Object(Vec<ObjectEntry>),
34	Generate(RecordIdKeyGen),
35	Range(Box<RecordIdKeyRangeLit>),
36}
37
38impl RecordIdKeyLit {
39	pub fn kind_supported(kind: &Kind) -> bool {
40		match kind {
41			Kind::Any => true,
42			Kind::Number => true,
43			Kind::Int => true,
44			Kind::String => true,
45			Kind::Uuid => true,
46			Kind::Array(_, _) => true,
47			Kind::Object => true,
48			Kind::Literal(l) => matches!(
49				l,
50				KindLiteral::Integer(_)
51					| KindLiteral::String(_)
52					| KindLiteral::Array(_)
53					| KindLiteral::Object(_)
54			),
55			Kind::Either(x) => x.iter().all(RecordIdKeyLit::kind_supported),
56			_ => false,
57		}
58	}
59}
60
61impl From<RecordIdKeyRangeLit> for RecordIdKeyLit {
62	fn from(v: RecordIdKeyRangeLit) -> Self {
63		Self::Range(Box::new(v))
64	}
65}
66
67impl ToSql for RecordIdKeyLit {
68	fn fmt_sql(&self, f: &mut String, fmt: SqlFormat) {
69		let sql_record_id_key_lit: crate::sql::RecordIdKeyLit = self.clone().into();
70		sql_record_id_key_lit.fmt_sql(f, fmt);
71	}
72}
73
74impl RecordIdKeyLit {
75	pub fn is_static(&self) -> bool {
76		match self {
77			RecordIdKeyLit::Number(_)
78			| RecordIdKeyLit::String(_)
79			| RecordIdKeyLit::Uuid(_)
80			| RecordIdKeyLit::Generate(_) => true,
81			RecordIdKeyLit::Range(record_id_key_range_lit) => record_id_key_range_lit.is_static(),
82			RecordIdKeyLit::Array(exprs) => exprs.iter().all(|x| x.is_static()),
83			RecordIdKeyLit::Object(items) => items.iter().all(|x| x.value.is_static()),
84		}
85	}
86
87	/// Whether evaluating this key can modify data; see [`Literal::read_only`].
88	pub fn read_only(&self) -> bool {
89		match self {
90			RecordIdKeyLit::Number(_)
91			| RecordIdKeyLit::String(_)
92			| RecordIdKeyLit::Uuid(_)
93			| RecordIdKeyLit::Generate(_) => true,
94			RecordIdKeyLit::Range(record_id_key_range_lit) => record_id_key_range_lit.read_only(),
95			RecordIdKeyLit::Array(exprs) => exprs.iter().all(|x| x.read_only()),
96			RecordIdKeyLit::Object(items) => items.iter().all(|x| x.value.read_only()),
97		}
98	}
99}
100
101impl From<crate::types::PublicRecordIdKey> for RecordIdKeyLit {
102	fn from(value: crate::types::PublicRecordIdKey) -> Self {
103		match value {
104			crate::types::PublicRecordIdKey::Number(x) => Self::Number(x),
105			crate::types::PublicRecordIdKey::String(x) => Self::String(x.into()),
106			crate::types::PublicRecordIdKey::Uuid(x) => Self::Uuid(x.into()),
107			crate::types::PublicRecordIdKey::Array(x) => {
108				Self::Array(x.into_iter().map(Expr::from_public_value).collect())
109			}
110			crate::types::PublicRecordIdKey::Object(x) => Self::Object(
111				x.into_iter()
112					.map(|(k, v)| ObjectEntry {
113						key: k.into(),
114						value: Expr::from_public_value(v),
115					})
116					.collect(),
117			),
118			crate::types::PublicRecordIdKey::Range(x) => {
119				Self::Range(Box::new(RecordIdKeyRangeLit {
120					start: match x.start {
121						Bound::Included(x) => Bound::Included(Self::from(x)),
122						Bound::Excluded(x) => Bound::Excluded(Self::from(x)),
123						Bound::Unbounded => Bound::Unbounded,
124					},
125					end: match x.end {
126						Bound::Included(x) => Bound::Included(Self::from(x)),
127						Bound::Excluded(x) => Bound::Excluded(Self::from(x)),
128						Bound::Unbounded => Bound::Unbounded,
129					},
130				}))
131			}
132		}
133	}
134}