graphql_query/visit/
path.rs

1use crate::error::Error;
2use std::fmt;
3
4#[derive(Clone, Debug, Default, PartialEq)]
5pub struct Path {
6    pub segments: Vec<PathSegment>,
7}
8
9impl Path {
10    pub fn push(&mut self, segment: PathSegment) {
11        self.segments.push(segment)
12    }
13
14    pub fn pop(&mut self) -> Option<PathSegment> {
15        self.segments.pop()
16    }
17}
18
19impl TryFrom<&str> for Path {
20    type Error = Error;
21
22    fn try_from(value: &str) -> Result<Self, Self::Error> {
23        let segments = value
24            .split('.')
25            .map(PathSegment::try_from)
26            .collect::<Result<Vec<_>, _>>()?;
27        Ok(Self { segments })
28    }
29}
30
31impl fmt::Display for Path {
32    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
33        write!(
34            f,
35            "{}",
36            self.segments
37                .iter()
38                .map(|segment| segment.to_string())
39                .collect::<Vec<_>>()
40                .join(".")
41        )
42    }
43}
44
45#[derive(Clone, Debug, PartialEq)]
46pub enum PathSegment {
47    Index(usize),
48
49    Arguments,
50    Directives,
51    Name,
52    SelectionSet,
53    Type,
54    Value,
55    Variable,
56    VariableDefinitions,
57}
58
59impl TryFrom<&str> for PathSegment {
60    type Error = Error;
61
62    fn try_from(value: &str) -> Result<Self, Self::Error> {
63        match value.parse::<usize>() {
64            Ok(index) => Ok(Self::Index(index)),
65            Err(_) => match value {
66                "arguments" => Ok(PathSegment::Arguments),
67                "directives" => Ok(PathSegment::Directives),
68                "name" => Ok(PathSegment::Name),
69                "selectionSet" => Ok(PathSegment::SelectionSet),
70                "type" => Ok(PathSegment::Type),
71                "value" => Ok(PathSegment::Value),
72                "variable" => Ok(PathSegment::Variable),
73                "variableDefinitions" => Ok(PathSegment::VariableDefinitions),
74                _ => Err(Error::new(format!("Invalid path segment {value}"), None)),
75            },
76        }
77    }
78}
79
80impl fmt::Display for PathSegment {
81    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
82        write!(
83            f,
84            "{}",
85            match self {
86                PathSegment::Index(index) => index.to_string(),
87                PathSegment::Arguments => String::from("arguments"),
88                PathSegment::Directives => String::from("directives"),
89                PathSegment::Name => String::from("name"),
90                PathSegment::SelectionSet => String::from("selectionSet"),
91                PathSegment::Type => String::from("type"),
92                PathSegment::Value => String::from("value"),
93                PathSegment::Variable => String::from("variable"),
94                PathSegment::VariableDefinitions => String::from("variableDefinitions"),
95            }
96        )
97    }
98}