bcder/encode/
values.rs

1//! Everything related to the `Values` trait.
2//!
3//! This is an internal module. Its public types are re-exported by the
4//! parent.
5
6use std::io;
7use std::marker::PhantomData;
8use crate::captured::Captured;
9use crate::length::Length;
10use crate::mode::Mode;
11use crate::tag::Tag;
12
13
14//------------ Values --------------------------------------------------------
15
16/// A type that is a value encoder.
17///
18/// Value encoders know how to encode themselves into a
19/// sequence of BER encoded values. While you can impl this trait for your
20/// type manually, in practice it is often easier to define a method called
21/// `encode` and let it return some dedicated value encoder type constructed
22/// from the types provided by this module.
23///
24/// A type implementing this trait should encodes itself into one or more
25/// BER values. That is, the type becomes the content or part of the content
26/// of a constructed value.
27pub trait Values {
28    /// Returns the length of the encoded values for the given mode.
29    fn encoded_len(&self, mode: Mode) -> usize;
30
31    /// Encodes the values in the given mode and writes them to `target`.
32    fn write_encoded<W: io::Write>(
33        &self,
34        mode: Mode,
35        target: &mut W
36    ) -> Result<(), io::Error>;
37
38
39    //--- Provided methods
40
41    /// Converts the encoder into one with an explicit tag.
42    fn explicit(self, tag: Tag) -> Constructed<Self>
43    where Self: Sized {
44        Constructed::new(tag, self)
45    }
46
47    /// Captures the encoded values in the given mode.
48    fn to_captured(&self, mode: Mode) -> Captured {
49        let mut target = Vec::new();
50        self.write_encoded(mode, &mut target).unwrap();
51        Captured::new(target.into(), mode, Default::default())
52    }
53}
54
55
56//--- Blanket impls
57
58impl<T: Values> Values for &'_ T {
59    fn encoded_len(&self, mode: Mode) -> usize {
60        (*self).encoded_len(mode)
61    }
62
63    fn write_encoded<W: io::Write>(
64        &self,
65        mode: Mode,
66        target: &mut W
67    ) -> Result<(), io::Error> {
68        (*self).write_encoded(mode, target)
69    }
70}
71
72
73//--- Impls for Tuples
74
75/// Macro for implementing `Values` for tuples.
76///
77/// This macro implements `Values` for all tuples up to a certain degree.
78/// It needs to be invoked as below. All the `Tx`s are the type parameters
79/// of the elements the tuple, the numbers are the tuple element numbers.
80/// The number need to be provided backwards ending in 0.
81///
82/// The `tuple` bit of the macro does the actual impl and invokes itself with
83/// one less tuple element. The `write` bit below is to implement
84/// `write_encoded` backwards (i.e., starting with the smallest number).
85macro_rules! tupl_impl {
86    // Termination: empty lists, do nothing.
87    ( tuple > ) => { };
88
89    // Impl values for the complete lists, then recurse to the lists without
90    // their heads.
91    ( tuple $t:ident $( $ttail:ident )* > $i:tt $( $itail:tt )* ) => {
92        impl<$t: Values, $( $ttail: Values ),*> Values
93                for ($t, $( $ttail ),*) {
94            fn encoded_len(&self, mode: Mode) -> usize {
95                self.$i.encoded_len(mode)
96                $(
97                    + self.$itail.encoded_len(mode)
98                )*
99            }
100
101            fn write_encoded<W: io::Write>(
102                &self,
103                mode: Mode,
104                target: &mut W
105            ) -> Result<(), io::Error> {
106                tupl_impl!( write self, mode, target, $i $( $itail )* );
107                Ok(())
108            }
109        }
110
111        tupl_impl!(
112             tuple $($ttail)* > $($itail)*
113        );
114    };
115
116    // Termination: empty lists, do nothing.
117    ( write $self:expr, $mode:expr, $target:expr, ) => { };
118
119    // Write all elements of tuple $self in mode $mode to $target in order.
120    ( write $self:expr, $mode:expr, $target:expr, $i:tt $($itail:tt)*) => {
121        tupl_impl!( write $self, $mode, $target, $($itail)* );
122        $self.$i.write_encoded($mode, $target)?
123    }
124}
125
126// The standard library implements things for tuples up to twelve elements,
127// so we do the same.
128tupl_impl!(
129    tuple T11 T10 T9 T8 T7 T6 T5 T4 T3 T2 T1 T0 > 11 10 9 8 7 6 5 4 3 2 1 0
130);
131
132
133//--- Impl for Option
134
135/// Encoding of an optional value.
136///
137/// This implementation encodes `None` as nothing, i.e., as an OPTIONAL
138/// in ASN.1 parlance.
139impl<V: Values> Values for Option<V> {
140    fn encoded_len(&self, mode: Mode) -> usize {
141        match self {
142            Some(v) => v.encoded_len(mode),
143            None => 0
144        }
145    }
146
147    fn write_encoded<W: io::Write>(
148        &self,
149        mode: Mode,
150        target: &mut W
151    ) -> Result<(), io::Error> {
152        match self {
153            Some(v) => v.write_encoded(mode, target),
154            None => Ok(())
155        }
156    }
157}
158
159
160//--- Impl for slice and Vec
161
162impl<V: Values> Values for [V] {
163    fn encoded_len(&self, mode: Mode) -> usize {
164        self.iter().map(|v| v.encoded_len(mode)).sum()
165    }
166
167    fn write_encoded<W: io::Write>(&self, mode: Mode, target: &mut W)
168        -> Result<(), io::Error>
169    {
170        for i in self {
171            i.write_encoded(mode, target)?;
172        };
173        Ok(())
174    }
175}
176
177impl<V: Values> Values for Vec<V> {
178    fn encoded_len(&self, mode: Mode) -> usize {
179        self.iter().map(|v| v.encoded_len(mode)).sum()
180    }
181
182    fn write_encoded<W: io::Write>(&self, mode: Mode, target: &mut W)
183        -> Result<(), io::Error>
184    {
185        for i in self {
186            i.write_encoded(mode, target)?;
187        };
188        Ok(())
189    }
190}
191
192
193//------------ Constructed ---------------------------------------------------
194
195/// A value encoder for a single constructed value.
196pub struct Constructed<V> {
197    /// The tag of the value.
198    tag: Tag,
199
200    /// A value encoder for the content of the value.
201    inner: V,
202}
203
204impl<V> Constructed<V> {
205    /// Creates a new constructed value encoder from a tag and content.
206    ///
207    /// The returned value will encode as a single constructed value with
208    /// the given tag and whatever `inner` encodeds to as its content.
209    pub fn new(tag: Tag, inner: V) -> Self {
210        Constructed { tag, inner }
211    }
212}
213
214impl<V: Values> Values for Constructed<V> {
215    fn encoded_len(&self, mode: Mode) -> usize {
216        let len = self.inner.encoded_len(mode);
217        let len = len + match mode {
218            Mode::Ber | Mode::Der => {
219                Length::Definite(len).encoded_len()
220            }
221            Mode::Cer => {
222                Length::Indefinite.encoded_len()
223                + EndOfValue.encoded_len(mode)
224            }
225        };
226        self.tag.encoded_len() + len
227    }
228
229    fn write_encoded<W: io::Write>(
230        &self,
231        mode: Mode,
232        target: &mut W
233    ) -> Result<(), io::Error> {
234        self.tag.write_encoded(true, target)?;
235        match mode {
236            Mode::Ber | Mode::Der => {
237                Length::Definite(self.inner.encoded_len(mode))
238                    .write_encoded(target)?;
239                self.inner.write_encoded(mode, target)
240            }
241            Mode::Cer => {
242                Length::Indefinite.write_encoded(target)?;
243                self.inner.write_encoded(mode, target)?;
244                EndOfValue.write_encoded(mode, target)
245            }
246        }
247    }
248}
249
250
251//------------ Choice2 -------------------------------------------------------
252
253/// A value encoder for a two-variant enum.
254///
255/// Instead of implementing `Values` for an enum manually, you can just
256/// define a method `encode` that returns a value of this type.
257pub enum Choice2<L, R> {
258    /// The first choice.
259    One(L),
260
261    /// The second choice.
262    Two(R)
263}
264
265impl<L: Values, R: Values> Values for Choice2<L, R> {
266    fn encoded_len(&self, mode: Mode) -> usize {
267        match *self {
268            Choice2::One(ref inner) => inner.encoded_len(mode),
269            Choice2::Two(ref inner) => inner.encoded_len(mode),
270        }
271    }
272
273    fn write_encoded<W: io::Write>(
274        &self,
275        mode: Mode,
276        target: &mut W
277    ) -> Result<(), io::Error> {
278        match *self {
279            Choice2::One(ref inner) => inner.write_encoded(mode, target),
280            Choice2::Two(ref inner) => inner.write_encoded(mode, target),
281        }
282    }
283}
284
285
286//------------ Choice3 -------------------------------------------------------
287
288/// A value encoder for a three-variant enum.
289///
290/// Instead of implementing `Values` for an enum manually, you can just
291/// define a method `encode` that returns a value of this type.
292pub enum Choice3<L, C, R> {
293    /// The first choice.
294    One(L),
295
296    /// The second choice.
297    Two(C),
298
299    /// The third choice.
300    Three(R)
301}
302
303impl<L: Values, C: Values, R: Values> Values for Choice3<L, C, R> {
304    fn encoded_len(&self, mode: Mode) -> usize {
305        match *self {
306            Choice3::One(ref inner) => inner.encoded_len(mode),
307            Choice3::Two(ref inner) => inner.encoded_len(mode),
308            Choice3::Three(ref inner) => inner.encoded_len(mode),
309        }
310    }
311
312    fn write_encoded<W: io::Write>(
313        &self,
314        mode: Mode,
315        target: &mut W
316    ) -> Result<(), io::Error> {
317        match *self {
318            Choice3::One(ref inner) => inner.write_encoded(mode, target),
319            Choice3::Two(ref inner) => inner.write_encoded(mode, target),
320            Choice3::Three(ref inner) => inner.write_encoded(mode, target),
321        }
322    }
323}
324
325
326//--------------- Iter -------------------------------------------------------
327
328/// A wrapper for an iterator of values.
329///
330/// The wrapper is needed because a blanket impl on any iterator type is
331/// currently not possible.
332///
333/// Note that `T` needs to be clone because we need to be able to restart
334/// iterating at the beginning.
335pub struct Iter<T>(pub T);
336
337impl<T> Iter<T> {
338    /// Creates a new iterator encoder atop `iter`.
339    pub fn new(iter: T) -> Self {
340        Iter(iter)
341    }
342}
343
344/// Wraps an iterator over value encoders into a value encoder.
345pub fn iter<T>(iter: T) -> Iter<T> {
346    Iter::new(iter)
347}
348
349
350//--- IntoIterator
351
352impl<T: IntoIterator> IntoIterator for Iter<T> {
353    type Item = <T as IntoIterator>::Item;
354    type IntoIter = <T as IntoIterator>::IntoIter;
355
356    fn into_iter(self) -> Self::IntoIter {
357        self.0.into_iter()
358    }
359}
360
361impl<T: Clone + IntoIterator> IntoIterator for &'_ Iter<T> {
362    type Item = <T as IntoIterator>::Item;
363    type IntoIter = <T as IntoIterator>::IntoIter;
364
365    fn into_iter(self) -> Self::IntoIter {
366        self.0.clone().into_iter()
367    }
368}
369
370
371//--- Values
372
373impl<T> Values for Iter<T>
374where T: Clone + IntoIterator, <T as IntoIterator>::Item: Values {
375    fn encoded_len(&self, mode: Mode) -> usize {
376        self.into_iter().map(|item| item.encoded_len(mode)).sum()
377    }
378
379    fn write_encoded<W: io::Write>(
380        &self,
381        mode: Mode,
382        target: &mut W
383    ) -> Result<(), io::Error> {
384        self.into_iter().try_for_each(|item| item.write_encoded(mode, target))
385    }
386}
387
388
389//------------ Slice ---------------------------------------------------------
390
391/// A wrapper for a slice of encodable values.
392///
393/// A value of this type will take something that can provide a reference to
394/// a slice of some value and a closure that converts the values of the slice
395/// into something encodable.
396pub struct Slice<T, F, U, V>
397where T: AsRef<[U]>, F: Fn(&U) -> V {
398    /// The slice value.
399    value: T,
400
401    /// The converter function.
402    f: F,
403
404    /// A markers for extra type arguments.
405    marker: PhantomData<(U, V)>,
406}
407
408impl<T, F, U, V> Slice<T, F, U, V>
409where T: AsRef<[U]>, F: Fn(&U) -> V {
410    /// Creates a new wrapper for a given value and closure.
411    pub fn new(value: T, f: F) -> Self {
412        Slice { value, f, marker: PhantomData }
413    }
414}
415
416/// Creates an encodable wrapper around a slice.
417///
418/// The function takes a value of a type that can be converted into a slice of
419/// some type and a function that converts references to slice elements into
420/// some encoder.
421pub fn slice<T, F, U, V>(value: T, f: F) -> Slice<T, F, U, V>
422where T: AsRef<[U]>, F: Fn(&U) -> V {
423    Slice::new(value, f)
424}
425
426
427//--- Values
428
429impl<T, F, U, V> Values for Slice<T, F, U, V>
430where T: AsRef<[U]>, F: Fn(&U) -> V, V: Values {
431    fn encoded_len(&self, mode: Mode) -> usize {
432        self.value.as_ref().iter().map(|v| (self.f)(v).encoded_len(mode)).sum()
433    }
434
435    fn write_encoded<W: io::Write>(
436        &self,
437        mode: Mode,
438        target: &mut W
439    ) -> Result<(), io::Error> {
440        self.value.as_ref().iter().try_for_each(|v|
441            (self.f)(v).write_encoded(mode, target)
442        )
443    }
444}
445
446
447//------------ Nothing -------------------------------------------------------
448
449/// A encoder for nothing.
450///
451/// Unsurprisingly, this encodes as zero octets of content. It can be useful
452/// for writing an encoder for an enum where some of the variants shouldn’t
453/// result in content at all.
454pub struct Nothing;
455
456impl Values for Nothing {
457    fn encoded_len(&self, _mode: Mode) -> usize {
458        0
459    }
460
461    fn write_encoded<W: io::Write>(
462        &self,
463        _mode: Mode,
464        _target: &mut W
465    ) -> Result<(), io::Error> {
466        Ok(())
467    }
468}
469
470
471//============ Standard Functions ============================================
472
473/// Returns a value encoder for a SEQUENCE containing `inner`.
474pub fn sequence<V: Values>(inner: V) -> impl Values {
475    Constructed::new(Tag::SEQUENCE, inner)
476}
477
478/// Returns a value encoder for a SEQUENCE with the given tag.
479///
480/// This is identical to `Constructed::new(tag, inner)`. It merely provides a
481/// more memorial name.
482pub fn sequence_as<V: Values>(tag: Tag, inner: V) -> impl Values {
483    Constructed::new(tag, inner)
484}
485
486/// Returns a value encoder for a SET containing `inner`.
487pub fn set<V: Values>(inner: V) -> impl Values {
488    Constructed::new(Tag::SET, inner)
489}
490
491/// Returns a value encoder for a SET with the given tag.
492///
493/// This is identical to `Constructed::new(tag, inner)`. It merely provides a
494/// more memorial name.
495pub fn set_as<V: Values>(tag: Tag, inner: V) -> impl Values {
496    Constructed::new(tag, inner)
497}
498
499/// Returns the length for a structure based on the tag and content length.
500///
501/// This is necessary because the length octets have a different length
502/// depending on the content length.
503pub fn total_encoded_len(tag: Tag, content_l: usize) -> usize {
504    tag.encoded_len() + Length::Definite(content_l).encoded_len() + content_l
505}
506
507/// Writes the header for a value.
508///
509/// The header in the sense of this function is the identifier octets and the
510/// length octets.
511pub fn write_header<W: io::Write>(
512    target: &mut W,
513    tag: Tag,
514    constructed: bool,
515    content_length: usize
516) -> Result<(), io::Error> {
517    tag.write_encoded(constructed, target)?;
518    Length::Definite(content_length).write_encoded(target)?;
519    Ok(())
520}
521
522
523//============ Helper Types ==================================================
524
525//------------ EndOfValue ----------------------------------------------------
526
527/// A value encoder for the end of value marker.
528struct EndOfValue;
529
530impl Values for EndOfValue {
531    fn encoded_len(&self, _: Mode) -> usize {
532        2
533    }
534
535    fn write_encoded<W: io::Write>(
536        &self,
537        _: Mode,
538        target: &mut W
539    ) -> Result<(), io::Error> {
540        let buf = [0, 0];
541        target.write_all(&buf)
542    }
543}
544
545
546//============ Tests =========================================================
547
548#[cfg(test)]
549mod test {
550    use super::*;
551    use crate::encode::PrimitiveContent;
552
553    #[test]
554    fn encode_2_tuple() {
555        let mut res = Vec::new();
556        (0.encode(), 1.encode()).write_encoded(Mode::Der, &mut res).unwrap();
557        assert_eq!(res, b"\x02\x01\0\x02\x01\x01");
558    }
559
560    #[test]
561    fn encode_4_tuple() {
562        let mut res = Vec::new();
563        (0.encode(), 1.encode(), 2.encode(), 3.encode())
564            .write_encoded(Mode::Der, &mut res).unwrap();
565        assert_eq!(res, b"\x02\x01\0\x02\x01\x01\x02\x01\x02\x02\x01\x03");
566    }
567}