esre 0.1.1

alt regex library
Documentation
use crate::entities::re::ParseJsonError;
use serde_json::{Map, Value};

pub(crate) trait FieldGetter {
    type T;
    fn with_field<R>(
        dict: &Map<String, Value>,
        key: &str,
        predicate: &dyn Fn(Option<&Self::T>) -> Result<R, ParseJsonError>,
    ) -> Result<R, ParseJsonError>;

    fn with_primary_field<R>(
        dict: &Map<String, Value>,
        key: &str,
        predicate: &dyn Fn(&Self::T) -> Result<R, ParseJsonError>,
    ) -> Result<Option<R>, ParseJsonError> {
        Self::with_field(dict, key, &|f| match f {
            Some(val) => Ok(Some(predicate(val)?)),
            _ => Ok(None),
        })
    }

    fn with_param_field<R>(
        dict: &Map<String, Value>,
        key: &str,
        predicate: &dyn Fn(&Self::T) -> Result<R, ParseJsonError>,
    ) -> Result<R, ParseJsonError> {
        Self::with_field(dict, key, &|f| match f {
            Some(val) => predicate(val),
            _ => ParseJsonError::not_found(key),
        })
    }

    fn with_param_nullable_field<R>(
        dict: &Map<String, Value>,
        key: &str,
        predicate: &dyn Fn(Option<&Self::T>) -> Result<R, ParseJsonError>,
    ) -> Result<R, ParseJsonError> {
        if let Some(Value::Null) = dict.get(&key.to_string()) {
            return predicate(None);
        }
        Self::with_field(dict, key, &|f| match f {
            Some(val) => predicate(Some(val)),
            _ => ParseJsonError::not_found(key),
        })
    }
}

pub struct UsizeFieldGetter {}
pub struct BoolFieldGetter {}
pub struct StrFieldGetter {}
pub struct VecFieldGetter {}
pub struct ValueFieldGetter {}

impl FieldGetter for UsizeFieldGetter {
    type T = usize;

    fn with_field<R>(
        dict: &Map<String, Value>,
        key: &str,
        predicate: &dyn Fn(Option<&usize>) -> Result<R, ParseJsonError>,
    ) -> Result<R, ParseJsonError> {
        match dict.get(&key.to_string()) {
            Some(Value::Number(num)) => {
                let int = match num.as_u64() {
                    Some(val) => val as usize,
                    _ => return ParseJsonError::invalid_value(key, "int"),
                };
                predicate(Some(&int))
            }
            Some(_) => ParseJsonError::invalid_value(key, "int"),
            None => predicate(None),
        }
    }
}

impl FieldGetter for BoolFieldGetter {
    type T = bool;

    fn with_field<R>(
        dict: &Map<String, Value>,
        key: &str,
        predicate: &dyn Fn(Option<&Self::T>) -> Result<R, ParseJsonError>,
    ) -> Result<R, ParseJsonError> {
        match dict.get(&key.to_string()) {
            Some(Value::Bool(ref val)) => predicate(Some(val)),
            Some(_) => ParseJsonError::invalid_value(key, "bool"),
            None => predicate(None),
        }
    }
}

impl FieldGetter for VecFieldGetter {
    type T = Vec<Value>;

    fn with_field<R>(
        dict: &Map<String, Value>,
        key: &str,
        predicate: &dyn Fn(Option<&Self::T>) -> Result<R, ParseJsonError>,
    ) -> Result<R, ParseJsonError> {
        match dict.get(&key.to_string()) {
            Some(Value::Array(ref val)) => predicate(Some(val)),
            Some(_) => ParseJsonError::invalid_value(key, "list"),
            None => predicate(None),
        }
    }
}

impl FieldGetter for StrFieldGetter {
    type T = String;

    fn with_field<R>(
        dict: &Map<String, Value>,
        key: &str,
        predicate: &dyn Fn(Option<&Self::T>) -> Result<R, ParseJsonError>,
    ) -> Result<R, ParseJsonError> {
        match dict.get(&key.to_string()) {
            Some(Value::String(ref val)) => predicate(Some(val)),
            Some(_) => ParseJsonError::invalid_value(key, "str"),
            None => predicate(None),
        }
    }
}

impl FieldGetter for ValueFieldGetter {
    type T = Value;

    fn with_field<R>(
        dict: &Map<String, Value>,
        key: &str,
        predicate: &dyn Fn(Option<&Self::T>) -> Result<R, ParseJsonError>,
    ) -> Result<R, ParseJsonError> {
        predicate(dict.get(&key.to_string()))
    }
}