+89
-1
crates/jacquard/src/lib.rs
+89
-1
crates/jacquard/src/lib.rs
···
1
-
#![doc = include_str!("../../../README.md")]
1
+
//! # Jacquard
2
+
//!
3
+
//! A suite of Rust crates for the AT Protocol.
4
+
//!
5
+
//!
6
+
//! ## Goals
7
+
//!
8
+
//! - Validated, spec-compliant, easy to work with, and performant baseline types (including typed at:// uris)
9
+
//! - Batteries-included, but easily replaceable batteries.
10
+
//! - Easy to extend with custom lexicons
11
+
//! - lexicon Value type for working with unknown atproto data (dag-cbor or json)
12
+
//! - order of magnitude less boilerplate than some existing crates
13
+
//! - either the codegen produces code that's easy to work with, or there are good handwritten wrappers
14
+
//! - didDoc type with helper methods for getting handles, multikey, and PDS endpoint
15
+
//! - use as much or as little from the crates as you need
16
+
//!
17
+
//!
18
+
//! ## Example
19
+
//!
20
+
//! Dead simple api client. Logs in, prints the latest 5 posts from your timeline.
21
+
//!
22
+
//! ```rust
23
+
//! # use clap::Parser;
24
+
//! # use jacquard::CowStr;
25
+
//! use jacquard::api::app_bsky::feed::get_timeline::GetTimeline;
26
+
//! use jacquard::api::com_atproto::server::create_session::CreateSession;
27
+
//! use jacquard::client::{AuthenticatedClient, Session, XrpcClient};
28
+
//! # use miette::IntoDiagnostic;
29
+
//!
30
+
//! # #[derive(Parser, Debug)]
31
+
//! # #[command(author, version, about = "Jacquard - AT Protocol client demo")]
32
+
//! # struct Args {
33
+
//! # /// Username/handle (e.g., alice.mosphere.at)
34
+
//! # #[arg(short, long)]
35
+
//! # username: CowStr<'static>,
36
+
//! #
37
+
//! # /// PDS URL (e.g., https://bsky.social)
38
+
//! # #[arg(long, default_value = "https://bsky.social")]
39
+
//! # pds: CowStr<'static>,
40
+
//! #
41
+
//! # /// App password
42
+
//! # #[arg(short, long)]
43
+
//! # password: CowStr<'static>,
44
+
//! # }
45
+
//!
46
+
//! #[tokio::main]
47
+
//! async fn main() -> miette::Result<()> {
48
+
//! let args = Args::parse();
49
+
//!
50
+
//! // Create HTTP client
51
+
//! let mut client = AuthenticatedClient::new(reqwest::Client::new(), args.pds);
52
+
//!
53
+
//! // Create session
54
+
//! let session = Session::from(
55
+
//! client
56
+
//! .send(
57
+
//! CreateSession::new()
58
+
//! .identifier(args.username)
59
+
//! .password(args.password)
60
+
//! .build(),
61
+
//! )
62
+
//! .await?
63
+
//! .into_output()?,
64
+
//! );
65
+
//!
66
+
//! println!("logged in as {} ({})", session.handle, session.did);
67
+
//! client.set_session(session);
68
+
//!
69
+
//! // Fetch timeline
70
+
//! println!("\nfetching timeline...");
71
+
//! let timeline = client
72
+
//! .send(GetTimeline::new().limit(5).build())
73
+
//! .await?
74
+
//! .into_output()?;
75
+
//!
76
+
//! println!("\ntimeline ({} posts):", timeline.feed.len());
77
+
//! for (i, post) in timeline.feed.iter().enumerate() {
78
+
//! println!("\n{}. by {}", i + 1, post.post.author.handle);
79
+
//! println!(
80
+
//! " {}",
81
+
//! serde_json::to_string_pretty(&post.post.record).into_diagnostic()?
82
+
//! );
83
+
//! }
84
+
//!
85
+
//! Ok(())
86
+
//! }
87
+
//! ```
88
+
//!
89
+
2
90
#![warn(missing_docs)]
3
91
4
92
/// XRPC client traits and basic implementation