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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#![allow(clippy::single_char_lifetime_names)]
use core::fmt;
use std::{
borrow::Cow,
collections::HashSet,
ops::RangeInclusive,
};
use tracing_subscriber::fmt::format;
#[derive(Debug, thiserror::Error)]
pub enum Error {
#[error("Illegal character {0}: {1}")]
IllegalCharacter(char, String),
#[error("Unknown field: {0}")]
UnknownField(String),
#[error("Empty field found")]
EmptyField,
}
#[derive(Debug)]
pub struct Fmtr<'fmtstr> {
fmt_str: Cow<'fmtstr, str>,
field_ranges: Vec<RangeInclusive<usize>>,
field_names: Vec<&'static str>,
}
impl<'fmtstr> Fmtr<'fmtstr> {
pub fn new(
fmt_str: impl Into<Cow<'fmtstr, str>>,
fields: &HashSet<&'static str>,
) -> Result<Self, Error> {
let fmt_str = fmt_str.into();
let mut start = None;
let mut in_escape = false;
let mut field_ranges: Vec<RangeInclusive<usize>> = Vec::with_capacity(fields.len());
let mut field_names: Vec<&'static str> = Vec::with_capacity(fields.len());
for (xi, x) in fmt_str.char_indices() {
if let Some(strt) = start {
if x == '{' || x == '\\' {
return Err(Error::IllegalCharacter(
x,
"found inside field name block".to_string(),
));
}
if x == '}' {
#[allow(clippy::integer_arithmetic)] if strt + 1 == xi {
return Err(Error::EmptyField);
}
field_ranges.push(strt..=xi);
#[allow(clippy::indexing_slicing, clippy::integer_arithmetic)]
let ff = &fmt_str[(strt + 1)..xi];
if let Some(f) = fields.get(ff) {
field_names.push(*f);
start = None;
} else {
return Err(Error::UnknownField(ff.to_string()));
}
}
} else {
if x == '\\' {
in_escape = true;
continue; }
if !in_escape {
if x == '}' {
return Err(Error::IllegalCharacter(
x,
"found outside field name block".to_string(),
));
} else if x == '{' {
start = Some(xi);
}
}
}
in_escape = false;
}
Ok(Self {
fmt_str,
field_ranges,
field_names,
})
}
pub fn field_from_id(&self, i: usize) -> Option<&'static str> {
self.field_names.get(i).copied()
}
#[allow(clippy::unwrap_in_result)]
pub fn write<'writer>(
&self,
mut writer: format::Writer<'writer>,
value_writer: &impl FieldValueWriter,
) -> fmt::Result {
let mut last = 0;
for (i, range) in self.field_ranges.iter().enumerate() {
#[allow(clippy::indexing_slicing)]
write!(writer.by_ref(), "{}", &self.fmt_str[last..*range.start()])?;
#[allow(clippy::unwrap_used)]
let field = self.field_from_id(i).unwrap();
value_writer.write_value(writer.by_ref(), field)?;
#[allow(clippy::integer_arithmetic)]
{
last = range.end() + 1;
}
}
#[allow(clippy::indexing_slicing)]
write!(writer, "{}", &self.fmt_str[last..])?;
writeln!(writer)
}
}
pub trait FieldValueWriter {
fn write_value(&self, writer: format::Writer<'_>, field: &'static str) -> fmt::Result;
}