prototext_core/serialize/common/
format.rs1use crate::decoder::{ProtoTextContent, ProtoTextField};
7
8use super::escape::{escape_bytes, escape_string};
9use super::floats::{format_double_protoc, format_float_protoc};
10use super::scalars::{
11 format_bool_protoc, format_enum_protoc, format_fixed32_protoc, format_fixed64_protoc,
12 format_int32_protoc, format_int64_protoc, format_sfixed32_protoc, format_sfixed64_protoc,
13 format_sint32_protoc, format_sint64_protoc, format_uint32_protoc, format_uint64_protoc,
14 format_wire_fixed32_protoc, format_wire_fixed64_protoc, format_wire_varint_protoc,
15};
16
17pub fn format_protoc_value(field: &ProtoTextField, include_wire_types: bool) -> Option<String> {
25 match &field.content {
26 ProtoTextContent::InvalidTagType(_)
28 | ProtoTextContent::InvalidVarint(_)
29 | ProtoTextContent::InvalidFixed64(_)
30 | ProtoTextContent::InvalidFixed32(_)
31 | ProtoTextContent::InvalidBytesLength(_)
32 | ProtoTextContent::TruncatedBytes(_)
33 | ProtoTextContent::InvalidPackedRecords(_)
34 | ProtoTextContent::InvalidString(_)
35 | ProtoTextContent::InvalidGroupEnd(_) => None,
36
37 ProtoTextContent::WireVarint(v) => {
39 if include_wire_types {
40 Some(format_wire_varint_protoc(*v))
41 } else {
42 None
43 }
44 }
45 ProtoTextContent::WireFixed64(v) => {
46 if include_wire_types {
47 Some(format_wire_fixed64_protoc(*v))
48 } else {
49 None
50 }
51 }
52 ProtoTextContent::WireFixed32(v) => {
53 if include_wire_types {
54 Some(format_wire_fixed32_protoc(*v))
55 } else {
56 None
57 }
58 }
59 ProtoTextContent::WireBytes(b) => {
60 if include_wire_types {
61 Some(format!("\"{}\"", escape_bytes(b)))
62 } else {
63 None
64 }
65 }
66
67 ProtoTextContent::Int64(v) => Some(format_int64_protoc(*v)),
69 ProtoTextContent::Uint64(v) => Some(format_uint64_protoc(*v)),
70 ProtoTextContent::Int32(v) => Some(format_int32_protoc(*v)),
71 ProtoTextContent::Uint32(v) => Some(format_uint32_protoc(*v)),
72 ProtoTextContent::Bool(v) => Some(format_bool_protoc(*v).to_owned()),
73 ProtoTextContent::Enum(v) => Some(format_enum_protoc(*v)),
74 ProtoTextContent::Sint32(v) => Some(format_sint32_protoc(*v)),
75 ProtoTextContent::Sint64(v) => Some(format_sint64_protoc(*v)),
76
77 ProtoTextContent::Double(v) => Some(format_double_protoc(*v)),
79 ProtoTextContent::PFixed64(v) => Some(format_fixed64_protoc(*v)),
80 ProtoTextContent::Sfixed64(v) => Some(format_sfixed64_protoc(*v)),
81
82 ProtoTextContent::Float(v) => Some(format_float_protoc(*v)),
84 ProtoTextContent::PFixed32(v) => Some(format_fixed32_protoc(*v)),
85 ProtoTextContent::Sfixed32(v) => Some(format_sfixed32_protoc(*v)),
86
87 ProtoTextContent::StringVal(s) => Some(format!("\"{}\"", escape_string(s))),
89 ProtoTextContent::BytesVal(b) => Some(format!("\"{}\"", escape_bytes(b))),
90
91 ProtoTextContent::MessageVal(_)
93 | ProtoTextContent::Group(_)
94 | ProtoTextContent::WireGroup(_) => None,
95
96 ProtoTextContent::Doubles(vs) => Some(format!(
98 "[{}]",
99 vs.iter()
100 .map(|v| format_double_protoc(*v))
101 .collect::<Vec<_>>()
102 .join(", ")
103 )),
104 ProtoTextContent::Floats(vs) => Some(format!(
105 "[{}]",
106 vs.iter()
107 .map(|v| format_float_protoc(*v))
108 .collect::<Vec<_>>()
109 .join(", ")
110 )),
111 ProtoTextContent::Int64s(vs) => Some(format!(
112 "[{}]",
113 vs.iter()
114 .map(|v| format_int64_protoc(*v))
115 .collect::<Vec<_>>()
116 .join(", ")
117 )),
118 ProtoTextContent::Uint64s(vs) => Some(format!(
119 "[{}]",
120 vs.iter()
121 .map(|v| format_uint64_protoc(*v))
122 .collect::<Vec<_>>()
123 .join(", ")
124 )),
125 ProtoTextContent::Int32s(vs) => Some(format!(
126 "[{}]",
127 vs.iter()
128 .map(|v| format_int32_protoc(*v))
129 .collect::<Vec<_>>()
130 .join(", ")
131 )),
132 ProtoTextContent::Fixed64s(vs) => Some(format!(
133 "[{}]",
134 vs.iter()
135 .map(|v| format_fixed64_protoc(*v))
136 .collect::<Vec<_>>()
137 .join(", ")
138 )),
139 ProtoTextContent::Fixed32s(vs) => Some(format!(
140 "[{}]",
141 vs.iter()
142 .map(|v| format_fixed32_protoc(*v))
143 .collect::<Vec<_>>()
144 .join(", ")
145 )),
146 ProtoTextContent::Bools(vs) => Some(format!(
147 "[{}]",
148 vs.iter()
149 .map(|v| format_bool_protoc(*v))
150 .collect::<Vec<_>>()
151 .join(", ")
152 )),
153 ProtoTextContent::Uint32s(vs) => Some(format!(
154 "[{}]",
155 vs.iter()
156 .map(|v| format_uint32_protoc(*v))
157 .collect::<Vec<_>>()
158 .join(", ")
159 )),
160 ProtoTextContent::Enums(vs) => Some(format!(
161 "[{}]",
162 vs.iter()
163 .map(|v| format_enum_protoc(*v))
164 .collect::<Vec<_>>()
165 .join(", ")
166 )),
167 ProtoTextContent::Sfixed32s(vs) => Some(format!(
168 "[{}]",
169 vs.iter()
170 .map(|v| format_sfixed32_protoc(*v))
171 .collect::<Vec<_>>()
172 .join(", ")
173 )),
174 ProtoTextContent::Sfixed64s(vs) => Some(format!(
175 "[{}]",
176 vs.iter()
177 .map(|v| format_sfixed64_protoc(*v))
178 .collect::<Vec<_>>()
179 .join(", ")
180 )),
181 ProtoTextContent::Sint32s(vs) => Some(format!(
182 "[{}]",
183 vs.iter()
184 .map(|v| format_sint32_protoc(*v))
185 .collect::<Vec<_>>()
186 .join(", ")
187 )),
188 ProtoTextContent::Sint64s(vs) => Some(format!(
189 "[{}]",
190 vs.iter()
191 .map(|v| format_sint64_protoc(*v))
192 .collect::<Vec<_>>()
193 .join(", ")
194 )),
195
196 ProtoTextContent::Unset => None,
197 }
198}
199
200#[inline]
203pub fn is_nested(content: &ProtoTextContent) -> bool {
204 matches!(
205 content,
206 ProtoTextContent::MessageVal(_)
207 | ProtoTextContent::Group(_)
208 | ProtoTextContent::WireGroup(_)
209 )
210}
211
212#[inline]
213pub fn is_invalid(content: &ProtoTextContent) -> bool {
214 matches!(
215 content,
216 ProtoTextContent::InvalidTagType(_)
217 | ProtoTextContent::InvalidVarint(_)
218 | ProtoTextContent::InvalidFixed64(_)
219 | ProtoTextContent::InvalidFixed32(_)
220 | ProtoTextContent::InvalidBytesLength(_)
221 | ProtoTextContent::TruncatedBytes(_)
222 | ProtoTextContent::InvalidPackedRecords(_)
223 | ProtoTextContent::InvalidString(_)
224 | ProtoTextContent::InvalidGroupEnd(_)
225 )
226}
227
228pub struct Modifier {
233 pub text: String,
234}
235
236pub fn get_modifiers(field: &ProtoTextField) -> Vec<Modifier> {
237 let mut out = Vec::new();
238
239 if let Some(v) = field.tag_overhang_count {
240 out.push(Modifier {
241 text: format!("tag_overhang_count: {}", v),
242 });
243 }
244 if field.tag_is_out_of_range {
245 out.push(Modifier {
246 text: "tag_is_out_of_range: true".to_owned(),
247 });
248 }
249 if let Some(v) = field.value_overhang_count {
250 out.push(Modifier {
251 text: format!("value_overhang_count: {}", v),
252 });
253 }
254 if let Some(v) = field.length_overhang_count {
255 out.push(Modifier {
256 text: format!("length_overhang_count: {}", v),
257 });
258 }
259 if let Some(v) = field.missing_bytes_count {
260 out.push(Modifier {
261 text: format!("missing_bytes_count: {}", v),
262 });
263 }
264 if let Some(v) = field.mismatched_group_end {
265 out.push(Modifier {
266 text: format!("mismatched_group_end: {}", v),
267 });
268 }
269 if field.open_ended_group {
270 out.push(Modifier {
271 text: "open_ended_group: true".to_owned(),
272 });
273 }
274 if let Some(v) = field.end_tag_overhang_count {
275 out.push(Modifier {
276 text: format!("end_tag_overhang_count: {}", v),
277 });
278 }
279 if field.end_tag_is_out_of_range {
280 out.push(Modifier {
281 text: "end_tag_is_out_of_range: true".to_owned(),
282 });
283 }
284 if field.proto2_has_type_mismatch {
285 out.push(Modifier {
286 text: "proto2_has_type_mismatch: true".to_owned(),
287 });
288 }
289 if !field.records_overhung_count.is_empty() {
290 let vals: Vec<String> = field
291 .records_overhung_count
292 .iter()
293 .map(|v| v.to_string())
294 .collect();
295 out.push(Modifier {
296 text: format!("records_overhung_count: [{}]", vals.join(", ")),
297 });
298 }
299 out
300}