1use common::fmt::Fmt;
2use surrealdb_types::{SqlFormat, ToSql, write_sql};
3
4use crate::{CoverStmts, Expr, Idiom};
5
6#[derive(Clone, Debug, PartialEq, Eq)]
7#[cfg_attr(feature = "arbitrary", derive(::arbitrary::Arbitrary))]
8pub enum Fields {
9 Value(Box<Selector>),
11 Select(
13 #[cfg_attr(feature = "arbitrary", arbitrary(with = crate::arbitrary::atleast_one))]
14 Vec<Field>,
15 ),
16}
17
18impl Fields {
19 pub fn all() -> Fields {
21 Fields::Select(vec![Field::All])
22 }
23
24 pub fn contains_all(&self) -> bool {
25 match self {
26 Fields::Value(_) => false,
27 Fields::Select(fields) => fields.iter().any(|x| matches!(x, Field::All)),
28 }
29 }
30}
31
32impl ToSql for Fields {
33 fn fmt_sql(&self, f: &mut String, fmt: SqlFormat) {
34 match self {
35 Fields::Value(v) => {
36 f.push_str("VALUE ");
37 v.fmt_sql(f, fmt);
38 }
39 Fields::Select(x) => write_sql!(f, fmt, "{}", Fmt::comma_separated(x)),
40 }
41 }
42}
43
44#[derive(Clone, Debug, Default, PartialEq, Eq)]
45#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
46pub enum Field {
47 #[default]
49 All,
50 Single(Selector),
52}
53
54#[derive(Clone, Debug, PartialEq, Eq)]
55pub struct Selector {
56 pub expr: Expr,
57 pub alias: Option<Idiom>,
58}
59
60impl ToSql for Field {
61 fn fmt_sql(&self, f: &mut String, fmt: SqlFormat) {
62 match self {
63 Self::All => f.push('*'),
64 Self::Single(s) => s.fmt_sql(f, fmt),
65 }
66 }
67}
68
69impl ToSql for Selector {
70 fn fmt_sql(&self, f: &mut String, fmt: SqlFormat) {
71 write_sql!(f, fmt, "{}", CoverStmts(&self.expr));
72 if let Some(alias) = &self.alias {
73 f.push_str(" AS ");
74 alias.fmt_sql(f, fmt);
75 }
76 }
77}