Skip to content

Added the ability to add newlines when formatting arguments #23

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 49 additions & 3 deletions src/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,14 @@ pub(crate) struct Formatter<'a> {
#[derive(Debug, PartialEq, Clone)]
pub struct Style {
indent: u32,
multiline_arguments: bool,
}

impl Default for Style {
fn default() -> Style {
Style {
indent: 2,
multiline_arguments: false,
}
}
}
Expand All @@ -34,6 +36,12 @@ impl Style {
self.indent = indent;
self
}

/// Set whether to add new lines between arguments
pub fn multiline_arguments(&mut self, multiline_arguments: bool) -> &mut Self {
self.multiline_arguments = multiline_arguments;
self
}
}

pub(crate) trait Displayable {
Expand All @@ -59,15 +67,44 @@ impl<'a> Formatter<'a> {
self.buf.push('\n');
}

pub fn start_argument_block(&mut self, open_char: char) {
self.buf.push(open_char);
if self.style.multiline_arguments {
self.inc_indent();
}
}

pub fn end_argument_block(&mut self, close_char: char) {
if self.style.multiline_arguments {
self.endline();
self.dec_indent();
self.indent();
}
self.buf.push(close_char);
}

pub fn start_argument(&mut self) {
if self.style.multiline_arguments {
self.endline();
self.indent();
}
}

pub fn deliniate_argument(&mut self) {
self.buf.push(',');
if !self.style.multiline_arguments {
self.buf.push(' ');
}
}

pub fn start_block(&mut self) {
self.buf.push('{');
self.endline();
self.indent += self.style.indent;
self.inc_indent();
}

pub fn end_block(&mut self) {
self.indent = self.indent.checked_sub(self.style.indent)
.expect("negative indent");
self.dec_indent();
self.indent();
self.buf.push('}');
self.endline();
Expand Down Expand Up @@ -128,6 +165,15 @@ impl<'a> Formatter<'a> {
self.buf.push_str(r#"""""#);
}
}

fn inc_indent(&mut self) {
self.indent += self.style.indent;
}

fn dec_indent(&mut self) {
self.indent = self.indent.checked_sub(self.style.indent)
.expect("negative indent");
}
}

pub(crate) fn format_directives<'a, T>(dirs: &[Directive<'a, T>], f: &mut Formatter)
Expand Down
75 changes: 41 additions & 34 deletions src/query/format.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
use std::fmt;

use crate::format::{Displayable, Formatter, Style, format_directives};
use crate::format::{format_directives, Displayable, Formatter, Style};

use crate::query::ast::*;


impl<'a, T: Text<'a>> Document<'a, T>
impl<'a, T: Text<'a>> Document<'a, T>
where T: Text<'a>,
{
/// Format a document according to style
Expand All @@ -23,7 +23,7 @@ fn to_string<T: Displayable>(v: &T) -> String {
formatter.into_string()
}

impl<'a, T: Text<'a>> Displayable for Document<'a, T>
impl<'a, T: Text<'a>> Displayable for Document<'a, T>
where T: Text<'a>,
{
fn display(&self, f: &mut Formatter) {
Expand All @@ -33,7 +33,7 @@ impl<'a, T: Text<'a>> Displayable for Document<'a, T>
}
}

impl<'a, T: Text<'a>> Displayable for Definition<'a, T>
impl<'a, T: Text<'a>> Displayable for Definition<'a, T>
where T: Text<'a>,
{
fn display(&self, f: &mut Formatter) {
Expand All @@ -44,7 +44,7 @@ impl<'a, T: Text<'a>> Displayable for Definition<'a, T>
}
}

impl<'a, T: Text<'a>> Displayable for OperationDefinition<'a, T>
impl<'a, T: Text<'a>> Displayable for OperationDefinition<'a, T>
where T: Text<'a>,
{
fn display(&self, f: &mut Formatter) {
Expand All @@ -57,7 +57,7 @@ impl<'a, T: Text<'a>> Displayable for OperationDefinition<'a, T>
}
}

impl<'a, T: Text<'a>> Displayable for FragmentDefinition<'a, T>
impl<'a, T: Text<'a>> Displayable for FragmentDefinition<'a, T>
where T: Text<'a>,
{
fn display(&self, f: &mut Formatter) {
Expand All @@ -77,7 +77,7 @@ impl<'a, T: Text<'a>> Displayable for FragmentDefinition<'a, T>
}
}

impl<'a, T: Text<'a>> Displayable for SelectionSet<'a, T>
impl<'a, T: Text<'a>> Displayable for SelectionSet<'a, T>
where T: Text<'a>,
{
fn display(&self, f: &mut Formatter) {
Expand All @@ -91,7 +91,7 @@ impl<'a, T: Text<'a>> Displayable for SelectionSet<'a, T>
}
}

impl<'a, T: Text<'a>> Displayable for Selection<'a, T>
impl<'a, T: Text<'a>> Displayable for Selection<'a, T>
where T: Text<'a>,
{
fn display(&self, f: &mut Formatter) {
Expand All @@ -103,25 +103,27 @@ impl<'a, T: Text<'a>> Displayable for Selection<'a, T>
}
}

fn format_arguments<'a, T: Text<'a>>(arguments: &[(T::Value, Value<'a, T>)], f: &mut Formatter)
fn format_arguments<'a, T: Text<'a>>(arguments: &[(T::Value, Value<'a, T>)], f: &mut Formatter)
where T: Text<'a>,
{
if !arguments.is_empty() {
f.write("(");
f.write(arguments[0].0.as_ref());
f.start_argument_block('(');
f.start_argument();
f.write(&arguments[0].0.as_ref());
f.write(": ");
arguments[0].1.display(f);
for arg in &arguments[1..] {
f.write(", ");
f.write(arg.0.as_ref());
f.deliniate_argument();
f.start_argument();
f.write(&arg.0.as_ref());
f.write(": ");
arg.1.display(f);
}
f.write(")");
f.end_argument_block(')');
}
}

impl<'a, T: Text<'a>> Displayable for Field<'a, T>
impl<'a, T: Text<'a>> Displayable for Field<'a, T>
where T: Text<'a>,
{
fn display(&self, f: &mut Formatter) {
Expand All @@ -146,7 +148,7 @@ impl<'a, T: Text<'a>> Displayable for Field<'a, T>
}
}

impl<'a, T: Text<'a>> Displayable for Query<'a, T>
impl<'a, T: Text<'a>> Displayable for Query<'a, T>
where T: Text<'a>,
{
fn display(&self, f: &mut Formatter) {
Expand Down Expand Up @@ -176,7 +178,7 @@ impl<'a, T: Text<'a>> Displayable for Query<'a, T>
}
}

impl<'a, T: Text<'a>> Displayable for Mutation<'a, T>
impl<'a, T: Text<'a>> Displayable for Mutation<'a, T>
where T: Text<'a>,
{
fn display(&self, f: &mut Formatter) {
Expand Down Expand Up @@ -206,7 +208,7 @@ impl<'a, T: Text<'a>> Displayable for Mutation<'a, T>
}
}

impl<'a, T: Text<'a>> Displayable for Subscription<'a, T>
impl<'a, T: Text<'a>> Displayable for Subscription<'a, T>
where T: Text<'a>,
{
fn display(&self, f: &mut Formatter) {
Expand Down Expand Up @@ -234,7 +236,7 @@ impl<'a, T: Text<'a>> Displayable for Subscription<'a, T>
}
}

impl<'a, T: Text<'a>> Displayable for VariableDefinition<'a, T>
impl<'a, T: Text<'a>> Displayable for VariableDefinition<'a, T>
where T: Text<'a>,
{
fn display(&self, f: &mut Formatter) {
Expand All @@ -249,7 +251,7 @@ impl<'a, T: Text<'a>> Displayable for VariableDefinition<'a, T>
}
}

impl<'a, T: Text<'a>> Displayable for Type<'a, T>
impl<'a, T: Text<'a>> Displayable for Type<'a, T>
where T: Text<'a>,
{
fn display(&self, f: &mut Formatter) {
Expand All @@ -268,12 +270,15 @@ impl<'a, T: Text<'a>> Displayable for Type<'a, T>
}
}

impl<'a, T: Text<'a>> Displayable for Value<'a, T>
impl<'a, T: Text<'a>> Displayable for Value<'a, T>
where T: Text<'a>,
{
fn display(&self, f: &mut Formatter) {
match *self {
Value::Variable(ref name) => { f.write("$"); f.write(name.as_ref()); },
Value::Variable(ref name) => {
f.write("$");
f.write(name.as_ref());
}
Value::Int(ref num) => f.write(&format!("{}", num.0)),
Value::Float(val) => f.write(&format!("{}", val)),
Value::String(ref val) => f.write_quoted(val),
Expand All @@ -282,36 +287,39 @@ impl<'a, T: Text<'a>> Displayable for Value<'a, T>
Value::Null => f.write("null"),
Value::Enum(ref name) => f.write(name.as_ref()),
Value::List(ref items) => {
f.write("[");
f.start_argument_block('[');
if !items.is_empty() {
f.start_argument();
items[0].display(f);
for item in &items[1..] {
f.write(", ");
f.deliniate_argument();
f.start_argument();
item.display(f);
}
}
f.write("]");
f.end_argument_block(']');
}
Value::Object(ref items) => {
f.write("{");
f.start_argument_block('{');
let mut first = true;
for (name, value) in items.iter() {
if first {
first = false;
} else {
f.write(", ");
f.deliniate_argument();
}
f.start_argument();
f.write(name.as_ref());
f.write(": ");
value.display(f);
}
f.write("}");
f.end_argument_block('}');
}
}
}
}

impl<'a, T: Text<'a>> Displayable for InlineFragment<'a, T>
impl<'a, T: Text<'a>> Displayable for InlineFragment<'a, T>
where T: Text<'a>,
{
fn display(&self, f: &mut Formatter) {
Expand All @@ -331,7 +339,7 @@ impl<'a, T: Text<'a>> Displayable for InlineFragment<'a, T>
}
}

impl<'a, T: Text<'a>> Displayable for TypeCondition<'a, T>
impl<'a, T: Text<'a>> Displayable for TypeCondition<'a, T>
where T: Text<'a>,
{
fn display(&self, f: &mut Formatter) {
Expand All @@ -344,7 +352,7 @@ impl<'a, T: Text<'a>> Displayable for TypeCondition<'a, T>
}
}

impl<'a, T: Text<'a>> Displayable for FragmentSpread<'a, T>
impl<'a, T: Text<'a>> Displayable for FragmentSpread<'a, T>
where T: Text<'a>,
{
fn display(&self, f: &mut Formatter) {
Expand All @@ -356,7 +364,7 @@ impl<'a, T: Text<'a>> Displayable for FragmentSpread<'a, T>
}
}

impl<'a, T: Text<'a>> Displayable for Directive<'a, T>
impl<'a, T: Text<'a>> Displayable for Directive<'a, T>
where T: Text<'a>,
{
fn display(&self, f: &mut Formatter) {
Expand All @@ -366,9 +374,8 @@ impl<'a, T: Text<'a>> Displayable for Directive<'a, T>
}
}


impl_display!(
'a
'a
Document,
Definition,
OperationDefinition,
Expand Down
9 changes: 9 additions & 0 deletions tests/queries/directive_args_multiline.graphql
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
query {
node @dir(
a: 1,
b: "2",
c: true,
d: false,
e: null
)
}
9 changes: 9 additions & 0 deletions tests/queries/query_arguments_multiline.graphql
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
query {
node(
id: 1
)
node(
id: 1,
one: 3
)
}
9 changes: 9 additions & 0 deletions tests/queries/query_array_argument_multiline.graphql
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
query {
node(
id: [
5,
6,
7
]
)
}
9 changes: 9 additions & 0 deletions tests/queries/query_object_argument_multiline.graphql
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
query {
node(
id: 1,
obj: {
key1: 123,
key2: 456
}
)
}
Loading