cynic-parser 0.11.1

A fast, correct and easy to use GraphQL parser
Documentation
use std::fmt::{self, Write};

use crate::{common::OperationType, executable::*, printing::indent::indented};

impl fmt::Display for ExecutableDocument {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        let use_short_form = {
            let mut operation_iter = self.operations();
            let first_op = operation_iter.next();
            match (first_op, operation_iter.next()) {
                (Some(first_op), None) => {
                    first_op.name().is_none()
                        && first_op.description().is_none()
                        && first_op.operation_type() == OperationType::Query
                        && first_op.directives().len() == 0
                        && first_op.variable_definitions().len() == 0
                }
                _ => false,
            }
        };

        for (i, definition) in self.definitions().enumerate() {
            if i != 0 {
                writeln!(f)?;
            }
            match definition {
                ExecutableDefinition::Operation(op) if use_short_form => {
                    write!(f, "{}", op.selection_set())?;
                }
                ExecutableDefinition::Operation(op) => {
                    write!(f, "{op}")?;
                }
                ExecutableDefinition::Fragment(fragment) => {
                    write!(f, "{fragment}")?;
                }
            }
        }

        Ok(())
    }
}

impl fmt::Display for OperationDefinition<'_> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        if let Some(description) = self.description() {
            write!(f, "{description}")?;
        }
        write!(f, "{}", self.operation_type())?;
        if let Some(name) = self.name() {
            write!(f, " {name}")?;
        }
        writeln!(
            f,
            "{}{} {}",
            self.variable_definitions(),
            self.directives(),
            self.selection_set()
        )
    }
}

impl fmt::Display for FragmentDefinition<'_> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        if let Some(description) = self.description() {
            write!(f, "{description}")?;
        }
        writeln!(
            f,
            "fragment {} on {}{} {}",
            self.name(),
            self.type_condition(),
            self.directives(),
            self.selection_set()
        )
    }
}

impl<'a> fmt::Display for iter::Iter<'a, VariableDefinition<'a>> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        if self.len() != 0 {
            write!(f, "(")?;
            for (i, definition) in self.clone().enumerate() {
                if i != 0 {
                    write!(f, ", ")?;
                }
                write!(f, "{definition}")?;
            }
            write!(f, ")")?;
        }
        Ok(())
    }
}

impl std::fmt::Display for VariableDefinition<'_> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        if let Some(description) = self.description() {
            write!(f, "\n{description}")?;
        }
        write!(f, "${}: {}", self.name(), self.ty())?;

        if let Some(default) = self.default_value() {
            write!(f, " = {}", default)?;
        }

        write!(f, "{}", self.directives())
    }
}

impl<'a> std::fmt::Display for iter::Iter<'a, Selection<'a>> {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        if self.len() != 0 {
            writeln!(f, "{{")?;
            for child in self.clone() {
                writeln!(indented(f, 2), "{}", child)?;
            }
            write!(f, "}}")?;
        }
        Ok(())
    }
}

impl fmt::Display for Selection<'_> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Selection::Field(field) => {
                write!(f, "{field}")
            }
            Selection::InlineFragment(fragment) => {
                write!(f, "{fragment}")
            }
            Selection::FragmentSpread(spread) => {
                write!(f, "{spread}")
            }
        }
    }
}

impl fmt::Display for FieldSelection<'_> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        if let Some(alias) = self.alias() {
            write!(f, "{}: ", alias)?;
        }

        let space = if self.selection_set().len() != 0 {
            " "
        } else {
            ""
        };

        write!(
            f,
            "{}{}{}{space}{}",
            self.name(),
            self.arguments(),
            self.directives(),
            self.selection_set()
        )
    }
}

impl fmt::Display for InlineFragment<'_> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "...")?;

        if let Some(on_type) = self.type_condition() {
            write!(f, " on {}", on_type)?;
        }

        write!(f, "{} {}", self.directives(), self.selection_set())
    }
}

impl fmt::Display for FragmentSpread<'_> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "... {}{}", self.fragment_name(), self.directives())
    }
}

impl<'a> fmt::Display for iter::Iter<'a, Directive<'a>> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        for directive in self.clone() {
            write!(f, " {directive}")?;
        }
        Ok(())
    }
}

impl fmt::Display for Directive<'_> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "@{}{}", self.name(), self.arguments())
    }
}

impl<'a> fmt::Display for iter::Iter<'a, Argument<'a>> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        if self.len() != 0 {
            write!(f, "(")?;
            for (i, arg) in self.clone().enumerate() {
                if i != 0 {
                    write!(f, ", ")?;
                }
                write!(f, "{}", arg)?;
            }
            write!(f, ")")?;
        }
        Ok(())
    }
}

impl fmt::Display for Argument<'_> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}: {}", self.name(), self.value())
    }
}

impl fmt::Display for Description<'_> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self.literal().kind() {
            crate::common::StringLiteralKind::String => {
                writeln!(f, "\"{}\"", self.literal().raw_untrimmed_str())
            }
            crate::common::StringLiteralKind::Block => {
                writeln!(f, "\"\"\"{}\"\"\"", self.literal().raw_untrimmed_str())
            }
        }
    }
}