A better Rust ATProto crate

docs fixes

Changed files
+19 -30
crates
jacquard
src
identity
jacquard-common
+1 -1
crates/jacquard-common/src/lib.rs
··· 6 6 pub use smol_str; 7 7 pub use url; 8 8 9 - /// A copy-on-write immutable string type that uses [`SmolStr`] for 9 + /// A copy-on-write immutable string type that uses [`smol_str::SmolStr`] for 10 10 /// the "owned" variant. 11 11 #[macro_use] 12 12 pub mod cowstr;
-2
crates/jacquard-common/src/types/crypto.rs
··· 22 22 23 23 /// Known multicodec key codecs for Multikey public keys 24 24 /// 25 - 26 - /// ``` 27 25 #[derive(Debug, Clone, Copy, PartialEq, Eq)] 28 26 pub enum KeyCodec { 29 27 /// Ed25519
+2 -2
crates/jacquard-common/src/types/did_doc.rs
··· 35 35 #[serde(borrow)] 36 36 pub id: Did<'a>, 37 37 38 - /// Alternate identifiers for the subject, such as at://<handle> 38 + /// Alternate identifiers for the subject, such as at://\<handle\> 39 39 #[serde(borrow)] 40 40 pub also_known_as: Option<Vec<CowStr<'a>>>, 41 41 ··· 66 66 } 67 67 68 68 impl<'a> DidDocument<'a> { 69 - /// Extract validated handles from `alsoKnownAs` entries like `at://<handle>`. 69 + /// Extract validated handles from `alsoKnownAs` entries like `at://\<handle\>`. 70 70 pub fn handles(&self) -> Vec<Handle<'static>> { 71 71 self.also_known_as 72 72 .as_ref()
+2 -2
crates/jacquard/src/identity/resolver.rs
··· 161 161 /// Handle → DID fallback step. 162 162 #[derive(Debug, Clone, Copy, PartialEq, Eq)] 163 163 pub enum HandleStep { 164 - /// DNS TXT _atproto.<handle> 164 + /// DNS TXT _atproto.\<handle\> 165 165 DnsTxt, 166 - /// HTTPS GET https://<handle>/.well-known/atproto-did 166 + /// HTTPS GET https://\<handle\>/.well-known/atproto-did 167 167 HttpsWellKnown, 168 168 /// XRPC com.atproto.identity.resolveHandle against a provided PDS base 169 169 PdsResolveHandle,
+14 -23
crates/jacquard/src/lib.rs
··· 46 46 //! #[tokio::main] 47 47 //! async fn main() -> miette::Result<()> { 48 48 //! let args = Args::parse(); 49 - //! 50 49 //! // Create HTTP client 51 50 //! let url = url::Url::parse(&args.pds).unwrap(); 52 51 //! let client = BasicClient::new(url); 53 - //! 54 52 //! // Create session 55 53 //! let session = Session::from( 56 54 //! client ··· 63 61 //! .await? 64 62 //! .into_output()?, 65 63 //! ); 66 - //! 67 - //! println!("logged in as {} ({})", session.handle, session.did); 68 64 //! client.set_session(session).await.unwrap(); 69 - //! 70 65 //! // Fetch timeline 71 66 //! println!("\nfetching timeline..."); 72 67 //! let timeline = client 73 68 //! .send(GetTimeline::new().limit(5).build()) 74 69 //! .await? 75 70 //! .into_output()?; 76 - //! 77 71 //! println!("\ntimeline ({} posts):", timeline.feed.len()); 78 72 //! for (i, post) in timeline.feed.iter().enumerate() { 79 73 //! println!("\n{}. by {}", i + 1, post.post.author.handle); ··· 82 76 //! serde_json::to_string_pretty(&post.post.record).into_diagnostic()? 83 77 //! ); 84 78 //! } 85 - //! 86 79 //! Ok(()) 87 80 //! } 88 81 //! ``` 89 82 //! 90 - //! ## Clients 83 + //! ## Client options: 91 84 //! 92 85 //! - Stateless XRPC: any `HttpClient` (e.g., `reqwest::Client`) implements `XrpcExt`, 93 86 //! which provides `xrpc(base: Url) -> XrpcCall` for per-request calls with 94 87 //! optional `CallOptions` (auth, proxy, labelers, headers). Useful when you 95 88 //! want to pass auth on each call or build advanced flows. 96 - //! Example 97 - //! ```ignore 98 - //! use jacquard::client::XrpcExt; 99 - //! use jacquard::api::app_bsky::feed::get_author_feed::GetAuthorFeed; 100 - //! use jacquard::types::ident::AtIdentifier; 101 - //! 89 + //! ```no_run 90 + //! # use jacquard::client::XrpcExt; 91 + //! # use jacquard::api::app_bsky::feed::get_author_feed::GetAuthorFeed; 92 + //! # use jacquard::types::ident::AtIdentifier; 93 + //! # 102 94 //! #[tokio::main] 103 95 //! async fn main() -> anyhow::Result<()> { 104 96 //! let http = reqwest::Client::new(); ··· 124 116 //! `AtClient<reqwest::Client, MemoryTokenStore>` with a `new(Url)` constructor. 125 117 //! 126 118 //! Per-request overrides (stateless) 127 - //! ```ignore 128 - //! use jacquard::client::{XrpcExt, AuthorizationToken}; 129 - //! use jacquard::api::app_bsky::feed::get_author_feed::GetAuthorFeed; 130 - //! use jacquard::types::ident::AtIdentifier; 131 - //! use jacquard::CowStr; 132 - //! use miette::IntoDiagnostic; 133 - //! 119 + //! ```no_run 120 + //! # use jacquard::client::{XrpcExt, AuthorizationToken}; 121 + //! # use jacquard::api::app_bsky::feed::get_author_feed::GetAuthorFeed; 122 + //! # use jacquard::types::ident::AtIdentifier; 123 + //! # use jacquard::CowStr; 124 + //! # use miette::IntoDiagnostic; 125 + //! # 134 126 //! #[tokio::main] 135 127 //! async fn main() -> miette::Result<()> { 136 128 //! let http = reqwest::Client::new(); ··· 157 149 //! - Use `MemoryTokenStore` for ephemeral sessions, tests, and CLIs. 158 150 //! - For persistence, `FileTokenStore` stores session tokens as JSON on disk. 159 151 //! See `client::token::FileTokenStore` docs for details. 160 - //! Example 161 - //! ```ignore 152 + //! ```no_run 162 153 //! use jacquard::client::{AtClient, FileTokenStore}; 163 154 //! let base = url::Url::parse("https://bsky.social").unwrap(); 164 155 //! let store = FileTokenStore::new("/tmp/jacquard-session.json");