Skip to content

Commit 33c29b5

Browse files
committed
Add trace support for json, fix ParsedValue matches_inner
1 parent c76b6f8 commit 33c29b5

File tree

4 files changed

+53
-15
lines changed

4 files changed

+53
-15
lines changed

doodle-formats/src/main.rs

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -263,19 +263,33 @@ fn main() -> Result<(), Box<dyn std::error::Error + 'static>> {
263263
let program = Compiler::compile_program(&module, &format)?;
264264

265265
let input = fs::read(filename)?;
266-
let (value, _) = program.run(ReadCtxt::new(&input))?;
267-
268266
match output {
269-
FileOutput::Debug => println!("{value:?}"),
270-
FileOutput::Json => serde_json::to_writer(std::io::stdout(), &value).unwrap(),
271-
FileOutput::Tree if !trace => {
272-
doodle::output::tree::print_decoded_value(&module, &value, &format);
267+
FileOutput::Debug => {
268+
let (value, _) = program.run(ReadCtxt::new(&input))?;
269+
println!("{value:?}");
270+
}
271+
FileOutput::Json => {
272+
if trace {
273+
let (p_value, _) = program.run_with_loc(ReadCtxt::new(&input))?;
274+
serde_json::to_writer(std::io::stdout(), &p_value).unwrap()
275+
} else {
276+
let (value, _) = program.run(ReadCtxt::new(&input))?;
277+
serde_json::to_writer(std::io::stdout(), &value).unwrap()
278+
}
273279
}
274280
FileOutput::Tree => {
275-
let (p_value, _) = program.run_with_loc(ReadCtxt::new(&input))?;
276-
doodle::output::tree::print_parsed_decoded_value(&module, &p_value, &format);
281+
if trace {
282+
let (p_value, _) = program.run_with_loc(ReadCtxt::new(&input))?;
283+
doodle::output::tree::print_parsed_decoded_value(
284+
&module, &p_value, &format,
285+
);
286+
} else {
287+
let (value, _) = program.run(ReadCtxt::new(&input))?;
288+
doodle::output::tree::print_decoded_value(&module, &value, &format);
289+
}
277290
}
278291
FileOutput::Flat => {
292+
let (value, _) = program.run(ReadCtxt::new(&input))?;
279293
doodle::output::flat::print_decoded_value(&module, &value, &format);
280294
}
281295
}

src/decoder.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ impl Value {
149149
(Pattern::Int(bounds), Value::U16(n)) => bounds.contains(usize::from(*n)),
150150
(Pattern::Int(bounds), Value::U32(n)) => bounds.contains(usize::try_from(*n).unwrap()),
151151
(Pattern::Int(bounds), Value::U64(n)) => bounds.contains(usize::try_from(*n).unwrap()),
152+
(Pattern::Int(bounds), Value::Usize(n)) => bounds.contains(*n),
152153
(Pattern::Char(c0), Value::Char(c1)) => c0 == c1,
153154
(Pattern::Tuple(ps), Value::Tuple(vs)) if ps.len() == vs.len() => {
154155
for (p, v) in Iterator::zip(ps.iter(), vs.iter()) {
@@ -247,6 +248,8 @@ impl Value {
247248
/// # Panics
248249
///
249250
/// Panics if the value is not numeric.
251+
///
252+
/// May additionally panic in rare cases such as `u64`-to-`usize` conversion on 32-bit architectures.
250253
pub(crate) fn unwrap_usize(&self) -> usize {
251254
match self {
252255
Value::U8(n) => usize::from(*n),
@@ -979,7 +982,7 @@ pub struct Program {
979982
}
980983

981984
impl Program {
982-
fn new() -> Self {
985+
pub(crate) fn new() -> Self {
983986
let decoders = Vec::new();
984987
Program { decoders }
985988
}

src/decoder/seq_kind.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use std::{borrow::Cow, fmt::Debug, ops::Index};
33
use serde::Serialize;
44

55
#[derive(Clone, PartialEq, Debug, Serialize, Hash, Eq)]
6+
#[serde(tag = "tag", content = "data")]
67
// NOTE - T must be clone in order for `Dup` to be well-founded, as non-Clone values cannot be duped
78
pub enum SeqKind<T: Clone> {
89
Strict(Vec<T>),

src/loc_decoder.rs

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,11 @@ use crate::read::ReadCtxt;
1111
use crate::{
1212
Arith, BaseKind, DynFormat, Endian, Expr, Format, IntRel, Label, Pattern, UnaryOp, ViewExpr,
1313
};
14+
use serde::Serialize;
1415
use std::borrow::Cow;
1516
use std::cmp::Ordering;
1617

17-
#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)]
18+
#[derive(Clone, Copy, Debug, PartialEq, Eq, Default, Serialize)]
1819
pub enum ParseLoc {
1920
InBuffer {
2021
offset: usize,
@@ -124,9 +125,10 @@ impl ParseLoc {
124125
}
125126

126127
/// Helper type for associating a [`ParseLoc`] with a value of a generic type.
127-
#[derive(Clone, Copy, Debug)]
128+
#[derive(Clone, Copy, Debug, Serialize)]
128129
pub struct Parsed<T: Clone> {
129130
pub(crate) loc: ParseLoc,
131+
#[serde(rename = "data")]
130132
pub(crate) inner: T,
131133
}
132134

@@ -143,7 +145,8 @@ impl<T: Clone> AsRef<T> for Parsed<T> {
143145
}
144146
}
145147

146-
#[derive(Clone, Debug)]
148+
#[derive(Clone, Debug, Serialize)]
149+
#[serde(tag = "tag", content = "data")]
147150
pub enum ParsedValue {
148151
/// Flat parses of the sub-set of `Value` variants that do not contain any embedded `Value` terms
149152
Flat(Parsed<Value>),
@@ -408,6 +411,14 @@ impl ParsedValue {
408411
}
409412
(Pattern::Option(None), ParsedValue::Option(None)) => true,
410413
(Pattern::Option(Some(p)), ParsedValue::Option(Some(v))) => v.matches_inner(scope, p),
414+
(Pattern::Int(bounds), ParsedValue::Flat(Parsed { inner: v, .. })) => match v {
415+
Value::U8(n) => bounds.contains(usize::from(*n)),
416+
Value::U16(n) => bounds.contains(usize::from(*n)),
417+
Value::U32(n) => bounds.contains(usize::try_from(*n).unwrap()),
418+
Value::U64(n) => bounds.contains(usize::try_from(*n).unwrap()),
419+
Value::Usize(n) => bounds.contains(*n),
420+
_ => false,
421+
},
411422
_ => false,
412423
}
413424
}
@@ -792,9 +803,18 @@ impl Expr {
792803
Expr::AsU8(x) => Cow::Owned(ParsedValue::from_evaluated(
793804
match x.eval_value_with_loc(scope) {
794805
Value::U8(x) => Value::U8(x),
795-
Value::U16(x) => Value::U8(u8::try_from(x).unwrap()),
796-
Value::U32(x) => Value::U8(u8::try_from(x).unwrap()),
797-
Value::U64(x) => Value::U8(u8::try_from(x).unwrap()),
806+
Value::U16(x) => Value::U8(u8::try_from(x).unwrap_or_else(|err| {
807+
panic!("cannot perform AsU8 cast on u16 {x}: {err}")
808+
})),
809+
Value::U32(x) => Value::U8(u8::try_from(x).unwrap_or_else(|err| {
810+
panic!("cannot perform AsU8 cast on u32 {x}: {err}")
811+
})),
812+
Value::U64(x) => Value::U8(u8::try_from(x).unwrap_or_else(|err| {
813+
panic!("cannot perform AsU8 cast on u64 {x}: {err}")
814+
})),
815+
Value::Usize(x) => Value::U8(u8::try_from(x).unwrap_or_else(|err| {
816+
panic!("cannot perform AsU8 cast on usize {x}: {err}")
817+
})),
798818
x => panic!("cannot convert {x:?} to U8"),
799819
},
800820
)),

0 commit comments

Comments
 (0)