leo_ast/indent_display.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
// Copyright (C) 2019-2025 Provable Inc.
// This file is part of the Leo library.
// The Leo library is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// The Leo library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
use std::{fmt, fmt::Write};
/// Implements `Display` by putting 4 spaces in front of each line
/// of `T`'s output.
pub struct Indent<T>(pub T);
impl<T: fmt::Display> fmt::Display for Indent<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(IndentWriter { f, new_line: true }, "{}", self.0)
}
}
const SPACES: &str = " ";
struct IndentWriter<'a, 'b> {
new_line: bool,
f: &'b mut fmt::Formatter<'a>,
}
impl Write for IndentWriter<'_, '_> {
fn write_str(&mut self, s: &str) -> fmt::Result {
let mut iter = s.lines().peekable();
while let Some(line) = iter.next() {
if self.new_line {
self.f.write_str(SPACES)?;
}
self.f.write_str(line)?;
if iter.peek().is_some() || s.ends_with('\n') {
self.f.write_str("\n")?;
self.new_line = true;
} else {
self.new_line = false;
}
}
Ok(())
}
}