1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
//! The BER mode.
//!
//! This is a private module. It’s public items are re-exported by the parent.

use crate::decode;
use crate::decode::DecodeError;


//------------ Mode ----------------------------------------------------------

/// The BER Mode.
///
/// X.680 defines not one but three sets of related encoding rules. All three
/// follow the same basic ideas but implement them in slightly different
/// ways.
///
/// This type represents these rules. The [`decode`] method provides a way to
/// decode a source using the specific decoding mode. You can also change
/// the decoding mode later on through the `set_mode` methods of [`Primitive`]
/// and [`Constructed`].
///
/// [`decode´]: #method.decode
/// [`Primitive`]: decode/struct.Primitive.html
/// [`Constructed`]: decode/struct.Constructed.html
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
pub enum Mode {
    /// Basic Encoding Rules.
    ///
    /// These are the most flexible rules, allowing alternative encodings for
    /// some types as well as indefinite length values.
    #[default]
    Ber,

    /// Canonical Encoding Rules.
    ///
    /// These rules always employ indefinite length encoding for constructed
    /// values and the shortest possible form for primitive values.  There
    /// are additional restrictions for certain types.
    Cer,

    /// Distinguished Encoding Rules.
    ///
    /// These rules always employ definite length values and require the
    /// shortest possible encoding. Additional rules apply to some types.
    Der,
}

impl Mode {
    /// Decode a source using a specific mode.
    ///
    /// The method will attempt to decode `source` using the rules represented
    /// by this value. The closure `op` will be given the content of the
    /// source as a sequence of values. The closure does not need to process
    /// all values in the source.
    pub fn decode<S, F, T>(
        self, source: S, op: F,
    ) -> Result<T, DecodeError<<S::Source as decode::Source>::Error>>
    where
        S: decode::IntoSource,
        F: FnOnce(
            &mut decode::Constructed<S::Source>
        ) -> Result<T, DecodeError<<S::Source as decode::Source>::Error>>,
    {
        decode::Constructed::decode(source, self, op)
    }

    /// Returns whether the mode is `Mode::Ber`.
    pub fn is_ber(self) -> bool {
        matches!(self, Mode::Ber)
    }

    /// Returns whether the mode is `Mode::Cer`.
    pub fn is_cer(self) -> bool {
        matches!(self, Mode::Cer)
    }

    /// Returns whether the mode is `Mode::Der`.
    pub fn is_der(self) -> bool {
        matches!(self, Mode::Der)
    }
}