pnwkit_core/
variable.rs

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}