use std::str::FromStr;
use serde::Serialize;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
#[serde(rename_all = "snake_case")]
pub enum Kind {
Object,
Interface,
Union,
Enum,
InputObject,
Scalar,
Directive,
Field,
InputField,
EnumValue,
Query,
Mutation,
Subscription,
}
impl Kind {
pub fn as_str(self) -> &'static str {
match self {
Kind::Object => "object",
Kind::Interface => "interface",
Kind::Union => "union",
Kind::Enum => "enum",
Kind::InputObject => "input_object",
Kind::Scalar => "scalar",
Kind::Directive => "directive",
Kind::Field => "field",
Kind::InputField => "input_field",
Kind::EnumValue => "enum_value",
Kind::Query => "query",
Kind::Mutation => "mutation",
Kind::Subscription => "subscription",
}
}
pub fn weight(self) -> i64 {
match self {
Kind::Query | Kind::Mutation | Kind::Subscription => 60,
Kind::Object
| Kind::Interface
| Kind::Union
| Kind::Enum
| Kind::InputObject
| Kind::Scalar => 40,
Kind::Directive => 30,
Kind::Field | Kind::InputField => 20,
Kind::EnumValue => 10,
}
}
}
impl FromStr for Kind {
type Err = anyhow::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(match s.to_lowercase().as_str() {
"object" | "objects" | "type" | "types" => Kind::Object,
"interface" | "interfaces" => Kind::Interface,
"union" | "unions" => Kind::Union,
"enum" | "enums" => Kind::Enum,
"input" | "input_object" | "input_objects" | "inputobject" => Kind::InputObject,
"scalar" | "scalars" => Kind::Scalar,
"directive" | "directives" => Kind::Directive,
"field" | "fields" => Kind::Field,
"input_field" | "input_fields" | "inputfield" => Kind::InputField,
"enum_value" | "enum_values" | "enumvalue" => Kind::EnumValue,
"query" | "queries" => Kind::Query,
"mutation" | "mutations" => Kind::Mutation,
"subscription" | "subscriptions" => Kind::Subscription,
other => anyhow::bail!(
"unknown kind {other:?} — valid: object, interface, union, enum, \
input_object, scalar, directive, field, input_field, enum_value, \
query, mutation, subscription (plurals ok)"
),
})
}
}
#[derive(Debug, Clone, Serialize)]
pub struct SchemaRecord {
pub path: String,
pub name: String,
pub kind: Kind,
#[serde(skip_serializing_if = "Option::is_none")]
pub parent: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub type_ref: Option<String>,
#[serde(skip_serializing_if = "Vec::is_empty")]
pub args: Vec<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub deprecated: Option<String>,
#[serde(skip_serializing_if = "Vec::is_empty")]
pub directives: Vec<String>,
}