embeddenator_cli/commands/
mount.rs1#[cfg(feature = "fuse")]
4use anyhow::Result;
5#[cfg(feature = "fuse")]
6use embeddenator_fs::embrfs::{EmbrFS, DEFAULT_CHUNK_SIZE};
7#[cfg(feature = "fuse")]
8use embeddenator_fs::fuse_shim::{mount, EngramFS, MountOptions};
9#[cfg(feature = "fuse")]
10use embeddenator_vsa::ReversibleVSAConfig;
11#[cfg(feature = "fuse")]
12use std::path::PathBuf;
13
14#[cfg(feature = "fuse")]
15pub fn handle_mount(
16 engram: PathBuf,
17 manifest: PathBuf,
18 mountpoint: PathBuf,
19 allow_other: bool,
20 _foreground: bool,
21 verbose: bool,
22) -> Result<()> {
23 if verbose {
24 println!("Embeddenator v{} - FUSE Mount", env!("CARGO_PKG_VERSION"));
25 println!("============================");
26 }
27
28 let engram_data = EmbrFS::load_engram(&engram)?;
30 let manifest_data = EmbrFS::load_manifest(&manifest)?;
31 let config = ReversibleVSAConfig::default();
32
33 if verbose {
34 println!("Loaded engram: {}", engram.display());
35 println!("Loaded manifest: {} files", manifest_data.files.len());
36 }
37
38 let fuse_fs = EngramFS::new(true);
40
41 for file_entry in &manifest_data.files {
42 let mut reconstructed = Vec::new();
44
45 for &chunk_id in &file_entry.chunks {
46 if let Some(chunk_vec) = engram_data.codebook.get(&chunk_id) {
47 let decoded =
50 chunk_vec.decode_data(&config, Some(&file_entry.path), DEFAULT_CHUNK_SIZE);
51
52 let chunk_data = if let Some(corrected) =
54 engram_data.corrections.apply(chunk_id as u64, &decoded)
55 {
56 corrected
57 } else {
58 decoded
60 };
61
62 reconstructed.extend_from_slice(&chunk_data);
63 }
64 }
65
66 reconstructed.truncate(file_entry.size);
68
69 if let Err(e) = fuse_fs.add_file(&file_entry.path, reconstructed) {
71 if verbose {
72 eprintln!("Warning: Failed to add {}: {}", file_entry.path, e);
73 }
74 }
75 }
76
77 if verbose {
78 println!(
79 "Populated {} files into FUSE filesystem",
80 fuse_fs.file_count()
81 );
82 println!("Total size: {} bytes", fuse_fs.total_size());
83 println!("Mounting at: {}", mountpoint.display());
84 println!();
85 }
86
87 if !mountpoint.exists() {
89 anyhow::bail!("Mountpoint does not exist: {}", mountpoint.display());
90 }
91
92 let options = MountOptions {
94 read_only: true,
95 allow_other,
96 allow_root: !allow_other,
97 fsname: format!("engram:{}", engram.display()),
98 };
99
100 println!("EngramFS mounted at {}", mountpoint.display());
102 println!("Use 'fusermount -u {}' to unmount", mountpoint.display());
103
104 mount(fuse_fs, &mountpoint, options)?;
105
106 if verbose {
107 println!("\nUnmounted.");
108 }
109
110 Ok(())
111}
112
113#[cfg(not(feature = "fuse"))]
114pub fn handle_mount(
115 _engram: std::path::PathBuf,
116 _manifest: std::path::PathBuf,
117 _mountpoint: std::path::PathBuf,
118 _allow_other: bool,
119 _foreground: bool,
120 _verbose: bool,
121) -> anyhow::Result<()> {
122 anyhow::bail!("FUSE support not enabled. Build with --features fuse")
123}