1use crate::util::{opt_u32, read_str, read_u32le, read_u8};
2use std::convert::TryInto;
3use std::fmt::{self, Display, Formatter};
4use std::io::{self, Read};
5
6#[derive(Debug)]
19pub struct Node {
20 parent_id: Option<u32>,
21 parent_line_no: u32,
22 node_type: NodeType,
23 quiet: bool,
24}
25impl Node {
26 pub(crate) fn read_from(mut input: impl Read) -> Result<Self, io::Error> {
27 let parent_id = opt_u32(read_u32le(&mut input)?);
28 let parent_line_no = read_u32le(&mut input)?;
29 let (node_type, quiet) = NodeType::read_from(input)?;
30
31 Ok(Node {
32 parent_id,
33 parent_line_no,
34 node_type,
35 quiet,
36 })
37 }
38
39 pub fn parent(&self) -> Option<(u32, u32)> {
42 self.parent_id.map(|id| (id, self.parent_line_no))
43 }
44
45 pub fn type_data(&self) -> &NodeType {
47 &self.node_type
48 }
49
50 pub fn is_quiet(&self) -> &bool {
52 &self.quiet
53 }
54
55 pub fn is_rept(&self) -> bool {
57 matches!(self.type_data(), NodeType::Rept(..))
58 }
59}
60
61#[derive(Debug)]
63pub enum NodeType {
64 Rept(Vec<u32>),
67 File(Vec<u8>),
70 Macro(Vec<u8>),
73}
74impl NodeType {
75 fn read_from(mut input: impl Read) -> Result<(Self, bool), io::Error> {
76 let node_type = read_u8(&mut input)?;
77 let quiet = (node_type & 0x80) != 0;
78 match node_type & 0x7F {
79 0 => {
80 let depth = read_u32le(&mut input)?.try_into().unwrap();
81 let mut iters = Vec::with_capacity(depth);
82 for _ in 0..depth {
83 iters.push(read_u32le(&mut input)?);
84 }
85 Ok((NodeType::Rept(iters), quiet))
86 }
87 1 => Ok((NodeType::File(read_str(input)?), quiet)),
88 2 => Ok((NodeType::Macro(read_str(input)?), quiet)),
89 _ => Err(io::Error::new(
90 io::ErrorKind::InvalidData,
91 "Invalid fstack node type",
92 )),
93 }
94 }
95}
96impl Display for NodeType {
97 fn fmt(&self, fmt: &mut Formatter) -> Result<(), fmt::Error> {
98 use NodeType::*;
99
100 match self {
101 Rept(iters) => {
102 for iter in iters {
103 write!(fmt, "::REPT~{iter}")?;
104 }
105 }
106 File(name) | Macro(name) => write!(fmt, "{}", String::from_utf8_lossy(name))?,
107 };
108 Ok(())
109 }
110}