1use crate::{error::ErrorChain, Asn1DerError};
2use core::{iter, slice};
3
4pub trait Source: Sized {
6 fn read(&mut self) -> Result<u8, Asn1DerError>;
8
9 #[cfg_attr(feature = "no_panic", no_panic::no_panic)]
11 fn counting_source(self, ctr: &mut usize) -> CountingSource<Self> {
12 CountingSource { source: self, ctr }
13 }
14 #[cfg_attr(feature = "no_panic", no_panic::no_panic)]
16 fn copying_source<U: Sink>(self, sink: U) -> CopyingSource<Self, U> {
17 CopyingSource { source: self, sink }
18 }
19}
20impl<S: Source> Source for &mut S {
21 #[cfg_attr(feature = "no_panic", no_panic::no_panic)]
22 fn read(&mut self) -> Result<u8, Asn1DerError> {
23 (*self).read()
24 }
25}
26impl<'a> Source for slice::Iter<'a, u8> {
27 #[cfg_attr(feature = "no_panic", no_panic::no_panic)]
28 fn read(&mut self) -> Result<u8, Asn1DerError> {
29 match self.next() {
30 Some(e) => Ok(*e),
31 None => Err(eio!("Cannot read beyond end of slice-iterator")),
32 }
33 }
34}
35impl<'a, A: Iterator<Item = &'a u8>, B: Iterator<Item = &'a u8>> Source for iter::Chain<A, B> {
36 #[cfg_attr(feature = "no_panic", no_panic::no_panic)]
37 fn read(&mut self) -> Result<u8, Asn1DerError> {
38 match self.next() {
39 Some(e) => Ok(*e),
40 None => Err(eio!("Cannot read beyond end of chain-iterator")),
41 }
42 }
43}
44impl<'a, I: Iterator<Item = &'a u8> + 'a> Source for iter::Skip<I> {
45 #[cfg_attr(feature = "no_panic", no_panic::no_panic)]
46 fn read(&mut self) -> Result<u8, Asn1DerError> {
47 match self.next() {
48 Some(e) => Ok(*e),
49 None => Err(eio!("Cannot read beyond end of chain-iterator")),
50 }
51 }
52}
53
54pub struct CountingSource<'a, S: Source> {
60 source: S,
61 ctr: &'a mut usize,
62}
63impl<'a, S: Source> Source for CountingSource<'a, S> {
64 #[cfg_attr(feature = "no_panic", no_panic::no_panic)]
65 fn read(&mut self) -> Result<u8, Asn1DerError> {
66 let e = self.source.read().propagate(e!("Failed to read element from underlying source"))?;
67 match self.ctr.checked_add(1) {
68 Some(ctr_next) => {
69 *self.ctr = ctr_next;
70 Ok(e)
71 }
72 _ => Err(eio!("Cannot read more because the position counter would overflow")),
73 }
74 }
75}
76
77pub struct CopyingSource<S: Source, U: Sink> {
82 source: S,
83 sink: U,
84}
85impl<S: Source, U: Sink> CopyingSource<S, U> {
86 #[cfg_attr(feature = "no_panic", no_panic::no_panic)]
88 pub fn copy_next(&mut self) -> Result<(), Asn1DerError> {
89 self.read()?;
90 Ok(())
91 }
92 #[cfg_attr(feature = "no_panic", no_panic::no_panic)]
94 pub fn copy_n(&mut self, n: usize) -> Result<(), Asn1DerError> {
95 (0..n).try_for_each(|_| self.copy_next())
96 }
97}
98impl<S: Source, U: Sink> Source for CopyingSource<S, U> {
99 #[cfg_attr(feature = "no_panic", no_panic::no_panic)]
100 fn read(&mut self) -> Result<u8, Asn1DerError> {
101 let e = self.source.read().propagate(e!("Failed to read element from underlying source"))?;
102 self.sink.write(e).propagate(e!("Failed to copy element to sink"))?;
103 Ok(e)
104 }
105}
106
107pub trait Sink: Sized {
109 fn write(&mut self, e: u8) -> Result<(), Asn1DerError>;
111 #[cfg_attr(feature = "no_panic", no_panic::no_panic)]
113 fn counting_sink(self, ctr: &mut usize) -> CountingSink<Self> {
114 CountingSink { sink: self, ctr }
115 }
116}
117impl<S: Sink> Sink for &mut S {
118 #[cfg_attr(feature = "no_panic", no_panic::no_panic)]
119 fn write(&mut self, e: u8) -> Result<(), Asn1DerError> {
120 (*self).write(e)
121 }
122}
123impl<'a> Sink for slice::IterMut<'a, u8> {
124 #[cfg_attr(feature = "no_panic", no_panic::no_panic)]
125 fn write(&mut self, e: u8) -> Result<(), Asn1DerError> {
126 match self.next() {
127 Some(t) => {
128 *t = e;
129 Ok(())
130 }
131 None => Err(eio!("Cannot write beyond end of slice-iterator")),
132 }
133 }
134}
135#[cfg(all(feature = "std", not(feature = "no_panic")))]
136impl Sink for Vec<u8> {
137 fn write(&mut self, e: u8) -> Result<(), Asn1DerError> {
138 self.push(e);
139 Ok(())
140 }
141}
142
143pub struct CountingSink<'a, S: Sink> {
148 sink: S,
149 ctr: &'a mut usize,
150}
151impl<'a, S: Sink> Sink for CountingSink<'a, S> {
152 #[cfg_attr(feature = "no_panic", no_panic::no_panic)]
153 fn write(&mut self, e: u8) -> Result<(), Asn1DerError> {
154 self.sink.write(e).propagate(e!("Failed to write element to underlying source"))?;
155 *self.ctr = match self.ctr.checked_add(1) {
156 Some(ctr_next) => ctr_next,
157 None => Err(eio!("Cannot write more because the position counter would overflow"))?,
158 };
159 Ok(())
160 }
161}
162
163pub struct SliceSink<'a> {
165 slice: &'a mut [u8],
166 pos: &'a mut usize,
167}
168impl<'a> SliceSink<'a> {
169 #[cfg_attr(feature = "no_panic", no_panic::no_panic)]
171 pub fn new(slice: &'a mut [u8], pos: &'a mut usize) -> Self {
172 Self { slice, pos }
173 }
174}
175impl<'a> Sink for SliceSink<'a> {
176 #[cfg_attr(feature = "no_panic", no_panic::no_panic)]
177 fn write(&mut self, e: u8) -> Result<(), Asn1DerError> {
178 match self.slice.get_mut(*self.pos) {
179 Some(t) => match self.pos.checked_add(1) {
180 Some(pos_next) => {
181 *self.pos = pos_next;
182 *t = e;
183 Ok(())
184 }
185 None => Err(eio!("Cannot write more because the position counter would overflow"))?,
186 },
187 None => Err(eio!("Cannot write beyond the end-of-slice"))?,
188 }
189 }
190}
191impl<'a> From<SliceSink<'a>> for &'a [u8] {
192 #[cfg_attr(feature = "no_panic", no_panic::no_panic)]
193 fn from(sink: SliceSink<'a>) -> Self {
194 match sink.slice.len() {
195 len if *sink.pos < len => &sink.slice[..*sink.pos],
196 _ => sink.slice,
197 }
198 }
199}
200
201#[cfg(all(feature = "std", not(feature = "no_panic")))]
203pub struct VecBacking<'a>(pub &'a mut Vec<u8>);
204#[cfg(all(feature = "std", not(feature = "no_panic")))]
205impl<'a> Sink for VecBacking<'a> {
206 fn write(&mut self, e: u8) -> Result<(), Asn1DerError> {
207 self.0.push(e);
208 Ok(())
209 }
210}
211#[cfg(all(feature = "std", not(feature = "no_panic")))]
212impl<'a> From<VecBacking<'a>> for &'a [u8] {
213 fn from(backing: VecBacking<'a>) -> &'a [u8] {
214 backing.0.as_slice()
215 }
216}