flowcore 1.0.0

Structures shared between runtime and clients
Documentation
use std::marker::PhantomData;

use serde::Deserialize;
use url::Url;

use crate::errors::{Result, ResultExt};

use super::deserializer::Deserializer;

/// Struct representing a Generic deserializer of content stored in Json format
#[derive(Default)]
pub struct JsonDeserializer<'a, T>
where
    T: Deserialize<'a>,
{
    t: PhantomData<&'a T>,
}

impl<'a, T> JsonDeserializer<'a, T>
where
    T: Deserialize<'a>,
{
    /// Create a new `JsonDeserializer`
    pub fn new() -> Self {
        JsonDeserializer { t: PhantomData }
    }
}

impl<'a, T> Deserializer<'a, T> for JsonDeserializer<'a, T>
where
    T: Deserialize<'a>,
{
    fn deserialize(&self, contents: &'a str, url: Option<&Url>) -> Result<T> {
        serde_json::from_str(contents).chain_err(|| {
            format!(
                "Error deserializing Json from: '{}'",
                url.map_or("URL unknown".to_owned(), std::string::ToString::to_string)
            )
        })
    }

    fn name(&self) -> &'static str {
        "Json"
    }
}

#[cfg(test)]
#[allow(clippy::unwrap_used, clippy::expect_used)]
mod test {
    use serde_derive::{Deserialize, Serialize};

    use super::super::deserializer::Deserializer;
    use super::JsonDeserializer;

    #[derive(Serialize, Deserialize, Debug, Clone)]
    #[serde(untagged)]
    #[allow(clippy::module_name_repetitions)]
    pub enum TestStruct {
        /// The process is actually a `Flow`
        FlowProcess(String),
        /// The process is actually a `Function`
        FunctionProcess(String),
    }

    #[test]
    fn invalid_json() {
        let json = JsonDeserializer::<TestStruct>::new();
        assert!(
            json.deserialize("=", None).is_err(),
            "Should not have parsed correctly as is invalid JSON"
        );
    }
}