+1
-1
crates/jacquard-axum/src/service_auth.rs
+1
-1
crates/jacquard-axum/src/service_auth.rs
···
+3
-12
crates/jacquard-common/src/cowstr.rs
+3
-12
crates/jacquard-common/src/cowstr.rs
·········-pub fn deserialize_owned<'de, T, D>(deserializer: D) -> Result<<T as IntoStatic>::Output, D::Error>
+2
-1
crates/jacquard-common/src/into_static.rs
+2
-1
crates/jacquard-common/src/into_static.rs
···/// The "owned" variant of the type. For `Cow<'a, str>`, this is `Cow<'static, str>`, for example.
+12
-2
crates/jacquard-common/src/lib.rs
+12
-2
crates/jacquard-common/src/lib.rs
······+pub fn deserialize_owned<'de, T, D>(deserializer: D) -> Result<<T as IntoStatic>::Output, D::Error>
+1
-1
crates/jacquard-common/src/types/collection.rs
+1
-1
crates/jacquard-common/src/types/collection.rs
···+/// from this collection. Used by [`AgentSessionExt::get_record`](https://docs.rs/jacquard/latest/jacquard/client/trait.AgentSessionExt.html) to return properly typed responses.
+79
-25
crates/jacquard/src/lib.rs
+79
-25
crates/jacquard/src/lib.rs
···+//! A suite of Rust crates intended to make it much easier to get started with atproto development,+//! designed in a way which makes things simple that almost every other atproto library seems to make difficult.+//! It is also designed around zero-copy/borrowed deserialization: types like [`Post<'_>`](https://docs.rs/jacquard-api/latest/jacquard_api/app_bsky/feed/post/struct.Post.html) can borrow data (via the [`CowStr<'_>`](https://docs.rs/jacquard/latest/jacquard/cowstr/enum.CowStr.html) type and a host of other types built on top of it) directly from the response buffer instead of allocating owned copies. Owned versions are themselves mostly inlined or reference-counted pointers and are therefore still quite efficient. The `IntoStatic` trait (which is derivable) makes it easy to get an owned version and avoid worrying about lifetimes.···+//! - [`jacquard-common`](https://docs.rs/jacquard-common/latest/jacquard_common/index.html) - AT Protocol types (DIDs, handles, at-URIs, NSIDs, TIDs, CIDs, etc.)+//! - [`jacquard-api`](https://docs.rs/jacquard-api/latest/jacquard_api/index.html) - Generated API bindings from 646+ lexicon schemas+//! - [`jacquard-axum`](https://docs.rs/jacquard-axum/latest/jacquard_axum/index.html) - Server-side XRPC handler extractors for Axum framework (not re-exported, depends on jacquard)+//! - [`jacquard-oauth`](https://docs.rs/jacquard-oauth/latest/jacquard_oauth/index.html) - OAuth/DPoP flow implementation with session management+//! - [`jacquard-identity`](https://docs.rs/jacquard-identity/latest/jacquard_identity/index.html) - Identity resolution (handle → DID, DID → Doc, OAuth metadata)+//! - [`jacquard-lexicon`](https://docs.rs/jacquard-lexicon/latest/jacquard_lexicon/index.html) - Lexicon resolution, fetching, parsing and Rust code generation from schemas+//! - [`jacquard-derive`](https://docs.rs/jacquard-derive/latest/jacquard_derive/index.html) - Macros (`#[lexicon]`, `#[open_union]`, `#[derive(IntoStatic)]`)+//! You'll notice a bunch of lifetimes all over Jacquard types, examples, and so on. If you're newer+//! to Rust or have simply avoided them, they're part of how Rust knows how long to keep something+//! internally) but Rust is perhaps the one language that makes them explicit, because they're part+//! of how it validates that things are memory-safe, and being able to give information to the compiler+//! about how long it can expect something to stick around lets the compiler reason out much more+//! sophisticated things. [The Rust book](https://doc.rust-lang.org/book/ch10-03-lifetime-syntax.html) has a section on them if you want a refresher.+//! > On Jacquard types like [`CowStr`], a `'static` lifetime parameter is used to refer to the owned+//! This is somewhat in tension with the 'make things simpler' goal of the crate, but it is honestly+//! pretty straightforward once you know the deal, and Jacquard provides a number of escape hatches+//! Because explicit lifetimes are somewhat unique to Rust and are not something you may be used to+//! thinking about, they can seem a bit scary to work with. Normally the compiler is pretty good at+//! them, but Jacquard is [built around borrowed deserialization](https://docs.rs/jacquard-common/latest/jacquard_common/#working-with-lifetimes-and-zero-copy-deserialization) and types. This is for reasons of+//! speed and efficiency, because borrowing from your source buffer saves copying the data around.+//! However, it does mean that any Jacquard type that can borrow (not all of them do) is annotated+//! with a lifetime, to confirm that all the borrowed bits are ["covariant"](https://doc.rust-lang.org/nomicon/subtyping.html), i.e. that they all live+//! at least the same amount of time, and that lifetime matches or exceeds the lifetime of the data+//! structure. This also imposes certain restrictions on deserialization. Namely the [`DeserializeOwned`](https://serde.rs/lifetimes.html)+//! bound does not apply to almost any types in Jacquard. There is a [`deserialize_owned`] function+//! which you can use in a serde `deserialize_with` attribute to help, but the general pattern is+//! Easy mode for jacquard is to mostly just use `'static` for your lifetime params and derive/use+//! [`.into_static()`] as needed. When writing, first see if you can get away with `Thing<'_>`+//! and let the compiler infer. second-easiest after that is `Thing<'static>`, third-easiest is giving+//! everything one lifetime, e.g. `fn foo<'a>(&'a self, thing: Thing<'a>) -> /* thing with lifetime 'a */`.+//! When parsing the output of atproto API calls, you can call `.into_output()` on the `Response<R>`+//! `from_writer()` type deserialization functions, or features like Axum's `Json` extractor, as they+//! have DeserializeOwned bounds and cannot borrow from their buffer. Either use Jacquard's features+//! to get an owned version or follow the same [patterns](https://whtwnd.com/nonbinary.computer/3m33efvsylz2s) it uses in your own code.···//! - Stateful client (OAuth): `OAuthClient<S, T>` and `OAuthSession<S, T>` where `S: ClientAuthStore` and//! `T: OAuthResolver + HttpClient`. The client is used to authenticate, returning a session which handles authentication and token refresh internally.-//! - `Agent<A: AgentSession>` Session abstracts over the above two options. Currently it is a thin wrapper, but this will be the thing that gets all the convenience helpers.+//! - `Agent<A: AgentSession>` Session abstracts over the above two options and provides some useful convenience features via the [`AgentSessionExt`] trait.···-//! - [`jacquard-common`] - AT Protocol types (DIDs, handles, at-URIs, NSIDs, TIDs, CIDs, etc.)-//! - [`jacquard-axum`] - Server-side XRPC handler extractors for Axum framework (not re-exported, depends on jacquard)-//! - [`jacquard-lexicon`] - Lexicon resolution, fetching, parsing and Rust code generation from schemas···