1use super::*;
7
8use alloc::borrow::Cow;
9use core::panic::Location;
10
11#[allow(dead_code)]
13pub struct ParserInfo {
14 name: Cow<'static, str>,
15 display: Rc<dyn fmt::Display>,
16 location: Location<'static>,
17}
18
19impl ParserInfo {
20 pub(crate) fn new(
21 name: impl Into<Cow<'static, str>>,
22 display: Rc<dyn fmt::Display>,
23 location: Location<'static>,
24 ) -> Self {
25 Self {
26 name: name.into(),
27 display,
28 location,
29 }
30 }
31}
32
33pub enum ParseEvent {
35 Info(String),
37}
38
39#[deprecated(
41 note = "This trait is excluded from the semver guarantees of chumsky. If you decide to use it, broken builds are your fault."
42)]
43pub trait Debugger {
44 fn scope<R, Info: FnOnce() -> ParserInfo, F: FnOnce(&mut Self) -> R>(
46 &mut self,
47 info: Info,
48 f: F,
49 ) -> R;
50 fn emit_with<F: FnOnce() -> ParseEvent>(&mut self, f: F);
52 fn invoke<I: Clone, O, P: Parser<I, O> + ?Sized>(
54 &mut self,
55 parser: &P,
56 stream: &mut StreamOf<I, P::Error>,
57 ) -> PResult<I, O, P::Error>;
58}
59
60pub struct Verbose {
62 events: Vec<Result<ParseEvent, (ParserInfo, Self)>>,
64}
65
66impl Verbose {
67 pub(crate) fn new() -> Self {
68 Self { events: Vec::new() }
69 }
70
71 #[allow(unused_variables)]
72 fn print_inner(&self, depth: usize) {
73 #[cfg(feature = "std")]
75 for event in &self.events {
76 for _ in 0..depth * 4 {
77 print!(" ");
78 }
79 match event {
80 Ok(ParseEvent::Info(s)) => println!("{}", s),
81 Err((info, scope)) => {
82 println!(
83 "Entered {} at line {} in {}",
84 info.display,
85 info.location.line(),
86 info.location.file()
87 );
88 scope.print_inner(depth + 1);
89 }
90 }
91 }
92 }
93
94 pub(crate) fn print(&self) {
95 self.print_inner(0)
96 }
97}
98
99impl Debugger for Verbose {
100 fn scope<R, Info: FnOnce() -> ParserInfo, F: FnOnce(&mut Self) -> R>(
101 &mut self,
102 info: Info,
103 f: F,
104 ) -> R {
105 let mut verbose = Verbose { events: Vec::new() };
106 let res = f(&mut verbose);
107 self.events.push(Err((info(), verbose)));
108 res
109 }
110
111 fn emit_with<F: FnOnce() -> ParseEvent>(&mut self, f: F) {
112 self.events.push(Ok(f()));
113 }
114
115 fn invoke<I: Clone, O, P: Parser<I, O> + ?Sized>(
116 &mut self,
117 parser: &P,
118 stream: &mut StreamOf<I, P::Error>,
119 ) -> PResult<I, O, P::Error> {
120 parser.parse_inner_verbose(self, stream)
121 }
122}
123
124pub struct Silent {
126 phantom: PhantomData<()>,
127}
128
129impl Silent {
130 pub(crate) fn new() -> Self {
131 Self {
132 phantom: PhantomData,
133 }
134 }
135}
136
137impl Debugger for Silent {
138 fn scope<R, Info: FnOnce() -> ParserInfo, F: FnOnce(&mut Self) -> R>(
139 &mut self,
140 _: Info,
141 f: F,
142 ) -> R {
143 f(self)
144 }
145 fn emit_with<F: FnOnce() -> ParseEvent>(&mut self, _: F) {}
146
147 fn invoke<I: Clone, O, P: Parser<I, O> + ?Sized>(
148 &mut self,
149 parser: &P,
150 stream: &mut StreamOf<I, P::Error>,
151 ) -> PResult<I, O, P::Error> {
152 parser.parse_inner_silent(self, stream)
153 }
154}