nixfmt_rs 0.4.0

Rust implementation of nixfmt with exact Haskell compatibility
Documentation
//! `Dump` implementations for IR (intermediate representation) nodes

use super::{Dump, Writer, dump_list};
use crate::doc::{Doc, Elem, GroupKind, IR, Spacing, TextKind};
use crate::format_constructor;

impl Dump for Doc {
    fn dump<W: Writer>(&self, w: &mut W) {
        self.0.dump(w);
    }
    fn is_simple(&self) -> bool {
        self.0.is_simple()
    }
    fn has_delimiters(&self) -> bool {
        self.0.has_delimiters()
    }
    fn is_empty(&self) -> bool {
        self.0.is_empty()
    }
}

impl Dump for IR {
    fn dump<W: Writer>(&self, w: &mut W) {
        // Same layout as Vec<Elem>, but without bumping depth so the top-level
        // dump stays at column 0 like the Haskell reference output.
        dump_list(w, &self.0, false);
        if !self.0.is_empty() {
            // Final newline to match nixfmt output.
            w.newline();
        }
    }
}

impl Dump for Spacing {
    fn dump<W: Writer>(&self, w: &mut W) {
        crate::dump_enum!(self, w, {
            Newlines(n) => [n],
            Softbreak => [],
            Break => [],
            Hardspace => [],
            Softspace => [],
            Space => [],
            Hardline => [],
            Emptyline => [],
        });
    }

    fn is_simple(&self) -> bool {
        !matches!(self, Self::Newlines(_))
    }

    fn renders_inline_parens(&self) -> bool {
        matches!(self, Self::Newlines(_))
    }
}

impl Dump for GroupKind {
    fn dump<W: Writer>(&self, w: &mut W) {
        // Reference `nixfmt --ir` uses Haskell constructor names; preserve
        // them so the snapshot diffing against the reference stays exact.
        w.write_plain(match self {
            Self::Regular => "RegularG",
            Self::Priority => "Priority",
            Self::Transparent => "Transparent",
        });
    }

    fn is_simple(&self) -> bool {
        true
    }
}

impl Dump for TextKind {
    fn dump<W: Writer>(&self, w: &mut W) {
        w.write_plain(match self {
            Self::Regular => "RegularT",
            Self::Comment => "Comment",
            Self::TrailingComment => "TrailingComment",
            Self::Trailing => "Trailing",
        });
    }

    fn is_simple(&self) -> bool {
        true
    }
}

impl Dump for Elem {
    fn dump<W: Writer>(&self, w: &mut W) {
        crate::dump_enum!(self, w, {
            Text(nest, off, ann, text) => [nest, off, ann, text],
            Spacing(sp) => [sp],
            Group(ann, doc) => [ann, doc],
            Nest(n, o) => [n, o],
        });
    }

    fn is_simple(&self) -> bool {
        matches!(
            self,
            Self::Spacing(_) | Self::Text(_, _, _, _) | Self::Nest(..)
        )
    }
}