1use super::{BerObject, BerObjectContent, BitStringObject};
2use alloc::vec::Vec;
3use asn1_rs::{ASN1DateTime, Any, Class, Oid, Tag};
4
5#[allow(unused_variables)]
20pub trait VisitMut<'a> {
21 fn visit_ber_mut(&mut self, ber: &'_ mut BerObject<'a>, depth: usize) {}
23
24 fn visit_ber_bitstring_mut(
26 &mut self,
27 ignored: &mut u8,
28 data: &'a mut BitStringObject,
29 depth: usize,
30 ) {
31 }
32
33 fn visit_ber_bmpstring_mut(&mut self, s: &'a mut &'_ str, depth: usize) {}
35
36 fn visit_ber_boolean_mut(&mut self, b: &'a mut bool, depth: usize) {}
38
39 fn visit_ber_endofcontent_mut(&mut self, depth: usize) {}
41
42 fn visit_ber_enum_mut(&mut self, e: &'a mut u64, depth: usize) {}
44
45 fn visit_ber_generalstring_mut(&mut self, s: &'a mut &'_ str, depth: usize) {}
47
48 fn visit_ber_generalizedtime_mut(&mut self, t: &'a ASN1DateTime, depth: usize) {}
50
51 fn visit_ber_graphicstring_mut(&mut self, s: &'a mut &'_ str, depth: usize) {}
53
54 fn visit_ber_ia5string_mut(&mut self, s: &'a mut &'_ str, depth: usize) {}
56
57 fn visit_ber_integer_mut(&mut self, raw_bytes: &'a mut &'_ [u8], depth: usize) {}
59
60 fn visit_ber_null_mut(&mut self, depth: usize) {}
62
63 fn visit_ber_numericstring_mut(&mut self, s: &'a mut &'_ str, depth: usize) {}
65
66 fn visit_ber_oid_mut(&mut self, oid: &'a mut Oid, depth: usize) {}
68
69 fn visit_ber_objectdescriptor_mut(&mut self, s: &'a mut &'_ str, depth: usize) {}
71
72 fn visit_ber_octetstring_mut(&mut self, b: &'a [u8], depth: usize) {}
74
75 fn visit_ber_optional_mut(&mut self, obj: Option<&'a mut BerObject<'a>>, depth: usize) {}
77
78 fn visit_ber_printablestring_mut(&mut self, s: &'a mut &'_ str, depth: usize) {}
80
81 fn visit_ber_relative_oid_mut(&mut self, oid: &'a mut Oid, depth: usize) {}
83
84 fn visit_ber_sequence_mut(&mut self, l: &'_ mut Vec<BerObject<'a>>, depth: usize) {}
86
87 fn visit_ber_set_mut(&mut self, ber: &'_ mut Vec<BerObject<'a>>, depth: usize) {}
89
90 fn visit_ber_teletexstring_mut(&mut self, s: &'a mut &'_ str, depth: usize) {}
92
93 fn visit_ber_tagged_mut(
95 &mut self,
96 class: &'a mut Class,
97 tag: &'a mut Tag,
98 obj: &'a mut BerObject<'a>,
99 depth: usize,
100 ) {
101 }
102
103 fn visit_ber_utctime_mut(&mut self, t: &'a ASN1DateTime, depth: usize) {}
105
106 fn visit_ber_utf8string_mut(&mut self, s: &'a str, depth: usize) {}
108
109 fn visit_ber_universalstring_mut(&mut self, raw_bytes: &'a mut &'_ [u8], depth: usize) {}
111
112 fn visit_ber_videotextstring_mut(&mut self, raw_bytes: &'a mut &'_ str, depth: usize) {}
114
115 fn visit_ber_visiblestring_mut(&mut self, raw_bytes: &'a mut &'_ str, depth: usize) {}
117
118 fn visit_ber_unknown_mut(&mut self, ber: &'_ mut Any<'a>, depth: usize) {}
120
121 fn run(&mut self, ber: &'a mut BerObject<'a>) {
125 visit_ber_bfs_mut(self, ber, 0)
126 }
127
128 fn run_at(&mut self, ber: &'a mut BerObject<'a>, depth: usize) {
134 visit_ber_bfs_mut(self, ber, depth)
135 }
136}
137
138fn visit_ber_bfs_mut<'a, V>(v: &mut V, ber: &'a mut BerObject<'a>, depth: usize)
139where
140 V: VisitMut<'a> + ?Sized,
141{
142 v.visit_ber_mut(ber, depth);
143
144 match ber.content {
145 BerObjectContent::BitString(ref mut ignored, ref mut data) => {
146 v.visit_ber_bitstring_mut(ignored, data, depth);
147 }
148 BerObjectContent::BmpString(ref mut s) => v.visit_ber_bmpstring_mut(s, depth),
149 BerObjectContent::Boolean(ref mut b) => v.visit_ber_boolean_mut(b, depth),
150 BerObjectContent::EndOfContent => v.visit_ber_endofcontent_mut(depth),
151 BerObjectContent::Enum(ref mut val) => v.visit_ber_enum_mut(val, depth),
152 BerObjectContent::GeneralString(ref mut s) => v.visit_ber_generalstring_mut(s, depth),
153 BerObjectContent::GeneralizedTime(ref t) => v.visit_ber_generalizedtime_mut(t, depth),
154 BerObjectContent::GraphicString(ref mut s) => v.visit_ber_graphicstring_mut(s, depth),
155 BerObjectContent::IA5String(ref mut s) => v.visit_ber_ia5string_mut(s, depth),
156 BerObjectContent::Integer(ref mut s) => v.visit_ber_integer_mut(s, depth),
157 BerObjectContent::Null => v.visit_ber_null_mut(depth),
158 BerObjectContent::NumericString(ref mut s) => v.visit_ber_numericstring_mut(s, depth),
159 BerObjectContent::OID(ref mut oid) => v.visit_ber_oid_mut(oid, depth),
160 BerObjectContent::ObjectDescriptor(ref mut s) => v.visit_ber_objectdescriptor_mut(s, depth),
161 BerObjectContent::OctetString(ref mut b) => v.visit_ber_octetstring_mut(b, depth),
162 BerObjectContent::Optional(ref mut obj) => {
163 let opt = obj.as_mut().map(|b| b.as_mut());
164 v.visit_ber_optional_mut(opt, depth)
165 }
166 BerObjectContent::PrintableString(ref mut s) => v.visit_ber_printablestring_mut(s, depth),
167 BerObjectContent::RelativeOID(ref mut oid) => v.visit_ber_relative_oid_mut(oid, depth),
168 BerObjectContent::Sequence(ref mut l) => {
169 v.visit_ber_sequence_mut(l, depth);
170 for item in l.iter_mut() {
171 visit_ber_bfs_mut(v, item, depth + 1);
172 }
173 }
174 BerObjectContent::Set(ref mut l) => {
175 v.visit_ber_set_mut(l, depth);
176 for item in l.iter_mut() {
177 visit_ber_bfs_mut(v, item, depth + 1);
178 }
179 }
180 BerObjectContent::T61String(ref mut s) => v.visit_ber_teletexstring_mut(s, depth),
181 BerObjectContent::Tagged(ref mut class, ref mut tag, ref mut obj) => {
182 v.visit_ber_tagged_mut(class, tag, obj.as_mut(), depth)
183 }
184 BerObjectContent::UTCTime(ref t) => v.visit_ber_utctime_mut(t, depth),
185 BerObjectContent::UTF8String(ref mut s) => v.visit_ber_utf8string_mut(s, depth),
186 BerObjectContent::UniversalString(ref mut b) => v.visit_ber_universalstring_mut(b, depth),
187 BerObjectContent::Unknown(ref mut inner) => v.visit_ber_unknown_mut(inner, depth),
188 BerObjectContent::VideotexString(ref mut s) => v.visit_ber_videotextstring_mut(s, depth),
189 BerObjectContent::VisibleString(ref mut s) => v.visit_ber_visiblestring_mut(s, depth),
190 }
191}
192
193#[cfg(test)]
194mod tests {
195 use super::VisitMut;
196 use crate::ber::BerObject;
197
198 #[derive(Debug)]
199 struct BerObjectVisitor {}
200
201 impl<'a> VisitMut<'a> for BerObjectVisitor {
202 fn visit_ber_mut(&mut self, ber: &'_ mut BerObject<'a>, depth: usize) {
203 eprintln!("Depth {}: Object with tag {}", depth, ber.tag());
204 }
205 }
206}