atproto repo as vfs
1use anyhow::Result;
2use atpfs::{
3 cli::{opts, SubCommand},
4 resolve_did, resolve_pds, AtpFS,
5};
6
7use std::sync::Arc;
8use tokio::runtime::Handle;
9
10async fn run_app(args: Vec<String>) -> Result<()> {
11 let opts = opts().run_inner(args.as_slice());
12
13 if let Err(err) = opts {
14 err.print_message(80);
15 return Ok(());
16 }
17
18 let opts = opts.unwrap();
19
20 println!("resolving identity for: {}", opts.identifier);
21 let did = resolve_did(&opts.identifier).await?;
22 println!("resolved DID: {}", did);
23 let pds = resolve_pds(&did).await?;
24 println!("resolved PDS: {}", pds);
25
26 let fs = Arc::new(AtpFS::new(did, pds).await);
27
28 match opts.cmd {
29 SubCommand::Ls { path } => {
30 let files = fs.read_dir(&path).await?;
31 for item in files {
32 println!("{}", item);
33 }
34 }
35 #[cfg(target_os = "linux")]
36 SubCommand::Fuse { mount_point } => {
37 use atpfs::fuse::AtpFuse;
38 use easy_fuser::{prelude::*, templates::DefaultFuseHandler};
39
40 let options = vec![MountOption::RO, MountOption::FSName("atproto".to_string())];
41
42 let handle = Handle::current();
43
44 let fuse_handler = AtpFuse {
45 fs,
46 inner: DefaultFuseHandler::new(),
47 runtime: handle,
48 };
49
50 println!("mounting at {:?}...", mount_point);
51 tokio::task::block_in_place(|| {
52 easy_fuser::mount(fuse_handler, mount_point, &options, 4)
53 })?;
54 }
55 }
56
57 Ok(())
58}
59
60#[tokio::main]
61async fn main() -> Result<()> {
62 let args: Vec<String> = std::env::args().skip(1).collect();
63 run_app(args).await
64}