1use urna_format::UrnaError;
7use urna_format::layout::SECTION_CHUNKS_CANONICAL;
8use urna_format::reader::UrnaView;
9use urna_format::sections::decode_chunks_canonical;
10
11use crate::error::RuntimeError;
12use crate::mmap_file::MmapUrnaFile;
13
14impl MmapUrnaFile {
15 pub fn canonical_texts(&self) -> Result<Vec<String>, RuntimeError> {
22 let view = UrnaView::from_bytes(&self._mmap)?;
23 let n = view.header.n_chunks as usize;
24 decode_chunks_canonical(&view.decoded_section(SECTION_CHUNKS_CANONICAL)?, n)
25 .map_err(RuntimeError::Format)
26 }
27
28 pub fn chunk_ids(&self) -> &[String] {
32 &self.chunk_ids
33 }
34
35 pub fn inspect_json(&self) -> Result<String, RuntimeError> {
39 let view = UrnaView::from_bytes(&self._mmap)?;
40 let magic = std::str::from_utf8(&view.header.magic)
41 .unwrap_or("")
42 .to_string();
43 let sections: Vec<serde_json::Value> = view
44 .section_table
45 .iter()
46 .map(|e| {
47 let name = urna_format::layout::section_name(e.section_id).unwrap_or("unknown");
48 serde_json::json!({
49 "section_id": e.section_id,
50 "name": name,
51 "encoding": e.encoding,
52 "offset": e.offset,
53 "size": e.size,
54 "checksum": hex::encode(e.checksum),
55 })
56 })
57 .collect();
58 let doc = serde_json::json!({
59 "magic": magic,
60 "version_major": view.header.version_major,
61 "version_minor": view.header.version_minor,
62 "format_version": view.manifest.format_version,
63 "schema_version": view.manifest.schema_version,
64 "embedding_dim": view.header.embedding_dim,
65 "n_chunks": view.header.n_chunks,
66 "n_embeddings": view.header.n_embeddings,
67 "file_size": view.header.file_size,
68 "manifest": view.manifest,
69 "sections": sections,
70 "blobs": self.blob_refs_json(),
71 "spaces": self.spaces_json(),
72 "file_hash": view.file_hash_hex(),
73 "content_hash": view.content_hash_hex()?,
74 "simd_backend": self.simd_backend().name(),
75 });
76 serde_json::to_string(&doc).map_err(|e| RuntimeError::Format(UrnaError::Json(e)))
77 }
78
79 fn spaces_json(&self) -> serde_json::Value {
84 match &self.spaces {
85 None => serde_json::Value::Null,
86 Some(spaces) => spaces
87 .iter()
88 .map(|s| {
89 serde_json::json!({
90 "name": s.entry.name,
91 "space_index": s.entry.space_index,
92 "dim": s.entry.dim,
93 "dtype": s.entry.dtype_str(),
94 "model_hash": s.entry.model_hash,
95 "n_vectors": s.entry.n_vectors,
96 "band_bytes": s.size,
97 })
98 })
99 .collect(),
100 }
101 }
102
103 fn blob_refs_json(&self) -> serde_json::Value {
108 match self.blob_refs() {
109 None => serde_json::Value::Null,
110 Some(refs) => refs
111 .iter()
112 .map(|r| {
113 serde_json::json!({
114 "content_hash": format!("sha256:{}", hex::encode(r.content_hash)),
115 "original_uri": r.original_uri,
116 "byte_len": r.byte_len,
117 "inlined": r.inlined,
118 })
119 })
120 .collect(),
121 }
122 }
123}