harmony-jolt 0.7.0

JSON to JSON transformation library using the JOLT spec
Documentation
use std::collections::HashSet;
use std::fmt;

use serde::de::{self, Visitor};
use serde::{
    de::{Error as _, Deserializer},
    Deserialize,
};

use super::ast::{Rhs, Lhs, Stars};

#[derive(Debug, PartialEq, Eq, Clone)]
pub enum InfallibleLhs {
    DollarSign(usize, usize),
    At(usize, Box<Rhs>),
    Square(String),
}

#[derive(Debug, Clone, PartialEq, Eq, Default)]
pub struct Object {
    pub infallible: Vec<(InfallibleLhs, Vec<Rhs>)>,
    pub literal: Vec<(String, REntry)>,
    pub amp: Vec<((usize, usize), REntry)>,
    pub pipes: Vec<(Vec<Stars>, REntry)>,
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub enum REntry {
    Obj(Box<Object>),
    Rhs(Vec<Rhs>),
    Thrash,
}

struct RhsVisitor;

impl Visitor<'_> for RhsVisitor {
    type Value = Rhs;

    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        formatter.write_str("right hand side expression")
    }

    fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
    where
        E: de::Error,
    {
        self.visit_str(&v)
    }

    fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
    where
        E: de::Error,
    {
        Rhs::parse(value).map_err(|e| E::custom(format!("failed to parse: {value}.error={e}")))
    }
}

impl<'de> Deserialize<'de> for Rhs {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        deserializer.deserialize_any(RhsVisitor)
    }
}

struct RhssVisitor;

impl<'de> Visitor<'de> for RhssVisitor {
    type Value = Vec<Rhs>;

    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        formatter.write_str("Right hand side expression or a array of rhs expressions")
    }

    fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
    where
        E: de::Error,
    {
        self.visit_str(&v)
    }

    fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
    where
        E: de::Error,
    {
        let r = Rhs::parse(value)
            .map_err(|e| E::custom(format!("failed to parse: {value}.error={e}")))?;
        Ok(vec![r])
    }

    fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
    where
        A: de::SeqAccess<'de>,
    {
        let mut arr = Vec::new();
        while let Some(rhs) = seq.next_element::<Rhss>()? {
            arr.extend_from_slice(&rhs.0);
        }
        Ok(arr)
    }
}

struct Rhss(Vec<Rhs>);

impl<'de> Deserialize<'de> for Rhss {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        deserializer.deserialize_any(RhssVisitor).map(Rhss)
    }
}

struct ObjectVisitor;

impl<'de> Visitor<'de> for ObjectVisitor {
    type Value = Object;

    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        formatter.write_str("map")
    }

    fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
    where
        A: de::MapAccess<'de>,
        A::Error: de::Error,
    {
        let mut obj = Object::default();

        let mut key_set = HashSet::new();

        while let Some(lhs_s) = map.next_key::<String>()? {
            let lhs = LhsVisitor.visit_str(&lhs_s)?;

            if !key_set.insert(lhs_s) {
                return Err(A::Error::custom("duplicate lhs"));
            }

            match lhs {
                Lhs::DollarSign(idx0, idx1) => {
                    obj.infallible.push((
                        InfallibleLhs::DollarSign(idx0, idx1),
                        map.next_value::<Rhss>()?.0,
                    ));
                }
                Lhs::Amp(idx0, idx1) => {
                    obj.amp.push(((idx0, idx1), map.next_value()?));
                }
                Lhs::At(idx, rhs) => {
                    obj.infallible
                        .push((InfallibleLhs::At(idx, rhs), map.next_value::<Rhss>()?.0));
                }
                Lhs::Square(lit) => {
                    obj.infallible
                        .push((InfallibleLhs::Square(lit), map.next_value::<Rhss>()?.0));
                }
                Lhs::Pipes(pipes) => {
                    obj.pipes.push((pipes, map.next_value()?));
                }
                Lhs::Literal(lit) => {
                    obj.literal.push((lit, map.next_value()?));
                }
            }
        }

        Ok(obj)
    }
}

impl<'de> Deserialize<'de> for Object {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        deserializer.deserialize_map(ObjectVisitor)
    }
}

struct LhsVisitor;

impl Visitor<'_> for LhsVisitor {
    type Value = Lhs;

    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        formatter.write_str("Left hand side expression")
    }

    fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
    where
        E: de::Error,
    {
        self.visit_str(&v)
    }

    fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
    where
        E: de::Error,
    {
        Lhs::parse(value).map_err(|e| E::custom(format!("failed to parse: {value}.error={e}")))
    }
}

impl<'de> Deserialize<'de> for Lhs {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        deserializer.deserialize_any(LhsVisitor)
    }
}

struct REntryVisitor;

impl<'de> Visitor<'de> for REntryVisitor {
    type Value = REntry;

    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        formatter.write_str("Right hand side object or expression")
    }

    fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
    where
        E: de::Error,
    {
        self.visit_str(&v)
    }

    fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
    where
        E: de::Error,
    {
        RhsVisitor.visit_str(value).map(|r| REntry::Rhs(vec![r]))
    }

    fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
    where
        A: de::SeqAccess<'de>,
    {
        let mut arr = Vec::new();

        while let Some(rhs) = seq.next_element()? {
            arr.push(rhs);
        }

        Ok(REntry::Rhs(arr))
    }

    fn visit_map<A>(self, map: A) -> Result<Self::Value, A::Error>
    where
        A: de::MapAccess<'de>,
    {
        ObjectVisitor
            .visit_map(map)
            .map(|obj| REntry::Obj(Box::new(obj)))
    }

    fn visit_none<E>(self) -> Result<Self::Value, E>
    where
        E: de::Error,
    {
        Ok(REntry::Thrash)
    }

    fn visit_unit<E>(self) -> Result<Self::Value, E>
    where
        E: de::Error,
    {
        self.visit_none()
    }
}

impl<'de> Deserialize<'de> for REntry {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        deserializer.deserialize_any(REntryVisitor)
    }
}