/rust/registry/src/index.crates.io-1949cf8c6b5b557f/der-parser-8.2.0/src/ber/visit.rs
Line | Count | Source |
1 | | use super::{BerObject, BerObjectContent, BitStringObject}; |
2 | | use asn1_rs::{ASN1DateTime, Any, Class, Oid, Tag}; |
3 | | |
4 | | /// BER object tree traversal to walk a shared borrow of a BER object |
5 | | /// |
6 | | /// When implementing your own visitor, define your own `visit_ber_xxx` methods. |
7 | | /// |
8 | | /// Note that `visit_ber` is called for every object, so if you implement multiple visitor methods they |
9 | | /// will be called multiple times for the same object. Generally, if `visit_ber` is implemented, then other |
10 | | /// methods are not needed. |
11 | | /// |
12 | | /// For example, on a `Sequence` item, `visit_ber` is called first, then `visit_ber_sequence`, and then |
13 | | /// `visit_ber` for every sequence object (recursively). |
14 | | /// |
15 | | /// Entry point: use the [`Visit::run`] or [`Visit::run_at`] methods. |
16 | | /// |
17 | | /// Visitor functions |
18 | | #[allow(unused_variables)] |
19 | | pub trait Visit<'a> { |
20 | | /// Called for every BER object |
21 | 0 | fn visit_ber(&mut self, ber: &'_ BerObject<'a>, depth: usize) {} |
22 | | |
23 | | /// Called for BER bitstring objects |
24 | 0 | fn visit_ber_bitstring(&mut self, ignored: u8, data: &'a BitStringObject, depth: usize) {} |
25 | | |
26 | | /// Called for BER bmpstring objects |
27 | 0 | fn visit_ber_bmpstring(&mut self, s: &'a str, depth: usize) {} |
28 | | |
29 | | /// Called for BER boolean objects |
30 | 0 | fn visit_ber_boolean(&mut self, b: bool, depth: usize) {} |
31 | | |
32 | | /// Called for BER end-of-content objects |
33 | 0 | fn visit_ber_endofcontent(&mut self, depth: usize) {} |
34 | | |
35 | | /// Called for BER enum objects |
36 | 0 | fn visit_ber_enum(&mut self, e: u64, depth: usize) {} |
37 | | |
38 | | /// Called for BER generalstring objects |
39 | 0 | fn visit_ber_generalstring(&mut self, s: &'a str, depth: usize) {} |
40 | | |
41 | | /// Called for BER generalizedtime objects |
42 | 0 | fn visit_ber_generalizedtime(&mut self, t: &'a ASN1DateTime, depth: usize) {} |
43 | | |
44 | | /// Called for BER graphicstring objects |
45 | 0 | fn visit_ber_graphicstring(&mut self, s: &'a str, depth: usize) {} |
46 | | |
47 | | /// Called for BER ia5string objects |
48 | 0 | fn visit_ber_ia5string(&mut self, s: &'a str, depth: usize) {} |
49 | | |
50 | | /// Called for BER integer objects |
51 | 0 | fn visit_ber_integer(&mut self, raw_bytes: &'a [u8], depth: usize) {} |
52 | | |
53 | | /// Called for BER null objects |
54 | 0 | fn visit_ber_null(&mut self, depth: usize) {} |
55 | | |
56 | | /// Called for BER numericstring objects |
57 | 0 | fn visit_ber_numericstring(&mut self, s: &'a str, depth: usize) {} |
58 | | |
59 | | /// Called for BER OID objects |
60 | 0 | fn visit_ber_oid(&mut self, oid: &'a Oid, depth: usize) {} |
61 | | |
62 | | /// Called for BER object descriptor objects |
63 | 0 | fn visit_ber_objectdescriptor(&mut self, s: &'a str, depth: usize) {} |
64 | | |
65 | | /// Called for BER octetstring objects |
66 | 0 | fn visit_ber_octetstring(&mut self, b: &'a [u8], depth: usize) {} |
67 | | |
68 | | /// Called for BER optional objects |
69 | 0 | fn visit_ber_optional(&mut self, obj: Option<&'a BerObject<'a>>, depth: usize) {} |
70 | | |
71 | | /// Called for BER printablestring objects |
72 | 0 | fn visit_ber_printablestring(&mut self, s: &'a str, depth: usize) {} |
73 | | |
74 | | /// Called for BER relative OID objects |
75 | 0 | fn visit_ber_relative_oid(&mut self, oid: &'a Oid, depth: usize) {} |
76 | | |
77 | | /// Called for BER sequence objects |
78 | 0 | fn visit_ber_sequence(&mut self, ber: &'_ [BerObject<'a>], depth: usize) {} |
79 | | |
80 | | /// Called for BER set objects |
81 | 0 | fn visit_ber_set(&mut self, ber: &'_ [BerObject<'a>], depth: usize) {} |
82 | | |
83 | | /// Called for BER teletexstring objects |
84 | 0 | fn visit_ber_teletexstring(&mut self, s: &'a str, depth: usize) {} |
85 | | |
86 | | /// Called for BER tagged objects |
87 | 0 | fn visit_ber_tagged(&mut self, class: Class, tag: Tag, obj: &'_ BerObject<'a>, depth: usize) {} |
88 | | |
89 | | /// Called for BER generalizedtime objects |
90 | 0 | fn visit_ber_utctime(&mut self, t: &'a ASN1DateTime, depth: usize) {} |
91 | | |
92 | | /// Called for BER utf8string objects |
93 | 0 | fn visit_ber_utf8string(&mut self, s: &'a str, depth: usize) {} |
94 | | |
95 | | /// Called for BER universalstring objects |
96 | 0 | fn visit_ber_universalstring(&mut self, raw_bytes: &'a [u8], depth: usize) {} |
97 | | |
98 | | /// Called for BER videotexstring objects |
99 | 0 | fn visit_ber_videotextstring(&mut self, raw_bytes: &'a str, depth: usize) {} |
100 | | |
101 | | /// Called for BER visiblestring objects |
102 | 0 | fn visit_ber_visiblestring(&mut self, raw_bytes: &'a str, depth: usize) {} |
103 | | |
104 | | /// Called for BER unknown objects |
105 | 0 | fn visit_ber_unknown(&mut self, ber: &'_ Any<'a>, depth: usize) {} |
106 | | |
107 | | /// Perform a BFS traversal of the BER object, calling the visitor functions during he traversal |
108 | | /// |
109 | | /// Usually, this method should not be redefined (unless implementing a custom traversal) |
110 | 0 | fn run(&mut self, ber: &'a BerObject<'a>) { |
111 | 0 | visit_ber_bfs(self, ber, 0) |
112 | 0 | } |
113 | | |
114 | | /// Perform a BFS traversal of the BER object, calling the visitor functions during he traversal |
115 | | /// |
116 | | /// Start at specified depth. |
117 | | /// |
118 | | /// Usually, this method should not be redefined (unless implementing a custom traversal) |
119 | 0 | fn run_at(&mut self, ber: &'a BerObject<'a>, depth: usize) { |
120 | 0 | visit_ber_bfs(self, ber, depth) |
121 | 0 | } |
122 | | } |
123 | | |
124 | 0 | fn visit_ber_bfs<'a, V>(v: &mut V, ber: &'a BerObject<'a>, depth: usize) |
125 | 0 | where |
126 | 0 | V: Visit<'a> + ?Sized, |
127 | | { |
128 | 0 | v.visit_ber(ber, depth); |
129 | | |
130 | 0 | match ber.content { |
131 | 0 | BerObjectContent::BitString(ignored, ref data) => { |
132 | 0 | v.visit_ber_bitstring(ignored, data, depth); |
133 | 0 | } |
134 | 0 | BerObjectContent::BmpString(s) => v.visit_ber_bmpstring(s, depth), |
135 | 0 | BerObjectContent::Boolean(b) => v.visit_ber_boolean(b, depth), |
136 | 0 | BerObjectContent::EndOfContent => v.visit_ber_endofcontent(depth), |
137 | 0 | BerObjectContent::Enum(val) => v.visit_ber_enum(val, depth), |
138 | 0 | BerObjectContent::GeneralString(s) => v.visit_ber_generalstring(s, depth), |
139 | 0 | BerObjectContent::GeneralizedTime(ref t) => v.visit_ber_generalizedtime(t, depth), |
140 | 0 | BerObjectContent::GraphicString(s) => v.visit_ber_graphicstring(s, depth), |
141 | 0 | BerObjectContent::IA5String(s) => v.visit_ber_ia5string(s, depth), |
142 | 0 | BerObjectContent::Integer(s) => v.visit_ber_integer(s, depth), |
143 | 0 | BerObjectContent::Null => v.visit_ber_null(depth), |
144 | 0 | BerObjectContent::NumericString(s) => v.visit_ber_numericstring(s, depth), |
145 | 0 | BerObjectContent::OID(ref oid) => v.visit_ber_oid(oid, depth), |
146 | 0 | BerObjectContent::ObjectDescriptor(s) => v.visit_ber_objectdescriptor(s, depth), |
147 | 0 | BerObjectContent::OctetString(b) => v.visit_ber_octetstring(b, depth), |
148 | 0 | BerObjectContent::Optional(ref obj) => { |
149 | 0 | let opt = obj.as_ref().map(|b| b.as_ref()); |
150 | 0 | v.visit_ber_optional(opt, depth) |
151 | | } |
152 | 0 | BerObjectContent::PrintableString(s) => v.visit_ber_printablestring(s, depth), |
153 | 0 | BerObjectContent::RelativeOID(ref oid) => v.visit_ber_relative_oid(oid, depth), |
154 | 0 | BerObjectContent::Sequence(ref l) => { |
155 | 0 | v.visit_ber_sequence(l, depth); |
156 | 0 | for item in l.iter() { |
157 | 0 | visit_ber_bfs(v, item, depth + 1); |
158 | 0 | } |
159 | | } |
160 | 0 | BerObjectContent::Set(ref l) => { |
161 | 0 | v.visit_ber_set(l, depth); |
162 | 0 | for item in l.iter() { |
163 | 0 | visit_ber_bfs(v, item, depth + 1); |
164 | 0 | } |
165 | | } |
166 | 0 | BerObjectContent::T61String(s) => v.visit_ber_teletexstring(s, depth), |
167 | 0 | BerObjectContent::Tagged(class, tag, ref obj) => { |
168 | 0 | v.visit_ber_tagged(class, tag, obj.as_ref(), depth) |
169 | | } |
170 | 0 | BerObjectContent::UTCTime(ref t) => v.visit_ber_utctime(t, depth), |
171 | 0 | BerObjectContent::UTF8String(s) => v.visit_ber_utf8string(s, depth), |
172 | 0 | BerObjectContent::UniversalString(b) => v.visit_ber_universalstring(b, depth), |
173 | 0 | BerObjectContent::Unknown(ref inner) => v.visit_ber_unknown(inner, depth), |
174 | 0 | BerObjectContent::VideotexString(s) => v.visit_ber_videotextstring(s, depth), |
175 | 0 | BerObjectContent::VisibleString(s) => v.visit_ber_visiblestring(s, depth), |
176 | | } |
177 | 0 | } |
178 | | |
179 | | #[cfg(test)] |
180 | | mod tests { |
181 | | use super::Visit; |
182 | | use crate::ber::BerObject; |
183 | | |
184 | | #[derive(Debug)] |
185 | | struct BerObjectVisitor {} |
186 | | |
187 | | impl<'a> Visit<'a> for BerObjectVisitor { |
188 | | fn visit_ber(&mut self, ber: &'_ BerObject<'a>, depth: usize) { |
189 | | eprintln!("Depth {}: Object with tag {}", depth, ber.tag()); |
190 | | } |
191 | | } |
192 | | } |