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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#[cfg(feature = "debug")]
mod internals;
use crate::error::ErrMode;
use crate::stream::Stream;
use crate::Parser;
#[cfg(all(feature = "debug", not(feature = "std")))]
compile_error!("`debug` requires `std`");
#[cfg_attr(not(feature = "debug"), allow(unused_variables))]
#[cfg_attr(not(feature = "debug"), allow(unused_mut))]
pub fn trace<I: Stream, O, E>(
name: impl crate::lib::std::fmt::Display,
mut parser: impl Parser<I, O, E>,
) -> impl Parser<I, O, E> {
#[cfg(feature = "debug")]
{
let mut call_count = 0;
move |i: I| {
let depth = internals::Depth::new();
let original = i.clone();
internals::start(*depth, &name, call_count, &original);
let res = parser.parse_next(i);
let consumed = res.as_ref().ok().map(|(i, _)| {
if i.eof_offset() == 0 {
original.eof_offset()
} else {
original.offset_to(i)
}
});
let severity = internals::Severity::with_result(&res);
internals::end(*depth, &name, call_count, consumed, severity);
call_count += 1;
res
}
}
#[cfg(not(feature = "debug"))]
{
parser
}
}
#[cfg_attr(not(feature = "debug"), allow(unused_variables))]
pub(crate) fn trace_result<T, E>(
name: impl crate::lib::std::fmt::Display,
res: &Result<T, ErrMode<E>>,
) {
#[cfg(feature = "debug")]
{
let depth = internals::Depth::existing();
let severity = internals::Severity::with_result(res);
internals::result(*depth, &name, severity);
}
}
#[test]
#[cfg(feature = "std")]
#[cfg_attr(miri, ignore)]
#[cfg(unix)]
#[cfg(feature = "debug")]
fn example() {
use term_transcript::{test::TestConfig, ShellOptions};
let path = snapbox::cmd::compile_example("string", ["--features=debug"]).unwrap();
let current_dir = path.parent().unwrap();
let cmd = path.file_name().unwrap();
let cmd = format!("./{}", cmd.to_string_lossy());
TestConfig::new(
ShellOptions::default()
.with_current_dir(current_dir)
.with_env("CLICOLOR_FORCE", "1"),
)
.test("assets/trace.svg", [cmd.as_str()]);
}