use std::collections::{BTreeMap, HashMap};
use serde::{Deserialize, Serialize};
#[allow(unused_imports)]
use crate as surrealdb_types;
use crate::{Object, SurrealValue, Value};
#[derive(Clone, Debug, Default, Eq, PartialEq, SurrealValue, Serialize, Deserialize)]
#[surreal(crate = "crate")]
#[serde(transparent)]
pub struct Variables(BTreeMap<String, Value>);
impl Variables {
pub fn new() -> Self {
Self(BTreeMap::new())
}
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
pub fn len(&self) -> usize {
self.0.len()
}
pub fn iter(&self) -> std::collections::btree_map::Iter<'_, String, Value> {
self.0.iter()
}
pub fn get(&self, key: &str) -> Option<&Value> {
self.0.get(key)
}
pub fn insert(&mut self, key: impl Into<String>, value: impl SurrealValue) {
self.0.insert(key.into(), value.into_value());
}
pub fn remove(&mut self, key: &str) {
self.0.remove(key);
}
pub fn extend(&mut self, other: Variables) {
self.0.extend(other.0);
}
}
impl IntoIterator for Variables {
type Item = (String, Value);
type IntoIter = std::collections::btree_map::IntoIter<String, Value>;
fn into_iter(self) -> Self::IntoIter {
self.0.into_iter()
}
}
impl FromIterator<(String, Value)> for Variables {
fn from_iter<T: IntoIterator<Item = (String, Value)>>(iter: T) -> Self {
Self(iter.into_iter().collect())
}
}
impl From<BTreeMap<String, Value>> for Variables {
fn from(map: BTreeMap<String, Value>) -> Self {
Self(map)
}
}
impl From<BTreeMap<String, String>> for Variables {
fn from(map: BTreeMap<String, String>) -> Self {
Self(map.into_iter().map(|(k, v)| (k, Value::String(v))).collect())
}
}
impl From<HashMap<String, String>> for Variables {
fn from(map: HashMap<String, String>) -> Self {
Self(map.into_iter().map(|(k, v)| (k, Value::String(v))).collect())
}
}
impl From<Object> for Variables {
fn from(obj: Object) -> Self {
Self(obj.0)
}
}
impl From<Variables> for Object {
fn from(vars: Variables) -> Self {
Object(vars.0)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_variables_serde() {
let vars = Variables::new();
let json = serde_json::to_string(&vars).unwrap();
assert_eq!(json, "{}");
let vars1 = serde_json::from_str::<Variables>("{\"name\":{\"String\":\"John\"}}").unwrap();
assert_eq!(vars1.get("name"), Some(&Value::String("John".to_string())));
let vars2 =
Variables::from_iter(vec![("name".to_string(), "John".to_string().into_value())]);
let json = serde_json::to_string(&vars2).unwrap();
assert_eq!(json, "{\"name\":{\"String\":\"John\"}}");
}
}