musli/context/
same.rs

1use core::error::Error;
2use core::fmt;
3use core::marker::PhantomData;
4
5use crate::alloc::{self, Allocator, String};
6#[cfg(feature = "alloc")]
7use crate::alloc::{System, SYSTEM};
8#[cfg(test)]
9use crate::mode::Binary;
10use crate::Context;
11
12use super::ContextError;
13#[cfg(test)]
14use super::ErrorMarker;
15
16/// A simple non-diagnostical capturing context which simply emits the original
17/// error.
18///
19/// Using this should result in code which essentially just uses the emitted
20/// error type directly.
21pub struct Same<M, E, A>
22where
23    E: ContextError,
24{
25    alloc: A,
26    _marker: PhantomData<(M, E)>,
27}
28
29#[cfg(feature = "alloc")]
30#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
31impl<M, E> Same<M, E, &'static System>
32where
33    E: ContextError,
34{
35    /// Construct a new same-error context with a custom allocator.
36    pub fn new() -> Self {
37        Self::with_alloc(&SYSTEM)
38    }
39}
40
41impl<M, E, A> Same<M, E, A>
42where
43    E: ContextError,
44{
45    /// Construct a new `Same` context with a custom allocator.
46    pub fn with_alloc(alloc: A) -> Self {
47        Self {
48            alloc,
49            _marker: PhantomData,
50        }
51    }
52}
53
54#[cfg(test)]
55impl<A> Same<Binary, ErrorMarker, A> {
56    /// Construct a new `Same` capturing context.
57    pub(crate) fn with_marker(alloc: A) -> Self {
58        Self::with_alloc(alloc)
59    }
60}
61
62impl<M, E, A> Context for Same<M, E, A>
63where
64    A: Allocator,
65    M: 'static,
66    E: ContextError,
67{
68    type Mode = M;
69    type Error = E;
70    type Mark = ();
71    type Allocator = A;
72    type String<'this> = String<'this, A> where Self: 'this;
73
74    #[inline]
75    fn clear(&self) {}
76
77    #[inline]
78    fn alloc(&self) -> &Self::Allocator {
79        &self.alloc
80    }
81
82    #[inline]
83    fn collect_string<T>(&self, value: &T) -> Result<Self::String<'_>, Self::Error>
84    where
85        T: ?Sized + fmt::Display,
86    {
87        alloc::collect_string(self, value)
88    }
89
90    #[inline]
91    fn custom<T>(&self, message: T) -> Self::Error
92    where
93        T: 'static + Send + Sync + Error,
94    {
95        E::custom(message)
96    }
97
98    #[inline]
99    fn message<T>(&self, message: T) -> Self::Error
100    where
101        T: fmt::Display,
102    {
103        E::message(message)
104    }
105}
106
107#[cfg(feature = "alloc")]
108#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
109impl<M, E> Default for Same<M, E, &'static System>
110where
111    E: ContextError,
112{
113    #[inline]
114    fn default() -> Self {
115        Self::new()
116    }
117}