serde-select 0.1.0-alpha.1

Query serde de/serializable objects
Documentation
use crate::error::*;

use serde::Serialize;
use serde::Deserialize;

pub enum ObjectType {
    Atom,
    Map,
    Array,
}

pub trait Object<'doc>: Serialize + Deserialize<'doc> + Clone {
    fn get_type(&self) -> ObjectType;
    fn has_key(&self, key: &str) -> bool;
    fn has_index(&self, idx: usize) -> bool;

    fn at_index<'a>(&'a self, idx: usize) -> Result<Option<&'a Self>>;
    fn at_index_mut<'a>(&'a mut self, idx: usize) -> Result<Option<&'a mut Self>>;
    fn at_key<'a>(&'a self, key: &str) -> Result<Option<&'a Self>>;
    fn at_key_mut<'a>(&'a mut self, key: &str) -> Result<Option<&'a mut Self>>;

    fn array_len(&self) -> Option<usize>;
}

#[cfg(feature = "backend_toml")]
impl<'doc> Object<'doc> for toml::Value {
    fn get_type(&self) -> ObjectType {
        match self {
            toml::Value::Boolean(_)
                | toml::Value::Datetime(_)
                | toml::Value::Float(_)
                | toml::Value::Integer(_)
                | toml::Value::String(_) => ObjectType::Atom,

            toml::Value::Array(_) => ObjectType::Array,
            toml::Value::Table(_) => ObjectType::Map,
        }
    }

    fn has_key(&self, key: &str) -> bool {
        match self {
            toml::Value::Table(t) => t.contains_key(key),
            _ => false
        }
    }

    fn has_index(&self, idx: usize) -> bool {
        match self {
            toml::Value::Array(a) => a.len() > idx,
            _ => false
        }
    }

    fn at_index<'a>(&'a self, idx: usize) -> Result<Option<&'a Self>> {
        match self {
            toml::Value::Array(a) => Ok(a.get(idx)),
            toml::Value::Table(_) => Err(crate::error::Error::NoIndexInTable(idx)),
            _ => Err(crate::error::Error::QueryingValueAsArray(idx)),
        }
    }

    fn at_index_mut<'a>(&'a mut self, idx: usize) -> Result<Option<&'a mut Self>> {
        match self {
            toml::Value::Array(a) => Ok(a.get_mut(idx)),
            toml::Value::Table(_) => Err(crate::error::Error::NoIndexInTable(idx)),
            _ => Err(crate::error::Error::QueryingValueAsArray(idx)),
        }
    }

    fn at_key<'a>(&'a self, key: &str) -> Result<Option<&'a Self>> {
        match self {
            toml::Value::Table(t) => Ok(t.get(key)),
            toml::Value::Array(_) => Err(crate::error::Error::NoIdentifierInArray(key.to_string())),
            _ => Err(crate::error::Error::QueryingValueAsTable(key.to_string())),
        }
    }

    fn at_key_mut<'a>(&'a mut self, key: &str) -> Result<Option<&'a mut Self>> {
        match self {
            toml::Value::Table(t) => Ok(t.get_mut(key)),
            toml::Value::Array(_) => Err(crate::error::Error::NoIdentifierInArray(key.to_string())),
            _ => Err(crate::error::Error::QueryingValueAsTable(key.to_string())),
        }
    }

    fn array_len(&self) -> Option<usize> {
        match self {
            toml::Value::Array(a) => Some(a.len()),
            _ => None ,
        }
    }
}


#[cfg(feature = "backend_serde_json")]
impl<'doc> Object<'doc> for serde_json::Value {
    fn get_type(&self) -> ObjectType {
        match self {
            serde_json::Value::Null
                | serde_json::Value::Bool(_)
                | serde_json::Value::Number(_)
                | serde_json::Value::String(_) => ObjectType::Atom,

            serde_json::Value::Array(_) => ObjectType::Array,
            serde_json::Value::Object(_) => ObjectType::Map,
        }
    }

    fn has_key(&self, key: &str) -> bool {
        match self {
            serde_json::Value::Object(t) => t.contains_key(key),
            _ => false
        }
    }

    fn has_index(&self, idx: usize) -> bool {
        match self {
            serde_json::Value::Array(a) => a.len() > idx,
            _ => false
        }
    }

    fn at_index<'a>(&'a self, idx: usize) -> Result<Option<&'a Self>> {
        match self {
            serde_json::Value::Array(a) => Ok(a.get(idx)),
            serde_json::Value::Object(_) => Err(crate::error::Error::NoIndexInTable(idx)),
            _ => Err(crate::error::Error::QueryingValueAsArray(idx)),
        }
    }

    fn at_index_mut<'a>(&'a mut self, idx: usize) -> Result<Option<&'a mut Self>> {
        match self {
            serde_json::Value::Array(a) => Ok(a.get_mut(idx)),
            serde_json::Value::Object(_) => Err(crate::error::Error::NoIndexInTable(idx)),
            _ => Err(crate::error::Error::QueryingValueAsArray(idx)),
        }
    }

    fn at_key<'a>(&'a self, key: &str) -> Result<Option<&'a Self>> {
        match self {
            serde_json::Value::Object(t) => Ok(t.get(key)),
            serde_json::Value::Array(_) => Err(crate::error::Error::NoIdentifierInArray(key.to_string())),
            _ => Err(crate::error::Error::QueryingValueAsTable(key.to_string())),
        }
    }

    fn at_key_mut<'a>(&'a mut self, key: &str) -> Result<Option<&'a mut Self>> {
        match self {
            serde_json::Value::Object(t) => Ok(t.get_mut(key)),
            serde_json::Value::Array(_) => Err(crate::error::Error::NoIdentifierInArray(key.to_string())),
            _ => Err(crate::error::Error::QueryingValueAsTable(key.to_string())),
        }
    }

    fn array_len(&self) -> Option<usize> {
        match self {
            serde_json::Value::Array(a) => Some(a.len()),
            _ => None ,
        }
    }
}