pub mod fs; use clap::Parser; use fuser::MountOption; use std::path::PathBuf; use furumi_client_core::FurumiClient; #[derive(Parser, Debug)] #[command(version, about, long_about = None)] struct Args { /// Server address to connect to #[arg(short, long, env = "FURUMI_SERVER", default_value = "http://[::1]:50051")] server: String, /// Authentication Bearer token (leave empty if auth is disabled on server) #[arg(short, long, env = "FURUMI_TOKEN", default_value = "")] token: String, /// Mount point directory #[arg(short, long, env = "FURUMI_MOUNT")] mount: PathBuf, } fn main() -> Result<(), Box> { tracing_subscriber::fmt::init(); let args = Args::parse(); if !args.mount.exists() || !args.mount.is_dir() { eprintln!("Error: Mount point {:?} does not exist or is not a directory", args.mount); std::process::exit(1); } // Create a robust tokio runtime for the background gRPC work let rt = tokio::runtime::Builder::new_multi_thread() .enable_all() .build()?; let client = rt.block_on(async { FurumiClient::connect(&args.server, &args.token).await })?; let fs = fs::FurumiFuse::new(client, rt.handle().clone()); let options = vec![ MountOption::RO, MountOption::FSName("furumi-ng".to_string()), MountOption::NoExec, // Better security for media mount ]; println!("Mounting Furumi-ng to {:?}", args.mount); fuser::mount2(fs, args.mount, &options)?; Ok(()) }