smart-tree 8.0.1

Smart Tree - An intelligent, AI-friendly directory visualization tool
Documentation
// JSON Decoder - Convert quantum format to JSON
// Shows how all formats are now just decoders of the quantum stream

use super::{QuantumDecoder, QuantumEntry, TraversalCode};
use anyhow::Result;
use serde_json::{json, Value};
use std::io::Write;

pub struct JsonDecoder {
    stack: Vec<Value>,
    current_children: Vec<Value>,
}

impl Default for JsonDecoder {
    fn default() -> Self {
        Self::new()
    }
}

impl JsonDecoder {
    pub fn new() -> Self {
        Self {
            stack: Vec::new(),
            current_children: Vec::new(),
        }
    }
}

impl QuantumDecoder for JsonDecoder {
    fn init(&mut self, writer: &mut dyn Write) -> Result<()> {
        writeln!(writer, "{{")?;
        writeln!(writer, "  \"format\": \"quantum-decoded\",")?;
        writeln!(writer, "  \"version\": \"1.0\",")?;
        writeln!(writer, "  \"tree\": [")?;
        Ok(())
    }

    fn decode_entry(&mut self, entry: &QuantumEntry, _writer: &mut dyn Write) -> Result<()> {
        let mut node = json!({
            "name": entry.name,
            "type": if entry.is_dir { "directory" } else { "file" },
        });

        if let Some(size) = entry.size {
            node["size"] = json!(size);
        }

        if let Some(perms) = entry.perms_delta {
            node["permissions_delta"] = json!(format!("0x{:04x}", perms));
        }

        match entry.traversal {
            TraversalCode::Deeper => {
                // Starting a new directory level
                node["children"] = json!([]);
                self.stack.push(node);
            }
            TraversalCode::Back => {
                // Exiting directory level
                if let Some(mut parent) = self.stack.pop() {
                    parent["children"] = json!(self.current_children.clone());
                    self.current_children.clear();
                    self.current_children.push(parent);
                }
            }
            TraversalCode::Same => {
                // Same level
                self.current_children.push(node);
            }
            TraversalCode::Summary => {
                // Summary node
                self.current_children.push(node);
            }
        }

        Ok(())
    }

    fn finish(&mut self, writer: &mut dyn Write) -> Result<()> {
        // Finalize any remaining stack
        while let Some(mut parent) = self.stack.pop() {
            parent["children"] = json!(self.current_children.clone());
            self.current_children.clear();
            self.current_children.push(parent);
        }

        // Write the tree
        let tree_json = serde_json::to_string_pretty(&self.current_children)?;
        write!(writer, "{}", tree_json)?;

        writeln!(writer, "\n  ]")?;
        writeln!(writer, "}}")?;
        Ok(())
    }
}