use std::collections::{HashMap, HashSet};
use std::hash::{Hash, Hasher};
#[derive(Debug, Clone, PartialEq)]
pub enum Value {
Int(i64),
Str(String),
Bool(bool),
Map(HashMap<Value, Value>),
List(Vec<Value>),
Set(HashSet<Value>),
None,
}
impl Eq for Value {}
impl Hash for Value {
fn hash<H: Hasher>(&self, state: &mut H) {
use Value::*;
std::mem::discriminant(self).hash(state);
match self {
Int(v) => v.hash(state),
Str(s) => s.hash(state),
Bool(b) => b.hash(state),
Map(_) | List(_) | Set(_) | None => {}
}
}
}
impl Value {
pub fn as_int(&self) -> Option<i64> {
if let Value::Int(v) = self {
Some(*v)
} else {
None
}
}
pub fn as_str(&self) -> Option<&str> {
if let Value::Str(s) = self {
Some(s)
} else {
None
}
}
pub fn as_bool(&self) -> Option<bool> {
if let Value::Bool(b) = self {
Some(*b)
} else {
None
}
}
pub fn from_map(map: HashMap<Value, Value>) -> Self {
Value::Map(map)
}
pub fn from_list(list: Vec<Value>) -> Self {
Value::List(list)
}
pub fn from_set(set: HashSet<Value>) -> Self {
Value::Set(set)
}
}
pub fn sorted_map_entries<'a>(
map: &'a HashMap<Value, Value>,
) -> Vec<(&'a Value, &'a Value)> {
let mut entries: Vec<_> = map.iter().collect();
entries.sort_by(|a, b| {
format!("{:?}", a.0).cmp(&format!("{:?}", b.0)) });
entries
}