Skip to content

Commit

Permalink
feat: directives in generics
Browse files Browse the repository at this point in the history
  • Loading branch information
gabotechs committed Nov 8, 2022
1 parent 99c9d9b commit db06e09
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 5 deletions.
33 changes: 30 additions & 3 deletions graphqxl_parser/src/ast_generic_block_def.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
use pest::iterators::Pair;

use crate::ast_description::{parse_description_and_continue, DescriptionAndNext};
use crate::ast_directive::parse_directive;
use crate::parser::Rule;
use crate::utils::unknown_rule_error;
use crate::{
parse_generic_call, parse_identifier, BlockDefType, GenericCall, Identifier, OwnedSpan,
ValueType,
parse_generic_call, parse_identifier, BlockDefType, Directive, GenericCall, Identifier,
OwnedSpan, ValueType,
};

#[derive(Debug, Clone, PartialEq)]
Expand All @@ -14,6 +15,7 @@ pub struct GenericBlockDef {
pub description: String,
pub kind: BlockDefType,
pub name: Identifier,
pub directives: Vec<Directive>,
pub block_def: Identifier,
pub generic_call: GenericCall,
}
Expand All @@ -23,6 +25,7 @@ impl GenericBlockDef {
GenericBlockDef {
kind,
description: "".to_string(),
directives: vec![],
span: OwnedSpan::default(),
name: Identifier::from(name),
block_def: Identifier::from(block_def),
Expand All @@ -47,6 +50,11 @@ impl GenericBlockDef {
self.generic_call.arg(arg);
self.clone()
}

pub fn directive(&mut self, directive: Directive) -> Self {
self.directives.push(directive);
self.clone()
}
}

fn _parse_generic_block_def(
Expand All @@ -58,13 +66,20 @@ fn _parse_generic_block_def(
let mut childs = pair.into_inner();
let DescriptionAndNext(description, next) = parse_description_and_continue(&mut childs, file);
let name = parse_identifier(next, file)?;
let block_def = parse_identifier(childs.next().unwrap(), file)?;
let mut directives = vec![];
let mut child = childs.next().unwrap();
while let Rule::directive = &child.as_rule() {
directives.push(parse_directive(child.clone(), file)?);
child = childs.next().unwrap();
}
let block_def = parse_identifier(child, file)?;
let generic_call = parse_generic_call(childs.next().unwrap(), file)?;

Ok(GenericBlockDef {
kind,
description,
span,
directives,
name,
block_def,
generic_call,
Expand Down Expand Up @@ -123,6 +138,18 @@ mod tests {
)
}

#[test]
fn test_parses_generic_type_def_with_description_and_directive() {
assert_eq!(
parse_input("\"description\"type MyType @dir = OtherType<String>"),
Ok(
GenericBlockDef::type_def("MyType", "OtherType", ValueType::string(),)
.description("description")
.directive(Directive::build("dir"))
)
)
}

#[test]
fn test_parses_generic_input_def_with_two_args() {
assert_eq!(
Expand Down
4 changes: 2 additions & 2 deletions graphqxl_parser/src/grammar.pest
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ schema_def = { description? ~ "schema" ~ schema_selection_set }
schema_key = @{ "query" | "mutation" | "subscription" }
schema_selection_set = { "{" ~ schema_field+ ~ "}"}
schema_field = { schema_key ~ ":" ~ identifier }
generic_type_def = { description? ~ "type " ~ identifier ~ "=" ~ identifier ~ generic_call }
generic_type_def = { description? ~ "type " ~ identifier ~ directive* ~ "=" ~ identifier ~ generic_call }
type_def = { description? ~ "type " ~ identifier ~ generic? ~ implements? ~ directive* ~ type_selection_set }
implements = { "implements" ~ identifier ~ ("&" ~ identifier)* }
type_selection_set = { "{" ~ (field_with_args | spread_reference)* ~ "}" }
generic_input_def = { "input " ~ identifier ~ "=" ~ identifier ~ generic_call }
generic_input_def = { description? ~ "input " ~ identifier ~ directive* ~ "=" ~ identifier ~ generic_call }
input_def = { description? ~ "input " ~ identifier ~ generic? ~ directive* ~ input_selection_set }
input_selection_set = { "{" ~ (field_without_args | spread_reference)* ~ "}" }
enum_def = { description? ~ "enum " ~ identifier ~ directive* ~ enum_selection_set }
Expand Down
3 changes: 3 additions & 0 deletions graphqxl_transpiler/src/transpile_generic_block_def.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ fn resolve_block_def(
let mut resolved_block_def = unresolved_block_def.clone();
resolved_block_def.generic = None;
resolved_block_def.name = generic_block_def.name.clone();
resolved_block_def
.directives
.extend(generic_block_def.directives.clone());

let mut description_replacements = HashMap::from([
(BLOCK_NAME.to_string(), generic_block_def.name.id.clone()),
Expand Down
11 changes: 11 additions & 0 deletions src/test/generics.graphqxl
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
directive @dir on OBJECT
directive @dir2 on OBJECT
directive @dir3 on OBJECT

type Generic<T U> @dir @dir2 {
t: T
u: U
}

"description"
type Concrete @dir3 = Generic<String Int>
13 changes: 13 additions & 0 deletions src/test/generics.graphqxl.result
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
directive @dir on OBJECT

directive @dir2 on OBJECT

directive @dir3 on OBJECT

"description"
type Concrete @dir @dir2 @dir3 {
t: String
u: Int
}


0 comments on commit db06e09

Please sign in to comment.