117 lines
2.3 KiB
Rust
117 lines
2.3 KiB
Rust
use std::io::Write;
|
|
use std::marker::PhantomData;
|
|
|
|
use crate::syntax::*;
|
|
|
|
use crate::ser::error::Result;
|
|
use super::{Format, FormatEngine, FastRealFormat};
|
|
|
|
pub type DefaultPrettyFormat = PrettyFormat<TwoSpaces>;
|
|
|
|
pub trait IndentStyle {
|
|
const LEVEL: &'static [u8];
|
|
}
|
|
|
|
pub struct OneTab;
|
|
pub struct TwoSpaces;
|
|
pub struct FourSpaces;
|
|
|
|
impl IndentStyle for OneTab {
|
|
const LEVEL: &'static [u8] = &[
|
|
WHITESPACE_TAB_CHAR
|
|
];
|
|
}
|
|
|
|
impl IndentStyle for TwoSpaces {
|
|
const LEVEL: &'static [u8] = &[
|
|
WHITESPACE_SPACE_CHAR,
|
|
WHITESPACE_SPACE_CHAR
|
|
];
|
|
}
|
|
|
|
impl IndentStyle for FourSpaces {
|
|
const LEVEL: &'static [u8] = &[
|
|
WHITESPACE_SPACE_CHAR,
|
|
WHITESPACE_SPACE_CHAR,
|
|
WHITESPACE_SPACE_CHAR,
|
|
WHITESPACE_SPACE_CHAR
|
|
];
|
|
}
|
|
|
|
pub struct PrettyFormat<I: IndentStyle> {
|
|
indent_style: PhantomData<I>
|
|
}
|
|
|
|
impl<I: IndentStyle> PrettyFormat<I> {
|
|
fn style_before_write(e: &mut PrettyFormatEngine, w: &mut Write) -> Result<()> {
|
|
match e.delim {
|
|
DICT_END_CHAR | LIST_END_CHAR => {
|
|
e.level -= 1;
|
|
Self::write_newline(w)?;
|
|
Self::write_indentation(e, w)?;
|
|
},
|
|
_ => ()
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
fn style_after_write(e: &mut PrettyFormatEngine, w: &mut Write) -> Result<()> {
|
|
match e.delim {
|
|
DICT_START_CHAR | LIST_START_CHAR => {
|
|
e.level += 1;
|
|
Self::write_newline(w)?;
|
|
Self::write_indentation(e, w)?;
|
|
},
|
|
DICT_KV_SEPARATOR_CHAR => {
|
|
Self::write_space(w)?;
|
|
},
|
|
COMMA_CHAR => {
|
|
Self::write_newline(w)?;
|
|
Self::write_indentation(e, w)?;
|
|
},
|
|
_ => ()
|
|
}
|
|
e.delim = 0;
|
|
Ok(())
|
|
}
|
|
|
|
fn write_space(w: &mut Write) -> Result<()> {
|
|
w.write(&[WHITESPACE_SPACE_CHAR])?;
|
|
Ok(())
|
|
}
|
|
|
|
fn write_newline(w: &mut Write) -> Result<()> {
|
|
w.write(&[NEWLINE_LF_CHAR])?;
|
|
Ok(())
|
|
}
|
|
|
|
fn write_indentation(e: &mut PrettyFormatEngine, w: &mut Write) -> Result<()> {
|
|
for _ in 0..e.level {
|
|
w.write(I::LEVEL)?;
|
|
}
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
#[derive(Default)]
|
|
pub struct PrettyFormatEngine {
|
|
level: usize,
|
|
delim: u8
|
|
}
|
|
|
|
impl FormatEngine for PrettyFormatEngine {
|
|
fn mark_delim(&mut self, delim: u8) {
|
|
self.delim = delim;
|
|
}
|
|
}
|
|
|
|
impl<I: IndentStyle> Format for PrettyFormat<I> {
|
|
type Engine = PrettyFormatEngine;
|
|
type RealFormat = FastRealFormat;
|
|
|
|
fn write<W: Write>(e: &mut PrettyFormatEngine, w: &mut Write, bytes: &[u8]) -> Result<()> {
|
|
Self::style_before_write(e, w)?;
|
|
w.write(bytes)?;
|
|
Self::style_after_write(e, w)
|
|
}
|
|
} |