pnwkit_core/
field.rs

1use crate::{data::Object, Value, Variable};
2use dashmap::DashMap;
3
4#[derive(Clone, Debug)]
5pub enum FieldType {
6    Node(Field),
7    Leaf(String),
8}
9
10#[derive(Debug, Clone)]
11pub struct Field {
12    pub(crate) name: String,
13    pub(crate) alias: Option<String>,
14    pub(crate) arguments: Object,
15    pub(crate) fields: Vec<FieldType>,
16    pub(crate) paginate: bool,
17    pub(crate) paginate_name: bool,
18}
19
20impl Field {
21    pub fn set_name(mut self, name: String) -> Self {
22        self.name = name;
23        self
24    }
25
26    pub fn set_alias(mut self, alias: String) -> Self {
27        self.alias = Some(alias);
28        self
29    }
30
31    pub fn set_argument(self, name: String, value: Value) -> Self {
32        self.arguments.insert(name, value);
33        self
34    }
35
36    pub fn add_field(mut self, field: FieldType) -> Self {
37        self.fields.push(field);
38        self
39    }
40
41    pub fn add_field_node(mut self, field: Field) -> Self {
42        self.fields.push(FieldType::Node(field));
43        self
44    }
45
46    pub fn add_field_leaf(mut self, field: &str) -> Self {
47        self.fields.push(FieldType::Leaf(field.into()));
48        self
49    }
50
51    pub fn will_paginate(mut self) -> Self {
52        self.paginate = true;
53        self.paginate_name = true;
54        self
55    }
56
57    pub fn is_paginated(mut self) -> Self {
58        self.paginate = true;
59        self
60    }
61
62    pub(crate) fn get_variables(&self) -> Vec<Variable> {
63        let mut vars = Vec::new();
64        for i in self.arguments.iter() {
65            if let Value::Variable(variable) = i.value() {
66                vars.push(variable.clone());
67            }
68        }
69        for field in &self.fields {
70            match field {
71                FieldType::Node(field) => vars.extend(field.get_variables()),
72                FieldType::Leaf(_) => {},
73            }
74        }
75        vars
76    }
77
78    pub(crate) fn tree_will_paginate(&self) -> bool {
79        if self.paginate {
80            return true;
81        }
82        for field in &self.fields {
83            match field {
84                FieldType::Node(field) => {
85                    if field.tree_will_paginate() {
86                        return true;
87                    }
88                },
89                FieldType::Leaf(_) => {},
90            }
91        }
92        false
93    }
94
95    pub(crate) fn valid(&self) -> Result<(), String> {
96        if self.name.is_empty() {
97            return Err("Field name cannot be empty".into());
98        }
99        Ok(())
100    }
101}
102
103impl Default for Field {
104    fn default() -> Self {
105        Self {
106            name: String::new(),
107            alias: None,
108            arguments: DashMap::new(),
109            fields: Vec::new(),
110            paginate: false,
111            paginate_name: false,
112        }
113    }
114}
115
116pub fn field(name: &str) -> Field {
117    Field::default().set_name(name.into())
118}
119
120pub fn field_as(name: &str, alias: &str) -> Field {
121    Field::default()
122        .set_name(name.into())
123        .set_alias(alias.into())
124}