1use std::fmt;
2
3use crate::error::*;
4use crate::token::*;
5use crate::TokenSink;
6
7#[derive(Debug)]
9pub enum PrintError<DE: Error> {
10 Downstream(DE),
12
13 Print(std::io::Error),
15}
16
17impl<DE: Error> Error for PrintError<DE> {
18 fn invalid_token(token: Token<'_>, expected: Option<TokenTypes>) -> Self {
19 Self::Downstream(DE::invalid_token(token, expected))
20 }
21
22 fn invalid_field(field: &str) -> Self {
23 Self::Downstream(DE::invalid_field(field))
24 }
25
26 fn missing_fields(fields: &[&str]) -> Self {
27 Self::Downstream(DE::missing_fields(fields))
28 }
29
30 fn invalid_variant(variant: EnumVariant<'_>) -> Self {
31 Self::Downstream(DE::invalid_variant(variant))
32 }
33
34 fn unexpected_end(expected: Option<TokenTypes>) -> Self {
35 Self::Downstream(DE::unexpected_end(expected))
36 }
37}
38
39impl<DE: Error> fmt::Display for PrintError<DE> {
40 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
41 match self {
42 Self::Downstream(err) => fmt::Display::fmt(err, f),
43 Self::Print(err) => fmt::Display::fmt(err, f),
44 }
45 }
46}
47
48impl<DE: Error> std::error::Error for PrintError<DE> {}
49
50pub struct PrintingTokenSink<'a: 'b, 'b, S: TokenSink, W: std::io::Write> {
75 sink: &'b mut S,
76 prefix: &'a str,
77 writer: W,
78 indent: usize,
79}
80
81impl<'a: 'b, 'b, S: TokenSink, W: std::io::Write> PrintingTokenSink<'a, 'b, S, W> {
82 pub fn new(sink: &'b mut S, writer: W, prefix: &'a str) -> Self {
85 Self {
86 sink,
87 prefix,
88 writer,
89 indent: 0,
90 }
91 }
92
93 fn print_token(&mut self, token: &Token<'_>, indent: usize) -> std::io::Result<()> {
94 let prefix = self.prefix;
95
96 writeln!(
97 self.writer,
98 "{}{:indent$}{:?}",
99 prefix,
100 "",
101 token,
102 indent = 2 * indent
103 )?;
104
105 Ok(())
106 }
107}
108
109impl<'a: 'b, 'b, S: TokenSink, W: std::io::Write> TokenSink for PrintingTokenSink<'a, 'b, S, W> {
110 type Error = PrintError<S::Error>;
111
112 fn yield_token(&mut self, token: Token<'_>) -> Result<bool, Self::Error> {
113 if token.is_end() {
114 self.indent -= 1;
115 }
116
117 self.print_token(&token, self.indent)
118 .map_err(|err| PrintError::Print(err))?;
119
120 if token.is_start() {
121 self.indent += 1;
122 }
123
124 self.sink
125 .yield_token(token)
126 .map_err(|err| PrintError::Downstream(err))
127 }
128
129 fn expect_tokens(&mut self) -> Option<TokenTypes> {
130 self.sink.expect_tokens()
131 }
132}
133
134#[cfg(test)]
135mod tests {
136 use super::*;
137 use crate::into::*;
138 use crate::vec::*;
139
140 #[test]
141 fn test_printing_token_sink() {
142 let mut got = TokenVec::new();
143 let mut output = Vec::new();
144 vec![42u32]
145 .into_tokens(&mut PrintingTokenSink::new(&mut got, &mut output, "T: "))
146 .unwrap();
147 assert_eq!(
148 String::from_utf8(output).unwrap(),
149 "T: Seq(SeqMeta { size_hint: Some(1) })\nT: U32(42)\nT: EndSeq\n"
150 );
151 }
152}