1mod access;
2mod error_marker;
3mod rich_error;
4mod stack_context;
5#[cfg(feature = "alloc")]
6mod system_context;
7pub use self::error_marker::ErrorMarker;
8mod error;
9pub use self::error::Error;
10
11use core::cell::{Cell, UnsafeCell};
12use core::fmt;
13use core::marker::PhantomData;
14
15use musli::context::StdError;
16use musli::mode::DefaultMode;
17use musli::{Allocator, Context};
18
19use crate::buf::{self, BufString};
20
21#[cfg(feature = "alloc")]
22pub use self::system_context::SystemContext;
23
24pub use self::stack_context::StackContext;
25
26pub use self::rich_error::RichError;
27
28pub struct Same<A, M, E> {
34 alloc: A,
35 _marker: PhantomData<(M, E)>,
36}
37
38impl<A, M, E> Same<A, M, E> {
39 pub fn new(alloc: A) -> Self {
41 Self {
42 alloc,
43 _marker: PhantomData,
44 }
45 }
46}
47
48impl<A> Same<A, DefaultMode, ErrorMarker> {
49 #[inline]
51 #[doc(hidden)]
52 pub fn marker(alloc: A) -> Self {
53 Self::new(alloc)
54 }
55}
56
57impl<A, M, E> Default for Same<A, M, E>
58where
59 A: Default,
60{
61 #[inline]
62 fn default() -> Self {
63 Self {
64 alloc: A::default(),
65 _marker: PhantomData,
66 }
67 }
68}
69
70impl<A, M, E> Context for Same<A, M, E>
71where
72 A: Allocator,
73 E: Error,
74{
75 type Mode = M;
76 type Error = E;
77 type Mark = ();
78 type Buf<'this> = A::Buf<'this> where Self: 'this;
79 type BufString<'this> = BufString<A::Buf<'this>> where Self: 'this;
80
81 #[inline]
82 fn alloc(&self) -> Option<Self::Buf<'_>> {
83 self.alloc.alloc()
84 }
85
86 #[inline]
87 fn collect_string<T>(&self, value: &T) -> Result<Self::BufString<'_>, Self::Error>
88 where
89 T: ?Sized + fmt::Display,
90 {
91 buf::collect_string(self, value)
92 }
93
94 #[inline]
95 fn custom<T>(&self, message: T) -> Self::Error
96 where
97 T: 'static + Send + Sync + StdError,
98 {
99 E::custom(message)
100 }
101
102 #[inline]
103 fn message<T>(&self, message: T) -> Self::Error
104 where
105 T: fmt::Display,
106 {
107 E::message(message)
108 }
109}
110
111pub struct Ignore<A, M, E> {
114 alloc: A,
115 error: Cell<bool>,
116 _marker: PhantomData<(M, E)>,
117}
118
119impl<A, M, E> Default for Ignore<A, M, E>
120where
121 A: Default,
122{
123 #[inline]
124 fn default() -> Self {
125 Self {
126 alloc: A::default(),
127 error: Cell::new(false),
128 _marker: PhantomData,
129 }
130 }
131}
132
133impl<A, M, E> Ignore<A, M, E> {
134 pub fn new(alloc: A) -> Self {
136 Self {
137 alloc,
138 error: Cell::new(false),
139 _marker: PhantomData,
140 }
141 }
142}
143
144impl<A> Ignore<A, DefaultMode, ErrorMarker> {
145 #[doc(hidden)]
147 pub fn marker(alloc: A) -> Self {
148 Self::new(alloc)
149 }
150}
151
152impl<A, M, E> Ignore<A, M, E>
153where
154 E: Error,
155{
156 pub fn unwrap(self) -> E {
158 if self.error.get() {
159 return E::message("error");
160 }
161
162 panic!("did not error")
163 }
164}
165
166impl<A, M, E: 'static> Context for Ignore<A, M, E>
167where
168 A: Allocator,
169{
170 type Mode = M;
171 type Error = ErrorMarker;
172 type Mark = ();
173 type Buf<'this> = A::Buf<'this> where Self: 'this;
174 type BufString<'this> = BufString<A::Buf<'this>> where Self: 'this;
175
176 #[inline]
177 fn alloc(&self) -> Option<Self::Buf<'_>> {
178 self.alloc.alloc()
179 }
180
181 #[inline]
182 fn collect_string<T>(&self, value: &T) -> Result<Self::BufString<'_>, Self::Error>
183 where
184 T: ?Sized + fmt::Display,
185 {
186 buf::collect_string(self, value)
187 }
188
189 #[inline]
190 fn custom<T>(&self, _: T) -> ErrorMarker
191 where
192 T: 'static + Send + Sync + fmt::Display + fmt::Debug,
193 {
194 self.error.set(true);
195 ErrorMarker
196 }
197
198 #[inline]
199 fn message<T>(&self, _: T) -> ErrorMarker
200 where
201 T: fmt::Display,
202 {
203 self.error.set(true);
204 ErrorMarker
205 }
206}
207
208pub struct Capture<A, M, E> {
210 alloc: A,
211 error: UnsafeCell<Option<E>>,
212 _marker: PhantomData<M>,
213}
214
215impl<A, M, E> Capture<A, M, E> {
216 pub fn new(alloc: A) -> Self {
218 Self {
219 alloc,
220 error: UnsafeCell::new(None),
221 _marker: PhantomData,
222 }
223 }
224
225 pub fn unwrap(self) -> E {
227 if let Some(error) = self.error.into_inner() {
228 return error;
229 }
230
231 panic!("no error captured")
232 }
233}
234
235impl<A, M, E> Context for Capture<A, M, E>
236where
237 A: Allocator,
238 E: Error,
239{
240 type Mode = M;
241 type Error = ErrorMarker;
242 type Mark = ();
243 type Buf<'this> = A::Buf<'this> where Self: 'this;
244 type BufString<'this> = BufString<A::Buf<'this>> where Self: 'this;
245
246 #[inline]
247 fn alloc(&self) -> Option<Self::Buf<'_>> {
248 self.alloc.alloc()
249 }
250
251 #[inline]
252 fn collect_string<T>(&self, value: &T) -> Result<Self::BufString<'_>, Self::Error>
253 where
254 T: ?Sized + fmt::Display,
255 {
256 buf::collect_string(self, value)
257 }
258
259 #[inline]
260 fn custom<T>(&self, error: T) -> ErrorMarker
261 where
262 T: 'static + Send + Sync + StdError,
263 {
264 unsafe {
267 self.error.get().replace(Some(E::custom(error)));
268 }
269
270 ErrorMarker
271 }
272
273 #[inline]
274 fn message<T>(&self, message: T) -> ErrorMarker
275 where
276 T: fmt::Display,
277 {
278 unsafe {
281 self.error.get().replace(Some(E::message(message)));
282 }
283
284 ErrorMarker
285 }
286}
287
288impl<A, M, E> Default for Capture<A, M, E>
289where
290 A: Default,
291{
292 #[inline]
293 fn default() -> Self {
294 Self::new(A::default())
295 }
296}