Skip to content

Commit

Permalink
Add From extension AST to definition AST
Browse files Browse the repository at this point in the history
Summary:
I have a problem where I've got some generic functions to operate over SDL definitions. I define a trait, and implement that trait once per definition type.

By default, I need to *explicitly* define this trait for each type extension, too. But instead, I can have a helper function that takes in <Def: MyTrait + From<Ext>, Ext> and internally uses `Def::from(ext).my_trait_fn()`

By implementing the From trait, I can have a wrapper method that first converts my extensions to regular definitions, then operate on that. Which greatly reduces the likelihood that I make a copy-paste error.

Reviewed By: ginfung

Differential Revision: D48239949

fbshipit-source-id: 8f401bfb335ca3c2afe0a08c3bd6b69da8a927b6
  • Loading branch information
mjmahone authored and facebook-github-bot committed Aug 15, 2023
1 parent e0fb6f8 commit d4ca7d9
Showing 1 changed file with 108 additions and 0 deletions.
108 changes: 108 additions & 0 deletions compiler/crates/graphql-syntax/src/node/type_system.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use super::constant_value::StringNode;
use super::executable::OperationKind;
use super::primitive::*;
use super::type_annotation::TypeAnnotation;
use crate::TokenKind;

#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug)]
pub enum TypeSystemDefinition {
Expand Down Expand Up @@ -154,6 +155,18 @@ impl fmt::Display for TypeSystemDefinition {
}
}

/// This trait provides a *single* known into method, so we don't need
/// to type method usages that utilize this trait and call into_definition().
/// It may be useful in the future to define a DefinitionIntoExtension trait
/// that does the inverse, but we haven't needed it yet (add it when we do!).
pub trait ExtensionIntoDefinition: Sized {
type DefinitionType: From<Self>;

fn into_definition(self) -> Self::DefinitionType {
self.into()
}
}

#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug)]
pub struct SchemaDefinition {
pub directives: Vec<ConstantDirective>,
Expand All @@ -165,6 +178,28 @@ pub struct SchemaExtension {
pub directives: Vec<ConstantDirective>,
pub operation_types: Option<List<OperationTypeDefinition>>,
}
impl From<SchemaExtension> for SchemaDefinition {
fn from(ext: SchemaExtension) -> Self {
Self {
directives: ext.directives,
operation_types: ext.operation_types.unwrap_or(List {
span: Span::empty(),
start: Token {
span: Span::empty(),
kind: TokenKind::OpenBrace,
},
items: Vec::new(),
end: Token {
span: Span::empty(),
kind: TokenKind::CloseBrace,
},
}),
}
}
}
impl ExtensionIntoDefinition for SchemaExtension {
type DefinitionType = SchemaDefinition;
}

#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug)]
pub struct OperationTypeDefinition {
Expand Down Expand Up @@ -210,6 +245,19 @@ pub struct ObjectTypeExtension {
pub directives: Vec<ConstantDirective>,
pub fields: Option<List<FieldDefinition>>,
}
impl From<ObjectTypeExtension> for ObjectTypeDefinition {
fn from(ext: ObjectTypeExtension) -> Self {
Self {
name: ext.name,
interfaces: ext.interfaces,
directives: ext.directives,
fields: ext.fields,
}
}
}
impl ExtensionIntoDefinition for ObjectTypeExtension {
type DefinitionType = ObjectTypeDefinition;
}

#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug)]
pub struct InterfaceTypeDefinition {
Expand All @@ -226,6 +274,19 @@ pub struct InterfaceTypeExtension {
pub directives: Vec<ConstantDirective>,
pub fields: Option<List<FieldDefinition>>,
}
impl From<InterfaceTypeExtension> for InterfaceTypeDefinition {
fn from(ext: InterfaceTypeExtension) -> Self {
Self {
name: ext.name,
interfaces: ext.interfaces,
directives: ext.directives,
fields: ext.fields,
}
}
}
impl ExtensionIntoDefinition for InterfaceTypeExtension {
type DefinitionType = InterfaceTypeDefinition;
}

#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug)]
pub struct UnionTypeDefinition {
Expand All @@ -240,6 +301,18 @@ pub struct UnionTypeExtension {
pub directives: Vec<ConstantDirective>,
pub members: Vec<Identifier>,
}
impl From<UnionTypeExtension> for UnionTypeDefinition {
fn from(ext: UnionTypeExtension) -> Self {
Self {
name: ext.name,
directives: ext.directives,
members: ext.members,
}
}
}
impl ExtensionIntoDefinition for UnionTypeExtension {
type DefinitionType = UnionTypeDefinition;
}

#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug)]
pub struct ScalarTypeDefinition {
Expand All @@ -252,6 +325,17 @@ pub struct ScalarTypeExtension {
pub name: Identifier,
pub directives: Vec<ConstantDirective>,
}
impl From<ScalarTypeExtension> for ScalarTypeDefinition {
fn from(ext: ScalarTypeExtension) -> Self {
Self {
name: ext.name,
directives: ext.directives,
}
}
}
impl ExtensionIntoDefinition for ScalarTypeExtension {
type DefinitionType = ScalarTypeDefinition;
}

#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug)]
pub struct EnumTypeDefinition {
Expand All @@ -266,6 +350,18 @@ pub struct EnumTypeExtension {
pub directives: Vec<ConstantDirective>,
pub values: Option<List<EnumValueDefinition>>,
}
impl From<EnumTypeExtension> for EnumTypeDefinition {
fn from(ext: EnumTypeExtension) -> Self {
Self {
name: ext.name,
directives: ext.directives,
values: ext.values,
}
}
}
impl ExtensionIntoDefinition for EnumTypeExtension {
type DefinitionType = EnumTypeDefinition;
}

#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug)]
pub struct InputObjectTypeDefinition {
Expand All @@ -280,6 +376,18 @@ pub struct InputObjectTypeExtension {
pub directives: Vec<ConstantDirective>,
pub fields: Option<List<InputValueDefinition>>,
}
impl From<InputObjectTypeExtension> for InputObjectTypeDefinition {
fn from(ext: InputObjectTypeExtension) -> Self {
Self {
name: ext.name,
directives: ext.directives,
fields: ext.fields,
}
}
}
impl ExtensionIntoDefinition for InputObjectTypeExtension {
type DefinitionType = InputObjectTypeDefinition;
}

#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug)]
pub struct EnumValueDefinition {
Expand Down

0 comments on commit d4ca7d9

Please sign in to comment.