swh-mosaic 0.3.1

MOdular Storage of Archived and Indexed Contents from Software Heritage
Documentation
// Copyright (C) 2026  The Software Heritage developers
// See the AUTHORS file at the top-level directory of this distribution
// License: GNU General Public License version 3, or any later version
// See top-level LICENSE file for more information

//! implementation of the `swh-mosaic ebml-dump` subcommand

use crate::{
    backends::{MmapMosaicBackend, MosaicBackend},
    Position,
};
use anyhow::Result;
use std::path::Path;

/// Debugging tool: prints EBML tags and their offsets to the standard output
pub fn ebml_dump(filename: &Path, from: Option<usize>, to: Option<usize>) -> Result<()> {
    // don't use "from" because we don't know if it's really pointing to an EBML element
    let mut offset = Position(0);
    let backend = MmapMosaicBackend::new(filename)?;
    let mut indentation = String::from("");
    let mut unindent_offsets = Vec::<Position>::new();
    let width = to.unwrap_or(backend.len()).to_string().len();
    while let Ok((tag, size, next_offset)) = backend.read_one_tag_and_size(offset) {
        if offset >= from.unwrap_or(0) {
            println!("{: >w$?} {}{:?}", offset.0, indentation, tag, w = width);
        }
        if tag.is_master() {
            offset = next_offset;
            unindent_offsets.push(offset + size);
            indentation.push_str("    ");
        } else {
            offset = next_offset + size;
        }
        if let Some(o) = unindent_offsets.last() {
            if *o == offset {
                indentation.truncate(indentation.len() - 4);
            }
        }
        if let Some(maximum) = to {
            if offset >= maximum {
                break;
            }
        }
    }
    Ok(())
}