mod display;
mod parse;
use std::fmt;
type ParseResult<T> = Result<T, ParseError>;
#[derive(Debug)]
pub struct ParseError;
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]
pub enum Path<'a> {
SchemaDefinition,
SchemaExtension(usize),
TypeDefinition(&'a str, Option<PathInType<'a>>),
TypeExtension(&'a str, usize, Option<PathInType<'a>>),
DirectiveDefinition(&'a str),
}
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]
pub enum PathInType<'a> {
InField(&'a str, Option<PathInField<'a>>),
InDirective(&'a str, usize),
InterfaceImplementation(&'a str),
}
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]
pub enum PathInField<'a> {
InArgument(&'a str, Option<PathInArgument<'a>>),
InDirective(&'a str, usize),
}
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]
pub enum PathInArgument<'a> {
InDirective(&'a str, usize),
}
fn is_valid_graphql_name(s: &str) -> bool {
let mut chars = s.chars();
let Some(first_char) = chars.next() else {
return false;
};
if !first_char.is_ascii_alphabetic() && first_char != '_' {
return false;
}
for c in chars {
if !c.is_ascii_alphanumeric() && c != '_' {
return false;
}
}
true
}
#[cfg(test)]
mod tests {
#![allow(clippy::panic)]
use super::*;
#[test]
fn error_tests() {
fn expect_error(path: &str) {
match Path::parse(path) {
Err(_) => (),
Ok(found) => panic!("Expected error for path: {path}, got: {found:?}"),
}
}
for case in [
"",
"s:",
"s:meow",
":schema[-1]",
":schema.something",
":s",
":s[1]",
":something",
"t:something",
"something.:s",
"10",
"test.",
"test[10].",
"test.@siblings.",
"myObject._abc1.@requires",
"_my_object.@key",
"@",
"_my_object.@",
"@test[0]",
"myObject.&MyInterface.a",
"myObject.&MyInterface.",
"myObject._abc1.arg1.",
"myObject._abc1.arg1.something",
"myObject._abc1.arg1.@requires",
] {
expect_error(case);
}
}
#[test]
fn roundtrip_tests() {
fn test(path: &str) {
let Ok(parsed) = Path::parse(path) else {
panic!("Failed to parse path: {path}")
};
let formatted = parsed.to_string();
assert_eq!(path, formatted);
}
for case in [
":schema",
":schema[0]",
":schema[1]",
":schema[100]",
"@meow",
"@deprecated",
"@something__else",
"@join__type",
"my_union",
"__my_input_object[32]",
"_my_object.id",
"_my_object.@key[0]",
"myObject[10].id",
"myObject.@join__type[0]",
"myObject._abc1",
"myObject._abc1.@requires[0]",
"myObject._abc1.@requires[100]",
"myObject._abc1.arg1",
"myObject._abc1.arg1.@deprecated[0]",
"myObject.&MyInterface",
] {
test(case);
}
}
}