1use std::fmt;
2
3use crate::input::{Input, Rewind, ParserInfo};
4
5pub trait Debugger<I: Input> {
6 fn on_entry(&mut self, info: &ParserInfo);
7 fn on_exit(&mut self, info: &ParserInfo, ok: bool, ctxt: I::Context);
8}
9
10pub struct Options<I> {
11 pub stacked_context: bool,
12 pub debugger: Option<Box<dyn Debugger<I>>>,
13}
14
15impl<I> fmt::Debug for Options<I> {
16 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
17 f.debug_struct("Options")
18 .field("stacked_context", &self.stacked_context)
19 .field("debugger", &self.debugger.is_some())
20 .finish()
21 }
22}
23
24impl<I: Input> Default for Options<I> {
25 #[cfg(debug_assertions)]
26 fn default() -> Self {
27 Options {
28 stacked_context: true,
29 debugger: Some(Box::<crate::debug::TreeDebugger>::default()),
30 }
31 }
32
33 #[cfg(not(debug_assertions))]
34 fn default() -> Self {
35 Options {
36 stacked_context: false,
37 debugger: None,
38 }
39 }
40}
41
42#[derive(Debug)]
43pub struct Pear<I: Input> {
44 pub input: I,
45 #[doc(hidden)]
46 pub emit_error: bool,
47 #[doc(hidden)]
48 pub options: Options<I>
49}
50
51impl<I: Input> Pear<I> {
52 pub fn new<A>(input: A) -> Pear<I> where I: From<A> {
53 Pear::from(I::from(input))
54 }
55}
56
57impl<I: Input> From<I> for Pear<I> {
58 fn from(input: I) -> Pear<I> {
59 Pear { input, emit_error: true, options: Options::default() }
60 }
61}
62
63impl<I: Input> std::ops::Deref for Pear<I> {
64 type Target = I;
65 fn deref(&self) -> &Self::Target {
66 &self.input
67 }
68}
69
70impl<I: Input> std::ops::DerefMut for Pear<I> {
71 fn deref_mut(&mut self) -> &mut Self::Target {
72 &mut self.input
73 }
74}
75
76impl<I: Input> Input for Pear<I> {
77 type Token = I::Token;
78 type Slice = I::Slice;
79 type Many = I::Many;
80
81 type Marker = I::Marker;
82 type Context = I::Context;
83
84 #[inline(always)]
85 fn token(&mut self) -> Option<Self::Token> {
86 self.input.token()
87 }
88
89 #[inline(always)]
90 fn slice(&mut self, n: usize) -> Option<Self::Slice> {
91 self.input.slice(n)
92 }
93
94 #[inline(always)]
95 fn has(&mut self, n: usize) -> bool {
96 self.input.has(n)
97 }
98
99 #[inline(always)]
100 fn peek<F>(&mut self, cond: F) -> bool
101 where F: FnMut(&Self::Token) -> bool
102 {
103 self.input.peek(cond)
104 }
105
106 #[inline(always)]
107 fn peek_slice<F>(&mut self, n: usize, cond: F) -> bool
108 where F: FnMut(&Self::Slice) -> bool
109 {
110 self.input.peek_slice(n, cond)
111 }
112
113 #[inline(always)]
114 fn eat<F>(&mut self, cond: F) -> Option<Self::Token>
115 where F: FnMut(&Self::Token) -> bool
116 {
117 self.input.eat(cond)
118 }
119
120 #[inline(always)]
121 fn eat_slice<F>(&mut self, n: usize, cond: F) -> Option<Self::Slice>
122 where F: FnMut(&Self::Slice) -> bool
123 {
124 self.input.eat_slice(n, cond)
125 }
126
127 #[inline(always)]
128 fn take<F>(&mut self, cond: F) -> Self::Many
129 where F: FnMut(&Self::Token) -> bool
130 {
131 self.input.take(cond)
132 }
133
134 #[inline(always)]
135 fn skip<F>(&mut self, cond: F) -> usize
136 where F: FnMut(&Self::Token) -> bool
137 {
138 self.input.skip(cond)
139 }
140
141 #[inline(always)]
142 fn mark(&mut self, info: &ParserInfo) -> Self::Marker {
143 self.input.mark(info)
144 }
145
146 #[inline(always)]
147 fn context(&mut self, mark: Self::Marker) -> Self::Context {
148 self.input.context(mark)
149 }
150}
151
152impl<I: Input + Rewind> Rewind for Pear<I> {
153 fn rewind_to(&mut self, marker: Self::Marker) {
154 self.input.rewind_to(marker)
155 }
156}