2023-11-18 13:56:13 +00:00
|
|
|
use crate::sql::{fmt::Fmt, strand::no_nul_bytes, Graph, Ident, Idiom, Number, Value};
|
2023-08-17 18:03:46 +00:00
|
|
|
use revision::revisioned;
|
2022-01-13 17:36:41 +00:00
|
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
use std::fmt;
|
|
|
|
use std::str;
|
|
|
|
|
2022-10-27 12:23:24 +00:00
|
|
|
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)]
|
2023-08-17 18:03:46 +00:00
|
|
|
#[revisioned(revision = 1)]
|
2024-01-09 15:34:52 +00:00
|
|
|
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
|
2022-01-13 17:36:41 +00:00
|
|
|
pub enum Part {
|
|
|
|
All,
|
2023-08-01 07:30:13 +00:00
|
|
|
Flatten,
|
2022-01-13 17:36:41 +00:00
|
|
|
Last,
|
|
|
|
First,
|
|
|
|
Field(Ident),
|
|
|
|
Index(Number),
|
|
|
|
Where(Value),
|
|
|
|
Graph(Graph),
|
2023-03-31 15:42:29 +00:00
|
|
|
Value(Value),
|
2023-07-15 07:08:26 +00:00
|
|
|
Start(Value),
|
2023-05-09 17:48:14 +00:00
|
|
|
Method(#[serde(with = "no_nul_bytes")] String, Vec<Value>),
|
2022-01-13 17:36:41 +00:00
|
|
|
}
|
|
|
|
|
2022-04-07 08:07:18 +00:00
|
|
|
impl From<i32> for Part {
|
|
|
|
fn from(v: i32) -> Self {
|
2022-10-04 21:51:18 +00:00
|
|
|
Self::Index(v.into())
|
2022-04-07 08:07:18 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-01-22 21:16:13 +00:00
|
|
|
impl From<isize> for Part {
|
|
|
|
fn from(v: isize) -> Self {
|
2022-10-04 21:51:18 +00:00
|
|
|
Self::Index(v.into())
|
2022-01-22 21:16:13 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<usize> for Part {
|
|
|
|
fn from(v: usize) -> Self {
|
2022-10-04 21:51:18 +00:00
|
|
|
Self::Index(v.into())
|
2022-01-22 21:16:13 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-03-31 15:42:29 +00:00
|
|
|
impl From<String> for Part {
|
|
|
|
fn from(v: String) -> Self {
|
|
|
|
Self::Field(v.into())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-01-13 17:36:41 +00:00
|
|
|
impl From<Number> for Part {
|
|
|
|
fn from(v: Number) -> Self {
|
2022-10-04 21:51:18 +00:00
|
|
|
Self::Index(v)
|
2022-01-13 17:36:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<Ident> for Part {
|
|
|
|
fn from(v: Ident) -> Self {
|
2022-10-04 21:51:18 +00:00
|
|
|
Self::Field(v)
|
2022-01-13 17:36:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<Graph> for Part {
|
|
|
|
fn from(v: Graph) -> Self {
|
2022-10-04 21:51:18 +00:00
|
|
|
Self::Graph(v)
|
2022-01-13 17:36:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<&str> for Part {
|
|
|
|
fn from(v: &str) -> Self {
|
2022-01-22 21:16:13 +00:00
|
|
|
match v.parse::<isize>() {
|
2022-10-04 21:51:18 +00:00
|
|
|
Ok(v) => Self::from(v),
|
|
|
|
_ => Self::from(v.to_owned()),
|
2022-01-22 21:16:13 +00:00
|
|
|
}
|
2022-01-13 17:36:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-06-04 08:55:05 +00:00
|
|
|
impl Part {
|
2023-05-09 22:17:29 +00:00
|
|
|
/// Check if we require a writeable transaction
|
|
|
|
pub(crate) fn writeable(&self) -> bool {
|
|
|
|
match self {
|
2023-07-15 07:08:26 +00:00
|
|
|
Part::Start(v) => v.writeable(),
|
2023-05-09 22:17:29 +00:00
|
|
|
Part::Where(v) => v.writeable(),
|
|
|
|
Part::Value(v) => v.writeable(),
|
|
|
|
Part::Method(_, v) => v.iter().any(Value::writeable),
|
|
|
|
_ => false,
|
|
|
|
}
|
|
|
|
}
|
2022-10-19 09:55:19 +00:00
|
|
|
/// Returns a yield if an alias is specified
|
2022-06-04 08:55:05 +00:00
|
|
|
pub(crate) fn alias(&self) -> Option<&Idiom> {
|
|
|
|
match self {
|
|
|
|
Part::Graph(v) => v.alias.as_ref(),
|
|
|
|
_ => None,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-01-13 17:36:41 +00:00
|
|
|
impl fmt::Display for Part {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
match self {
|
2022-10-04 21:51:18 +00:00
|
|
|
Part::All => f.write_str("[*]"),
|
|
|
|
Part::Last => f.write_str("[$]"),
|
|
|
|
Part::First => f.write_str("[0]"),
|
2023-07-15 07:08:26 +00:00
|
|
|
Part::Start(v) => write!(f, "{v}"),
|
2023-02-03 11:47:07 +00:00
|
|
|
Part::Field(v) => write!(f, ".{v}"),
|
2023-08-01 07:30:13 +00:00
|
|
|
Part::Flatten => f.write_str("…"),
|
2023-02-03 11:47:07 +00:00
|
|
|
Part::Index(v) => write!(f, "[{v}]"),
|
|
|
|
Part::Where(v) => write!(f, "[WHERE {v}]"),
|
|
|
|
Part::Graph(v) => write!(f, "{v}"),
|
2023-07-15 07:08:26 +00:00
|
|
|
Part::Value(v) => write!(f, "[{v}]"),
|
2023-03-31 18:44:16 +00:00
|
|
|
Part::Method(v, a) => write!(f, ".{v}({})", Fmt::comma_separated(a)),
|
2022-01-13 17:36:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-02-22 19:05:58 +00:00
|
|
|
// ------------------------------
|
|
|
|
|
|
|
|
pub trait Next<'a> {
|
|
|
|
fn next(&'a self) -> &[Part];
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> Next<'a> for &'a [Part] {
|
|
|
|
fn next(&'a self) -> &'a [Part] {
|
|
|
|
match self.len() {
|
|
|
|
0 => &[],
|
|
|
|
_ => &self[1..],
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|