Skip to main content

st/decoders/
json.rs

1// JSON Decoder - Convert quantum format to JSON
2// Shows how all formats are now just decoders of the quantum stream
3
4use super::{QuantumDecoder, QuantumEntry, TraversalCode};
5use anyhow::Result;
6use serde_json::{json, Value};
7use std::io::Write;
8
9pub struct JsonDecoder {
10    stack: Vec<Value>,
11    current_children: Vec<Value>,
12}
13
14impl Default for JsonDecoder {
15    fn default() -> Self {
16        Self::new()
17    }
18}
19
20impl JsonDecoder {
21    pub fn new() -> Self {
22        Self {
23            stack: Vec::new(),
24            current_children: Vec::new(),
25        }
26    }
27}
28
29impl QuantumDecoder for JsonDecoder {
30    fn init(&mut self, writer: &mut dyn Write) -> Result<()> {
31        writeln!(writer, "{{")?;
32        writeln!(writer, "  \"format\": \"quantum-decoded\",")?;
33        writeln!(writer, "  \"version\": \"1.0\",")?;
34        writeln!(writer, "  \"tree\": [")?;
35        Ok(())
36    }
37
38    fn decode_entry(&mut self, entry: &QuantumEntry, _writer: &mut dyn Write) -> Result<()> {
39        let mut node = json!({
40            "name": entry.name,
41            "type": if entry.is_dir { "directory" } else { "file" },
42        });
43
44        if let Some(size) = entry.size {
45            node["size"] = json!(size);
46        }
47
48        if let Some(perms) = entry.perms_delta {
49            node["permissions_delta"] = json!(format!("0x{:04x}", perms));
50        }
51
52        match entry.traversal {
53            TraversalCode::Deeper => {
54                // Starting a new directory level
55                node["children"] = json!([]);
56                self.stack.push(node);
57            }
58            TraversalCode::Back => {
59                // Exiting directory level
60                if let Some(mut parent) = self.stack.pop() {
61                    parent["children"] = json!(self.current_children.clone());
62                    self.current_children.clear();
63                    self.current_children.push(parent);
64                }
65            }
66            TraversalCode::Same => {
67                // Same level
68                self.current_children.push(node);
69            }
70            TraversalCode::Summary => {
71                // Summary node
72                self.current_children.push(node);
73            }
74        }
75
76        Ok(())
77    }
78
79    fn finish(&mut self, writer: &mut dyn Write) -> Result<()> {
80        // Finalize any remaining stack
81        while let Some(mut parent) = self.stack.pop() {
82            parent["children"] = json!(self.current_children.clone());
83            self.current_children.clear();
84            self.current_children.push(parent);
85        }
86
87        // Write the tree
88        let tree_json = serde_json::to_string_pretty(&self.current_children)?;
89        write!(writer, "{}", tree_json)?;
90
91        writeln!(writer, "\n  ]")?;
92        writeln!(writer, "}}")?;
93        Ok(())
94    }
95}