1#![allow(unused_imports)]
2
3use crate::ParseResult;
4
5pub(crate) mod macros {
6 macro_rules! debug_eprintln {
7 ($msg: expr, $( $args:expr ),* ) => {
8 #[cfg(feature = "debug")]
9 {
10 use colored::Colorize;
11 let s = $msg.to_string().green();
12 eprintln!("{} {}", s, format!($($args),*));
13 }
14 };
15}
16
17 #[allow(unused_macros)]
18 macro_rules! trace_eprintln {
19 ($msg: expr, $( $args:expr ),* ) => {
20 #[cfg(feature = "trace")]
21 {
22 use colored::Colorize;
23 let s = $msg.to_string().green();
24 eprintln!("{} {}", s, format!($($args),*));
25 }
26 };
27}
28
29 pub(crate) use debug_eprintln;
30 pub(crate) use trace_eprintln;
31}
32
33use macros::*;
34
35#[cfg(feature = "debug")]
36fn eprintln_hex_dump(bytes: &[u8], max_len: usize) {
37 use core::cmp::min;
38 use nom::HexDisplay;
39
40 let m = min(bytes.len(), max_len);
41 eprint!("{}", &bytes[..m].to_hex(16));
42 if bytes.len() > max_len {
43 eprintln!("... <continued>");
44 }
45}
46
47#[cfg(not(feature = "debug"))]
48#[inline]
49pub fn trace_generic<F, I, O, E>(_msg: &str, _fname: &str, f: F, input: I) -> Result<O, E>
50where
51 F: Fn(I) -> Result<O, E>,
52{
53 f(input)
54}
55
56#[cfg(feature = "debug")]
57pub fn trace_generic<F, I, O, E>(msg: &str, fname: &str, f: F, input: I) -> Result<O, E>
58where
59 F: Fn(I) -> Result<O, E>,
60 E: core::fmt::Display,
61{
62 trace_eprintln!(msg, "⤷ {}", fname);
63 let output = f(input);
64 match &output {
65 Err(e) => {
66 debug_eprintln!(msg, "↯ {} failed: {}", fname, e.to_string().red());
67 }
68 _ => {
69 debug_eprintln!(msg, "⤶ {}", fname);
70 }
71 }
72 output
73}
74
75#[cfg(not(feature = "debug"))]
76#[inline]
77pub fn trace<'a, T, E, F>(_msg: &str, f: F, input: &'a [u8]) -> ParseResult<'a, T, E>
78where
79 F: Fn(&'a [u8]) -> ParseResult<'a, T, E>,
80{
81 f(input)
82}
83
84#[cfg(feature = "debug")]
85pub fn trace<'a, T, E, F>(msg: &str, f: F, input: &'a [u8]) -> ParseResult<'a, T, E>
86where
87 F: Fn(&'a [u8]) -> ParseResult<'a, T, E>,
88{
89 trace_eprintln!(
90 msg,
91 "⤷ input (len={}, type={})",
92 input.len(),
93 core::any::type_name::<T>()
94 );
95 let res = f(input);
96 match &res {
97 Ok((_rem, _)) => {
98 trace_eprintln!(
99 msg,
100 "⤶ Parsed {} bytes, {} remaining",
101 input.len() - _rem.len(),
102 _rem.len()
103 );
104 }
105 Err(_) => {
106 debug_eprintln!(msg, "↯ Parsing failed at location:");
108 eprintln_hex_dump(input, 16);
109 }
110 }
111 res
112}
113
114#[cfg(feature = "debug")]
115#[cfg(test)]
116mod tests {
117
118 use std::collections::HashSet;
119
120 use crate::*;
121 use alloc::collections::BTreeSet;
122 use hex_literal::hex;
123
124 #[test]
125 fn debug_from_ber_any() {
126 assert!(Any::from_ber(&hex!("01 01 ff")).is_ok());
127 }
128
129 #[test]
130 fn debug_from_ber_failures() {
131 eprintln!("--");
133 assert!(<Vec<u16>>::from_ber(&hex!("02 01 00")).is_err());
134 }
135
136 #[test]
137 fn debug_from_ber_sequence_indefinite() {
138 let input = &hex!("30 80 02 03 01 00 01 00 00");
139 let (rem, result) = Sequence::from_ber(input).expect("parsing failed");
140 assert_eq!(result.as_ref(), &input[2..7]);
141 assert_eq!(rem, &[]);
142 eprintln!("--");
143 let (rem, result) = <Vec<u32>>::from_ber(input).expect("parsing failed");
144 assert_eq!(&result, &[65537]);
145 assert_eq!(rem, &[]);
146 }
147
148 #[test]
149 fn debug_from_ber_sequence_of() {
150 let input = &hex!("30 03 01 01 00");
152 eprintln!("--");
153 let _ = <SequenceOf<u32>>::from_ber(input).expect_err("parsing should fail");
154 eprintln!("--");
155 let _ = <Vec<u32>>::from_ber(input).expect_err("parsing should fail");
156 }
157
158 #[test]
159 fn debug_from_ber_u32() {
160 assert!(u32::from_ber(&hex!("02 01 01")).is_ok());
161 }
162
163 #[test]
164 fn debug_from_der_any() {
165 assert!(Any::from_der(&hex!("01 01 ff")).is_ok());
166 }
167
168 #[test]
169 fn debug_from_der_bool() {
170 eprintln!("** first test is ok**");
171 assert!(<bool>::from_der(&hex!("01 01 ff")).is_ok());
172 eprintln!("** second test fails when parsing ANY (eof)**");
173 assert!(<bool>::from_der(&hex!("01 02 ff")).is_err());
174 eprintln!("** second test fails when checking DER constraints**");
175 assert!(<bool>::from_der(&hex!("01 01 f0")).is_err());
176 eprintln!("** second test fails during TryFrom**");
177 assert!(<bool>::from_der(&hex!("01 02 ff ff")).is_err());
178 }
179
180 #[test]
181 fn debug_from_der_failures() {
182 use crate::Sequence;
183
184 eprintln!("--");
186 assert!(u16::from_der(&hex!("ff 00")).is_err());
187 eprintln!("--");
189 assert!(u16::from_der(&hex!("30 80 00 00")).is_err());
190 eprintln!("--");
192 assert!(bool::from_der(&hex!("01 01 7f")).is_err());
193 eprintln!("--");
195 let _ = Sequence::from_der(&hex!("30 81 04 00 00"));
196 }
197
198 #[test]
199 fn debug_from_der_sequence() {
200 let input = &hex!("30 08 02 03 01 00 01 02 01 01");
202 let (rem, result) = <Vec<u32>>::from_der(input).expect("parsing failed");
203 assert_eq!(&result, &[65537, 1]);
204 assert_eq!(rem, &[]);
205 }
206
207 #[test]
208 fn debug_from_der_sequence_fail() {
209 let input = &hex!("31 03 01 01 44");
211 let _ = <Vec<bool>>::from_der(input).expect_err("parsing should fail");
212 let input = &hex!("30 03 01 01 44");
214 let _ = <Vec<bool>>::from_der(input).expect_err("parsing should fail");
215 }
216
217 #[test]
218 fn debug_from_der_sequence_of() {
219 use crate::SequenceOf;
220 let input = &hex!("30 03 01 01 00");
222 eprintln!("--");
223 let _ = <SequenceOf<u32>>::from_der(input).expect_err("parsing should fail");
224 eprintln!("--");
225 let _ = <Vec<u32>>::from_der(input).expect_err("parsing should fail");
226 }
227
228 #[test]
229 fn debug_from_der_set_fail() {
230 let input = &hex!("31 03 01 01 44");
232 let _ = <BTreeSet<bool>>::from_der(input).expect_err("parsing should fail");
233 }
234
235 #[test]
236 fn debug_from_der_set_of() {
237 use crate::SetOf;
238 use alloc::collections::BTreeSet;
239
240 let input = &hex!("31 03 01 01 00");
242 eprintln!("--");
243 let _ = <SetOf<u32>>::from_der(input).expect_err("parsing should fail");
244 eprintln!("--");
245 let _ = <BTreeSet<u32>>::from_der(input).expect_err("parsing should fail");
246 eprintln!("--");
247 let _ = <HashSet<u32>>::from_der(input).expect_err("parsing should fail");
248 }
249
250 #[test]
251 fn debug_from_der_string_ok() {
252 let input = &hex!("0c 0a 53 6f 6d 65 2d 53 74 61 74 65");
253 let (rem, result) = Utf8String::from_der(input).expect("parsing failed");
254 assert_eq!(result.as_ref(), "Some-State");
255 assert_eq!(rem, &[]);
256 }
257
258 #[test]
259 fn debug_from_der_string_fail() {
260 let input = &hex!("12 03 41 42 43");
262 let _ = NumericString::from_der(input).expect_err("parsing should fail");
263 }
264}