memvid_cli/commands/
debug.rs1use std::path::PathBuf;
4
5use anyhow::{bail, Result};
6use clap::{ArgAction, Args};
7
8use crate::utils::open_read_only_mem;
9
10#[derive(Args)]
12pub struct DebugSegmentArgs {
13 #[arg(value_name = "FILE", value_parser = clap::value_parser!(PathBuf))]
14 pub file: PathBuf,
15 #[arg(long = "segment-id", value_name = "ID")]
16 pub segment_id: u64,
17 #[arg(long = "hex-dump", action = ArgAction::SetTrue)]
18 pub hex_dump: bool,
19 #[arg(long = "max-bytes", value_name = "N", default_value = "256")]
20 pub max_bytes: usize,
21}
22
23pub fn handle_debug_segment(args: DebugSegmentArgs) -> Result<()> {
25 let mut mem = open_read_only_mem(&args.file)?;
26 let Some((descriptor, bytes)) = mem.read_vec_segment(args.segment_id)? else {
27 bail!(
28 "vector segment {} not found in {}",
29 args.segment_id,
30 args.file.display()
31 );
32 };
33
34 println!("Vector segment {}", descriptor.common.segment_id);
35 println!(" offset: {}", descriptor.common.bytes_offset);
36 println!(" length: {} bytes", descriptor.common.bytes_length);
37 println!(" checksum: {}", hex::encode(descriptor.common.checksum));
38 println!(" vectors: {}", descriptor.vector_count);
39 println!(" dimension: {}", descriptor.dimension);
40 println!(" compression: {:?}", descriptor.vector_compression);
41 println!(" bytes loaded: {}", bytes.len());
42
43 if args.hex_dump {
44 if args.max_bytes == 0 {
45 println!("Hex dump skipped: --max-bytes is 0");
46 return Ok(());
47 }
48 if bytes.is_empty() {
49 println!("Hex dump skipped: segment contains no bytes");
50 return Ok(());
51 }
52 let limit = bytes.len().min(args.max_bytes);
53 println!("Hex dump (showing {} of {} bytes):", limit, bytes.len());
54 for (row, chunk) in bytes[..limit].chunks(16).enumerate() {
55 let offset = row * 16;
56 print!("{offset:08x}: ");
57 for i in 0..16 {
58 if let Some(byte) = chunk.get(i) {
59 print!("{byte:02x} ");
60 } else {
61 print!(" ");
62 }
63 }
64 print!("|");
65 for byte in chunk {
66 let ch = if (0x20..=0x7e).contains(byte) {
67 *byte as char
68 } else {
69 '.'
70 };
71 print!("{ch}");
72 }
73 println!("|");
74 }
75 }
76
77 Ok(())
78}