]>
git.proxmox.com Git - rustc.git/blob - src/libtest/formatters/json.rs
3 pub(crate) struct JsonFormatter
<T
> {
4 out
: OutputLocation
<T
>,
7 impl<T
: Write
> JsonFormatter
<T
> {
8 pub fn new(out
: OutputLocation
<T
>) -> Self {
12 fn writeln_message(&mut self, s
: &str) -> io
::Result
<()> {
13 assert
!(!s
.contains('
\n'
));
15 self.out
.write_all(s
.as_ref())?
;
16 self.out
.write_all(b
"\n")
19 fn write_message(&mut self, s
: &str) -> io
::Result
<()> {
20 assert
!(!s
.contains('
\n'
));
22 self.out
.write_all(s
.as_ref())
30 stdout
: Option
<Cow
<'_
, str>>,
33 self.write_message(&*format
!(
34 r
#"{{ "type": "{}", "name": "{}", "event": "{}""#,
37 if let Some(stdout) = stdout {
38 self.write_message(&*format!(
39 r#", "stdout": "{}""#,
43 if let Some(extra) = extra {
44 self.write_message(&*format!(
49 self.writeln_message(" }")
53 impl<T: Write> OutputFormatter for JsonFormatter<T> {
54 fn write_run_start(&mut self, test_count: usize) -> io::Result<()> {
55 self.writeln_message(&*format!(
56 r#"{{ "type": "suite", "event": "started", "test_count": {} }}"#,
61 fn write_test_start(&mut self, desc: &TestDesc) -> io::Result<()> {
62 self.writeln_message(&*format!(
63 r#"{{ "type": "test", "event": "started", "name": "{}" }}"#,
73 state
: &ConsoleTestState
,
75 let stdout
= if (state
.options
.display_output
|| *result
!= TrOk
) && stdout
.len() > 0 {
76 Some(String
::from_utf8_lossy(stdout
))
81 TrOk
=> self.write_event("test", desc
.name
.as_slice(), "ok", stdout
, None
),
83 TrFailed
=> self.write_event("test", desc
.name
.as_slice(), "failed", stdout
, None
),
85 TrFailedMsg(ref m
) => self.write_event(
90 Some(&*format
!(r
#""message": "{}""#, EscapedString(m))),
93 TrIgnored
=> self.write_event("test", desc
.name
.as_slice(), "ignored", stdout
, None
),
96 self.write_event("test", desc
.name
.as_slice(), "allowed_failure", stdout
, None
)
100 let median
= bs
.ns_iter_summ
.median
as usize;
101 let deviation
= (bs
.ns_iter_summ
.max
- bs
.ns_iter_summ
.min
) as usize;
103 let mbps
= if bs
.mb_s
== 0 {
106 format
!(r
#", "mib_per_second": {}"#, bs.mb_s)
110 "{{ \"type\": \"bench\", \
113 \"deviation\": {}{} }}",
114 desc
.name
, median
, deviation
, mbps
117 self.writeln_message(&*line
)
122 fn write_timeout(&mut self, desc
: &TestDesc
) -> io
::Result
<()> {
123 self.writeln_message(&*format
!(
124 r
#"{{ "type": "test", "event": "timeout", "name": "{}" }}"#,
129 fn write_run_finish(&mut self, state: &ConsoleTestState) -> io::Result<bool> {
130 self.writeln_message(&*format!(
131 "{{ \"type\": \"suite\", \
135 \"allowed_fail\": {}, \
138 \"filtered_out\": {} }}",
139 if state.failed == 0 { "ok" } else { "failed" },
141 state.failed + state.allowed_fail,
148 Ok(state.failed == 0)
152 /// A formatting utility used to print strings with characters in need of escaping.
153 /// Base code taken form `libserialize::json::escape_str`
154 struct EscapedString<S: AsRef<str>>(S);
156 impl<S: AsRef<str>> ::std::fmt::Display for EscapedString<S> {
157 fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
160 for (i, byte) in self.0.as_ref().bytes().enumerate() {
161 let escaped = match byte {
164 b'
\x00'
=> "\\u0000",
165 b'
\x01'
=> "\\u0001",
166 b'
\x02'
=> "\\u0002",
167 b'
\x03'
=> "\\u0003",
168 b'
\x04'
=> "\\u0004",
169 b'
\x05'
=> "\\u0005",
170 b'
\x06'
=> "\\u0006",
171 b'
\x07'
=> "\\u0007",
175 b'
\x0b'
=> "\\u000b",
178 b'
\x0e'
=> "\\u000e",
179 b'
\x0f'
=> "\\u000f",
180 b'
\x10'
=> "\\u0010",
181 b'
\x11'
=> "\\u0011",
182 b'
\x12'
=> "\\u0012",
183 b'
\x13'
=> "\\u0013",
184 b'
\x14'
=> "\\u0014",
185 b'
\x15'
=> "\\u0015",
186 b'
\x16'
=> "\\u0016",
187 b'
\x17'
=> "\\u0017",
188 b'
\x18'
=> "\\u0018",
189 b'
\x19'
=> "\\u0019",
190 b'
\x1a'
=> "\\u001a",
191 b'
\x1b'
=> "\\u001b",
192 b'
\x1c'
=> "\\u001c",
193 b'
\x1d'
=> "\\u001d",
194 b'
\x1e'
=> "\\u001e",
195 b'
\x1f'
=> "\\u001f",
196 b'
\x7f'
=> "\\u007f",
203 f
.write_str(&self.0.as_ref()[start
..i
])?
;
206 f
.write_str(escaped
)?
;
211 if start
!= self.0.as_ref().len() {
212 f
.write_str(&self.0.as_ref()[start
..])?
;