hydrus-ptr-client 0.1.0

A http client for the hydrus ptr
Documentation
#![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
    }
}