1use dashmap::DashMap;
2use serde::{ser::SerializeMap, Serialize};
3
4use crate::{query::Query, Value};
5
6#[derive(Clone, Debug)]
7pub enum VariableType {
8 Int,
9 String,
10}
11
12#[derive(Clone, Debug)]
13pub struct Variable {
14 pub(crate) name: String,
15 pub(crate) variable_type: VariableType,
16}
17
18impl Serialize for Variable {
19 fn serialize<S>(&self, _serializer: S) -> Result<S::Ok, S::Error>
20 where
21 S: serde::Serializer,
22 {
23 unreachable!()
24 }
25}
26
27pub fn variable(name: &str, variable_type: VariableType) -> Variable {
28 Variable {
29 name: name.into(),
30 variable_type,
31 }
32}
33
34#[derive(Debug)]
35pub struct Variables(pub(crate) DashMap<String, Value>);
36
37impl Variables {
38 pub fn new() -> Self {
39 Self(DashMap::new())
40 }
41
42 pub fn with_capacity(capacity: usize) -> Self {
43 Self(DashMap::with_capacity(capacity))
44 }
45
46 pub fn for_query(query: &Query) -> Self {
47 let mut vars = query
48 .get_variables()
49 .iter()
50 .map(|v| v.name.clone())
51 .collect::<Vec<String>>();
52 vars.sort();
53 vars.dedup();
54 Self::with_capacity(vars.len())
55 }
56
57 pub fn set(&self, name: String, value: Value) -> &Self {
58 if self.0.contains_key(&name) {
59 self.0.remove(&name);
60 }
61 self.0.insert(name, value);
62 self
63 }
64
65 pub fn get(&self, name: String) -> Option<Value> {
66 self.0.get(&name).map(|v| v.value().clone())
67 }
68
69 pub(crate) fn valid(&self, names: Vec<String>) -> Result<(), String> {
70 for name in names {
71 if name.is_empty() {
72 return Err("empty variable name".into());
73 }
74 if !self.0.contains_key(&name) {
75 return Err(format!("missing variable: {}", name));
76 }
77 }
78 Ok(())
79 }
80
81 pub(crate) fn page_init(&self) {
82 if self.0.contains_key("__page") {
83 return;
84 }
85 self.set("__page".into(), Value::Int(1));
86 }
87}
88
89impl Default for Variables {
90 fn default() -> Self {
91 Self::new()
92 }
93}
94
95impl Serialize for Variables {
96 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
97 where
98 S: serde::Serializer,
99 {
100 let mut map = serializer.serialize_map(Some(self.0.len()))?;
101 for pair in self.0.iter() {
102 let (key, value) = pair.pair();
103 map.serialize_entry(key, value)?;
104 }
105 map.end()
106 }
107}