graphql-query 1.0.1

Stupendously fast and easy GraphQL Query Language handling.
Documentation
use crate::error::Error;
use std::fmt;

#[derive(Clone, Debug, Default, PartialEq)]
pub struct Path {
    pub segments: Vec<PathSegment>,
}

impl Path {
    pub fn push(&mut self, segment: PathSegment) {
        self.segments.push(segment)
    }

    pub fn pop(&mut self) -> Option<PathSegment> {
        self.segments.pop()
    }
}

impl TryFrom<&str> for Path {
    type Error = Error;

    fn try_from(value: &str) -> Result<Self, Self::Error> {
        let segments = value
            .split('.')
            .map(PathSegment::try_from)
            .collect::<Result<Vec<_>, _>>()?;
        Ok(Self { segments })
    }
}

impl fmt::Display for Path {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(
            f,
            "{}",
            self.segments
                .iter()
                .map(|segment| segment.to_string())
                .collect::<Vec<_>>()
                .join(".")
        )
    }
}

#[derive(Clone, Debug, PartialEq)]
pub enum PathSegment {
    Index(usize),

    Arguments,
    Directives,
    Name,
    SelectionSet,
    Type,
    Value,
    Variable,
    VariableDefinitions,
}

impl TryFrom<&str> for PathSegment {
    type Error = Error;

    fn try_from(value: &str) -> Result<Self, Self::Error> {
        match value.parse::<usize>() {
            Ok(index) => Ok(Self::Index(index)),
            Err(_) => match value {
                "arguments" => Ok(PathSegment::Arguments),
                "directives" => Ok(PathSegment::Directives),
                "name" => Ok(PathSegment::Name),
                "selectionSet" => Ok(PathSegment::SelectionSet),
                "type" => Ok(PathSegment::Type),
                "value" => Ok(PathSegment::Value),
                "variable" => Ok(PathSegment::Variable),
                "variableDefinitions" => Ok(PathSegment::VariableDefinitions),
                _ => Err(Error::new(format!("Invalid path segment {value}"), None)),
            },
        }
    }
}

impl fmt::Display for PathSegment {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(
            f,
            "{}",
            match self {
                PathSegment::Index(index) => index.to_string(),
                PathSegment::Arguments => String::from("arguments"),
                PathSegment::Directives => String::from("directives"),
                PathSegment::Name => String::from("name"),
                PathSegment::SelectionSet => String::from("selectionSet"),
                PathSegment::Type => String::from("type"),
                PathSegment::Value => String::from("value"),
                PathSegment::Variable => String::from("variable"),
                PathSegment::VariableDefinitions => String::from("variableDefinitions"),
            }
        )
    }
}