fuzzy-from-json-value 0.1.0

todo: write a description here
Documentation
// ---------------- [ File: fuzzy-from-json-value/src/fuzzy_from_json_value.rs ]
crate::ix!();

pub trait FuzzyFromJsonValue: Sized {
    fn fuzzy_from_json_value(value: &serde_json::Value) -> Result<Self,FuzzyFromJsonValueError>;
}

error_tree!{

    pub enum FuzzyFromJsonValueError {

        Serde(::serde_path_to_error::Error<::serde_json::Error>),
        SerdeJson(::serde_json::Error),

        #[display("Expected an object for {target_type}, got {actual:?}")]
        NotAnObject {
            target_type: &'static str,
            actual:      serde_json::Value,
        },

        #[display("MissingField: {field_name} for target={target_type}")]
        MissingField {
            field_name: &'static str,
            target_type: &'static str,
        },

        #[display("Could not deserialize {target_type}: {source}")]
        SerdeError {
            target_type: &'static str,
            source: serde_json::Error,
        },

        #[display("Other fuzzy error parsing {target_type}: {detail}")]
        Other {
            target_type: &'static str,
            detail:      String,
        },
    }
}

use serde_path_to_error::{self, Error as PathError};

/// Parse `value` into `T` and if there's a structure mismatch,
/// you get an error message that includes a *JSON pointer path*
/// to where the mismatch occurred.
pub fn from_value_pathaware<T>(value: &serde_json::Value) -> Result<T, serde_json::Error>
where
    T: serde::de::DeserializeOwned,
{
    let value_str = value.to_string();

    // (B) Turn that Value into a normal serde_json::Deserializer
    let deser = &mut ::serde_json::Deserializer::from_str(&value_str);

    let result: Result<T, _> = serde_path_to_error::deserialize(deser);

    // (C) Pass the deserializer to serde_path_to_error
    match result {
        Ok(cfg) => Ok(cfg),
        Err(path_err) => {
            let path_string = path_err.path().to_string();
            let underlying  = path_err.into_inner(); // the actual serde_json::Error
            warn!(
                "Fuzzy parse failed at path '{}': {}",
                path_string,
                underlying
            );
            Err(underlying)
        }
    }
}