surrealdb/sql/
part.rs

1use crate::sql::{fmt::Fmt, strand::no_nul_bytes, Graph, Ident, Idiom, Number, Value};
2use revision::revisioned;
3use serde::{Deserialize, Serialize};
4use std::fmt;
5use std::str;
6
7#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)]
8#[revisioned(revision = 1)]
9pub enum Part {
10	All,
11	Flatten,
12	Last,
13	First,
14	Field(Ident),
15	Index(Number),
16	Where(Value),
17	Graph(Graph),
18	Value(Value),
19	Start(Value),
20	Method(#[serde(with = "no_nul_bytes")] String, Vec<Value>),
21}
22
23impl From<i32> for Part {
24	fn from(v: i32) -> Self {
25		Self::Index(v.into())
26	}
27}
28
29impl From<isize> for Part {
30	fn from(v: isize) -> Self {
31		Self::Index(v.into())
32	}
33}
34
35impl From<usize> for Part {
36	fn from(v: usize) -> Self {
37		Self::Index(v.into())
38	}
39}
40
41impl From<String> for Part {
42	fn from(v: String) -> Self {
43		Self::Field(v.into())
44	}
45}
46
47impl From<Number> for Part {
48	fn from(v: Number) -> Self {
49		Self::Index(v)
50	}
51}
52
53impl From<Ident> for Part {
54	fn from(v: Ident) -> Self {
55		Self::Field(v)
56	}
57}
58
59impl From<Graph> for Part {
60	fn from(v: Graph) -> Self {
61		Self::Graph(v)
62	}
63}
64
65impl From<&str> for Part {
66	fn from(v: &str) -> Self {
67		match v.parse::<isize>() {
68			Ok(v) => Self::from(v),
69			_ => Self::from(v.to_owned()),
70		}
71	}
72}
73
74impl Part {
75	/// Check if we require a writeable transaction
76	pub(crate) fn writeable(&self) -> bool {
77		match self {
78			Part::Start(v) => v.writeable(),
79			Part::Where(v) => v.writeable(),
80			Part::Value(v) => v.writeable(),
81			Part::Method(_, v) => v.iter().any(Value::writeable),
82			_ => false,
83		}
84	}
85	/// Returns a yield if an alias is specified
86	pub(crate) fn alias(&self) -> Option<&Idiom> {
87		match self {
88			Part::Graph(v) => v.alias.as_ref(),
89			_ => None,
90		}
91	}
92}
93
94impl fmt::Display for Part {
95	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
96		match self {
97			Part::All => f.write_str("[*]"),
98			Part::Last => f.write_str("[$]"),
99			Part::First => f.write_str("[0]"),
100			Part::Start(v) => write!(f, "{v}"),
101			Part::Field(v) => write!(f, ".{v}"),
102			Part::Flatten => f.write_str("…"),
103			Part::Index(v) => write!(f, "[{v}]"),
104			Part::Where(v) => write!(f, "[WHERE {v}]"),
105			Part::Graph(v) => write!(f, "{v}"),
106			Part::Value(v) => write!(f, "[{v}]"),
107			Part::Method(v, a) => write!(f, ".{v}({})", Fmt::comma_separated(a)),
108		}
109	}
110}
111
112// ------------------------------
113
114pub trait Next<'a> {
115	fn next(&'a self) -> &[Part];
116}
117
118impl<'a> Next<'a> for &'a [Part] {
119	fn next(&'a self) -> &'a [Part] {
120		match self.len() {
121			0 => &[],
122			_ => &self[1..],
123		}
124	}
125}