You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

77 lines
2.2 KiB
Rust

#![allow(unused)]
use crate::constants::HYDRUS_TYPE_DICTIONARY;
use crate::hydrus_serializable::HydrusSerializable;
use crate::{Error, Result};
use serde::de::DeserializeOwned;
use serde::Deserialize;
use serde_json::Value;
#[derive(Clone, Debug, Deserialize)]
pub struct HydrusDictionary {
list_sim_sim: Vec<(Value, Value)>,
list_sim_ser: Vec<(Value, Value)>,
list_ser_sim: Vec<(Value, Value)>,
list_ser_ser: Vec<(Value, Value)>,
}
impl HydrusSerializable for HydrusDictionary {
fn type_id() -> u64 {
HYDRUS_TYPE_DICTIONARY
}
}
impl HydrusDictionary {
/// Returns the first value for a given key
pub fn get(&self, key: &Value) -> Option<&Value> {
self._get(key).into_iter().next()
}
/// Returns a single value by using a string as a key
pub fn get_by_str<K: AsRef<str>>(&self, key: K) -> Option<&Value> {
self.get(&key.as_ref().into())
}
/// Removes an element deserialized as the given type from the dictionary
pub fn take<D: DeserializeOwned>(&mut self, key: &Value) -> Result<D> {
let value = self
._take(key)
.ok_or_else(|| Error::MissingProperty(key.to_string()))?;
serde_json::from_value::<D>(value).map_err(Error::from)
}
/// Removes an element with the given string key deserialized as the requested type from the dictionary
pub fn take_by_str<D: DeserializeOwned>(&mut self, key: &str) -> Result<D> {
self.take(&key.into())
}
/// Returns all values for a given key
fn _get(&self, key: &Value) -> Vec<&Value> {
self.list_sim_sim
.iter()
.chain(self.list_sim_ser.iter())
.chain(self.list_ser_sim.iter())
.chain(self.list_ser_ser.iter())
.filter(|(k, _)| k == key)
.map(|(_, v)| v)
.collect()
}
fn _take(&mut self, key: &Value) -> Option<Value> {
for list in [
&mut self.list_sim_sim,
&mut self.list_sim_ser,
&mut self.list_ser_sim,
&mut self.list_ser_ser,
] {
let index = list.iter().position(|(k, _)| k == key);
if let Some(index) = index {
return Some(list.swap_remove(index).1);
}
}
None
}
}