···15151616This is a Cargo workspace with several crates:
17171818+- **jacquard**: Main library crate with XRPC client and public API surface (re-exports jacquard-api and jacquard-common)
1819- **jacquard-common**: Core AT Protocol types (DIDs, handles, at-URIs, NSIDs, TIDs, CIDs, etc.) and the `CowStr` type for efficient string handling
1920- **jacquard-lexicon**: Lexicon parsing and Rust code generation from lexicon schemas
2020-- **jacquard-api**: Generated API bindings (currently empty/in development)
2121-- **jacquard-derive**: Derive macros for lexicon structures
2222-- **jacquard**: Main binary (currently minimal)
2121+- **jacquard-api**: Generated API bindings from lexicon schemas (implementation detail, not directly used by consumers)
2222+- **jacquard-derive**: Attribute macros (`#[lexicon]`, `#[open_union]`) for lexicon structures
23232424## Development Commands
2525···57575858# Format and lint all
5959just pre-commit-all
6060+6161+# Generate API bindings from lexicon schemas
6262+cargo run -p jacquard-lexicon --bin jacquard-codegen -- -i <input_dir> -o <output_dir> [-r <root_module>]
6363+# Example:
6464+cargo run -p jacquard-lexicon --bin jacquard-codegen -- -i crates/jacquard-lexicon/tests/fixtures/lexicons/atproto/lexicons -o crates/jacquard-api/src -r crate
6065```
61666267## String Type Pattern
···101106- Use `cargo test <name>` to run specific tests
102107- Current test coverage: 89 tests in jacquard-common
103108109109+## Lexicon Code Generation
110110+111111+The `jacquard-codegen` binary generates Rust types from AT Protocol Lexicon schemas:
112112+113113+- Generates structs with `#[lexicon]` attribute for forward compatibility (captures unknown fields in `extra_data`)
114114+- Generates enums with `#[open_union]` attribute for handling unknown variants (unless marked `closed` in lexicon)
115115+- Resolves local refs (e.g., `#image` becomes `Image<'a>`)
116116+- Extracts doc comments from lexicon `description` fields
117117+- Adds header comments with `@generated` marker and lexicon NSID
118118+- Handles XRPC queries, procedures, subscriptions, and errors
119119+- Generates proper module tree with Rust 2018 style
120120+104121## Current State & Next Steps
105122106123### Completed
···110127- ✅ Data serialization: Full serialize/deserialize for `Data<'_>`, `Array`, `Object` with format-specific handling (JSON vs CBOR)
111128- ✅ CidLink wrapper type with automatic `{"$link": "cid"}` serialization in JSON
112129- ✅ Integration test with real Bluesky thread data validates round-trip correctness
130130+- ✅ Lexicon code generation with forward compatibility and proper lifetime handling
113131114132### Next Steps
115115-1. **Lexicon Code Generation**: Begin work on lexicon-to-Rust code generation now that core types are stable
133133+1. **Lexicon Resolution**: Fetch lexicons from web sources (atproto authorities, git repositories) and parse into corpus
134134+2. **Custom Lexicon Support**: Allow users to plug in their own generated lexicons alongside jacquard-api types in the client/server layer
135135+3. **Client Implementation**: Build HTTP client layer for XRPC operations in the main `jacquard` crate
136136+4. **Public API**: Design the main API surface in `jacquard` that re-exports and wraps generated types
137137+5. **DID Document Support**: Parsing, validation, and resolution of DID documents
138138+6. **OAuth Implementation**: OAuth flow support for authentication
139139+7. **Examples & Documentation**: Create examples and improve documentation
140140+8. **Testing**: Comprehensive tests for generated code and round-trip serialization
···11// @generated by jacquard-lexicon. DO NOT EDIT.
22//
33+// Lexicon: app.bsky.actor.defs
44+//
35// This file was automatically generated from Lexicon schemas.
46// Any manual changes will be overwritten on the next regeneration.
57
···11// @generated by jacquard-lexicon. DO NOT EDIT.
22//
33+// Lexicon: app.bsky.actor.getSuggestions
44+//
35// This file was automatically generated from Lexicon schemas.
46// Any manual changes will be overwritten on the next regeneration.
5766-#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
88+#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq, Default)]
79#[serde(rename_all = "camelCase")]
88-pub struct GetSuggestionsParams<'a> {
1010+pub struct GetSuggestions<'a> {
911 #[serde(skip_serializing_if = "std::option::Option::is_none")]
1012 #[serde(borrow)]
1113 pub cursor: std::option::Option<jacquard_common::CowStr<'a>>,
···1315 pub limit: std::option::Option<i64>,
1416}
15171818+impl Default for GetSuggestions<'_> {
1919+ fn default() -> Self {
2020+ Self {
2121+ cursor: Default::default(),
2222+ limit: Some(50i64),
2323+ }
2424+ }
2525+}
2626+1627#[jacquard_derive::lexicon]
1728#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
1829#[serde(rename_all = "camelCase")]
···2536 ///Snowflake for this recommendation, use when submitting recommendation events.
2637 #[serde(skip_serializing_if = "std::option::Option::is_none")]
2738 pub rec_id: std::option::Option<i64>,
3939+}
4040+4141+impl jacquard_common::types::xrpc::XrpcRequest for GetSuggestions<'_> {
4242+ const NSID: &'static str = "app.bsky.actor.getSuggestions";
4343+ const METHOD: jacquard_common::types::xrpc::XrpcMethod = jacquard_common::types::xrpc::XrpcMethod::Query;
4444+ const OUTPUT_ENCODING: &'static str = "application/json";
4545+ type Output<'de> = GetSuggestionsOutput<'de>;
4646+ type Err<'de> = jacquard_common::types::xrpc::GenericError;
2847}
+6
crates/jacquard-api/src/app_bsky/actor/profile.rs
···11// @generated by jacquard-lexicon. DO NOT EDIT.
22//
33+// Lexicon: app.bsky.actor.profile
44+//
35// This file was automatically generated from Lexicon schemas.
46// Any manual changes will be overwritten on the next regeneration.
57···5557pub enum ProfileRecordLabels<'a> {
5658 #[serde(rename = "com.atproto.label.defs#selfLabels")]
5759 DefsSelfLabels(Box<crate::com_atproto::label::SelfLabels<'a>>),
6060+}
6161+6262+impl jacquard_common::types::collection::Collection for Profile<'_> {
6363+ const NSID: &'static str = "app.bsky.actor.profile";
5864}
···11// @generated by jacquard-lexicon. DO NOT EDIT.
22//
33+// Lexicon: app.bsky.actor.searchActorsTypeahead
44+//
35// This file was automatically generated from Lexicon schemas.
46// Any manual changes will be overwritten on the next regeneration.
5766-#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
88+#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq, Default)]
79#[serde(rename_all = "camelCase")]
88-pub struct SearchActorsTypeaheadParams<'a> {
1010+pub struct SearchActorsTypeahead<'a> {
911 #[serde(skip_serializing_if = "std::option::Option::is_none")]
1012 pub limit: std::option::Option<i64>,
1113 #[serde(skip_serializing_if = "std::option::Option::is_none")]
···1618 pub term: std::option::Option<jacquard_common::CowStr<'a>>,
1719}
18202121+impl Default for SearchActorsTypeahead<'_> {
2222+ fn default() -> Self {
2323+ Self {
2424+ limit: Some(10i64),
2525+ q: Default::default(),
2626+ term: Default::default(),
2727+ }
2828+ }
2929+}
3030+1931#[jacquard_derive::lexicon]
2032#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
2133#[serde(rename_all = "camelCase")]
2234pub struct SearchActorsTypeaheadOutput<'a> {
2335 #[serde(borrow)]
2436 pub actors: Vec<crate::app_bsky::actor::ProfileViewBasic<'a>>,
3737+}
3838+3939+impl jacquard_common::types::xrpc::XrpcRequest for SearchActorsTypeahead<'_> {
4040+ const NSID: &'static str = "app.bsky.actor.searchActorsTypeahead";
4141+ const METHOD: jacquard_common::types::xrpc::XrpcMethod = jacquard_common::types::xrpc::XrpcMethod::Query;
4242+ const OUTPUT_ENCODING: &'static str = "application/json";
4343+ type Output<'de> = SearchActorsTypeaheadOutput<'de>;
4444+ type Err<'de> = jacquard_common::types::xrpc::GenericError;
2545}
+6
crates/jacquard-api/src/app_bsky/actor/status.rs
···11// @generated by jacquard-lexicon. DO NOT EDIT.
22//
33+// Lexicon: app.bsky.actor.status
44+//
35// This file was automatically generated from Lexicon schemas.
46// Any manual changes will be overwritten on the next regeneration.
57···2830pub enum StatusRecordEmbed<'a> {
2931 #[serde(rename = "app.bsky.embed.external")]
3032 External(Box<crate::app_bsky::embed::external::ExternalRecord<'a>>),
3333+}
3434+3535+impl jacquard_common::types::collection::Collection for Status<'_> {
3636+ const NSID: &'static str = "app.bsky.actor.status";
3137}
+2
crates/jacquard-api/src/app_bsky/bookmark.rs
···11// @generated by jacquard-lexicon. DO NOT EDIT.
22//
33+// Lexicon: app.bsky.bookmark.defs
44+//
35// This file was automatically generated from Lexicon schemas.
46// Any manual changes will be overwritten on the next regeneration.
57
···11// @generated by jacquard-lexicon. DO NOT EDIT.
22//
33+// Lexicon: app.bsky.bookmark.getBookmarks
44+//
35// This file was automatically generated from Lexicon schemas.
46// Any manual changes will be overwritten on the next regeneration.
5766-#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
88+#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq, Default)]
79#[serde(rename_all = "camelCase")]
88-pub struct GetBookmarksParams<'a> {
1010+pub struct GetBookmarks<'a> {
911 #[serde(skip_serializing_if = "std::option::Option::is_none")]
1012 #[serde(borrow)]
1113 pub cursor: std::option::Option<jacquard_common::CowStr<'a>>,
···1315 pub limit: std::option::Option<i64>,
1416}
15171818+impl Default for GetBookmarks<'_> {
1919+ fn default() -> Self {
2020+ Self {
2121+ cursor: Default::default(),
2222+ limit: Some(50i64),
2323+ }
2424+ }
2525+}
2626+1627#[jacquard_derive::lexicon]
1728#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
1829#[serde(rename_all = "camelCase")]
···2233 #[serde(skip_serializing_if = "std::option::Option::is_none")]
2334 #[serde(borrow)]
2435 pub cursor: std::option::Option<jacquard_common::CowStr<'a>>,
3636+}
3737+3838+impl jacquard_common::types::xrpc::XrpcRequest for GetBookmarks<'_> {
3939+ const NSID: &'static str = "app.bsky.bookmark.getBookmarks";
4040+ const METHOD: jacquard_common::types::xrpc::XrpcMethod = jacquard_common::types::xrpc::XrpcMethod::Query;
4141+ const OUTPUT_ENCODING: &'static str = "application/json";
4242+ type Output<'de> = GetBookmarksOutput<'de>;
4343+ type Err<'de> = jacquard_common::types::xrpc::GenericError;
2544}
+2
crates/jacquard-api/src/app_bsky/embed.rs
···11// @generated by jacquard-lexicon. DO NOT EDIT.
22//
33+// Lexicon: app.bsky.embed.defs
44+//
35// This file was automatically generated from Lexicon schemas.
46// Any manual changes will be overwritten on the next regeneration.
57
···11// @generated by jacquard-lexicon. DO NOT EDIT.
22//
33+// Lexicon: app.bsky.embed.external
44+//
35// This file was automatically generated from Lexicon schemas.
46// Any manual changes will be overwritten on the next regeneration.
57
+2
crates/jacquard-api/src/app_bsky/embed/images.rs
···11// @generated by jacquard-lexicon. DO NOT EDIT.
22//
33+// Lexicon: app.bsky.embed.images
44+//
35// This file was automatically generated from Lexicon schemas.
46// Any manual changes will be overwritten on the next regeneration.
57
+2
crates/jacquard-api/src/app_bsky/embed/record.rs
···11// @generated by jacquard-lexicon. DO NOT EDIT.
22//
33+// Lexicon: app.bsky.embed.record
44+//
35// This file was automatically generated from Lexicon schemas.
46// Any manual changes will be overwritten on the next regeneration.
57
···11// @generated by jacquard-lexicon. DO NOT EDIT.
22//
33+// Lexicon: app.bsky.embed.recordWithMedia
44+//
35// This file was automatically generated from Lexicon schemas.
46// Any manual changes will be overwritten on the next regeneration.
57
+2
crates/jacquard-api/src/app_bsky/embed/video.rs
···11// @generated by jacquard-lexicon. DO NOT EDIT.
22//
33+// Lexicon: app.bsky.embed.video
44+//
35// This file was automatically generated from Lexicon schemas.
46// Any manual changes will be overwritten on the next regeneration.
57
+2
crates/jacquard-api/src/app_bsky/feed.rs
···11// @generated by jacquard-lexicon. DO NOT EDIT.
22//
33+// Lexicon: app.bsky.feed.defs
44+//
35// This file was automatically generated from Lexicon schemas.
46// Any manual changes will be overwritten on the next regeneration.
57
···11// @generated by jacquard-lexicon. DO NOT EDIT.
22//
33+// Lexicon: app.bsky.feed.generator
44+//
35// This file was automatically generated from Lexicon schemas.
46// Any manual changes will be overwritten on the next regeneration.
57···4345pub enum GeneratorRecordLabels<'a> {
4446 #[serde(rename = "com.atproto.label.defs#selfLabels")]
4547 DefsSelfLabels(Box<crate::com_atproto::label::SelfLabels<'a>>),
4848+}
4949+5050+impl jacquard_common::types::collection::Collection for Generator<'_> {
5151+ const NSID: &'static str = "app.bsky.feed.generator";
4652}
···11// @generated by jacquard-lexicon. DO NOT EDIT.
22//
33+// Lexicon: app.bsky.feed.getTimeline
44+//
35// This file was automatically generated from Lexicon schemas.
46// Any manual changes will be overwritten on the next regeneration.
5766-#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
88+#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq, Default)]
79#[serde(rename_all = "camelCase")]
88-pub struct GetTimelineParams<'a> {
1010+pub struct GetTimeline<'a> {
911 #[serde(skip_serializing_if = "std::option::Option::is_none")]
1012 #[serde(borrow)]
1113 pub algorithm: std::option::Option<jacquard_common::CowStr<'a>>,
···1618 pub limit: std::option::Option<i64>,
1719}
18202121+impl Default for GetTimeline<'_> {
2222+ fn default() -> Self {
2323+ Self {
2424+ algorithm: Default::default(),
2525+ cursor: Default::default(),
2626+ limit: Some(50i64),
2727+ }
2828+ }
2929+}
3030+1931#[jacquard_derive::lexicon]
2032#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
2133#[serde(rename_all = "camelCase")]
···2537 pub cursor: std::option::Option<jacquard_common::CowStr<'a>>,
2638 #[serde(borrow)]
2739 pub feed: Vec<crate::app_bsky::feed::FeedViewPost<'a>>,
4040+}
4141+4242+impl jacquard_common::types::xrpc::XrpcRequest for GetTimeline<'_> {
4343+ const NSID: &'static str = "app.bsky.feed.getTimeline";
4444+ const METHOD: jacquard_common::types::xrpc::XrpcMethod = jacquard_common::types::xrpc::XrpcMethod::Query;
4545+ const OUTPUT_ENCODING: &'static str = "application/json";
4646+ type Output<'de> = GetTimelineOutput<'de>;
4747+ type Err<'de> = jacquard_common::types::xrpc::GenericError;
2848}
+6
crates/jacquard-api/src/app_bsky/feed/like.rs
···11// @generated by jacquard-lexicon. DO NOT EDIT.
22//
33+// Lexicon: app.bsky.feed.like
44+//
35// This file was automatically generated from Lexicon schemas.
46// Any manual changes will be overwritten on the next regeneration.
57···1416 #[serde(skip_serializing_if = "std::option::Option::is_none")]
1517 #[serde(borrow)]
1618 pub via: std::option::Option<crate::com_atproto::repo::strong_ref::StrongRef<'a>>,
1919+}
2020+2121+impl jacquard_common::types::collection::Collection for Like<'_> {
2222+ const NSID: &'static str = "app.bsky.feed.like";
1723}
+6
crates/jacquard-api/src/app_bsky/feed/post.rs
···11// @generated by jacquard-lexicon. DO NOT EDIT.
22//
33+// Lexicon: app.bsky.feed.post
44+//
35// This file was automatically generated from Lexicon schemas.
46// Any manual changes will be overwritten on the next regeneration.
57···7880pub enum PostRecordLabels<'a> {
7981 #[serde(rename = "com.atproto.label.defs#selfLabels")]
8082 DefsSelfLabels(Box<crate::com_atproto::label::SelfLabels<'a>>),
8383+}
8484+8585+impl jacquard_common::types::collection::Collection for Post<'_> {
8686+ const NSID: &'static str = "app.bsky.feed.post";
8187}
82888389#[jacquard_derive::lexicon]
+6
crates/jacquard-api/src/app_bsky/feed/postgate.rs
···11// @generated by jacquard-lexicon. DO NOT EDIT.
22//
33+// Lexicon: app.bsky.feed.postgate
44+//
35// This file was automatically generated from Lexicon schemas.
46// Any manual changes will be overwritten on the next regeneration.
57···2931 ///Reference (AT-URI) to the post record.
3032 #[serde(borrow)]
3133 pub post: jacquard_common::types::string::AtUri<'a>,
3434+}
3535+3636+impl jacquard_common::types::collection::Collection for Postgate<'_> {
3737+ const NSID: &'static str = "app.bsky.feed.postgate";
3238}
+6
crates/jacquard-api/src/app_bsky/feed/repost.rs
···11// @generated by jacquard-lexicon. DO NOT EDIT.
22//
33+// Lexicon: app.bsky.feed.repost
44+//
35// This file was automatically generated from Lexicon schemas.
46// Any manual changes will be overwritten on the next regeneration.
57···1416 #[serde(skip_serializing_if = "std::option::Option::is_none")]
1517 #[serde(borrow)]
1618 pub via: std::option::Option<crate::com_atproto::repo::strong_ref::StrongRef<'a>>,
1919+}
2020+2121+impl jacquard_common::types::collection::Collection for Repost<'_> {
2222+ const NSID: &'static str = "app.bsky.feed.repost";
1723}
···11// @generated by jacquard-lexicon. DO NOT EDIT.
22//
33+// Lexicon: app.bsky.feed.threadgate
44+//
35// This file was automatically generated from Lexicon schemas.
46// Any manual changes will be overwritten on the next regeneration.
57···4143 ///Reference (AT-URI) to the post record.
4244 #[serde(borrow)]
4345 pub post: jacquard_common::types::string::AtUri<'a>,
4646+}
4747+4848+impl jacquard_common::types::collection::Collection for Threadgate<'_> {
4949+ const NSID: &'static str = "app.bsky.feed.threadgate";
4450}
45514652///Allow replies from actors mentioned in your post.
+2
crates/jacquard-api/src/app_bsky/graph.rs
···11// @generated by jacquard-lexicon. DO NOT EDIT.
22//
33+// Lexicon: app.bsky.graph.defs
44+//
35// This file was automatically generated from Lexicon schemas.
46// Any manual changes will be overwritten on the next regeneration.
57
+6
crates/jacquard-api/src/app_bsky/graph/block.rs
···11// @generated by jacquard-lexicon. DO NOT EDIT.
22//
33+// Lexicon: app.bsky.graph.block
44+//
35// This file was automatically generated from Lexicon schemas.
46// Any manual changes will be overwritten on the next regeneration.
57···1214 ///DID of the account to be blocked.
1315 #[serde(borrow)]
1416 pub subject: jacquard_common::types::string::Did<'a>,
1717+}
1818+1919+impl jacquard_common::types::collection::Collection for Block<'_> {
2020+ const NSID: &'static str = "app.bsky.graph.block";
1521}
+6
crates/jacquard-api/src/app_bsky/graph/follow.rs
···11// @generated by jacquard-lexicon. DO NOT EDIT.
22//
33+// Lexicon: app.bsky.graph.follow
44+//
35// This file was automatically generated from Lexicon schemas.
46// Any manual changes will be overwritten on the next regeneration.
57···1113 pub created_at: jacquard_common::types::string::Datetime,
1214 #[serde(borrow)]
1315 pub subject: jacquard_common::types::string::Did<'a>,
1616+}
1717+1818+impl jacquard_common::types::collection::Collection for Follow<'_> {
1919+ const NSID: &'static str = "app.bsky.graph.follow";
1420}
···11// @generated by jacquard-lexicon. DO NOT EDIT.
22//
33+// Lexicon: app.bsky.graph.getSuggestedFollowsByActor
44+//
35// This file was automatically generated from Lexicon schemas.
46// Any manual changes will be overwritten on the next regeneration.
5768#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
79#[serde(rename_all = "camelCase")]
88-pub struct GetSuggestedFollowsByActorParams<'a> {
1010+pub struct GetSuggestedFollowsByActor<'a> {
911 #[serde(borrow)]
1012 pub actor: jacquard_common::types::ident::AtIdentifier<'a>,
1113}
···2224 pub rec_id: std::option::Option<i64>,
2325 #[serde(borrow)]
2426 pub suggestions: Vec<crate::app_bsky::actor::ProfileView<'a>>,
2727+}
2828+2929+impl jacquard_common::types::xrpc::XrpcRequest for GetSuggestedFollowsByActor<'_> {
3030+ const NSID: &'static str = "app.bsky.graph.getSuggestedFollowsByActor";
3131+ const METHOD: jacquard_common::types::xrpc::XrpcMethod = jacquard_common::types::xrpc::XrpcMethod::Query;
3232+ const OUTPUT_ENCODING: &'static str = "application/json";
3333+ type Output<'de> = GetSuggestedFollowsByActorOutput<'de>;
3434+ type Err<'de> = jacquard_common::types::xrpc::GenericError;
2535}
+6
crates/jacquard-api/src/app_bsky/graph/list.rs
···11// @generated by jacquard-lexicon. DO NOT EDIT.
22//
33+// Lexicon: app.bsky.graph.list
44+//
35// This file was automatically generated from Lexicon schemas.
46// Any manual changes will be overwritten on the next regeneration.
57···3840pub enum ListRecordLabels<'a> {
3941 #[serde(rename = "com.atproto.label.defs#selfLabels")]
4042 DefsSelfLabels(Box<crate::com_atproto::label::SelfLabels<'a>>),
4343+}
4444+4545+impl jacquard_common::types::collection::Collection for List<'_> {
4646+ const NSID: &'static str = "app.bsky.graph.list";
4147}
···11// @generated by jacquard-lexicon. DO NOT EDIT.
22//
33+// Lexicon: app.bsky.graph.listblock
44+//
35// This file was automatically generated from Lexicon schemas.
46// Any manual changes will be overwritten on the next regeneration.
57···1214 ///Reference (AT-URI) to the mod list record.
1315 #[serde(borrow)]
1416 pub subject: jacquard_common::types::string::AtUri<'a>,
1717+}
1818+1919+impl jacquard_common::types::collection::Collection for Listblock<'_> {
2020+ const NSID: &'static str = "app.bsky.graph.listblock";
1521}
···11// @generated by jacquard-lexicon. DO NOT EDIT.
22//
33+// Lexicon: app.bsky.graph.listitem
44+//
35// This file was automatically generated from Lexicon schemas.
46// Any manual changes will be overwritten on the next regeneration.
57···1517 ///The account which is included on the list.
1618 #[serde(borrow)]
1719 pub subject: jacquard_common::types::string::Did<'a>,
2020+}
2121+2222+impl jacquard_common::types::collection::Collection for Listitem<'_> {
2323+ const NSID: &'static str = "app.bsky.graph.listitem";
1824}
···11// @generated by jacquard-lexicon. DO NOT EDIT.
22//
33+// Lexicon: app.bsky.graph.starterpack
44+//
35// This file was automatically generated from Lexicon schemas.
46// Any manual changes will be overwritten on the next regeneration.
57···3638 ///Display name for starter pack; can not be empty.
3739 #[serde(borrow)]
3840 pub name: jacquard_common::CowStr<'a>,
4141+}
4242+4343+impl jacquard_common::types::collection::Collection for Starterpack<'_> {
4444+ const NSID: &'static str = "app.bsky.graph.starterpack";
3945}
···11// @generated by jacquard-lexicon. DO NOT EDIT.
22//
33+// Lexicon: app.bsky.graph.verification
44+//
35// This file was automatically generated from Lexicon schemas.
46// Any manual changes will be overwritten on the next regeneration.
57···1921 ///DID of the subject the verification applies to.
2022 #[serde(borrow)]
2123 pub subject: jacquard_common::types::string::Did<'a>,
2424+}
2525+2626+impl jacquard_common::types::collection::Collection for Verification<'_> {
2727+ const NSID: &'static str = "app.bsky.graph.verification";
2228}
+2
crates/jacquard-api/src/app_bsky/labeler.rs
···11// @generated by jacquard-lexicon. DO NOT EDIT.
22//
33+// Lexicon: app.bsky.labeler.defs
44+//
35// This file was automatically generated from Lexicon schemas.
46// Any manual changes will be overwritten on the next regeneration.
57
···11// @generated by jacquard-lexicon. DO NOT EDIT.
22//
33+// Lexicon: app.bsky.labeler.service
44+//
35// This file was automatically generated from Lexicon schemas.
46// Any manual changes will be overwritten on the next regeneration.
57···4143pub enum ServiceRecordLabels<'a> {
4244 #[serde(rename = "com.atproto.label.defs#selfLabels")]
4345 DefsSelfLabels(Box<crate::com_atproto::label::SelfLabels<'a>>),
4646+}
4747+4848+impl jacquard_common::types::collection::Collection for Service<'_> {
4949+ const NSID: &'static str = "app.bsky.labeler.service";
4450}
+2
crates/jacquard-api/src/app_bsky/notification.rs
···11// @generated by jacquard-lexicon. DO NOT EDIT.
22//
33+// Lexicon: app.bsky.notification.defs
44+//
35// This file was automatically generated from Lexicon schemas.
46// Any manual changes will be overwritten on the next regeneration.
57
···11// @generated by jacquard-lexicon. DO NOT EDIT.
22//
33+// Lexicon: app.bsky.notification.declaration
44+//
35// This file was automatically generated from Lexicon schemas.
46// Any manual changes will be overwritten on the next regeneration.
57···1113 ///A declaration of the user's preference for allowing activity subscriptions from other users. Absence of a record implies 'followers'.
1214 #[serde(borrow)]
1315 pub allow_subscriptions: jacquard_common::CowStr<'a>,
1616+}
1717+1818+impl jacquard_common::types::collection::Collection for Declaration<'_> {
1919+ const NSID: &'static str = "app.bsky.notification.declaration";
1420}
···11// @generated by jacquard-lexicon. DO NOT EDIT.
22//
33+// Lexicon: app.bsky.richtext.facet
44+//
35// This file was automatically generated from Lexicon schemas.
46// Any manual changes will be overwritten on the next regeneration.
57
+2
crates/jacquard-api/src/app_bsky/unspecced.rs
···11// @generated by jacquard-lexicon. DO NOT EDIT.
22//
33+// Lexicon: app.bsky.unspecced.defs
44+//
35// This file was automatically generated from Lexicon schemas.
46// Any manual changes will be overwritten on the next regeneration.
57
···11// @generated by jacquard-lexicon. DO NOT EDIT.
22//
33+// Lexicon: app.bsky.unspecced.searchStarterPacksSkeleton
44+//
35// This file was automatically generated from Lexicon schemas.
46// Any manual changes will be overwritten on the next regeneration.
5766-#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
88+#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq, Default)]
79#[serde(rename_all = "camelCase")]
88-pub struct SearchStarterPacksSkeletonParams<'a> {
1010+pub struct SearchStarterPacksSkeleton<'a> {
911 #[serde(skip_serializing_if = "std::option::Option::is_none")]
1012 #[serde(borrow)]
1113 pub cursor: std::option::Option<jacquard_common::CowStr<'a>>,
···1618 #[serde(skip_serializing_if = "std::option::Option::is_none")]
1719 #[serde(borrow)]
1820 pub viewer: std::option::Option<jacquard_common::types::string::Did<'a>>,
2121+}
2222+2323+impl Default for SearchStarterPacksSkeleton<'_> {
2424+ fn default() -> Self {
2525+ Self {
2626+ cursor: Default::default(),
2727+ limit: Some(25i64),
2828+ q: Default::default(),
2929+ viewer: Default::default(),
3030+ }
3131+ }
1932}
20332134#[jacquard_derive::lexicon]
···6376 Self::Unknown(err) => write!(f, "Unknown error: {:?}", err),
6477 }
6578 }
7979+}
8080+8181+impl jacquard_common::types::xrpc::XrpcRequest for SearchStarterPacksSkeleton<'_> {
8282+ const NSID: &'static str = "app.bsky.unspecced.searchStarterPacksSkeleton";
8383+ const METHOD: jacquard_common::types::xrpc::XrpcMethod = jacquard_common::types::xrpc::XrpcMethod::Query;
8484+ const OUTPUT_ENCODING: &'static str = "application/json";
8585+ type Output<'de> = SearchStarterPacksSkeletonOutput<'de>;
8686+ type Err<'de> = SearchStarterPacksSkeletonError<'de>;
6687}
+2
crates/jacquard-api/src/app_bsky/video.rs
···11// @generated by jacquard-lexicon. DO NOT EDIT.
22//
33+// Lexicon: app.bsky.video.defs
44+//
35// This file was automatically generated from Lexicon schemas.
46// Any manual changes will be overwritten on the next regeneration.
57
···11// @generated by jacquard-lexicon. DO NOT EDIT.
22//
33+// Lexicon: app.bsky.video.uploadVideo
44+//
35// This file was automatically generated from Lexicon schemas.
46// Any manual changes will be overwritten on the next regeneration.
5768#[jacquard_derive::lexicon]
79#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
810#[serde(rename_all = "camelCase")]
99-pub struct UploadVideoInput<'a> {}
1111+pub struct UploadVideo<'a> {}
1012#[jacquard_derive::lexicon]
1113#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
1214#[serde(rename_all = "camelCase")]
1315pub struct UploadVideoOutput<'a> {
1416 #[serde(borrow)]
1517 pub job_status: crate::app_bsky::video::JobStatus<'a>,
1818+}
1919+2020+impl jacquard_common::types::xrpc::XrpcRequest for UploadVideo<'_> {
2121+ const NSID: &'static str = "app.bsky.video.uploadVideo";
2222+ const METHOD: jacquard_common::types::xrpc::XrpcMethod = jacquard_common::types::xrpc::XrpcMethod::Procedure(
2323+ "video/mp4",
2424+ );
2525+ const OUTPUT_ENCODING: &'static str = "application/json";
2626+ type Output<'de> = UploadVideoOutput<'de>;
2727+ type Err<'de> = jacquard_common::types::xrpc::GenericError;
1628}
+2
crates/jacquard-api/src/chat_bsky/actor.rs
···11// @generated by jacquard-lexicon. DO NOT EDIT.
22//
33+// Lexicon: chat.bsky.actor.defs
44+//
35// This file was automatically generated from Lexicon schemas.
46// Any manual changes will be overwritten on the next regeneration.
57
···11// @generated by jacquard-lexicon. DO NOT EDIT.
22//
33+// Lexicon: chat.bsky.actor.declaration
44+//
35// This file was automatically generated from Lexicon schemas.
46// Any manual changes will be overwritten on the next regeneration.
57···1012pub struct Declaration<'a> {
1113 #[serde(borrow)]
1214 pub allow_incoming: jacquard_common::CowStr<'a>,
1515+}
1616+1717+impl jacquard_common::types::collection::Collection for Declaration<'_> {
1818+ const NSID: &'static str = "chat.bsky.actor.declaration";
1319}
···11// @generated by jacquard-lexicon. DO NOT EDIT.
22//
33+// Lexicon: chat.bsky.actor.exportAccountData
44+//
35// This file was automatically generated from Lexicon schemas.
46// Any manual changes will be overwritten on the next regeneration.
5768#[jacquard_derive::lexicon]
79#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
810#[serde(rename_all = "camelCase")]
99-pub struct ExportAccountDataOutput<'a> {}1111+pub struct ExportAccountDataOutput<'a> {}
1212+/// XRPC request marker type
1313+#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize)]
1414+pub struct ExportAccountData;
1515+impl jacquard_common::types::xrpc::XrpcRequest for ExportAccountData {
1616+ const NSID: &'static str = "chat.bsky.actor.exportAccountData";
1717+ const METHOD: jacquard_common::types::xrpc::XrpcMethod = jacquard_common::types::xrpc::XrpcMethod::Query;
1818+ const OUTPUT_ENCODING: &'static str = "application/jsonl";
1919+ type Output<'de> = ExportAccountDataOutput<'de>;
2020+ type Err<'de> = jacquard_common::types::xrpc::GenericError;
2121+}
+2
crates/jacquard-api/src/chat_bsky/convo.rs
···11// @generated by jacquard-lexicon. DO NOT EDIT.
22//
33+// Lexicon: chat.bsky.convo.defs
44+//
35// This file was automatically generated from Lexicon schemas.
46// Any manual changes will be overwritten on the next regeneration.
57
···11// @generated by jacquard-lexicon. DO NOT EDIT.
22//
33+// Lexicon: chat.bsky.moderation.updateActorAccess
44+//
35// This file was automatically generated from Lexicon schemas.
46// Any manual changes will be overwritten on the next regeneration.
5768#[jacquard_derive::lexicon]
79#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
810#[serde(rename_all = "camelCase")]
99-pub struct UpdateActorAccessInput<'a> {
1111+pub struct UpdateActorAccess<'a> {
1012 #[serde(borrow)]
1113 pub actor: jacquard_common::types::string::Did<'a>,
1214 pub allow_access: bool,
1315 #[serde(skip_serializing_if = "std::option::Option::is_none")]
1416 #[serde(borrow)]
1517 pub r#ref: std::option::Option<jacquard_common::CowStr<'a>>,
1818+}
1919+2020+impl jacquard_common::types::xrpc::XrpcRequest for UpdateActorAccess<'_> {
2121+ const NSID: &'static str = "chat.bsky.moderation.updateActorAccess";
2222+ const METHOD: jacquard_common::types::xrpc::XrpcMethod = jacquard_common::types::xrpc::XrpcMethod::Procedure(
2323+ "application/json",
2424+ );
2525+ const OUTPUT_ENCODING: &'static str = "application/json";
2626+ type Output<'de> = ();
2727+ type Err<'de> = jacquard_common::types::xrpc::GenericError;
1628}
+2
crates/jacquard-api/src/com_atproto/admin.rs
···11// @generated by jacquard-lexicon. DO NOT EDIT.
22//
33+// Lexicon: com.atproto.admin.defs
44+//
35// This file was automatically generated from Lexicon schemas.
46// Any manual changes will be overwritten on the next regeneration.
57
···11// @generated by jacquard-lexicon. DO NOT EDIT.
22//
33+// Lexicon: com.atproto.admin.sendEmail
44+//
35// This file was automatically generated from Lexicon schemas.
46// Any manual changes will be overwritten on the next regeneration.
5768#[jacquard_derive::lexicon]
79#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
810#[serde(rename_all = "camelCase")]
99-pub struct SendEmailInput<'a> {
1111+pub struct SendEmail<'a> {
1012 ///Additional comment by the sender that won't be used in the email itself but helpful to provide more context for moderators/reviewers
1113 #[serde(skip_serializing_if = "std::option::Option::is_none")]
1214 #[serde(borrow)]
···2729#[serde(rename_all = "camelCase")]
2830pub struct SendEmailOutput<'a> {
2931 pub sent: bool,
3232+}
3333+3434+impl jacquard_common::types::xrpc::XrpcRequest for SendEmail<'_> {
3535+ const NSID: &'static str = "com.atproto.admin.sendEmail";
3636+ const METHOD: jacquard_common::types::xrpc::XrpcMethod = jacquard_common::types::xrpc::XrpcMethod::Procedure(
3737+ "application/json",
3838+ );
3939+ const OUTPUT_ENCODING: &'static str = "application/json";
4040+ type Output<'de> = SendEmailOutput<'de>;
4141+ type Err<'de> = jacquard_common::types::xrpc::GenericError;
3042}
···11// @generated by jacquard-lexicon. DO NOT EDIT.
22//
33+// Lexicon: com.atproto.identity.defs
44+//
35// This file was automatically generated from Lexicon schemas.
46// Any manual changes will be overwritten on the next regeneration.
57
···11// @generated by jacquard-lexicon. DO NOT EDIT.
22//
33+// Lexicon: com.atproto.identity.updateHandle
44+//
35// This file was automatically generated from Lexicon schemas.
46// Any manual changes will be overwritten on the next regeneration.
5768#[jacquard_derive::lexicon]
79#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
810#[serde(rename_all = "camelCase")]
99-pub struct UpdateHandleInput<'a> {
1111+pub struct UpdateHandle<'a> {
1012 ///The new handle.
1113 #[serde(borrow)]
1214 pub handle: jacquard_common::types::string::Handle<'a>,
1515+}
1616+1717+impl jacquard_common::types::xrpc::XrpcRequest for UpdateHandle<'_> {
1818+ const NSID: &'static str = "com.atproto.identity.updateHandle";
1919+ const METHOD: jacquard_common::types::xrpc::XrpcMethod = jacquard_common::types::xrpc::XrpcMethod::Procedure(
2020+ "application/json",
2121+ );
2222+ const OUTPUT_ENCODING: &'static str = "application/json";
2323+ type Output<'de> = ();
2424+ type Err<'de> = jacquard_common::types::xrpc::GenericError;
1325}
+2
crates/jacquard-api/src/com_atproto/label.rs
···11// @generated by jacquard-lexicon. DO NOT EDIT.
22//
33+// Lexicon: com.atproto.label.defs
44+//
35// This file was automatically generated from Lexicon schemas.
46// Any manual changes will be overwritten on the next regeneration.
57
···11// @generated by jacquard-lexicon. DO NOT EDIT.
22//
33+// Lexicon: com.atproto.label.subscribeLabels
44+//
35// This file was automatically generated from Lexicon schemas.
46// Any manual changes will be overwritten on the next regeneration.
57···25272628#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
2729#[serde(rename_all = "camelCase")]
2828-pub struct SubscribeLabelsParams {
3030+pub struct SubscribeLabels {
2931 #[serde(skip_serializing_if = "std::option::Option::is_none")]
3032 pub cursor: std::option::Option<i64>,
3133}
···11// @generated by jacquard-lexicon. DO NOT EDIT.
22//
33+// Lexicon: com.atproto.lexicon.schema
44+//
35// This file was automatically generated from Lexicon schemas.
46// Any manual changes will be overwritten on the next regeneration.
57···1012pub struct Schema<'a> {
1113 ///Indicates the 'version' of the Lexicon language. Must be '1' for the current atproto/Lexicon schema system.
1214 pub lexicon: i64,
1515+}
1616+1717+impl jacquard_common::types::collection::Collection for Schema<'_> {
1818+ const NSID: &'static str = "com.atproto.lexicon.schema";
1319}
+2
crates/jacquard-api/src/com_atproto/moderation.rs
···11// @generated by jacquard-lexicon. DO NOT EDIT.
22//
33+// Lexicon: com.atproto.moderation.defs
44+//
35// This file was automatically generated from Lexicon schemas.
46// Any manual changes will be overwritten on the next regeneration.
57
···11// @generated by jacquard-lexicon. DO NOT EDIT.
22//
33+// Lexicon: com.atproto.moderation.createReport
44+//
35// This file was automatically generated from Lexicon schemas.
46// Any manual changes will be overwritten on the next regeneration.
5768#[jacquard_derive::lexicon]
79#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
810#[serde(rename_all = "camelCase")]
99-pub struct CreateReportInput<'a> {
1111+pub struct CreateReport<'a> {
1012 #[serde(skip_serializing_if = "std::option::Option::is_none")]
1113 #[serde(borrow)]
1214 pub mod_tool: std::option::Option<jacquard_common::types::value::Data<'a>>,
···1820 #[serde(borrow)]
1921 pub reason_type: crate::com_atproto::moderation::ReasonType<'a>,
2022 #[serde(borrow)]
2121- pub subject: CreateReportInputRecordSubject<'a>,
2323+ pub subject: CreateReportRecordSubject<'a>,
2224}
23252426#[jacquard_derive::open_union]
2527#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
2628#[serde(tag = "$type")]
2729#[serde(bound(deserialize = "'de: 'a"))]
2828-pub enum CreateReportInputRecordSubject<'a> {
3030+pub enum CreateReportRecordSubject<'a> {
2931 #[serde(rename = "com.atproto.admin.defs#repoRef")]
3032 DefsRepoRef(Box<crate::com_atproto::admin::RepoRef<'a>>),
3133 #[serde(rename = "com.atproto.repo.strongRef")]
···5860 DefsRepoRef(Box<crate::com_atproto::admin::RepoRef<'a>>),
5961 #[serde(rename = "com.atproto.repo.strongRef")]
6062 StrongRef(Box<crate::com_atproto::repo::strong_ref::StrongRef<'a>>),
6363+}
6464+6565+impl jacquard_common::types::xrpc::XrpcRequest for CreateReport<'_> {
6666+ const NSID: &'static str = "com.atproto.moderation.createReport";
6767+ const METHOD: jacquard_common::types::xrpc::XrpcMethod = jacquard_common::types::xrpc::XrpcMethod::Procedure(
6868+ "application/json",
6969+ );
7070+ const OUTPUT_ENCODING: &'static str = "application/json";
7171+ type Output<'de> = CreateReportOutput<'de>;
7272+ type Err<'de> = jacquard_common::types::xrpc::GenericError;
6173}
62746375///Moderation tool information for tracing the source of the action
+2
crates/jacquard-api/src/com_atproto/repo.rs
···11// @generated by jacquard-lexicon. DO NOT EDIT.
22//
33+// Lexicon: com.atproto.repo.defs
44+//
35// This file was automatically generated from Lexicon schemas.
46// Any manual changes will be overwritten on the next regeneration.
57
···11// @generated by jacquard-lexicon. DO NOT EDIT.
22//
33+// Lexicon: com.atproto.repo.strongRef
44+//
35// This file was automatically generated from Lexicon schemas.
46// Any manual changes will be overwritten on the next regeneration.
57
···11// @generated by jacquard-lexicon. DO NOT EDIT.
22//
33+// Lexicon: com.atproto.repo.uploadBlob
44+//
35// This file was automatically generated from Lexicon schemas.
46// Any manual changes will be overwritten on the next regeneration.
5768#[jacquard_derive::lexicon]
79#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
810#[serde(rename_all = "camelCase")]
99-pub struct UploadBlobInput<'a> {}
1111+pub struct UploadBlob<'a> {}
1012#[jacquard_derive::lexicon]
1113#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
1214#[serde(rename_all = "camelCase")]
1315pub struct UploadBlobOutput<'a> {
1416 #[serde(borrow)]
1517 pub blob: jacquard_common::types::blob::Blob<'a>,
1818+}
1919+2020+impl jacquard_common::types::xrpc::XrpcRequest for UploadBlob<'_> {
2121+ const NSID: &'static str = "com.atproto.repo.uploadBlob";
2222+ const METHOD: jacquard_common::types::xrpc::XrpcMethod = jacquard_common::types::xrpc::XrpcMethod::Procedure(
2323+ "*/*",
2424+ );
2525+ const OUTPUT_ENCODING: &'static str = "application/json";
2626+ type Output<'de> = UploadBlobOutput<'de>;
2727+ type Err<'de> = jacquard_common::types::xrpc::GenericError;
1628}
+2
crates/jacquard-api/src/com_atproto/server.rs
···11// @generated by jacquard-lexicon. DO NOT EDIT.
22//
33+// Lexicon: com.atproto.server.defs
44+//
35// This file was automatically generated from Lexicon schemas.
46// Any manual changes will be overwritten on the next regeneration.
57
···11// @generated by jacquard-lexicon. DO NOT EDIT.
22//
33+// Lexicon: com.atproto.server.deactivateAccount
44+//
35// This file was automatically generated from Lexicon schemas.
46// Any manual changes will be overwritten on the next regeneration.
5768#[jacquard_derive::lexicon]
79#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
810#[serde(rename_all = "camelCase")]
99-pub struct DeactivateAccountInput<'a> {
1111+pub struct DeactivateAccount<'a> {
1012 ///A recommendation to server as to how long they should hold onto the deactivated account before deleting.
1113 #[serde(skip_serializing_if = "std::option::Option::is_none")]
1214 pub delete_after: std::option::Option<jacquard_common::types::string::Datetime>,
1515+}
1616+1717+impl jacquard_common::types::xrpc::XrpcRequest for DeactivateAccount<'_> {
1818+ const NSID: &'static str = "com.atproto.server.deactivateAccount";
1919+ const METHOD: jacquard_common::types::xrpc::XrpcMethod = jacquard_common::types::xrpc::XrpcMethod::Procedure(
2020+ "application/json",
2121+ );
2222+ const OUTPUT_ENCODING: &'static str = "application/json";
2323+ type Output<'de> = ();
2424+ type Err<'de> = jacquard_common::types::xrpc::GenericError;
1325}
···11// @generated by jacquard-lexicon. DO NOT EDIT.
22//
33+// Lexicon: com.atproto.server.describeServer
44+//
35// This file was automatically generated from Lexicon schemas.
46// Any manual changes will be overwritten on the next regeneration.
57···4749 ///If true, a phone verification token must be supplied to create an account on this instance.
4850 #[serde(skip_serializing_if = "std::option::Option::is_none")]
4951 pub phone_verification_required: std::option::Option<bool>,
5252+}
5353+5454+/// XRPC request marker type
5555+#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize)]
5656+pub struct DescribeServer;
5757+impl jacquard_common::types::xrpc::XrpcRequest for DescribeServer {
5858+ const NSID: &'static str = "com.atproto.server.describeServer";
5959+ const METHOD: jacquard_common::types::xrpc::XrpcMethod = jacquard_common::types::xrpc::XrpcMethod::Query;
6060+ const OUTPUT_ENCODING: &'static str = "application/json";
6161+ type Output<'de> = DescribeServerOutput<'de>;
6262+ type Err<'de> = jacquard_common::types::xrpc::GenericError;
5063}
···11// @generated by jacquard-lexicon. DO NOT EDIT.
22//
33+// Lexicon: com.atproto.server.updateEmail
44+//
35// This file was automatically generated from Lexicon schemas.
46// Any manual changes will be overwritten on the next regeneration.
5768#[jacquard_derive::lexicon]
79#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
810#[serde(rename_all = "camelCase")]
99-pub struct UpdateEmailInput<'a> {
1111+pub struct UpdateEmail<'a> {
1012 #[serde(borrow)]
1113 pub email: jacquard_common::CowStr<'a>,
1214 #[serde(skip_serializing_if = "std::option::Option::is_none")]
···6668 Self::Unknown(err) => write!(f, "Unknown error: {:?}", err),
6769 }
6870 }
7171+}
7272+7373+impl jacquard_common::types::xrpc::XrpcRequest for UpdateEmail<'_> {
7474+ const NSID: &'static str = "com.atproto.server.updateEmail";
7575+ const METHOD: jacquard_common::types::xrpc::XrpcMethod = jacquard_common::types::xrpc::XrpcMethod::Procedure(
7676+ "application/json",
7777+ );
7878+ const OUTPUT_ENCODING: &'static str = "application/json";
7979+ type Output<'de> = ();
8080+ type Err<'de> = UpdateEmailError<'de>;
6981}
+2
crates/jacquard-api/src/com_atproto/sync.rs
···11// @generated by jacquard-lexicon. DO NOT EDIT.
22//
33+// Lexicon: com.atproto.sync.defs
44+//
35// This file was automatically generated from Lexicon schemas.
46// Any manual changes will be overwritten on the next regeneration.
57
···11// @generated by jacquard-lexicon. DO NOT EDIT.
22//
33+// Lexicon: com.atproto.sync.notifyOfUpdate
44+//
35// This file was automatically generated from Lexicon schemas.
46// Any manual changes will be overwritten on the next regeneration.
5768#[jacquard_derive::lexicon]
79#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
810#[serde(rename_all = "camelCase")]
99-pub struct NotifyOfUpdateInput<'a> {
1111+pub struct NotifyOfUpdate<'a> {
1012 ///Hostname of the current service (usually a PDS) that is notifying of update.
1113 #[serde(borrow)]
1214 pub hostname: jacquard_common::CowStr<'a>,
1515+}
1616+1717+impl jacquard_common::types::xrpc::XrpcRequest for NotifyOfUpdate<'_> {
1818+ const NSID: &'static str = "com.atproto.sync.notifyOfUpdate";
1919+ const METHOD: jacquard_common::types::xrpc::XrpcMethod = jacquard_common::types::xrpc::XrpcMethod::Procedure(
2020+ "application/json",
2121+ );
2222+ const OUTPUT_ENCODING: &'static str = "application/json";
2323+ type Output<'de> = ();
2424+ type Err<'de> = jacquard_common::types::xrpc::GenericError;
1325}
···11// @generated by jacquard-lexicon. DO NOT EDIT.
22//
33+// Lexicon: com.atproto.sync.subscribeRepos
44+//
35// This file was automatically generated from Lexicon schemas.
46// Any manual changes will be overwritten on the next regeneration.
57···83858486#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8587#[serde(rename_all = "camelCase")]
8686-pub struct SubscribeReposParams {
8888+pub struct SubscribeRepos {
8789 #[serde(skip_serializing_if = "std::option::Option::is_none")]
8890 pub cursor: std::option::Option<i64>,
8991}
···11// @generated by jacquard-lexicon. DO NOT EDIT.
22//
33+// Lexicon: tools.ozone.communication.defs
44+//
35// This file was automatically generated from Lexicon schemas.
46// Any manual changes will be overwritten on the next regeneration.
57
···11// @generated by jacquard-lexicon. DO NOT EDIT.
22//
33+// Lexicon: tools.ozone.moderation.defs
44+//
35// This file was automatically generated from Lexicon schemas.
46// Any manual changes will be overwritten on the next regeneration.
57
···11// @generated by jacquard-lexicon. DO NOT EDIT.
22//
33+// Lexicon: tools.ozone.moderation.searchRepos
44+//
35// This file was automatically generated from Lexicon schemas.
46// Any manual changes will be overwritten on the next regeneration.
5766-#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
88+#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq, Default)]
79#[serde(rename_all = "camelCase")]
88-pub struct SearchReposParams<'a> {
1010+pub struct SearchRepos<'a> {
911 #[serde(skip_serializing_if = "std::option::Option::is_none")]
1012 #[serde(borrow)]
1113 pub cursor: std::option::Option<jacquard_common::CowStr<'a>>,
···1921 pub term: std::option::Option<jacquard_common::CowStr<'a>>,
2022}
21232424+impl Default for SearchRepos<'_> {
2525+ fn default() -> Self {
2626+ Self {
2727+ cursor: Default::default(),
2828+ limit: Some(50i64),
2929+ q: Default::default(),
3030+ term: Default::default(),
3131+ }
3232+ }
3333+}
3434+2235#[jacquard_derive::lexicon]
2336#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
2437#[serde(rename_all = "camelCase")]
···2841 pub cursor: std::option::Option<jacquard_common::CowStr<'a>>,
2942 #[serde(borrow)]
3043 pub repos: Vec<crate::tools_ozone::moderation::RepoView<'a>>,
4444+}
4545+4646+impl jacquard_common::types::xrpc::XrpcRequest for SearchRepos<'_> {
4747+ const NSID: &'static str = "tools.ozone.moderation.searchRepos";
4848+ const METHOD: jacquard_common::types::xrpc::XrpcMethod = jacquard_common::types::xrpc::XrpcMethod::Query;
4949+ const OUTPUT_ENCODING: &'static str = "application/json";
5050+ type Output<'de> = SearchReposOutput<'de>;
5151+ type Err<'de> = jacquard_common::types::xrpc::GenericError;
3152}
+2
crates/jacquard-api/src/tools_ozone/report.rs
···11// @generated by jacquard-lexicon. DO NOT EDIT.
22//
33+// Lexicon: tools.ozone.report.defs
44+//
35// This file was automatically generated from Lexicon schemas.
46// Any manual changes will be overwritten on the next regeneration.
57
+2
crates/jacquard-api/src/tools_ozone/safelink.rs
···11// @generated by jacquard-lexicon. DO NOT EDIT.
22//
33+// Lexicon: tools.ozone.safelink.defs
44+//
35// This file was automatically generated from Lexicon schemas.
46// Any manual changes will be overwritten on the next regeneration.
57
···11// @generated by jacquard-lexicon. DO NOT EDIT.
22//
33+// Lexicon: tools.ozone.server.getConfig
44+//
35// This file was automatically generated from Lexicon schemas.
46// Any manual changes will be overwritten on the next regeneration.
57···2628 #[serde(skip_serializing_if = "std::option::Option::is_none")]
2729 #[serde(borrow)]
2830 pub viewer: std::option::Option<jacquard_common::types::value::Data<'a>>,
3131+}
3232+3333+/// XRPC request marker type
3434+#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize)]
3535+pub struct GetConfig;
3636+impl jacquard_common::types::xrpc::XrpcRequest for GetConfig {
3737+ const NSID: &'static str = "tools.ozone.server.getConfig";
3838+ const METHOD: jacquard_common::types::xrpc::XrpcMethod = jacquard_common::types::xrpc::XrpcMethod::Query;
3939+ const OUTPUT_ENCODING: &'static str = "application/json";
4040+ type Output<'de> = GetConfigOutput<'de>;
4141+ type Err<'de> = jacquard_common::types::xrpc::GenericError;
2942}
30433144#[jacquard_derive::lexicon]
+2
crates/jacquard-api/src/tools_ozone/set.rs
···11// @generated by jacquard-lexicon. DO NOT EDIT.
22//
33+// Lexicon: tools.ozone.set.defs
44+//
35// This file was automatically generated from Lexicon schemas.
46// Any manual changes will be overwritten on the next regeneration.
57
···11// @generated by jacquard-lexicon. DO NOT EDIT.
22//
33+// Lexicon: tools.ozone.set.addValues
44+//
35// This file was automatically generated from Lexicon schemas.
46// Any manual changes will be overwritten on the next regeneration.
5768#[jacquard_derive::lexicon]
79#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
810#[serde(rename_all = "camelCase")]
99-pub struct AddValuesInput<'a> {
1111+pub struct AddValues<'a> {
1012 ///Name of the set to add values to
1113 #[serde(borrow)]
1214 pub name: jacquard_common::CowStr<'a>,
1315 ///Array of string values to add to the set
1416 #[serde(borrow)]
1517 pub values: Vec<jacquard_common::CowStr<'a>>,
1818+}
1919+2020+impl jacquard_common::types::xrpc::XrpcRequest for AddValues<'_> {
2121+ const NSID: &'static str = "tools.ozone.set.addValues";
2222+ const METHOD: jacquard_common::types::xrpc::XrpcMethod = jacquard_common::types::xrpc::XrpcMethod::Procedure(
2323+ "application/json",
2424+ );
2525+ const OUTPUT_ENCODING: &'static str = "application/json";
2626+ type Output<'de> = ();
2727+ type Err<'de> = jacquard_common::types::xrpc::GenericError;
1628}
···11// @generated by jacquard-lexicon. DO NOT EDIT.
22//
33+// Lexicon: tools.ozone.set.upsertSet
44+//
35// This file was automatically generated from Lexicon schemas.
46// Any manual changes will be overwritten on the next regeneration.
5768#[jacquard_derive::lexicon]
79#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
810#[serde(rename_all = "camelCase")]
99-pub struct UpsertSetInput<'a> {
1111+pub struct UpsertSet<'a> {
1012 #[serde(flatten)]
1113 #[serde(borrow)]
1214 pub value: crate::tools_ozone::set::Set<'a>,
···1921 #[serde(flatten)]
2022 #[serde(borrow)]
2123 pub value: crate::tools_ozone::set::SetView<'a>,
2424+}
2525+2626+impl jacquard_common::types::xrpc::XrpcRequest for UpsertSet<'_> {
2727+ const NSID: &'static str = "tools.ozone.set.upsertSet";
2828+ const METHOD: jacquard_common::types::xrpc::XrpcMethod = jacquard_common::types::xrpc::XrpcMethod::Procedure(
2929+ "application/json",
3030+ );
3131+ const OUTPUT_ENCODING: &'static str = "application/json";
3232+ type Output<'de> = UpsertSetOutput<'de>;
3333+ type Err<'de> = jacquard_common::types::xrpc::GenericError;
2234}
+2
crates/jacquard-api/src/tools_ozone/setting.rs
···11// @generated by jacquard-lexicon. DO NOT EDIT.
22//
33+// Lexicon: tools.ozone.setting.defs
44+//
35// This file was automatically generated from Lexicon schemas.
46// Any manual changes will be overwritten on the next regeneration.
57
···11// @generated by jacquard-lexicon. DO NOT EDIT.
22//
33+// Lexicon: tools.ozone.setting.upsertOption
44+//
35// This file was automatically generated from Lexicon schemas.
46// Any manual changes will be overwritten on the next regeneration.
5768#[jacquard_derive::lexicon]
79#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
810#[serde(rename_all = "camelCase")]
99-pub struct UpsertOptionInput<'a> {
1111+pub struct UpsertOption<'a> {
1012 #[serde(skip_serializing_if = "std::option::Option::is_none")]
1113 #[serde(borrow)]
1214 pub description: std::option::Option<jacquard_common::CowStr<'a>>,
···2729pub struct UpsertOptionOutput<'a> {
2830 #[serde(borrow)]
2931 pub option: crate::tools_ozone::setting::Option<'a>,
3232+}
3333+3434+impl jacquard_common::types::xrpc::XrpcRequest for UpsertOption<'_> {
3535+ const NSID: &'static str = "tools.ozone.setting.upsertOption";
3636+ const METHOD: jacquard_common::types::xrpc::XrpcMethod = jacquard_common::types::xrpc::XrpcMethod::Procedure(
3737+ "application/json",
3838+ );
3939+ const OUTPUT_ENCODING: &'static str = "application/json";
4040+ type Output<'de> = UpsertOptionOutput<'de>;
4141+ type Err<'de> = jacquard_common::types::xrpc::GenericError;
3042}
+2
crates/jacquard-api/src/tools_ozone/signature.rs
···11// @generated by jacquard-lexicon. DO NOT EDIT.
22//
33+// Lexicon: tools.ozone.signature.defs
44+//
35// This file was automatically generated from Lexicon schemas.
46// Any manual changes will be overwritten on the next regeneration.
57
···11// @generated by jacquard-lexicon. DO NOT EDIT.
22//
33+// Lexicon: tools.ozone.signature.searchAccounts
44+//
35// This file was automatically generated from Lexicon schemas.
46// Any manual changes will be overwritten on the next regeneration.
5766-#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
88+#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq, Default)]
79#[serde(rename_all = "camelCase")]
88-pub struct SearchAccountsParams<'a> {
1010+pub struct SearchAccounts<'a> {
911 #[serde(skip_serializing_if = "std::option::Option::is_none")]
1012 #[serde(borrow)]
1113 pub cursor: std::option::Option<jacquard_common::CowStr<'a>>,
···1517 pub values: Vec<jacquard_common::CowStr<'a>>,
1618}
17192020+impl Default for SearchAccounts<'_> {
2121+ fn default() -> Self {
2222+ Self {
2323+ cursor: Default::default(),
2424+ limit: Some(50i64),
2525+ values: Default::default(),
2626+ }
2727+ }
2828+}
2929+1830#[jacquard_derive::lexicon]
1931#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
2032#[serde(rename_all = "camelCase")]
···2436 #[serde(skip_serializing_if = "std::option::Option::is_none")]
2537 #[serde(borrow)]
2638 pub cursor: std::option::Option<jacquard_common::CowStr<'a>>,
3939+}
4040+4141+impl jacquard_common::types::xrpc::XrpcRequest for SearchAccounts<'_> {
4242+ const NSID: &'static str = "tools.ozone.signature.searchAccounts";
4343+ const METHOD: jacquard_common::types::xrpc::XrpcMethod = jacquard_common::types::xrpc::XrpcMethod::Query;
4444+ const OUTPUT_ENCODING: &'static str = "application/json";
4545+ type Output<'de> = SearchAccountsOutput<'de>;
4646+ type Err<'de> = jacquard_common::types::xrpc::GenericError;
2747}
+2
crates/jacquard-api/src/tools_ozone/team.rs
···11// @generated by jacquard-lexicon. DO NOT EDIT.
22//
33+// Lexicon: tools.ozone.team.defs
44+//
35// This file was automatically generated from Lexicon schemas.
46// Any manual changes will be overwritten on the next regeneration.
57
···11// @generated by jacquard-lexicon. DO NOT EDIT.
22//
33+// Lexicon: tools.ozone.verification.defs
44+//
35// This file was automatically generated from Lexicon schemas.
46// Any manual changes will be overwritten on the next regeneration.
57
···11// @generated by jacquard-lexicon. DO NOT EDIT.
22//
33+// Lexicon: tools.ozone.verification.revokeVerifications
44+//
35// This file was automatically generated from Lexicon schemas.
46// Any manual changes will be overwritten on the next regeneration.
5768#[jacquard_derive::lexicon]
79#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
810#[serde(rename_all = "camelCase")]
99-pub struct RevokeVerificationsInput<'a> {
1111+pub struct RevokeVerifications<'a> {
1012 ///Reason for revoking the verification. This is optional and can be omitted if not needed.
1113 #[serde(skip_serializing_if = "std::option::Option::is_none")]
1214 #[serde(borrow)]
···2628 ///List of verification uris successfully revoked
2729 #[serde(borrow)]
2830 pub revoked_verifications: Vec<jacquard_common::types::string::AtUri<'a>>,
3131+}
3232+3333+impl jacquard_common::types::xrpc::XrpcRequest for RevokeVerifications<'_> {
3434+ const NSID: &'static str = "tools.ozone.verification.revokeVerifications";
3535+ const METHOD: jacquard_common::types::xrpc::XrpcMethod = jacquard_common::types::xrpc::XrpcMethod::Procedure(
3636+ "application/json",
3737+ );
3838+ const OUTPUT_ENCODING: &'static str = "application/json";
3939+ type Output<'de> = RevokeVerificationsOutput<'de>;
4040+ type Err<'de> = jacquard_common::types::xrpc::GenericError;
2941}
30423143///Error object for failed revocations
+4-5
crates/jacquard-common/src/types/collection.rs
···11use core::fmt;
2233-use serde::{Serialize, de};
33+use serde::Serialize;
4455use crate::types::{
66 aturi::UriPath,
···1111/// Trait for a collection of records that can be stored in a repository.
1212///
1313/// The records all have the same Lexicon schema.
1414-pub trait Collection: fmt::Debug {
1414+///
1515+/// Implemented on the record type itself.
1616+pub trait Collection: fmt::Debug + Serialize {
1517 /// The NSID for the Lexicon that defines the schema of records in this collection.
1618 const NSID: &'static str;
1717-1818- /// This collection's record type.
1919- type Record: fmt::Debug + de::DeserializeOwned + Serialize;
20192120 /// Returns the [`Nsid`] for the Lexicon that defines the schema of records in this
2221 /// collection.
+31-14
crates/jacquard-common/src/types/xrpc.rs
···11use serde::{Deserialize, Serialize};
22use std::error::Error;
33+use std::fmt::{self, Debug};
44+55+use crate::types::value::Data;
3647/// XRPC method type
58#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
···710 /// Query (HTTP GET)
811 Query,
912 /// Procedure (HTTP POST)
1010- Procedure,
1313+ Procedure(&'static str),
1114}
12151316impl XrpcMethod {
1417 /// Get the HTTP method string
1515- pub fn as_str(&self) -> &'static str {
1818+ pub const fn as_str(&self) -> &'static str {
1619 match self {
1720 Self::Query => "GET",
1818- Self::Procedure => "POST",
2121+ Self::Procedure(_) => "POST",
2222+ }
2323+ }
2424+2525+ pub const fn body_encoding(&self) -> Option<&'static str> {
2626+ match self {
2727+ Self::Query => None,
2828+ Self::Procedure(enc) => Some(enc),
1929 }
2030 }
2131}
···2333/// Trait for XRPC request types (queries and procedures)
2434///
2535/// This trait provides metadata about XRPC endpoints including the NSID,
2626-/// HTTP method, encoding types, and associated parameter/output types.
2727-pub trait XrpcRequest {
3636+/// HTTP method, encoding types, and associated output types.
3737+///
3838+/// The trait is implemented on the request parameters/input type itself.
3939+pub trait XrpcRequest: Serialize {
2840 /// The NSID for this XRPC method
2941 const NSID: &'static str;
30423143 /// XRPC method (query/GET or procedure/POST)
3244 const METHOD: XrpcMethod;
33453434- /// Input encoding (MIME type, e.g., "application/json")
3535- /// None for queries (no body)
3636- const INPUT_ENCODING: Option<&'static str>;
3737-3846 /// Output encoding (MIME type)
3947 const OUTPUT_ENCODING: &'static str;
4040-4141- /// Request parameters type (query params for queries, body for procedures)
4242- type Params: Serialize;
43484449 /// Response output type
4545- type Output: for<'de> Deserialize<'de>;
5050+ type Output<'de>: Deserialize<'de>;
46514752 /// Error type for this request
4848- type Err: Error;
5353+ type Err<'de>: Error;
4954}
5555+5656+/// Error type for XRPC endpoints that don't define any errors
5757+#[derive(Debug, Clone, PartialEq, Eq)]
5858+pub struct GenericError(Data<'static>);
5959+6060+impl fmt::Display for GenericError {
6161+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6262+ self.0.fmt(f)
6363+ }
6464+}
6565+6666+impl Error for GenericError {}