A better Rust ATProto crate
at main 1.7 kB view raw
1use clap::Parser; 2use jacquard::StreamingResponse; 3use jacquard::api::com_atproto::sync::get_blob::GetBlob; 4use jacquard::client::Agent; 5use jacquard::types::cid::Cid; 6use jacquard::types::did::Did; 7use jacquard::xrpc::XrpcStreamingClient; 8use jacquard_oauth::authstore::MemoryAuthStore; 9use jacquard_oauth::client::OAuthClient; 10use jacquard_oauth::loopback::LoopbackConfig; 11use n0_future::StreamExt; 12 13#[derive(Parser, Debug)] 14#[command( 15 author, 16 version, 17 about = "Download a blob from a PDS and stream the response, then display it, if it's an image" 18)] 19struct Args { 20 input: String, 21 #[arg(short, long)] 22 did: String, 23 #[arg(short, long)] 24 cid: String, 25} 26 27#[tokio::main] 28async fn main() -> miette::Result<()> { 29 let args = Args::parse(); 30 31 let oauth = OAuthClient::with_default_config(MemoryAuthStore::new()); 32 let session = oauth 33 .login_with_local_server(args.input, Default::default(), LoopbackConfig::default()) 34 .await?; 35 36 let agent: Agent<_> = Agent::from(session); 37 // Use the streaming `.download()` method with the generated API parameter struct 38 let output: StreamingResponse = agent 39 .download(GetBlob { 40 did: Did::new_owned(args.did)?, 41 cid: Cid::str(&args.cid), 42 }) 43 .await?; 44 45 let (parts, body_stream) = output.into_parts(); 46 47 println!("Parts: {:?}", parts); 48 49 let mut buf: Vec<u8> = Vec::new(); 50 let mut stream = body_stream.into_inner(); 51 52 while let Some(Ok(chunk)) = stream.as_mut().next().await { 53 buf.append(&mut chunk.to_vec()); 54 } 55 56 if let Ok(img) = image::load_from_memory(&buf) { 57 viuer::print(&img, &viuer::Config::default()).expect("Image printing failed."); 58 } 59 60 Ok(()) 61}