From d4ca7d919d041190ef25143b0a1fc634d4995581 Mon Sep 17 00:00:00 2001 From: Matt Mahoney Date: Mon, 14 Aug 2023 21:10:24 -0700 Subject: [PATCH] Add From extension AST to definition AST 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 , 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 --- .../graphql-syntax/src/node/type_system.rs | 108 ++++++++++++++++++ 1 file changed, 108 insertions(+) diff --git a/compiler/crates/graphql-syntax/src/node/type_system.rs b/compiler/crates/graphql-syntax/src/node/type_system.rs index bfe0332181e52..585c8a30bcb23 100644 --- a/compiler/crates/graphql-syntax/src/node/type_system.rs +++ b/compiler/crates/graphql-syntax/src/node/type_system.rs @@ -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 { @@ -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; + + fn into_definition(self) -> Self::DefinitionType { + self.into() + } +} + #[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug)] pub struct SchemaDefinition { pub directives: Vec, @@ -165,6 +178,28 @@ pub struct SchemaExtension { pub directives: Vec, pub operation_types: Option>, } +impl From 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 { @@ -210,6 +245,19 @@ pub struct ObjectTypeExtension { pub directives: Vec, pub fields: Option>, } +impl From 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 { @@ -226,6 +274,19 @@ pub struct InterfaceTypeExtension { pub directives: Vec, pub fields: Option>, } +impl From 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 { @@ -240,6 +301,18 @@ pub struct UnionTypeExtension { pub directives: Vec, pub members: Vec, } +impl From 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 { @@ -252,6 +325,17 @@ pub struct ScalarTypeExtension { pub name: Identifier, pub directives: Vec, } +impl From 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 { @@ -266,6 +350,18 @@ pub struct EnumTypeExtension { pub directives: Vec, pub values: Option>, } +impl From 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 { @@ -280,6 +376,18 @@ pub struct InputObjectTypeExtension { pub directives: Vec, pub fields: Option>, } +impl From 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 {