-13
.claude/settings.local.json
-13
.claude/settings.local.json
-151
CLAUDE.md
-151
CLAUDE.md
···
1
-
# CLAUDE.md
2
-
3
-
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
-
5
-
## Project Overview
6
-
7
-
Jacquard is a suite of Rust crates for the AT Protocol (atproto/Bluesky). The project emphasizes spec-compliant, validated, performant baseline types with minimal boilerplate. Key design goals:
8
-
9
-
- Validated AT Protocol types including typed at:// URIs
10
-
- Custom lexicon extension support
11
-
- Lexicon `Value` type for working with unknown atproto data (dag-cbor or json)
12
-
- Using as much or as little of the crates as needed
13
-
14
-
## Workspace Structure
15
-
16
-
This is a Cargo workspace with several crates:
17
-
18
-
- **jacquard**: Main library crate with XRPC client and public API surface (re-exports jacquard-api and jacquard-common)
19
-
- **jacquard-common**: Core AT Protocol types (DIDs, handles, at-URIs, NSIDs, TIDs, CIDs, etc.) and the `CowStr` type for efficient string handling
20
-
- **jacquard-lexicon**: Lexicon parsing and Rust code generation from lexicon schemas
21
-
- **jacquard-api**: Generated API bindings from lexicon schemas (implementation detail, not directly used by consumers)
22
-
- **jacquard-derive**: Attribute macros (`#[lexicon]`, `#[open_union]`) for lexicon structures
23
-
24
-
## Development Commands
25
-
26
-
### Using Nix (preferred)
27
-
```bash
28
-
# Enter dev shell
29
-
nix develop
30
-
31
-
# Build
32
-
nix build
33
-
34
-
# Run
35
-
nix develop -c cargo run
36
-
```
37
-
38
-
### Using Cargo/Just
39
-
```bash
40
-
# Build
41
-
cargo build
42
-
43
-
# Run tests
44
-
cargo test
45
-
46
-
# Run specific test
47
-
cargo test <test_name>
48
-
49
-
# Run specific package tests
50
-
cargo test -p <package_name>
51
-
52
-
# Run
53
-
cargo run
54
-
55
-
# Auto-recompile and run
56
-
just watch [ARGS]
57
-
58
-
# Format and lint all
59
-
just pre-commit-all
60
-
61
-
# Generate API bindings from lexicon schemas
62
-
cargo run -p jacquard-lexicon --bin jacquard-codegen -- -i <input_dir> -o <output_dir> [-r <root_module>]
63
-
# Example:
64
-
cargo run -p jacquard-lexicon --bin jacquard-codegen -- -i crates/jacquard-lexicon/tests/fixtures/lexicons/atproto/lexicons -o crates/jacquard-api/src -r crate
65
-
```
66
-
67
-
## String Type Pattern
68
-
69
-
The codebase uses a consistent pattern for validated string types. Each type should have:
70
-
71
-
### Constructors
72
-
- `new()`: Construct from a string slice with appropriate lifetime (borrows)
73
-
- `new_owned()`: Construct from `impl AsRef<str>`, taking ownership
74
-
- `new_static()`: Construct from `&'static str` using `SmolStr`/`CowStr`'s static constructor (no allocation)
75
-
- `raw()`: Same as `new()` but panics instead of returning `Result`
76
-
- `unchecked()`: Same as `new()` but doesn't validate (marked `unsafe`)
77
-
- `as_str()`: Return string slice
78
-
79
-
### Traits
80
-
All string types should implement:
81
-
- `Serialize` + `Deserialize` (custom impl for latter, sometimes for former)
82
-
- `FromStr`, `Display`
83
-
- `Debug`, `PartialEq`, `Eq`, `Hash`, `Clone`
84
-
- `From<T> for String`, `CowStr`, `SmolStr`
85
-
- `From<String>`, `From<CowStr>`, `From<SmolStr>`, or `TryFrom` if likely to fail
86
-
- `AsRef<str>`
87
-
- `Deref` with `Target = str` (usually)
88
-
89
-
### Implementation Details
90
-
- Use `#[repr(transparent)]` when possible (exception: at-uri type and components)
91
-
- Use `SmolStr` directly as inner type if most instances will be under 24 bytes
92
-
- Use `CowStr` for longer strings to allow borrowing from input
93
-
- Implement `IntoStatic` trait to take ownership of string types
94
-
95
-
## Code Style
96
-
97
-
- Avoid comments for self-documenting code
98
-
- Comments should not detail fixes when refactoring
99
-
- Professional writing within source code and comments only
100
-
- Prioritize long-term maintainability over implementation speed
101
-
102
-
## Testing
103
-
104
-
- Write test cases for all critical code
105
-
- Tests can be run per-package or workspace-wide
106
-
- Use `cargo test <name>` to run specific tests
107
-
- Current test coverage: 89 tests in jacquard-common
108
-
109
-
## Lexicon Code Generation
110
-
111
-
The `jacquard-codegen` binary generates Rust types from AT Protocol Lexicon schemas:
112
-
113
-
- Generates structs with `#[lexicon]` attribute for forward compatibility (captures unknown fields in `extra_data`)
114
-
- Generates enums with `#[open_union]` attribute for handling unknown variants (unless marked `closed` in lexicon)
115
-
- Resolves local refs (e.g., `#image` becomes `Image<'a>`)
116
-
- Extracts doc comments from lexicon `description` fields
117
-
- Adds header comments with `@generated` marker and lexicon NSID
118
-
- Handles XRPC queries, procedures, subscriptions, and errors
119
-
- Generates proper module tree with Rust 2018 style
120
-
- **XrpcRequest trait**: Implemented directly on params/input structs (not marker types), with GATs for Output<'de> and Err<'de>
121
-
- **IntoStatic trait**: All generated types implement `IntoStatic` to convert borrowed types to owned ('static) variants
122
-
- **Collection trait**: Implemented on record types directly, with const NSID
123
-
124
-
## Current State & Next Steps
125
-
126
-
### Completed
127
-
- โ
Comprehensive validation tests for all core string types (handle, DID, NSID, TID, record key, AT-URI, datetime, language, identifier)
128
-
- โ
Validated implementations against AT Protocol specs and TypeScript reference implementation
129
-
- โ
String type interface standardization (Language now has `new_static()`, Datetime has full conversion traits)
130
-
- โ
Data serialization: Full serialize/deserialize for `Data<'_>`, `Array`, `Object` with format-specific handling (JSON vs CBOR)
131
-
- โ
CidLink wrapper type with automatic `{"$link": "cid"}` serialization in JSON
132
-
- โ
Integration test with real Bluesky thread data validates round-trip correctness
133
-
- โ
Lexicon code generation with forward compatibility and proper lifetime handling
134
-
- โ
IntoStatic implementations for all generated types (structs, enums, unions)
135
-
- โ
XrpcRequest trait with GATs, implemented on params/input types directly
136
-
- โ
HttpClient and XrpcClient traits with generic send_xrpc implementation
137
-
- โ
Response wrapper with parse() (borrowed) and into_output() (owned) methods
138
-
- โ
Structured error types (ClientError, TransportError, EncodeError, DecodeError, HttpError, AuthError)
139
-
140
-
### Next Steps
141
-
1. **Concrete HttpClient Implementation**: Implement HttpClient for reqwest::Client and potentially other HTTP clients
142
-
2. **Error Handling Improvements**: Add XRPC error parsing, better HTTP status code handling, structured error responses
143
-
3. **Authentication**: Session management, token refresh, DPoP support
144
-
4. **Body Encoding**: Support for non-JSON encodings (CBOR, multipart, etc.) in procedures
145
-
5. **Lexicon Resolution**: Fetch lexicons from web sources (atproto authorities, git repositories) and parse into corpus
146
-
6. **Custom Lexicon Support**: Allow users to plug in their own generated lexicons alongside jacquard-api types in the client/server layer
147
-
7. **Public API**: Design the main API surface in `jacquard` that re-exports and wraps generated types
148
-
8. **DID Document Support**: Parsing, validation, and resolution of DID documents
149
-
9. **OAuth Implementation**: OAuth flow support for authentication
150
-
10. **Examples & Documentation**: Create examples and improve documentation
151
-
11. **Testing**: Comprehensive tests for generated code and round-trip serialization
+62
-2
Cargo.lock
+62
-2
Cargo.lock
···
187
187
]
188
188
189
189
[[package]]
190
+
name = "bon"
191
+
version = "3.7.2"
192
+
source = "registry+https://github.com/rust-lang/crates.io-index"
193
+
checksum = "c2529c31017402be841eb45892278a6c21a000c0a17643af326c73a73f83f0fb"
194
+
dependencies = [
195
+
"bon-macros",
196
+
"rustversion",
197
+
]
198
+
199
+
[[package]]
200
+
name = "bon-macros"
201
+
version = "3.7.2"
202
+
source = "registry+https://github.com/rust-lang/crates.io-index"
203
+
checksum = "d82020dadcb845a345591863adb65d74fa8dc5c18a0b6d408470e13b7adc7005"
204
+
dependencies = [
205
+
"darling",
206
+
"ident_case",
207
+
"prettyplease",
208
+
"proc-macro2",
209
+
"quote",
210
+
"rustversion",
211
+
"syn 2.0.106",
212
+
]
213
+
214
+
[[package]]
190
215
name = "borsh"
191
216
version = "1.5.7"
192
217
source = "registry+https://github.com/rust-lang/crates.io-index"
···
589
614
checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
590
615
dependencies = [
591
616
"libc",
592
-
"windows-sys 0.52.0",
617
+
"windows-sys 0.60.2",
593
618
]
594
619
595
620
[[package]]
621
+
name = "fastrand"
622
+
version = "2.3.0"
623
+
source = "registry+https://github.com/rust-lang/crates.io-index"
624
+
checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
625
+
626
+
[[package]]
596
627
name = "find-msvc-tools"
597
628
version = "0.1.2"
598
629
source = "registry+https://github.com/rust-lang/crates.io-index"
···
1115
1146
"http",
1116
1147
"jacquard-api",
1117
1148
"jacquard-common",
1149
+
"jacquard-derive",
1118
1150
"miette",
1119
1151
"reqwest",
1120
1152
"serde",
···
1122
1154
"serde_ipld_dagcbor",
1123
1155
"serde_json",
1124
1156
"thiserror 2.0.17",
1157
+
"tokio",
1125
1158
]
1126
1159
1127
1160
[[package]]
1128
1161
name = "jacquard-api"
1129
1162
version = "0.1.0"
1130
1163
dependencies = [
1164
+
"bon",
1131
1165
"bytes",
1132
1166
"jacquard-common",
1133
1167
"jacquard-derive",
···
1197
1231
"serde_repr",
1198
1232
"serde_with",
1199
1233
"syn 2.0.106",
1234
+
"tempfile",
1200
1235
"thiserror 2.0.17",
1201
1236
]
1202
1237
···
1749
1784
"errno",
1750
1785
"libc",
1751
1786
"linux-raw-sys",
1752
-
"windows-sys 0.52.0",
1787
+
"windows-sys 0.60.2",
1753
1788
]
1754
1789
1755
1790
[[package]]
···
2138
2173
]
2139
2174
2140
2175
[[package]]
2176
+
name = "tempfile"
2177
+
version = "3.23.0"
2178
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2179
+
checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16"
2180
+
dependencies = [
2181
+
"fastrand",
2182
+
"getrandom 0.3.3",
2183
+
"once_cell",
2184
+
"rustix",
2185
+
"windows-sys 0.60.2",
2186
+
]
2187
+
2188
+
[[package]]
2141
2189
name = "terminal_size"
2142
2190
version = "0.4.3"
2143
2191
source = "registry+https://github.com/rust-lang/crates.io-index"
···
2267
2315
"pin-project-lite",
2268
2316
"slab",
2269
2317
"socket2",
2318
+
"tokio-macros",
2270
2319
"windows-sys 0.59.0",
2320
+
]
2321
+
2322
+
[[package]]
2323
+
name = "tokio-macros"
2324
+
version = "2.5.0"
2325
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2326
+
checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8"
2327
+
dependencies = [
2328
+
"proc-macro2",
2329
+
"quote",
2330
+
"syn 2.0.106",
2271
2331
]
2272
2332
2273
2333
[[package]]
+34
-5
Cargo.toml
+34
-5
Cargo.toml
···
8
8
version = "0.1.0"
9
9
authors = ["Orual <orual@nonbinary.computer>"]
10
10
repository = "https://tangled.org/@nonbinary.computer/jacquard"
11
-
keywords = ["atproto", "at protocol", "bluesky", "api", "client"]
11
+
keywords = ["atproto", "at", "bluesky", "api", "client"]
12
12
categories = ["api-bindings", "web-programming::http-client"]
13
13
readme = "README.md"
14
-
documentation = "https://docs.rs/jacquard"
15
14
exclude = [".direnv"]
16
-
17
-
18
-
description = "A simple Rust project using Nix"
15
+
homepage = "https://tangled.org/@nonbinary.computer/jacquard"
16
+
license-file = "LICENSE"
19
17
18
+
description = "Simple and powerful AT Protocol client library for Rust"
20
19
21
20
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
22
21
23
22
[workspace.dependencies]
23
+
# CLI
24
24
clap = { version = "4.5", features = ["derive"] }
25
+
26
+
# Serialization
27
+
serde = { version = "1.0", features = ["derive"] }
28
+
serde_json = "1.0"
29
+
serde_with = "3.14"
30
+
serde_html_form = "0.2"
31
+
serde_ipld_dagcbor = "0.6"
32
+
serde_repr = "0.1"
33
+
34
+
# Error handling
35
+
miette = "7.6"
36
+
thiserror = "2.0"
37
+
38
+
# Data types
39
+
bytes = "1.10"
40
+
smol_str = { version = "0.3", features = ["serde"] }
41
+
url = "2.5"
42
+
43
+
# Proc macros
44
+
proc-macro2 = "1.0"
45
+
quote = "1.0"
46
+
syn = "2.0"
47
+
heck = "0.5"
48
+
itertools = "0.14"
49
+
prettyplease = "0.2"
50
+
51
+
# HTTP
52
+
http = "1.3"
53
+
reqwest = { version = "0.12", default-features = false }
+369
-17
LICENSE
+369
-17
LICENSE
···
1
-
MIT License
1
+
Mozilla Public License Version 2.0
2
+
==================================
3
+
4
+
1. Definitions
5
+
--------------
6
+
7
+
1.1. "Contributor"
8
+
means each individual or legal entity that creates, contributes to
9
+
the creation of, or owns Covered Software.
10
+
11
+
1.2. "Contributor Version"
12
+
means the combination of the Contributions of others (if any) used
13
+
by a Contributor and that particular Contributor's Contribution.
14
+
15
+
1.3. "Contribution"
16
+
means Covered Software of a particular Contributor.
17
+
18
+
1.4. "Covered Software"
19
+
means Source Code Form to which the initial Contributor has attached
20
+
the notice in Exhibit A, the Executable Form of such Source Code
21
+
Form, and Modifications of such Source Code Form, in each case
22
+
including portions thereof.
23
+
24
+
1.5. "Incompatible With Secondary Licenses"
25
+
means
26
+
27
+
(a) that the initial Contributor has attached the notice described
28
+
in Exhibit B to the Covered Software; or
29
+
30
+
(b) that the Covered Software was made available under the terms of
31
+
version 1.1 or earlier of the License, but not also under the
32
+
terms of a Secondary License.
33
+
34
+
1.6. "Executable Form"
35
+
means any form of the work other than Source Code Form.
36
+
37
+
1.7. "Larger Work"
38
+
means a work that combines Covered Software with other material, in
39
+
a separate file or files, that is not Covered Software.
40
+
41
+
1.8. "License"
42
+
means this document.
43
+
44
+
1.9. "Licensable"
45
+
means having the right to grant, to the maximum extent possible,
46
+
whether at the time of the initial grant or subsequently, any and
47
+
all of the rights conveyed by this License.
48
+
49
+
1.10. "Modifications"
50
+
means any of the following:
51
+
52
+
(a) any file in Source Code Form that results from an addition to,
53
+
deletion from, or modification of the contents of Covered
54
+
Software; or
55
+
56
+
(b) any new file in Source Code Form that contains any Covered
57
+
Software.
58
+
59
+
1.11. "Patent Claims" of a Contributor
60
+
means any patent claim(s), including without limitation, method,
61
+
process, and apparatus claims, in any patent Licensable by such
62
+
Contributor that would be infringed, but for the grant of the
63
+
License, by the making, using, selling, offering for sale, having
64
+
made, import, or transfer of either its Contributions or its
65
+
Contributor Version.
66
+
67
+
1.12. "Secondary License"
68
+
means either the GNU General Public License, Version 2.0, the GNU
69
+
Lesser General Public License, Version 2.1, the GNU Affero General
70
+
Public License, Version 3.0, or any later versions of those
71
+
licenses.
72
+
73
+
1.13. "Source Code Form"
74
+
means the form of the work preferred for making modifications.
75
+
76
+
1.14. "You" (or "Your")
77
+
means an individual or a legal entity exercising rights under this
78
+
License. For legal entities, "You" includes any entity that
79
+
controls, is controlled by, or is under common control with You. For
80
+
purposes of this definition, "control" means (a) the power, direct
81
+
or indirect, to cause the direction or management of such entity,
82
+
whether by contract or otherwise, or (b) ownership of more than
83
+
fifty percent (50%) of the outstanding shares or beneficial
84
+
ownership of such entity.
85
+
86
+
2. License Grants and Conditions
87
+
--------------------------------
88
+
89
+
2.1. Grants
90
+
91
+
Each Contributor hereby grants You a world-wide, royalty-free,
92
+
non-exclusive license:
93
+
94
+
(a) under intellectual property rights (other than patent or trademark)
95
+
Licensable by such Contributor to use, reproduce, make available,
96
+
modify, display, perform, distribute, and otherwise exploit its
97
+
Contributions, either on an unmodified basis, with Modifications, or
98
+
as part of a Larger Work; and
2
99
3
-
Copyright (c) 2023 Orual
100
+
(b) under Patent Claims of such Contributor to make, use, sell, offer
101
+
for sale, have made, import, and otherwise transfer either its
102
+
Contributions or its Contributor Version.
4
103
5
-
Permission is hereby granted, free of charge, to any person obtaining a copy
6
-
of this software and associated documentation files (the "Software"), to deal
7
-
in the Software without restriction, including without limitation the rights
8
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
-
copies of the Software, and to permit persons to whom the Software is
10
-
furnished to do so, subject to the following conditions:
104
+
2.2. Effective Date
11
105
12
-
The above copyright notice and this permission notice shall be included in all
13
-
copies or substantial portions of the Software.
106
+
The licenses granted in Section 2.1 with respect to any Contribution
107
+
become effective for each Contribution on the date the Contributor first
108
+
distributes such Contribution.
14
109
15
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
-
SOFTWARE.
110
+
2.3. Limitations on Grant Scope
111
+
112
+
The licenses granted in this Section 2 are the only rights granted under
113
+
this License. No additional rights or licenses will be implied from the
114
+
distribution or licensing of Covered Software under this License.
115
+
Notwithstanding Section 2.1(b) above, no patent license is granted by a
116
+
Contributor:
117
+
118
+
(a) for any code that a Contributor has removed from Covered Software;
119
+
or
120
+
121
+
(b) for infringements caused by: (i) Your and any other third party's
122
+
modifications of Covered Software, or (ii) the combination of its
123
+
Contributions with other software (except as part of its Contributor
124
+
Version); or
125
+
126
+
(c) under Patent Claims infringed by Covered Software in the absence of
127
+
its Contributions.
128
+
129
+
This License does not grant any rights in the trademarks, service marks,
130
+
or logos of any Contributor (except as may be necessary to comply with
131
+
the notice requirements in Section 3.4).
132
+
133
+
2.4. Subsequent Licenses
134
+
135
+
No Contributor makes additional grants as a result of Your choice to
136
+
distribute the Covered Software under a subsequent version of this
137
+
License (see Section 10.2) or under the terms of a Secondary License (if
138
+
permitted under the terms of Section 3.3).
139
+
140
+
2.5. Representation
141
+
142
+
Each Contributor represents that the Contributor believes its
143
+
Contributions are its original creation(s) or it has sufficient rights
144
+
to grant the rights to its Contributions conveyed by this License.
145
+
146
+
2.6. Fair Use
147
+
148
+
This License is not intended to limit any rights You have under
149
+
applicable copyright doctrines of fair use, fair dealing, or other
150
+
equivalents.
151
+
152
+
2.7. Conditions
153
+
154
+
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
155
+
in Section 2.1.
156
+
157
+
3. Responsibilities
158
+
-------------------
159
+
160
+
3.1. Distribution of Source Form
161
+
162
+
All distribution of Covered Software in Source Code Form, including any
163
+
Modifications that You create or to which You contribute, must be under
164
+
the terms of this License. You must inform recipients that the Source
165
+
Code Form of the Covered Software is governed by the terms of this
166
+
License, and how they can obtain a copy of this License. You may not
167
+
attempt to alter or restrict the recipients' rights in the Source Code
168
+
Form.
169
+
170
+
3.2. Distribution of Executable Form
171
+
172
+
If You distribute Covered Software in Executable Form then:
173
+
174
+
(a) such Covered Software must also be made available in Source Code
175
+
Form, as described in Section 3.1, and You must inform recipients of
176
+
the Executable Form how they can obtain a copy of such Source Code
177
+
Form by reasonable means in a timely manner, at a charge no more
178
+
than the cost of distribution to the recipient; and
179
+
180
+
(b) You may distribute such Executable Form under the terms of this
181
+
License, or sublicense it under different terms, provided that the
182
+
license for the Executable Form does not attempt to limit or alter
183
+
the recipients' rights in the Source Code Form under this License.
184
+
185
+
3.3. Distribution of a Larger Work
186
+
187
+
You may create and distribute a Larger Work under terms of Your choice,
188
+
provided that You also comply with the requirements of this License for
189
+
the Covered Software. If the Larger Work is a combination of Covered
190
+
Software with a work governed by one or more Secondary Licenses, and the
191
+
Covered Software is not Incompatible With Secondary Licenses, this
192
+
License permits You to additionally distribute such Covered Software
193
+
under the terms of such Secondary License(s), so that the recipient of
194
+
the Larger Work may, at their option, further distribute the Covered
195
+
Software under the terms of either this License or such Secondary
196
+
License(s).
197
+
198
+
3.4. Notices
199
+
200
+
You may not remove or alter the substance of any license notices
201
+
(including copyright notices, patent notices, disclaimers of warranty,
202
+
or limitations of liability) contained within the Source Code Form of
203
+
the Covered Software, except that You may alter any license notices to
204
+
the extent required to remedy known factual inaccuracies.
205
+
206
+
3.5. Application of Additional Terms
207
+
208
+
You may choose to offer, and to charge a fee for, warranty, support,
209
+
indemnity or liability obligations to one or more recipients of Covered
210
+
Software. However, You may do so only on Your own behalf, and not on
211
+
behalf of any Contributor. You must make it absolutely clear that any
212
+
such warranty, support, indemnity, or liability obligation is offered by
213
+
You alone, and You hereby agree to indemnify every Contributor for any
214
+
liability incurred by such Contributor as a result of warranty, support,
215
+
indemnity or liability terms You offer. You may include additional
216
+
disclaimers of warranty and limitations of liability specific to any
217
+
jurisdiction.
218
+
219
+
4. Inability to Comply Due to Statute or Regulation
220
+
---------------------------------------------------
221
+
222
+
If it is impossible for You to comply with any of the terms of this
223
+
License with respect to some or all of the Covered Software due to
224
+
statute, judicial order, or regulation then You must: (a) comply with
225
+
the terms of this License to the maximum extent possible; and (b)
226
+
describe the limitations and the code they affect. Such description must
227
+
be placed in a text file included with all distributions of the Covered
228
+
Software under this License. Except to the extent prohibited by statute
229
+
or regulation, such description must be sufficiently detailed for a
230
+
recipient of ordinary skill to be able to understand it.
231
+
232
+
5. Termination
233
+
--------------
234
+
235
+
5.1. The rights granted under this License will terminate automatically
236
+
if You fail to comply with any of its terms. However, if You become
237
+
compliant, then the rights granted under this License from a particular
238
+
Contributor are reinstated (a) provisionally, unless and until such
239
+
Contributor explicitly and finally terminates Your grants, and (b) on an
240
+
ongoing basis, if such Contributor fails to notify You of the
241
+
non-compliance by some reasonable means prior to 60 days after You have
242
+
come back into compliance. Moreover, Your grants from a particular
243
+
Contributor are reinstated on an ongoing basis if such Contributor
244
+
notifies You of the non-compliance by some reasonable means, this is the
245
+
first time You have received notice of non-compliance with this License
246
+
from such Contributor, and You become compliant prior to 30 days after
247
+
Your receipt of the notice.
248
+
249
+
5.2. If You initiate litigation against any entity by asserting a patent
250
+
infringement claim (excluding declaratory judgment actions,
251
+
counter-claims, and cross-claims) alleging that a Contributor Version
252
+
directly or indirectly infringes any patent, then the rights granted to
253
+
You by any and all Contributors for the Covered Software under Section
254
+
2.1 of this License shall terminate.
255
+
256
+
5.3. In the event of termination under Sections 5.1 or 5.2 above, all
257
+
end user license agreements (excluding distributors and resellers) which
258
+
have been validly granted by You or Your distributors under this License
259
+
prior to termination shall survive termination.
260
+
261
+
************************************************************************
262
+
* *
263
+
* 6. Disclaimer of Warranty *
264
+
* ------------------------- *
265
+
* *
266
+
* Covered Software is provided under this License on an "as is" *
267
+
* basis, without warranty of any kind, either expressed, implied, or *
268
+
* statutory, including, without limitation, warranties that the *
269
+
* Covered Software is free of defects, merchantable, fit for a *
270
+
* particular purpose or non-infringing. The entire risk as to the *
271
+
* quality and performance of the Covered Software is with You. *
272
+
* Should any Covered Software prove defective in any respect, You *
273
+
* (not any Contributor) assume the cost of any necessary servicing, *
274
+
* repair, or correction. This disclaimer of warranty constitutes an *
275
+
* essential part of this License. No use of any Covered Software is *
276
+
* authorized under this License except under this disclaimer. *
277
+
* *
278
+
************************************************************************
279
+
280
+
************************************************************************
281
+
* *
282
+
* 7. Limitation of Liability *
283
+
* -------------------------- *
284
+
* *
285
+
* Under no circumstances and under no legal theory, whether tort *
286
+
* (including negligence), contract, or otherwise, shall any *
287
+
* Contributor, or anyone who distributes Covered Software as *
288
+
* permitted above, be liable to You for any direct, indirect, *
289
+
* special, incidental, or consequential damages of any character *
290
+
* including, without limitation, damages for lost profits, loss of *
291
+
* goodwill, work stoppage, computer failure or malfunction, or any *
292
+
* and all other commercial damages or losses, even if such party *
293
+
* shall have been informed of the possibility of such damages. This *
294
+
* limitation of liability shall not apply to liability for death or *
295
+
* personal injury resulting from such party's negligence to the *
296
+
* extent applicable law prohibits such limitation. Some *
297
+
* jurisdictions do not allow the exclusion or limitation of *
298
+
* incidental or consequential damages, so this exclusion and *
299
+
* limitation may not apply to You. *
300
+
* *
301
+
************************************************************************
302
+
303
+
8. Litigation
304
+
-------------
305
+
306
+
Any litigation relating to this License may be brought only in the
307
+
courts of a jurisdiction where the defendant maintains its principal
308
+
place of business and such litigation shall be governed by laws of that
309
+
jurisdiction, without reference to its conflict-of-law provisions.
310
+
Nothing in this Section shall prevent a party's ability to bring
311
+
cross-claims or counter-claims.
312
+
313
+
9. Miscellaneous
314
+
----------------
315
+
316
+
This License represents the complete agreement concerning the subject
317
+
matter hereof. If any provision of this License is held to be
318
+
unenforceable, such provision shall be reformed only to the extent
319
+
necessary to make it enforceable. Any law or regulation which provides
320
+
that the language of a contract shall be construed against the drafter
321
+
shall not be used to construe this License against a Contributor.
322
+
323
+
10. Versions of the License
324
+
---------------------------
325
+
326
+
10.1. New Versions
327
+
328
+
Mozilla Foundation is the license steward. Except as provided in Section
329
+
10.3, no one other than the license steward has the right to modify or
330
+
publish new versions of this License. Each version will be given a
331
+
distinguishing version number.
332
+
333
+
10.2. Effect of New Versions
334
+
335
+
You may distribute the Covered Software under the terms of the version
336
+
of the License under which You originally received the Covered Software,
337
+
or under the terms of any subsequent version published by the license
338
+
steward.
339
+
340
+
10.3. Modified Versions
341
+
342
+
If you create software not governed by this License, and you want to
343
+
create a new license for such software, you may create and use a
344
+
modified version of this License if you rename the license and remove
345
+
any references to the name of the license steward (except to note that
346
+
such modified license differs from this License).
347
+
348
+
10.4. Distributing Source Code Form that is Incompatible With Secondary
349
+
Licenses
350
+
351
+
If You choose to distribute Source Code Form that is Incompatible With
352
+
Secondary Licenses under the terms of this version of the License, the
353
+
notice described in Exhibit B of this License must be attached.
354
+
355
+
Exhibit A - Source Code Form License Notice
356
+
-------------------------------------------
357
+
358
+
This Source Code Form is subject to the terms of the Mozilla Public
359
+
License, v. 2.0. If a copy of the MPL was not distributed with this
360
+
file, You can obtain one at http://mozilla.org/MPL/2.0/.
361
+
362
+
If it is not possible or desirable to put the notice in a particular
363
+
file, then You may include the notice in a location (such as a LICENSE
364
+
file in a relevant directory) where a recipient would be likely to look
365
+
for such a notice.
366
+
367
+
You may add additional accurate notices of copyright ownership.
368
+
369
+
Exhibit B - "Incompatible With Secondary Licenses" Notice
370
+
---------------------------------------------------------
371
+
372
+
This Source Code Form is "Incompatible With Secondary Licenses", as
373
+
defined by the Mozilla Public License, v. 2.0.
+74
-26
README.md
+74
-26
README.md
···
2
2
3
3
A suite of Rust crates for the AT Protocol.
4
4
5
+
[](https://crates.io/crates/jacquard) [](https://docs.rs/jacquard) [](./LICENSE)
6
+
5
7
## Goals
6
8
7
9
- Validated, spec-compliant, easy to work with, and performant baseline types (including typed at:// uris)
···
13
15
- didDoc type with helper methods for getting handles, multikey, and PDS endpoint
14
16
- use as much or as little from the crates as you need
15
17
18
+
19
+
## Example
20
+
21
+
Dead simple api client. Logs in, prints the latest 5 posts from your timeline.
22
+
23
+
```rust
24
+
use clap::Parser;
25
+
use jacquard::CowStr;
26
+
use jacquard::api::app_bsky::feed::get_timeline::GetTimeline;
27
+
use jacquard::api::com_atproto::server::create_session::CreateSession;
28
+
use jacquard::client::{AuthenticatedClient, Session, XrpcClient};
29
+
use miette::IntoDiagnostic;
30
+
31
+
#[derive(Parser, Debug)]
32
+
#[command(author, version, about = "Jacquard - AT Protocol client demo")]
33
+
struct Args {
34
+
/// Username/handle (e.g., alice.mosphere.at)
35
+
#[arg(short, long)]
36
+
username: CowStr<'static>,
37
+
38
+
/// PDS URL (e.g., https://bsky.social)
39
+
#[arg(long, default_value = "https://bsky.social")]
40
+
pds: CowStr<'static>,
41
+
42
+
/// App password
43
+
#[arg(short, long)]
44
+
password: CowStr<'static>,
45
+
}
46
+
47
+
#[tokio::main]
48
+
async fn main() -> miette::Result<()> {
49
+
let args = Args::parse();
50
+
51
+
// Create HTTP client
52
+
let mut client = AuthenticatedClient::new(reqwest::Client::new(), args.pds);
53
+
54
+
// Create session
55
+
let session = Session::from(
56
+
client
57
+
.send(
58
+
CreateSession::new()
59
+
.identifier(args.username)
60
+
.password(args.password)
61
+
.build(),
62
+
)
63
+
.await?
64
+
.into_output()?,
65
+
);
66
+
67
+
println!("logged in as {} ({})", session.handle, session.did);
68
+
client.set_session(session);
69
+
70
+
// Fetch timeline
71
+
println!("\nfetching timeline...");
72
+
let timeline = client
73
+
.send(GetTimeline::new().limit(5).build())
74
+
.await?
75
+
.into_output()?;
76
+
77
+
println!("\ntimeline ({} posts):", timeline.feed.len());
78
+
for (i, post) in timeline.feed.iter().enumerate() {
79
+
println!("\n{}. by {}", i + 1, post.post.author.handle);
80
+
println!(
81
+
" {}",
82
+
serde_json::to_string_pretty(&post.post.record).into_diagnostic()?
83
+
);
84
+
}
85
+
86
+
Ok(())
87
+
}
88
+
```
89
+
16
90
## Development
17
91
18
92
This repo uses [Flakes](https://nixos.asia/en/flakes) from the get-go.
···
29
103
```
30
104
31
105
There's also a [`justfile`](https://just.systems/) for Makefile-esque commands to be run inside of the devShell, and you can generally `cargo ...` or `just ...` whatever just fine if you don't want to use Nix and have the prerequisites installed.
32
-
33
-
34
-
35
-
### String types
36
-
Something of a note to self. Developing a pattern with the string types (may macro-ify at some point). Each needs:
37
-
- new(): constructing from a string slice with the right lifetime that borrows
38
-
- new_owned(): constructing from an impl AsRef<str>, taking ownership
39
-
- new_static(): construction from a &'static str, using SmolStr's/CowStr's new_static() constructor to not allocate
40
-
- raw(): same as new() but panics instead of erroring
41
-
- unchecked(): same as new() but doesn't validate. marked unsafe.
42
-
- as_str(): does what it says on the tin
43
-
#### Traits:
44
-
- Serialize + Deserialize (custom impl for latter, sometimes for former)
45
-
- FromStr
46
-
- Display
47
-
- Debug, PartialEq, Eq, Hash, Clone
48
-
- From<T> for String, CowStr, SmolStr,
49
-
- From<String>, From<CowStr>, From<SmolStr>, or TryFrom if likely enough to fail in practice to make panics common
50
-
- AsRef<str>
51
-
- Deref with Target = str (usually)
52
-
53
-
Use `#[repr(transparent)]` as much as possible. Main exception is at-uri type and components.
54
-
Use SmolStr directly as the inner type if most or all of the instances will be under 24 bytes, save lifetime headaches.
55
-
Use CowStr for longer to allow for borrowing from input.
56
-
57
-
TODO: impl IntoStatic trait to take ownership of string types
+27
-16
crates/jacquard/Cargo.toml
+27
-16
crates/jacquard/Cargo.toml
···
1
1
[package]
2
-
authors.workspace = true
3
-
# If you change the name here, you must also do it in flake.nix (and run `cargo generate-lockfile` afterwards)
4
2
name = "jacquard"
5
-
description = "A simple Rust project using Nix"
3
+
description.workspace = true
4
+
edition.workspace = true
6
5
version.workspace = true
7
-
edition.workspace = true
6
+
authors.workspace = true
7
+
repository.workspace = true
8
+
keywords.workspace = true
9
+
categories.workspace = true
10
+
readme.workspace = true
11
+
exclude.workspace = true
12
+
license-file.workspace = true
8
13
9
-
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
14
+
[features]
15
+
default = ["api_all"]
16
+
derive = ["dep:jacquard-derive"]
17
+
api = ["jacquard-api/com_atproto"]
18
+
api_all = ["api", "jacquard-api/app_bsky", "jacquard-api/chat_bsky", "jacquard-api/tools_ozone"]
10
19
11
20
[lib]
12
21
name = "jacquard"
···
17
26
path = "src/main.rs"
18
27
19
28
[dependencies]
20
-
bytes = "1.10"
21
-
clap = { workspace = true }
22
-
http = "1.3.1"
29
+
bytes.workspace = true
30
+
clap.workspace = true
31
+
http.workspace = true
23
32
jacquard-api = { version = "0.1.0", path = "../jacquard-api" }
24
-
jacquard-common = { path = "../jacquard-common" }
25
-
miette = "7.6.0"
26
-
reqwest = { version = "0.12.23", default-features = false, features = ["charset", "http2", "json", "system-proxy", "gzip", "rustls-tls"] }
27
-
serde = { version = "1.0", features = ["derive"] }
28
-
serde_html_form = "0.2"
29
-
serde_ipld_dagcbor = "0.6.4"
30
-
serde_json = "1.0"
31
-
thiserror = "2.0"
33
+
jacquard-common = { version = "0.1.0", path = "../jacquard-common" }
34
+
jacquard-derive = { version = "0.1.0", path = "../jacquard-derive", optional = true }
35
+
miette.workspace = true
36
+
reqwest = { workspace = true, features = ["charset", "http2", "json", "system-proxy", "gzip", "rustls-tls"] }
37
+
serde.workspace = true
38
+
serde_html_form.workspace = true
39
+
serde_ipld_dagcbor.workspace = true
40
+
serde_json.workspace = true
41
+
thiserror.workspace = true
42
+
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
+25
-16
crates/jacquard/src/client/error.rs
+25
-16
crates/jacquard/src/client/error.rs
···
1
+
//! Error types for XRPC client operations
2
+
1
3
use bytes::Bytes;
2
4
3
-
/// Client error type
5
+
/// Client error type wrapping all possible error conditions
4
6
#[derive(Debug, thiserror::Error, miette::Diagnostic)]
5
7
pub enum ClientError {
6
8
/// HTTP transport error
···
44
46
),
45
47
}
46
48
49
+
/// Transport-level errors that occur during HTTP communication
47
50
#[derive(Debug, thiserror::Error, miette::Diagnostic)]
48
51
pub enum TransportError {
52
+
/// Failed to establish connection to server
49
53
#[error("Connection error: {0}")]
50
54
Connect(String),
51
55
56
+
/// Request timed out
52
57
#[error("Request timeout")]
53
58
Timeout,
54
59
60
+
/// Request construction failed (malformed URI, headers, etc.)
55
61
#[error("Invalid request: {0}")]
56
62
InvalidRequest(String),
57
63
64
+
/// Other transport error
58
65
#[error("Transport error: {0}")]
59
66
Other(Box<dyn std::error::Error + Send + Sync>),
60
67
}
61
68
62
-
#[derive(Debug, thiserror::Error, miette::Diagnostic)]
63
-
pub enum EncodeError {
64
-
#[error("Failed to serialize query: {0}")]
65
-
Query(
66
-
#[from]
67
-
#[source]
68
-
serde_html_form::ser::Error,
69
-
),
70
-
#[error("Failed to serialize JSON: {0}")]
71
-
Json(
72
-
#[from]
73
-
#[source]
74
-
serde_json::Error,
75
-
),
76
-
}
69
+
// Re-export EncodeError from common
70
+
pub use jacquard_common::types::xrpc::EncodeError;
77
71
72
+
/// Response deserialization errors
78
73
#[derive(Debug, thiserror::Error, miette::Diagnostic)]
79
74
pub enum DecodeError {
75
+
/// JSON deserialization failed
80
76
#[error("Failed to deserialize JSON: {0}")]
81
77
Json(
82
78
#[from]
83
79
#[source]
84
80
serde_json::Error,
85
81
),
82
+
/// CBOR deserialization failed (local I/O)
86
83
#[error("Failed to deserialize CBOR: {0}")]
87
84
CborLocal(
88
85
#[from]
89
86
#[source]
90
87
serde_ipld_dagcbor::DecodeError<std::io::Error>,
91
88
),
89
+
/// CBOR deserialization failed (remote/reqwest)
92
90
#[error("Failed to deserialize CBOR: {0}")]
93
91
CborRemote(
94
92
#[from]
···
97
95
),
98
96
}
99
97
98
+
/// HTTP error response (non-200 status codes outside of XRPC error handling)
100
99
#[derive(Debug, thiserror::Error, miette::Diagnostic)]
101
100
pub struct HttpError {
101
+
/// HTTP status code
102
102
pub status: http::StatusCode,
103
+
/// Response body if available
103
104
pub body: Option<Bytes>,
104
105
}
105
106
···
115
116
}
116
117
}
117
118
119
+
/// Authentication and authorization errors
118
120
#[derive(Debug, thiserror::Error, miette::Diagnostic)]
119
121
pub enum AuthError {
122
+
/// Access token has expired (use refresh token to get a new one)
120
123
#[error("Access token expired")]
121
124
TokenExpired,
122
125
126
+
/// Access token is invalid or malformed
123
127
#[error("Invalid access token")]
124
128
InvalidToken,
125
129
130
+
/// Token refresh request failed
126
131
#[error("Token refresh failed")]
127
132
RefreshFailed,
128
133
134
+
/// Request requires authentication but none was provided
129
135
#[error("No authentication provided")]
130
136
NotAuthenticated,
137
+
138
+
/// Other authentication error
131
139
#[error("Authentication error: {0:?}")]
132
140
Other(http::HeaderValue),
133
141
}
134
142
143
+
/// Result type for client operations
135
144
pub type Result<T> = std::result::Result<T, ClientError>;
136
145
137
146
impl From<reqwest::Error> for TransportError {
+117
-12
crates/jacquard/src/client/response.rs
+117
-12
crates/jacquard/src/client/response.rs
···
1
+
//! XRPC response parsing and error handling
2
+
1
3
use bytes::Bytes;
4
+
use http::StatusCode;
2
5
use jacquard_common::IntoStatic;
6
+
use jacquard_common::smol_str::SmolStr;
3
7
use jacquard_common::types::xrpc::XrpcRequest;
8
+
use serde::Deserialize;
4
9
use std::marker::PhantomData;
5
10
11
+
use super::error::AuthError;
12
+
6
13
/// XRPC response wrapper that owns the response buffer
7
14
///
8
15
/// Allows borrowing from the buffer when parsing to avoid unnecessary allocations.
16
+
/// Supports both borrowed parsing (with `parse()`) and owned parsing (with `into_output()`).
9
17
pub struct Response<R: XrpcRequest> {
10
18
buffer: Bytes,
19
+
status: StatusCode,
11
20
_marker: PhantomData<R>,
12
21
}
13
22
14
23
impl<R: XrpcRequest> Response<R> {
15
-
/// Create a new response from a buffer
16
-
pub fn new(buffer: Bytes) -> Self {
24
+
/// Create a new response from a buffer and status code
25
+
pub fn new(buffer: Bytes, status: StatusCode) -> Self {
17
26
Self {
18
27
buffer,
28
+
status,
19
29
_marker: PhantomData,
20
30
}
21
31
}
22
32
33
+
/// Get the HTTP status code
34
+
pub fn status(&self) -> StatusCode {
35
+
self.status
36
+
}
37
+
23
38
/// Parse the response, borrowing from the internal buffer
24
39
pub fn parse(&self) -> Result<R::Output<'_>, XrpcError<R::Err<'_>>> {
25
40
// Use a helper to make lifetime inference work
···
35
50
serde_json::from_slice(buffer)
36
51
}
37
52
38
-
let output = parse_output::<R>(&self.buffer);
39
-
if let Ok(output) = output {
40
-
Ok(output)
41
-
} else {
42
-
// Try to parse as error
53
+
// 200: parse as output
54
+
if self.status.is_success() {
55
+
match parse_output::<R>(&self.buffer) {
56
+
Ok(output) => Ok(output),
57
+
Err(e) => Err(XrpcError::Decode(e)),
58
+
}
59
+
// 400: try typed XRPC error, fallback to generic error
60
+
} else if self.status.as_u16() == 400 {
43
61
match parse_error::<R>(&self.buffer) {
44
62
Ok(error) => Err(XrpcError::Xrpc(error)),
63
+
Err(_) => {
64
+
// Fallback to generic error (InvalidRequest, ExpiredToken, etc.)
65
+
match serde_json::from_slice::<GenericXrpcError>(&self.buffer) {
66
+
Ok(generic) => {
67
+
// Map auth-related errors to AuthError
68
+
match generic.error.as_str() {
69
+
"ExpiredToken" => Err(XrpcError::Auth(AuthError::TokenExpired)),
70
+
"InvalidToken" => Err(XrpcError::Auth(AuthError::InvalidToken)),
71
+
_ => Err(XrpcError::Generic(generic)),
72
+
}
73
+
}
74
+
Err(e) => Err(XrpcError::Decode(e)),
75
+
}
76
+
}
77
+
}
78
+
// 401: always auth error
79
+
} else {
80
+
match serde_json::from_slice::<GenericXrpcError>(&self.buffer) {
81
+
Ok(generic) => match generic.error.as_str() {
82
+
"ExpiredToken" => Err(XrpcError::Auth(AuthError::TokenExpired)),
83
+
"InvalidToken" => Err(XrpcError::Auth(AuthError::InvalidToken)),
84
+
_ => Err(XrpcError::Auth(AuthError::NotAuthenticated)),
85
+
},
45
86
Err(e) => Err(XrpcError::Decode(e)),
46
87
}
47
88
}
···
66
107
serde_json::from_slice(buffer)
67
108
}
68
109
69
-
let output = parse_output::<R>(&self.buffer);
70
-
if let Ok(output) = output {
71
-
Ok(output.into_static())
72
-
} else {
73
-
// Try to parse as error
110
+
// 200: parse as output
111
+
if self.status.is_success() {
112
+
match parse_output::<R>(&self.buffer) {
113
+
Ok(output) => Ok(output.into_static()),
114
+
Err(e) => Err(XrpcError::Decode(e)),
115
+
}
116
+
// 400: try typed XRPC error, fallback to generic error
117
+
} else if self.status.as_u16() == 400 {
74
118
match parse_error::<R>(&self.buffer) {
75
119
Ok(error) => Err(XrpcError::Xrpc(error.into_static())),
120
+
Err(_) => {
121
+
// Fallback to generic error (InvalidRequest, ExpiredToken, etc.)
122
+
match serde_json::from_slice::<GenericXrpcError>(&self.buffer) {
123
+
Ok(generic) => {
124
+
// Map auth-related errors to AuthError
125
+
match generic.error.as_ref() {
126
+
"ExpiredToken" => Err(XrpcError::Auth(AuthError::TokenExpired)),
127
+
"InvalidToken" => Err(XrpcError::Auth(AuthError::InvalidToken)),
128
+
_ => Err(XrpcError::Generic(generic)),
129
+
}
130
+
}
131
+
Err(e) => Err(XrpcError::Decode(e)),
132
+
}
133
+
}
134
+
}
135
+
// 401: always auth error
136
+
} else {
137
+
match serde_json::from_slice::<GenericXrpcError>(&self.buffer) {
138
+
Ok(generic) => match generic.error.as_ref() {
139
+
"ExpiredToken" => Err(XrpcError::Auth(AuthError::TokenExpired)),
140
+
"InvalidToken" => Err(XrpcError::Auth(AuthError::InvalidToken)),
141
+
_ => Err(XrpcError::Auth(AuthError::NotAuthenticated)),
142
+
},
76
143
Err(e) => Err(XrpcError::Decode(e)),
77
144
}
78
145
}
···
84
151
}
85
152
}
86
153
154
+
/// Generic XRPC error format for untyped errors like InvalidRequest
155
+
///
156
+
/// Used when the error doesn't match the endpoint's specific error enum
157
+
#[derive(Debug, Clone, Deserialize)]
158
+
pub struct GenericXrpcError {
159
+
/// Error code (e.g., "InvalidRequest")
160
+
pub error: SmolStr,
161
+
/// Optional error message with details
162
+
pub message: Option<SmolStr>,
163
+
}
164
+
165
+
impl std::fmt::Display for GenericXrpcError {
166
+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
167
+
if let Some(msg) = &self.message {
168
+
write!(f, "{}: {}", self.error, msg)
169
+
} else {
170
+
write!(f, "{}", self.error)
171
+
}
172
+
}
173
+
}
174
+
175
+
impl std::error::Error for GenericXrpcError {}
176
+
177
+
/// XRPC-specific errors returned from endpoints
178
+
///
179
+
/// Represents errors returned in the response body
180
+
/// Type parameter `E` is the endpoint's specific error enum type.
87
181
#[derive(Debug, thiserror::Error, miette::Diagnostic)]
88
182
pub enum XrpcError<E: std::error::Error + IntoStatic> {
183
+
/// Typed XRPC error from the endpoint's specific error enum
89
184
#[error("XRPC error: {0}")]
90
185
Xrpc(E),
186
+
187
+
/// Authentication error (ExpiredToken, InvalidToken, etc.)
188
+
#[error("Authentication error: {0}")]
189
+
Auth(#[from] AuthError),
190
+
191
+
/// Generic XRPC error not in the endpoint's error enum (e.g., InvalidRequest)
192
+
#[error("XRPC error: {0}")]
193
+
Generic(GenericXrpcError),
194
+
195
+
/// Failed to decode the response body
91
196
#[error("Failed to decode response: {0}")]
92
197
Decode(#[from] serde_json::Error),
93
198
}
+189
-27
crates/jacquard/src/client.rs
+189
-27
crates/jacquard/src/client.rs
···
1
+
//! XRPC client implementation for AT Protocol
2
+
//!
3
+
//! This module provides HTTP and XRPC client traits along with an authenticated
4
+
//! client implementation that manages session tokens.
5
+
1
6
mod error;
2
7
mod response;
3
8
4
9
use std::fmt::Display;
5
10
use std::future::Future;
6
11
7
-
pub use error::{ClientError, Result};
8
12
use bytes::Bytes;
13
+
pub use error::{ClientError, Result};
9
14
use http::{
10
15
HeaderName, HeaderValue, Request,
11
16
header::{AUTHORIZATION, CONTENT_TYPE, InvalidHeaderValue},
12
17
};
13
18
pub use response::Response;
14
-
use serde::Serialize;
19
+
20
+
use jacquard_common::{
21
+
CowStr, IntoStatic,
22
+
types::{
23
+
string::{Did, Handle},
24
+
xrpc::{XrpcMethod, XrpcRequest},
25
+
},
26
+
};
27
+
28
+
/// Implement HttpClient for reqwest::Client
29
+
impl HttpClient for reqwest::Client {
30
+
type Error = reqwest::Error;
15
31
16
-
use jacquard_common::{CowStr, types::xrpc::{XrpcMethod, XrpcRequest}};
32
+
async fn send_http(
33
+
&self,
34
+
request: Request<Vec<u8>>,
35
+
) -> core::result::Result<http::Response<Vec<u8>>, Self::Error> {
36
+
// Convert http::Request to reqwest::Request
37
+
let (parts, body) = request.into_parts();
17
38
39
+
let mut req = self.request(parts.method, parts.uri.to_string()).body(body);
40
+
41
+
// Copy headers
42
+
for (name, value) in parts.headers.iter() {
43
+
req = req.header(name.as_str(), value.as_bytes());
44
+
}
45
+
46
+
// Send request
47
+
let resp = req.send().await?;
48
+
49
+
// Convert reqwest::Response to http::Response
50
+
let mut builder = http::Response::builder().status(resp.status());
51
+
52
+
// Copy headers
53
+
for (name, value) in resp.headers().iter() {
54
+
builder = builder.header(name.as_str(), value.as_bytes());
55
+
}
56
+
57
+
// Read body
58
+
let body = resp.bytes().await?.to_vec();
59
+
60
+
Ok(builder.body(body).expect("Failed to build response"))
61
+
}
62
+
}
63
+
64
+
/// HTTP client trait for sending raw HTTP requests
18
65
pub trait HttpClient {
66
+
/// Error type returned by the HTTP client
19
67
type Error: std::error::Error + Display + Send + Sync + 'static;
20
68
/// Send an HTTP request and return the response.
21
69
fn send_http(
···
23
71
request: Request<Vec<u8>>,
24
72
) -> impl Future<Output = core::result::Result<http::Response<Vec<u8>>, Self::Error>>;
25
73
}
26
-
/// XRPC client trait
74
+
/// XRPC client trait for AT Protocol RPC calls
27
75
pub trait XrpcClient: HttpClient {
76
+
/// Get the base URI for XRPC requests (e.g., "https://bsky.social")
28
77
fn base_uri(&self) -> CowStr<'_>;
78
+
/// Get the authorization token for XRPC requests
29
79
#[allow(unused_variables)]
30
80
fn authorization_token(
31
81
&self,
···
52
102
53
103
pub(crate) const NSID_REFRESH_SESSION: &str = "com.atproto.server.refreshSession";
54
104
105
+
/// Authorization token types for XRPC requests
55
106
pub enum AuthorizationToken<'s> {
107
+
/// Bearer token (access JWT, refresh JWT to refresh the session)
56
108
Bearer(CowStr<'s>),
109
+
/// DPoP token (proof-of-possession) for OAuth
57
110
Dpop(CowStr<'s>),
58
111
}
59
112
···
68
121
}
69
122
}
70
123
71
-
/// HTTP headers which can be used in XPRC requests.
124
+
/// HTTP headers commonly used in XRPC requests
72
125
pub enum Header {
126
+
/// Content-Type header
73
127
ContentType,
128
+
/// Authorization header
74
129
Authorization,
130
+
/// `atproto-proxy` header - specifies which service (app server or other atproto service) the user's PDS should forward requests to as appropriate.
131
+
///
132
+
/// See: <https://atproto.com/specs/xrpc#service-proxying>
75
133
AtprotoProxy,
134
+
/// `atproto-accept-labelers` header used by clients to request labels from specific labelers to be included and applied in the response. See [label](https://atproto.com/specs/label) specification for details.
76
135
AtprotoAcceptLabelers,
77
136
}
78
137
···
98
157
99
158
// Add query parameters for Query methods
100
159
if let XrpcMethod::Query = R::METHOD {
101
-
if let Ok(qs) = serde_html_form::to_string(&request) {
102
-
if !qs.is_empty() {
103
-
uri.push('?');
104
-
uri.push_str(&qs);
105
-
}
160
+
let qs = serde_html_form::to_string(&request).map_err(error::EncodeError::from)?;
161
+
if !qs.is_empty() {
162
+
uri.push('?');
163
+
uri.push_str(&qs);
106
164
}
107
165
}
108
166
···
139
197
}
140
198
141
199
// Serialize body for procedures
142
-
let body = if let XrpcMethod::Procedure(encoding) = R::METHOD {
143
-
if encoding == "application/json" {
144
-
serde_json::to_vec(&request).map_err(error::EncodeError::Json)?
145
-
} else {
146
-
// For other encodings, we'd need different serialization
147
-
vec![]
148
-
}
200
+
let body = if let XrpcMethod::Procedure(_) = R::METHOD {
201
+
request.encode_body()?
149
202
} else {
150
203
vec![]
151
204
};
152
205
206
+
// TODO: make this not panic
153
207
let http_request = builder.body(body).expect("Failed to build HTTP request");
154
208
155
209
// Send HTTP request
156
-
let http_response = client.send_http(http_request).await.map_err(|e| {
157
-
error::TransportError::Other(Box::new(e))
158
-
})?;
210
+
let http_response = client
211
+
.send_http(http_request)
212
+
.await
213
+
.map_err(|e| error::TransportError::Other(Box::new(e)))?;
214
+
215
+
let status = http_response.status();
216
+
let buffer = Bytes::from(http_response.into_body());
159
217
160
-
// Check status
161
-
if !http_response.status().is_success() {
218
+
// XRPC errors come as 400/401 with structured error bodies
219
+
// Other error status codes (404, 500, etc.) are generic HTTP errors
220
+
if !status.is_success() && !matches!(status.as_u16(), 400 | 401) {
162
221
return Err(ClientError::Http(error::HttpError {
163
-
status: http_response.status(),
164
-
body: Some(Bytes::from(http_response.body().clone())),
222
+
status,
223
+
body: Some(buffer),
165
224
}));
166
225
}
167
226
168
-
// Convert to Response
169
-
let buffer = Bytes::from(http_response.into_body());
170
-
Ok(Response::new(buffer))
227
+
// Response will parse XRPC errors for 400/401, or output for 2xx
228
+
Ok(Response::new(buffer, status))
229
+
}
230
+
231
+
/// Session information from `com.atproto.server.createSession`
232
+
///
233
+
/// Contains the access and refresh tokens along with user identity information.
234
+
#[derive(Debug, Clone)]
235
+
pub struct Session {
236
+
/// Access token (JWT) used for authenticated requests
237
+
pub access_jwt: CowStr<'static>,
238
+
/// Refresh token (JWT) used to obtain new access tokens
239
+
pub refresh_jwt: CowStr<'static>,
240
+
/// User's DID (Decentralized Identifier)
241
+
pub did: Did<'static>,
242
+
/// User's handle (e.g., "alice.bsky.social")
243
+
pub handle: Handle<'static>,
244
+
}
245
+
246
+
impl From<jacquard_api::com_atproto::server::create_session::CreateSessionOutput<'_>> for Session {
247
+
fn from(
248
+
output: jacquard_api::com_atproto::server::create_session::CreateSessionOutput<'_>,
249
+
) -> Self {
250
+
Self {
251
+
access_jwt: output.access_jwt.into_static(),
252
+
refresh_jwt: output.refresh_jwt.into_static(),
253
+
did: output.did.into_static(),
254
+
handle: output.handle.into_static(),
255
+
}
256
+
}
257
+
}
258
+
259
+
/// Authenticated XRPC client wrapper that manages session tokens
260
+
///
261
+
/// Wraps an HTTP client and adds automatic Bearer token authentication for XRPC requests.
262
+
/// Handles both access tokens for regular requests and refresh tokens for session refresh.
263
+
pub struct AuthenticatedClient<C> {
264
+
client: C,
265
+
base_uri: CowStr<'static>,
266
+
session: Option<Session>,
267
+
}
268
+
269
+
impl<C> AuthenticatedClient<C> {
270
+
/// Create a new authenticated client with a base URI
271
+
///
272
+
/// # Example
273
+
/// ```ignore
274
+
/// let client = AuthenticatedClient::new(
275
+
/// reqwest::Client::new(),
276
+
/// CowStr::from("https://bsky.social")
277
+
/// );
278
+
/// ```
279
+
pub fn new(client: C, base_uri: CowStr<'static>) -> Self {
280
+
Self {
281
+
client,
282
+
base_uri: base_uri,
283
+
session: None,
284
+
}
285
+
}
286
+
287
+
/// Set the session obtained from `createSession` or `refreshSession`
288
+
pub fn set_session(&mut self, session: Session) {
289
+
self.session = Some(session);
290
+
}
291
+
292
+
/// Get the current session if one exists
293
+
pub fn session(&self) -> Option<&Session> {
294
+
self.session.as_ref()
295
+
}
296
+
297
+
/// Clear the current session locally
298
+
///
299
+
/// Note: This only clears the local session state. To properly revoke the session
300
+
/// server-side, use `com.atproto.server.deleteSession` before calling this.
301
+
pub fn clear_session(&mut self) {
302
+
self.session = None;
303
+
}
304
+
}
305
+
306
+
impl<C: HttpClient> HttpClient for AuthenticatedClient<C> {
307
+
type Error = C::Error;
308
+
309
+
fn send_http(
310
+
&self,
311
+
request: Request<Vec<u8>>,
312
+
) -> impl Future<Output = core::result::Result<http::Response<Vec<u8>>, Self::Error>> {
313
+
self.client.send_http(request)
314
+
}
315
+
}
316
+
317
+
impl<C: HttpClient> XrpcClient for AuthenticatedClient<C> {
318
+
fn base_uri(&self) -> CowStr<'_> {
319
+
self.base_uri.clone()
320
+
}
321
+
322
+
async fn authorization_token(&self, is_refresh: bool) -> Option<AuthorizationToken<'_>> {
323
+
if is_refresh {
324
+
self.session
325
+
.as_ref()
326
+
.map(|s| AuthorizationToken::Bearer(s.refresh_jwt.clone()))
327
+
} else {
328
+
self.session
329
+
.as_ref()
330
+
.map(|s| AuthorizationToken::Bearer(s.access_jwt.clone()))
331
+
}
332
+
}
171
333
}
+99
-1
crates/jacquard/src/lib.rs
+99
-1
crates/jacquard/src/lib.rs
···
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
+
90
+
#![warn(missing_docs)]
91
+
92
+
/// XRPC client traits and basic implementation
1
93
pub mod client;
2
94
3
-
// Re-export common types
95
+
#[cfg(feature = "api")]
96
+
/// If enabled, re-export the generated api crate
97
+
pub use jacquard_api as api;
4
98
pub use jacquard_common::*;
99
+
100
+
#[cfg(feature = "derive")]
101
+
/// if enabled, reexport the attribute macros
102
+
pub use jacquard_derive::*;
+55
-11
crates/jacquard/src/main.rs
+55
-11
crates/jacquard/src/main.rs
···
1
1
use clap::Parser;
2
-
use jacquard_api::com_atproto::repo::create_record::*;
2
+
use jacquard::CowStr;
3
+
use jacquard::api::app_bsky::feed::get_timeline::GetTimeline;
4
+
use jacquard::api::com_atproto::server::create_session::CreateSession;
5
+
use jacquard::client::{AuthenticatedClient, Session, XrpcClient};
6
+
use miette::IntoDiagnostic;
3
7
4
8
#[derive(Parser, Debug)]
5
-
#[command(author = "Orual", version, about)]
6
-
/// Application configuration
9
+
#[command(author, version, about = "Jacquard - AT Protocol client demo")]
7
10
struct Args {
8
-
/// whether to be verbose
9
-
#[arg(short = 'v')]
10
-
verbose: bool,
11
+
/// Username/handle (e.g., alice.bsky.social)
12
+
#[arg(short, long)]
13
+
username: CowStr<'static>,
14
+
15
+
/// PDS URL (e.g., https://bsky.social)
16
+
#[arg(long, default_value = "https://bsky.social")]
17
+
pds: CowStr<'static>,
11
18
12
-
/// an optional name to greet
13
-
#[arg()]
14
-
name: Option<String>,
19
+
/// App password
20
+
#[arg(short, long)]
21
+
password: CowStr<'static>,
15
22
}
23
+
#[tokio::main]
24
+
async fn main() -> miette::Result<()> {
25
+
let args = Args::parse();
16
26
17
-
fn main() {
18
-
let client = reqwest::Client::new();
27
+
// Create HTTP client
28
+
let mut client = AuthenticatedClient::new(reqwest::Client::new(), args.pds);
29
+
30
+
// Create session
31
+
let session = Session::from(
32
+
client
33
+
.send(
34
+
CreateSession::new()
35
+
.identifier(args.username)
36
+
.password(args.password)
37
+
.build(),
38
+
)
39
+
.await?
40
+
.into_output()?,
41
+
);
42
+
43
+
println!("logged in as {} ({})", session.handle, session.did);
44
+
client.set_session(session);
45
+
46
+
// Fetch timeline
47
+
println!("\nfetching timeline...");
48
+
let timeline = client
49
+
.send(GetTimeline::new().limit(5).build())
50
+
.await?
51
+
.into_output()?;
52
+
53
+
println!("\ntimeline ({} posts):", timeline.feed.len());
54
+
for (i, post) in timeline.feed.iter().enumerate() {
55
+
println!("\n{}. by {}", i + 1, post.post.author.handle);
56
+
println!(
57
+
" {}",
58
+
serde_json::to_string_pretty(&post.post.record).into_diagnostic()?
59
+
);
60
+
}
61
+
62
+
Ok(())
19
63
}
+8
-7
crates/jacquard-api/Cargo.toml
+8
-7
crates/jacquard-api/Cargo.toml
···
1
1
[package]
2
2
name = "jacquard-api"
3
+
description = "Generated AT Protocol API bindings for Jacquard"
3
4
edition.workspace = true
4
5
version.workspace = true
5
6
authors.workspace = true
···
7
8
keywords.workspace = true
8
9
categories.workspace = true
9
10
readme.workspace = true
10
-
documentation.workspace = true
11
11
exclude.workspace = true
12
-
description.workspace = true
12
+
license-file.workspace = true
13
13
14
14
[features]
15
-
default = ["app_bsky", "com_atproto", "tools_ozone", "chat_bsky"]
15
+
default = [ "com_atproto"]
16
16
app_bsky = []
17
17
chat_bsky = []
18
18
com_atproto = []
19
19
tools_ozone = []
20
20
21
21
[dependencies]
22
-
bytes = { version = "1.10.1", features = ["serde"] }
22
+
bon = "3"
23
+
bytes = { workspace = true, features = ["serde"] }
23
24
jacquard-common = { version = "0.1.0", path = "../jacquard-common" }
24
25
jacquard-derive = { version = "0.1.0", path = "../jacquard-derive" }
25
-
miette = "7.6.0"
26
-
serde = { version = "1.0.228", features = ["derive"] }
27
-
thiserror = "2.0.17"
26
+
miette.workspace = true
27
+
serde.workspace = true
28
+
thiserror.workspace = true
+10
-1
crates/jacquard-api/src/app_bsky/actor/get_preferences.rs
+10
-1
crates/jacquard-api/src/app_bsky/actor/get_preferences.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetPreferences {}
11
20
impl jacquard_common::IntoStatic for GetPreferences {
+10
-1
crates/jacquard-api/src/app_bsky/actor/get_profile.rs
+10
-1
crates/jacquard-api/src/app_bsky/actor/get_profile.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetProfile<'a> {
11
20
#[serde(borrow)]
+10
-1
crates/jacquard-api/src/app_bsky/actor/get_profiles.rs
+10
-1
crates/jacquard-api/src/app_bsky/actor/get_profiles.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetProfiles<'a> {
11
20
#[serde(borrow)]
+11
-1
crates/jacquard-api/src/app_bsky/actor/get_suggestions.rs
+11
-1
crates/jacquard-api/src/app_bsky/actor/get_suggestions.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetSuggestions<'a> {
11
20
#[serde(skip_serializing_if = "std::option::Option::is_none")]
12
21
#[serde(borrow)]
22
+
#[builder(into)]
13
23
pub cursor: std::option::Option<jacquard_common::CowStr<'a>>,
14
24
///(default: 50, min: 1, max: 100)
15
25
#[serde(skip_serializing_if = "std::option::Option::is_none")]
+17
-1
crates/jacquard-api/src/app_bsky/actor/put_preferences.rs
+17
-1
crates/jacquard-api/src/app_bsky/actor/put_preferences.rs
···
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
8
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
9
+
#[derive(
10
+
serde::Serialize,
11
+
serde::Deserialize,
12
+
Debug,
13
+
Clone,
14
+
PartialEq,
15
+
Eq,
16
+
bon::Builder
17
+
)]
10
18
#[serde(rename_all = "camelCase")]
19
+
#[builder(start_fn = new)]
11
20
pub struct PutPreferences<'a> {
12
21
#[serde(borrow)]
13
22
pub preferences: crate::app_bsky::actor::Preferences<'a>,
23
+
#[serde(flatten)]
24
+
#[serde(borrow)]
25
+
#[builder(default)]
26
+
pub extra_data: ::std::collections::BTreeMap<
27
+
::jacquard_common::smol_str::SmolStr,
28
+
::jacquard_common::types::value::Data<'a>,
29
+
>,
14
30
}
15
31
16
32
impl jacquard_common::IntoStatic for PutPreferences<'_> {
+13
-1
crates/jacquard-api/src/app_bsky/actor/search_actors.rs
+13
-1
crates/jacquard-api/src/app_bsky/actor/search_actors.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct SearchActors<'a> {
11
20
#[serde(skip_serializing_if = "std::option::Option::is_none")]
12
21
#[serde(borrow)]
22
+
#[builder(into)]
13
23
pub cursor: std::option::Option<jacquard_common::CowStr<'a>>,
14
24
///(default: 25, min: 1, max: 100)
15
25
#[serde(skip_serializing_if = "std::option::Option::is_none")]
16
26
pub limit: std::option::Option<i64>,
17
27
#[serde(skip_serializing_if = "std::option::Option::is_none")]
18
28
#[serde(borrow)]
29
+
#[builder(into)]
19
30
pub q: std::option::Option<jacquard_common::CowStr<'a>>,
20
31
#[serde(skip_serializing_if = "std::option::Option::is_none")]
21
32
#[serde(borrow)]
33
+
#[builder(into)]
22
34
pub term: std::option::Option<jacquard_common::CowStr<'a>>,
23
35
}
24
36
+12
-1
crates/jacquard-api/src/app_bsky/actor/search_actors_typeahead.rs
+12
-1
crates/jacquard-api/src/app_bsky/actor/search_actors_typeahead.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct SearchActorsTypeahead<'a> {
11
20
///(default: 10, min: 1, max: 100)
···
13
22
pub limit: std::option::Option<i64>,
14
23
#[serde(skip_serializing_if = "std::option::Option::is_none")]
15
24
#[serde(borrow)]
25
+
#[builder(into)]
16
26
pub q: std::option::Option<jacquard_common::CowStr<'a>>,
17
27
#[serde(skip_serializing_if = "std::option::Option::is_none")]
18
28
#[serde(borrow)]
29
+
#[builder(into)]
19
30
pub term: std::option::Option<jacquard_common::CowStr<'a>>,
20
31
}
21
32
+17
-1
crates/jacquard-api/src/app_bsky/bookmark/create_bookmark.rs
+17
-1
crates/jacquard-api/src/app_bsky/bookmark/create_bookmark.rs
···
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
8
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
9
+
#[derive(
10
+
serde::Serialize,
11
+
serde::Deserialize,
12
+
Debug,
13
+
Clone,
14
+
PartialEq,
15
+
Eq,
16
+
bon::Builder
17
+
)]
10
18
#[serde(rename_all = "camelCase")]
19
+
#[builder(start_fn = new)]
11
20
pub struct CreateBookmark<'a> {
12
21
#[serde(borrow)]
13
22
pub cid: jacquard_common::types::string::Cid<'a>,
14
23
#[serde(borrow)]
15
24
pub uri: jacquard_common::types::string::AtUri<'a>,
25
+
#[serde(flatten)]
26
+
#[serde(borrow)]
27
+
#[builder(default)]
28
+
pub extra_data: ::std::collections::BTreeMap<
29
+
::jacquard_common::smol_str::SmolStr,
30
+
::jacquard_common::types::value::Data<'a>,
31
+
>,
16
32
}
17
33
18
34
impl jacquard_common::IntoStatic for CreateBookmark<'_> {
+17
-1
crates/jacquard-api/src/app_bsky/bookmark/delete_bookmark.rs
+17
-1
crates/jacquard-api/src/app_bsky/bookmark/delete_bookmark.rs
···
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
8
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
9
+
#[derive(
10
+
serde::Serialize,
11
+
serde::Deserialize,
12
+
Debug,
13
+
Clone,
14
+
PartialEq,
15
+
Eq,
16
+
bon::Builder
17
+
)]
10
18
#[serde(rename_all = "camelCase")]
19
+
#[builder(start_fn = new)]
11
20
pub struct DeleteBookmark<'a> {
12
21
#[serde(borrow)]
13
22
pub uri: jacquard_common::types::string::AtUri<'a>,
23
+
#[serde(flatten)]
24
+
#[serde(borrow)]
25
+
#[builder(default)]
26
+
pub extra_data: ::std::collections::BTreeMap<
27
+
::jacquard_common::smol_str::SmolStr,
28
+
::jacquard_common::types::value::Data<'a>,
29
+
>,
14
30
}
15
31
16
32
impl jacquard_common::IntoStatic for DeleteBookmark<'_> {
+11
-1
crates/jacquard-api/src/app_bsky/bookmark/get_bookmarks.rs
+11
-1
crates/jacquard-api/src/app_bsky/bookmark/get_bookmarks.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetBookmarks<'a> {
11
20
#[serde(skip_serializing_if = "std::option::Option::is_none")]
12
21
#[serde(borrow)]
22
+
#[builder(into)]
13
23
pub cursor: std::option::Option<jacquard_common::CowStr<'a>>,
14
24
///(default: 50, min: 1, max: 100)
15
25
#[serde(skip_serializing_if = "std::option::Option::is_none")]
+11
-1
crates/jacquard-api/src/app_bsky/feed/get_actor_feeds.rs
+11
-1
crates/jacquard-api/src/app_bsky/feed/get_actor_feeds.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetActorFeeds<'a> {
11
20
#[serde(borrow)]
12
21
pub actor: jacquard_common::types::ident::AtIdentifier<'a>,
13
22
#[serde(skip_serializing_if = "std::option::Option::is_none")]
14
23
#[serde(borrow)]
24
+
#[builder(into)]
15
25
pub cursor: std::option::Option<jacquard_common::CowStr<'a>>,
16
26
///(default: 50, min: 1, max: 100)
17
27
#[serde(skip_serializing_if = "std::option::Option::is_none")]
+11
-1
crates/jacquard-api/src/app_bsky/feed/get_actor_likes.rs
+11
-1
crates/jacquard-api/src/app_bsky/feed/get_actor_likes.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetActorLikes<'a> {
11
20
#[serde(borrow)]
12
21
pub actor: jacquard_common::types::ident::AtIdentifier<'a>,
13
22
#[serde(skip_serializing_if = "std::option::Option::is_none")]
14
23
#[serde(borrow)]
24
+
#[builder(into)]
15
25
pub cursor: std::option::Option<jacquard_common::CowStr<'a>>,
16
26
///(default: 50, min: 1, max: 100)
17
27
#[serde(skip_serializing_if = "std::option::Option::is_none")]
+11
-1
crates/jacquard-api/src/app_bsky/feed/get_feed.rs
+11
-1
crates/jacquard-api/src/app_bsky/feed/get_feed.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetFeed<'a> {
11
20
#[serde(skip_serializing_if = "std::option::Option::is_none")]
12
21
#[serde(borrow)]
22
+
#[builder(into)]
13
23
pub cursor: std::option::Option<jacquard_common::CowStr<'a>>,
14
24
#[serde(borrow)]
15
25
pub feed: jacquard_common::types::string::AtUri<'a>,
+10
-1
crates/jacquard-api/src/app_bsky/feed/get_feed_generator.rs
+10
-1
crates/jacquard-api/src/app_bsky/feed/get_feed_generator.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetFeedGenerator<'a> {
11
20
#[serde(borrow)]
+10
-1
crates/jacquard-api/src/app_bsky/feed/get_feed_generators.rs
+10
-1
crates/jacquard-api/src/app_bsky/feed/get_feed_generators.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetFeedGenerators<'a> {
11
20
#[serde(borrow)]
+11
-1
crates/jacquard-api/src/app_bsky/feed/get_feed_skeleton.rs
+11
-1
crates/jacquard-api/src/app_bsky/feed/get_feed_skeleton.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetFeedSkeleton<'a> {
11
20
#[serde(skip_serializing_if = "std::option::Option::is_none")]
12
21
#[serde(borrow)]
22
+
#[builder(into)]
13
23
pub cursor: std::option::Option<jacquard_common::CowStr<'a>>,
14
24
#[serde(borrow)]
15
25
pub feed: jacquard_common::types::string::AtUri<'a>,
+11
-1
crates/jacquard-api/src/app_bsky/feed/get_likes.rs
+11
-1
crates/jacquard-api/src/app_bsky/feed/get_likes.rs
···
27
27
}
28
28
}
29
29
30
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
30
+
#[derive(
31
+
serde::Serialize,
32
+
serde::Deserialize,
33
+
Debug,
34
+
Clone,
35
+
PartialEq,
36
+
Eq,
37
+
bon::Builder
38
+
)]
39
+
#[builder(start_fn = new)]
31
40
#[serde(rename_all = "camelCase")]
32
41
pub struct GetLikes<'a> {
33
42
#[serde(skip_serializing_if = "std::option::Option::is_none")]
···
35
44
pub cid: std::option::Option<jacquard_common::types::string::Cid<'a>>,
36
45
#[serde(skip_serializing_if = "std::option::Option::is_none")]
37
46
#[serde(borrow)]
47
+
#[builder(into)]
38
48
pub cursor: std::option::Option<jacquard_common::CowStr<'a>>,
39
49
///(default: 50, min: 1, max: 100)
40
50
#[serde(skip_serializing_if = "std::option::Option::is_none")]
+11
-1
crates/jacquard-api/src/app_bsky/feed/get_list_feed.rs
+11
-1
crates/jacquard-api/src/app_bsky/feed/get_list_feed.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetListFeed<'a> {
11
20
#[serde(skip_serializing_if = "std::option::Option::is_none")]
12
21
#[serde(borrow)]
22
+
#[builder(into)]
13
23
pub cursor: std::option::Option<jacquard_common::CowStr<'a>>,
14
24
///(default: 50, min: 1, max: 100)
15
25
#[serde(skip_serializing_if = "std::option::Option::is_none")]
+10
-1
crates/jacquard-api/src/app_bsky/feed/get_post_thread.rs
+10
-1
crates/jacquard-api/src/app_bsky/feed/get_post_thread.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetPostThread<'a> {
11
20
///(default: 6, min: 0, max: 1000)
+10
-1
crates/jacquard-api/src/app_bsky/feed/get_posts.rs
+10
-1
crates/jacquard-api/src/app_bsky/feed/get_posts.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetPosts<'a> {
11
20
#[serde(borrow)]
+11
-1
crates/jacquard-api/src/app_bsky/feed/get_quotes.rs
+11
-1
crates/jacquard-api/src/app_bsky/feed/get_quotes.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetQuotes<'a> {
11
20
#[serde(skip_serializing_if = "std::option::Option::is_none")]
···
13
22
pub cid: std::option::Option<jacquard_common::types::string::Cid<'a>>,
14
23
#[serde(skip_serializing_if = "std::option::Option::is_none")]
15
24
#[serde(borrow)]
25
+
#[builder(into)]
16
26
pub cursor: std::option::Option<jacquard_common::CowStr<'a>>,
17
27
///(default: 50, min: 1, max: 100)
18
28
#[serde(skip_serializing_if = "std::option::Option::is_none")]
+11
-1
crates/jacquard-api/src/app_bsky/feed/get_reposted_by.rs
+11
-1
crates/jacquard-api/src/app_bsky/feed/get_reposted_by.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetRepostedBy<'a> {
11
20
#[serde(skip_serializing_if = "std::option::Option::is_none")]
···
13
22
pub cid: std::option::Option<jacquard_common::types::string::Cid<'a>>,
14
23
#[serde(skip_serializing_if = "std::option::Option::is_none")]
15
24
#[serde(borrow)]
25
+
#[builder(into)]
16
26
pub cursor: std::option::Option<jacquard_common::CowStr<'a>>,
17
27
///(default: 50, min: 1, max: 100)
18
28
#[serde(skip_serializing_if = "std::option::Option::is_none")]
+13
-4
crates/jacquard-api/src/app_bsky/feed/get_suggested_feeds.rs
+13
-4
crates/jacquard-api/src/app_bsky/feed/get_suggested_feeds.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetSuggestedFeeds<'a> {
11
20
#[serde(skip_serializing_if = "std::option::Option::is_none")]
12
21
#[serde(borrow)]
22
+
#[builder(into)]
13
23
pub cursor: std::option::Option<jacquard_common::CowStr<'a>>,
14
24
///(default: 50, min: 1, max: 100)
15
25
#[serde(skip_serializing_if = "std::option::Option::is_none")]
···
50
60
51
61
impl jacquard_common::types::xrpc::XrpcRequest for GetSuggestedFeeds<'_> {
52
62
const NSID: &'static str = "app.bsky.feed.getSuggestedFeeds";
53
-
const METHOD: jacquard_common::types::xrpc::XrpcMethod =
54
-
jacquard_common::types::xrpc::XrpcMethod::Query;
63
+
const METHOD: jacquard_common::types::xrpc::XrpcMethod = jacquard_common::types::xrpc::XrpcMethod::Query;
55
64
const OUTPUT_ENCODING: &'static str = "application/json";
56
65
type Output<'de> = GetSuggestedFeedsOutput<'de>;
57
66
type Err<'de> = jacquard_common::types::xrpc::GenericError<'de>;
58
-
}
67
+
}
+12
-1
crates/jacquard-api/src/app_bsky/feed/get_timeline.rs
+12
-1
crates/jacquard-api/src/app_bsky/feed/get_timeline.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetTimeline<'a> {
11
20
#[serde(skip_serializing_if = "std::option::Option::is_none")]
12
21
#[serde(borrow)]
22
+
#[builder(into)]
13
23
pub algorithm: std::option::Option<jacquard_common::CowStr<'a>>,
14
24
#[serde(skip_serializing_if = "std::option::Option::is_none")]
15
25
#[serde(borrow)]
26
+
#[builder(into)]
16
27
pub cursor: std::option::Option<jacquard_common::CowStr<'a>>,
17
28
///(default: 50, min: 1, max: 100)
18
29
#[serde(skip_serializing_if = "std::option::Option::is_none")]
+16
-1
crates/jacquard-api/src/app_bsky/feed/search_posts.rs
+16
-1
crates/jacquard-api/src/app_bsky/feed/search_posts.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct SearchPosts<'a> {
11
20
#[serde(skip_serializing_if = "std::option::Option::is_none")]
···
13
22
pub author: std::option::Option<jacquard_common::types::ident::AtIdentifier<'a>>,
14
23
#[serde(skip_serializing_if = "std::option::Option::is_none")]
15
24
#[serde(borrow)]
25
+
#[builder(into)]
16
26
pub cursor: std::option::Option<jacquard_common::CowStr<'a>>,
17
27
#[serde(skip_serializing_if = "std::option::Option::is_none")]
18
28
#[serde(borrow)]
29
+
#[builder(into)]
19
30
pub domain: std::option::Option<jacquard_common::CowStr<'a>>,
20
31
#[serde(skip_serializing_if = "std::option::Option::is_none")]
21
32
pub lang: std::option::Option<jacquard_common::types::string::Language>,
···
26
37
#[serde(borrow)]
27
38
pub mentions: std::option::Option<jacquard_common::types::ident::AtIdentifier<'a>>,
28
39
#[serde(borrow)]
40
+
#[builder(into)]
29
41
pub q: jacquard_common::CowStr<'a>,
30
42
#[serde(skip_serializing_if = "std::option::Option::is_none")]
31
43
#[serde(borrow)]
44
+
#[builder(into)]
32
45
pub since: std::option::Option<jacquard_common::CowStr<'a>>,
33
46
///(default: "latest")
34
47
#[serde(skip_serializing_if = "std::option::Option::is_none")]
35
48
#[serde(borrow)]
49
+
#[builder(into)]
36
50
pub sort: std::option::Option<jacquard_common::CowStr<'a>>,
37
51
#[serde(skip_serializing_if = "std::option::Option::is_none")]
38
52
#[serde(borrow)]
39
53
pub tag: std::option::Option<Vec<jacquard_common::CowStr<'a>>>,
40
54
#[serde(skip_serializing_if = "std::option::Option::is_none")]
41
55
#[serde(borrow)]
56
+
#[builder(into)]
42
57
pub until: std::option::Option<jacquard_common::CowStr<'a>>,
43
58
#[serde(skip_serializing_if = "std::option::Option::is_none")]
44
59
#[serde(borrow)]
+17
-1
crates/jacquard-api/src/app_bsky/feed/send_interactions.rs
+17
-1
crates/jacquard-api/src/app_bsky/feed/send_interactions.rs
···
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
8
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
9
+
#[derive(
10
+
serde::Serialize,
11
+
serde::Deserialize,
12
+
Debug,
13
+
Clone,
14
+
PartialEq,
15
+
Eq,
16
+
bon::Builder
17
+
)]
10
18
#[serde(rename_all = "camelCase")]
19
+
#[builder(start_fn = new)]
11
20
pub struct SendInteractions<'a> {
12
21
#[serde(borrow)]
13
22
pub interactions: Vec<crate::app_bsky::feed::Interaction<'a>>,
23
+
#[serde(flatten)]
24
+
#[serde(borrow)]
25
+
#[builder(default)]
26
+
pub extra_data: ::std::collections::BTreeMap<
27
+
::jacquard_common::smol_str::SmolStr,
28
+
::jacquard_common::types::value::Data<'a>,
29
+
>,
14
30
}
15
31
16
32
impl jacquard_common::IntoStatic for SendInteractions<'_> {
+11
-1
crates/jacquard-api/src/app_bsky/graph/get_actor_starter_packs.rs
+11
-1
crates/jacquard-api/src/app_bsky/graph/get_actor_starter_packs.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetActorStarterPacks<'a> {
11
20
#[serde(borrow)]
12
21
pub actor: jacquard_common::types::ident::AtIdentifier<'a>,
13
22
#[serde(skip_serializing_if = "std::option::Option::is_none")]
14
23
#[serde(borrow)]
24
+
#[builder(into)]
15
25
pub cursor: std::option::Option<jacquard_common::CowStr<'a>>,
16
26
///(default: 50, min: 1, max: 100)
17
27
#[serde(skip_serializing_if = "std::option::Option::is_none")]
+11
-1
crates/jacquard-api/src/app_bsky/graph/get_blocks.rs
+11
-1
crates/jacquard-api/src/app_bsky/graph/get_blocks.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetBlocks<'a> {
11
20
#[serde(skip_serializing_if = "std::option::Option::is_none")]
12
21
#[serde(borrow)]
22
+
#[builder(into)]
13
23
pub cursor: std::option::Option<jacquard_common::CowStr<'a>>,
14
24
///(default: 50, min: 1, max: 100)
15
25
#[serde(skip_serializing_if = "std::option::Option::is_none")]
+11
-1
crates/jacquard-api/src/app_bsky/graph/get_followers.rs
+11
-1
crates/jacquard-api/src/app_bsky/graph/get_followers.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetFollowers<'a> {
11
20
#[serde(borrow)]
12
21
pub actor: jacquard_common::types::ident::AtIdentifier<'a>,
13
22
#[serde(skip_serializing_if = "std::option::Option::is_none")]
14
23
#[serde(borrow)]
24
+
#[builder(into)]
15
25
pub cursor: std::option::Option<jacquard_common::CowStr<'a>>,
16
26
///(default: 50, min: 1, max: 100)
17
27
#[serde(skip_serializing_if = "std::option::Option::is_none")]
+11
-1
crates/jacquard-api/src/app_bsky/graph/get_follows.rs
+11
-1
crates/jacquard-api/src/app_bsky/graph/get_follows.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetFollows<'a> {
11
20
#[serde(borrow)]
12
21
pub actor: jacquard_common::types::ident::AtIdentifier<'a>,
13
22
#[serde(skip_serializing_if = "std::option::Option::is_none")]
14
23
#[serde(borrow)]
24
+
#[builder(into)]
15
25
pub cursor: std::option::Option<jacquard_common::CowStr<'a>>,
16
26
///(default: 50, min: 1, max: 100)
17
27
#[serde(skip_serializing_if = "std::option::Option::is_none")]
+11
-1
crates/jacquard-api/src/app_bsky/graph/get_known_followers.rs
+11
-1
crates/jacquard-api/src/app_bsky/graph/get_known_followers.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetKnownFollowers<'a> {
11
20
#[serde(borrow)]
12
21
pub actor: jacquard_common::types::ident::AtIdentifier<'a>,
13
22
#[serde(skip_serializing_if = "std::option::Option::is_none")]
14
23
#[serde(borrow)]
24
+
#[builder(into)]
15
25
pub cursor: std::option::Option<jacquard_common::CowStr<'a>>,
16
26
///(default: 50, min: 1, max: 100)
17
27
#[serde(skip_serializing_if = "std::option::Option::is_none")]
+11
-1
crates/jacquard-api/src/app_bsky/graph/get_list.rs
+11
-1
crates/jacquard-api/src/app_bsky/graph/get_list.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetList<'a> {
11
20
#[serde(skip_serializing_if = "std::option::Option::is_none")]
12
21
#[serde(borrow)]
22
+
#[builder(into)]
13
23
pub cursor: std::option::Option<jacquard_common::CowStr<'a>>,
14
24
///(default: 50, min: 1, max: 100)
15
25
#[serde(skip_serializing_if = "std::option::Option::is_none")]
+11
-1
crates/jacquard-api/src/app_bsky/graph/get_list_blocks.rs
+11
-1
crates/jacquard-api/src/app_bsky/graph/get_list_blocks.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetListBlocks<'a> {
11
20
#[serde(skip_serializing_if = "std::option::Option::is_none")]
12
21
#[serde(borrow)]
22
+
#[builder(into)]
13
23
pub cursor: std::option::Option<jacquard_common::CowStr<'a>>,
14
24
///(default: 50, min: 1, max: 100)
15
25
#[serde(skip_serializing_if = "std::option::Option::is_none")]
+11
-1
crates/jacquard-api/src/app_bsky/graph/get_list_mutes.rs
+11
-1
crates/jacquard-api/src/app_bsky/graph/get_list_mutes.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetListMutes<'a> {
11
20
#[serde(skip_serializing_if = "std::option::Option::is_none")]
12
21
#[serde(borrow)]
22
+
#[builder(into)]
13
23
pub cursor: std::option::Option<jacquard_common::CowStr<'a>>,
14
24
///(default: 50, min: 1, max: 100)
15
25
#[serde(skip_serializing_if = "std::option::Option::is_none")]
+11
-1
crates/jacquard-api/src/app_bsky/graph/get_lists.rs
+11
-1
crates/jacquard-api/src/app_bsky/graph/get_lists.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetLists<'a> {
11
20
#[serde(borrow)]
12
21
pub actor: jacquard_common::types::ident::AtIdentifier<'a>,
13
22
#[serde(skip_serializing_if = "std::option::Option::is_none")]
14
23
#[serde(borrow)]
24
+
#[builder(into)]
15
25
pub cursor: std::option::Option<jacquard_common::CowStr<'a>>,
16
26
///(default: 50, min: 1, max: 100)
17
27
#[serde(skip_serializing_if = "std::option::Option::is_none")]
+11
-1
crates/jacquard-api/src/app_bsky/graph/get_lists_with_membership.rs
+11
-1
crates/jacquard-api/src/app_bsky/graph/get_lists_with_membership.rs
···
28
28
}
29
29
}
30
30
31
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
31
+
#[derive(
32
+
serde::Serialize,
33
+
serde::Deserialize,
34
+
Debug,
35
+
Clone,
36
+
PartialEq,
37
+
Eq,
38
+
bon::Builder
39
+
)]
40
+
#[builder(start_fn = new)]
32
41
#[serde(rename_all = "camelCase")]
33
42
pub struct GetListsWithMembership<'a> {
34
43
#[serde(borrow)]
35
44
pub actor: jacquard_common::types::ident::AtIdentifier<'a>,
36
45
#[serde(skip_serializing_if = "std::option::Option::is_none")]
37
46
#[serde(borrow)]
47
+
#[builder(into)]
38
48
pub cursor: std::option::Option<jacquard_common::CowStr<'a>>,
39
49
///(default: 50, min: 1, max: 100)
40
50
#[serde(skip_serializing_if = "std::option::Option::is_none")]
+11
-1
crates/jacquard-api/src/app_bsky/graph/get_mutes.rs
+11
-1
crates/jacquard-api/src/app_bsky/graph/get_mutes.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetMutes<'a> {
11
20
#[serde(skip_serializing_if = "std::option::Option::is_none")]
12
21
#[serde(borrow)]
22
+
#[builder(into)]
13
23
pub cursor: std::option::Option<jacquard_common::CowStr<'a>>,
14
24
///(default: 50, min: 1, max: 100)
15
25
#[serde(skip_serializing_if = "std::option::Option::is_none")]
+10
-1
crates/jacquard-api/src/app_bsky/graph/get_relationships.rs
+10
-1
crates/jacquard-api/src/app_bsky/graph/get_relationships.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetRelationships<'a> {
11
20
#[serde(borrow)]
+10
-1
crates/jacquard-api/src/app_bsky/graph/get_starter_pack.rs
+10
-1
crates/jacquard-api/src/app_bsky/graph/get_starter_pack.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetStarterPack<'a> {
11
20
#[serde(borrow)]
+10
-1
crates/jacquard-api/src/app_bsky/graph/get_starter_packs.rs
+10
-1
crates/jacquard-api/src/app_bsky/graph/get_starter_packs.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetStarterPacks<'a> {
11
20
#[serde(borrow)]
+11
-1
crates/jacquard-api/src/app_bsky/graph/get_starter_packs_with_membership.rs
+11
-1
crates/jacquard-api/src/app_bsky/graph/get_starter_packs_with_membership.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetStarterPacksWithMembership<'a> {
11
20
#[serde(borrow)]
12
21
pub actor: jacquard_common::types::ident::AtIdentifier<'a>,
13
22
#[serde(skip_serializing_if = "std::option::Option::is_none")]
14
23
#[serde(borrow)]
24
+
#[builder(into)]
15
25
pub cursor: std::option::Option<jacquard_common::CowStr<'a>>,
16
26
///(default: 50, min: 1, max: 100)
17
27
#[serde(skip_serializing_if = "std::option::Option::is_none")]
+10
-1
crates/jacquard-api/src/app_bsky/graph/get_suggested_follows_by_actor.rs
+10
-1
crates/jacquard-api/src/app_bsky/graph/get_suggested_follows_by_actor.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetSuggestedFollowsByActor<'a> {
11
20
#[serde(borrow)]
+17
-1
crates/jacquard-api/src/app_bsky/graph/mute_actor.rs
+17
-1
crates/jacquard-api/src/app_bsky/graph/mute_actor.rs
···
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
8
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
9
+
#[derive(
10
+
serde::Serialize,
11
+
serde::Deserialize,
12
+
Debug,
13
+
Clone,
14
+
PartialEq,
15
+
Eq,
16
+
bon::Builder
17
+
)]
10
18
#[serde(rename_all = "camelCase")]
19
+
#[builder(start_fn = new)]
11
20
pub struct MuteActor<'a> {
12
21
#[serde(borrow)]
13
22
pub actor: jacquard_common::types::ident::AtIdentifier<'a>,
23
+
#[serde(flatten)]
24
+
#[serde(borrow)]
25
+
#[builder(default)]
26
+
pub extra_data: ::std::collections::BTreeMap<
27
+
::jacquard_common::smol_str::SmolStr,
28
+
::jacquard_common::types::value::Data<'a>,
29
+
>,
14
30
}
15
31
16
32
impl jacquard_common::IntoStatic for MuteActor<'_> {
+17
-1
crates/jacquard-api/src/app_bsky/graph/mute_actor_list.rs
+17
-1
crates/jacquard-api/src/app_bsky/graph/mute_actor_list.rs
···
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
8
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
9
+
#[derive(
10
+
serde::Serialize,
11
+
serde::Deserialize,
12
+
Debug,
13
+
Clone,
14
+
PartialEq,
15
+
Eq,
16
+
bon::Builder
17
+
)]
10
18
#[serde(rename_all = "camelCase")]
19
+
#[builder(start_fn = new)]
11
20
pub struct MuteActorList<'a> {
12
21
#[serde(borrow)]
13
22
pub list: jacquard_common::types::string::AtUri<'a>,
23
+
#[serde(flatten)]
24
+
#[serde(borrow)]
25
+
#[builder(default)]
26
+
pub extra_data: ::std::collections::BTreeMap<
27
+
::jacquard_common::smol_str::SmolStr,
28
+
::jacquard_common::types::value::Data<'a>,
29
+
>,
14
30
}
15
31
16
32
impl jacquard_common::IntoStatic for MuteActorList<'_> {
+17
-1
crates/jacquard-api/src/app_bsky/graph/mute_thread.rs
+17
-1
crates/jacquard-api/src/app_bsky/graph/mute_thread.rs
···
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
8
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
9
+
#[derive(
10
+
serde::Serialize,
11
+
serde::Deserialize,
12
+
Debug,
13
+
Clone,
14
+
PartialEq,
15
+
Eq,
16
+
bon::Builder
17
+
)]
10
18
#[serde(rename_all = "camelCase")]
19
+
#[builder(start_fn = new)]
11
20
pub struct MuteThread<'a> {
12
21
#[serde(borrow)]
13
22
pub root: jacquard_common::types::string::AtUri<'a>,
23
+
#[serde(flatten)]
24
+
#[serde(borrow)]
25
+
#[builder(default)]
26
+
pub extra_data: ::std::collections::BTreeMap<
27
+
::jacquard_common::smol_str::SmolStr,
28
+
::jacquard_common::types::value::Data<'a>,
29
+
>,
14
30
}
15
31
16
32
impl jacquard_common::IntoStatic for MuteThread<'_> {
+12
-1
crates/jacquard-api/src/app_bsky/graph/search_starter_packs.rs
+12
-1
crates/jacquard-api/src/app_bsky/graph/search_starter_packs.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct SearchStarterPacks<'a> {
11
20
#[serde(skip_serializing_if = "std::option::Option::is_none")]
12
21
#[serde(borrow)]
22
+
#[builder(into)]
13
23
pub cursor: std::option::Option<jacquard_common::CowStr<'a>>,
14
24
///(default: 25, min: 1, max: 100)
15
25
#[serde(skip_serializing_if = "std::option::Option::is_none")]
16
26
pub limit: std::option::Option<i64>,
17
27
#[serde(borrow)]
28
+
#[builder(into)]
18
29
pub q: jacquard_common::CowStr<'a>,
19
30
}
20
31
+17
-1
crates/jacquard-api/src/app_bsky/graph/unmute_actor.rs
+17
-1
crates/jacquard-api/src/app_bsky/graph/unmute_actor.rs
···
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
8
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
9
+
#[derive(
10
+
serde::Serialize,
11
+
serde::Deserialize,
12
+
Debug,
13
+
Clone,
14
+
PartialEq,
15
+
Eq,
16
+
bon::Builder
17
+
)]
10
18
#[serde(rename_all = "camelCase")]
19
+
#[builder(start_fn = new)]
11
20
pub struct UnmuteActor<'a> {
12
21
#[serde(borrow)]
13
22
pub actor: jacquard_common::types::ident::AtIdentifier<'a>,
23
+
#[serde(flatten)]
24
+
#[serde(borrow)]
25
+
#[builder(default)]
26
+
pub extra_data: ::std::collections::BTreeMap<
27
+
::jacquard_common::smol_str::SmolStr,
28
+
::jacquard_common::types::value::Data<'a>,
29
+
>,
14
30
}
15
31
16
32
impl jacquard_common::IntoStatic for UnmuteActor<'_> {
+17
-1
crates/jacquard-api/src/app_bsky/graph/unmute_actor_list.rs
+17
-1
crates/jacquard-api/src/app_bsky/graph/unmute_actor_list.rs
···
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
8
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
9
+
#[derive(
10
+
serde::Serialize,
11
+
serde::Deserialize,
12
+
Debug,
13
+
Clone,
14
+
PartialEq,
15
+
Eq,
16
+
bon::Builder
17
+
)]
10
18
#[serde(rename_all = "camelCase")]
19
+
#[builder(start_fn = new)]
11
20
pub struct UnmuteActorList<'a> {
12
21
#[serde(borrow)]
13
22
pub list: jacquard_common::types::string::AtUri<'a>,
23
+
#[serde(flatten)]
24
+
#[serde(borrow)]
25
+
#[builder(default)]
26
+
pub extra_data: ::std::collections::BTreeMap<
27
+
::jacquard_common::smol_str::SmolStr,
28
+
::jacquard_common::types::value::Data<'a>,
29
+
>,
14
30
}
15
31
16
32
impl jacquard_common::IntoStatic for UnmuteActorList<'_> {
+17
-1
crates/jacquard-api/src/app_bsky/graph/unmute_thread.rs
+17
-1
crates/jacquard-api/src/app_bsky/graph/unmute_thread.rs
···
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
8
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
9
+
#[derive(
10
+
serde::Serialize,
11
+
serde::Deserialize,
12
+
Debug,
13
+
Clone,
14
+
PartialEq,
15
+
Eq,
16
+
bon::Builder
17
+
)]
10
18
#[serde(rename_all = "camelCase")]
19
+
#[builder(start_fn = new)]
11
20
pub struct UnmuteThread<'a> {
12
21
#[serde(borrow)]
13
22
pub root: jacquard_common::types::string::AtUri<'a>,
23
+
#[serde(flatten)]
24
+
#[serde(borrow)]
25
+
#[builder(default)]
26
+
pub extra_data: ::std::collections::BTreeMap<
27
+
::jacquard_common::smol_str::SmolStr,
28
+
::jacquard_common::types::value::Data<'a>,
29
+
>,
14
30
}
15
31
16
32
impl jacquard_common::IntoStatic for UnmuteThread<'_> {
+10
-1
crates/jacquard-api/src/app_bsky/labeler/get_services.rs
+10
-1
crates/jacquard-api/src/app_bsky/labeler/get_services.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetServices<'a> {
11
20
///(default: false)
+10
-1
crates/jacquard-api/src/app_bsky/notification/get_preferences.rs
+10
-1
crates/jacquard-api/src/app_bsky/notification/get_preferences.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetPreferences {}
11
20
impl jacquard_common::IntoStatic for GetPreferences {
+10
-1
crates/jacquard-api/src/app_bsky/notification/get_unread_count.rs
+10
-1
crates/jacquard-api/src/app_bsky/notification/get_unread_count.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetUnreadCount {
11
20
#[serde(skip_serializing_if = "std::option::Option::is_none")]
+11
-1
crates/jacquard-api/src/app_bsky/notification/list_activity_subscriptions.rs
+11
-1
crates/jacquard-api/src/app_bsky/notification/list_activity_subscriptions.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct ListActivitySubscriptions<'a> {
11
20
#[serde(skip_serializing_if = "std::option::Option::is_none")]
12
21
#[serde(borrow)]
22
+
#[builder(into)]
13
23
pub cursor: std::option::Option<jacquard_common::CowStr<'a>>,
14
24
///(default: 50, min: 1, max: 100)
15
25
#[serde(skip_serializing_if = "std::option::Option::is_none")]
+11
-1
crates/jacquard-api/src/app_bsky/notification/list_notifications.rs
+11
-1
crates/jacquard-api/src/app_bsky/notification/list_notifications.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct ListNotifications<'a> {
11
20
#[serde(skip_serializing_if = "std::option::Option::is_none")]
12
21
#[serde(borrow)]
22
+
#[builder(into)]
13
23
pub cursor: std::option::Option<jacquard_common::CowStr<'a>>,
14
24
///(default: 50, min: 1, max: 100)
15
25
#[serde(skip_serializing_if = "std::option::Option::is_none")]
+17
-1
crates/jacquard-api/src/app_bsky/notification/put_activity_subscription.rs
+17
-1
crates/jacquard-api/src/app_bsky/notification/put_activity_subscription.rs
···
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
8
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
9
+
#[derive(
10
+
serde::Serialize,
11
+
serde::Deserialize,
12
+
Debug,
13
+
Clone,
14
+
PartialEq,
15
+
Eq,
16
+
bon::Builder
17
+
)]
10
18
#[serde(rename_all = "camelCase")]
19
+
#[builder(start_fn = new)]
11
20
pub struct PutActivitySubscription<'a> {
12
21
#[serde(borrow)]
13
22
pub activity_subscription: crate::app_bsky::notification::ActivitySubscription<'a>,
14
23
#[serde(borrow)]
15
24
pub subject: jacquard_common::types::string::Did<'a>,
25
+
#[serde(flatten)]
26
+
#[serde(borrow)]
27
+
#[builder(default)]
28
+
pub extra_data: ::std::collections::BTreeMap<
29
+
::jacquard_common::smol_str::SmolStr,
30
+
::jacquard_common::types::value::Data<'a>,
31
+
>,
16
32
}
17
33
18
34
impl jacquard_common::IntoStatic for PutActivitySubscription<'_> {
+17
-1
crates/jacquard-api/src/app_bsky/notification/put_preferences.rs
+17
-1
crates/jacquard-api/src/app_bsky/notification/put_preferences.rs
···
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
8
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
9
+
#[derive(
10
+
serde::Serialize,
11
+
serde::Deserialize,
12
+
Debug,
13
+
Clone,
14
+
PartialEq,
15
+
Eq,
16
+
bon::Builder
17
+
)]
10
18
#[serde(rename_all = "camelCase")]
19
+
#[builder(start_fn = new)]
11
20
pub struct PutPreferences<'a> {
12
21
pub priority: bool,
22
+
#[serde(flatten)]
23
+
#[serde(borrow)]
24
+
#[builder(default)]
25
+
pub extra_data: ::std::collections::BTreeMap<
26
+
::jacquard_common::smol_str::SmolStr,
27
+
::jacquard_common::types::value::Data<'a>,
28
+
>,
13
29
}
14
30
15
31
impl jacquard_common::IntoStatic for PutPreferences<'_> {
+17
-1
crates/jacquard-api/src/app_bsky/notification/put_preferences_v2.rs
+17
-1
crates/jacquard-api/src/app_bsky/notification/put_preferences_v2.rs
···
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
8
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
9
+
#[derive(
10
+
serde::Serialize,
11
+
serde::Deserialize,
12
+
Debug,
13
+
Clone,
14
+
PartialEq,
15
+
Eq,
16
+
bon::Builder
17
+
)]
10
18
#[serde(rename_all = "camelCase")]
19
+
#[builder(start_fn = new)]
11
20
pub struct PutPreferencesV2<'a> {
12
21
#[serde(skip_serializing_if = "std::option::Option::is_none")]
13
22
#[serde(borrow)]
···
68
77
#[serde(skip_serializing_if = "std::option::Option::is_none")]
69
78
#[serde(borrow)]
70
79
pub verified: std::option::Option<crate::app_bsky::notification::Preference<'a>>,
80
+
#[serde(flatten)]
81
+
#[serde(borrow)]
82
+
#[builder(default)]
83
+
pub extra_data: ::std::collections::BTreeMap<
84
+
::jacquard_common::smol_str::SmolStr,
85
+
::jacquard_common::types::value::Data<'a>,
86
+
>,
71
87
}
72
88
73
89
impl jacquard_common::IntoStatic for PutPreferencesV2<'_> {
+20
-1
crates/jacquard-api/src/app_bsky/notification/register_push.rs
+20
-1
crates/jacquard-api/src/app_bsky/notification/register_push.rs
···
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
8
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
9
+
#[derive(
10
+
serde::Serialize,
11
+
serde::Deserialize,
12
+
Debug,
13
+
Clone,
14
+
PartialEq,
15
+
Eq,
16
+
bon::Builder
17
+
)]
10
18
#[serde(rename_all = "camelCase")]
19
+
#[builder(start_fn = new)]
11
20
pub struct RegisterPush<'a> {
12
21
///Set to true when the actor is age restricted
13
22
#[serde(skip_serializing_if = "std::option::Option::is_none")]
14
23
pub age_restricted: std::option::Option<bool>,
15
24
#[serde(borrow)]
25
+
#[builder(into)]
16
26
pub app_id: jacquard_common::CowStr<'a>,
17
27
#[serde(borrow)]
28
+
#[builder(into)]
18
29
pub platform: jacquard_common::CowStr<'a>,
19
30
#[serde(borrow)]
20
31
pub service_did: jacquard_common::types::string::Did<'a>,
21
32
#[serde(borrow)]
33
+
#[builder(into)]
22
34
pub token: jacquard_common::CowStr<'a>,
35
+
#[serde(flatten)]
36
+
#[serde(borrow)]
37
+
#[builder(default)]
38
+
pub extra_data: ::std::collections::BTreeMap<
39
+
::jacquard_common::smol_str::SmolStr,
40
+
::jacquard_common::types::value::Data<'a>,
41
+
>,
23
42
}
24
43
25
44
impl jacquard_common::IntoStatic for RegisterPush<'_> {
+20
-1
crates/jacquard-api/src/app_bsky/notification/unregister_push.rs
+20
-1
crates/jacquard-api/src/app_bsky/notification/unregister_push.rs
···
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
8
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
9
+
#[derive(
10
+
serde::Serialize,
11
+
serde::Deserialize,
12
+
Debug,
13
+
Clone,
14
+
PartialEq,
15
+
Eq,
16
+
bon::Builder
17
+
)]
10
18
#[serde(rename_all = "camelCase")]
19
+
#[builder(start_fn = new)]
11
20
pub struct UnregisterPush<'a> {
12
21
#[serde(borrow)]
22
+
#[builder(into)]
13
23
pub app_id: jacquard_common::CowStr<'a>,
14
24
#[serde(borrow)]
25
+
#[builder(into)]
15
26
pub platform: jacquard_common::CowStr<'a>,
16
27
#[serde(borrow)]
17
28
pub service_did: jacquard_common::types::string::Did<'a>,
18
29
#[serde(borrow)]
30
+
#[builder(into)]
19
31
pub token: jacquard_common::CowStr<'a>,
32
+
#[serde(flatten)]
33
+
#[serde(borrow)]
34
+
#[builder(default)]
35
+
pub extra_data: ::std::collections::BTreeMap<
36
+
::jacquard_common::smol_str::SmolStr,
37
+
::jacquard_common::types::value::Data<'a>,
38
+
>,
20
39
}
21
40
22
41
impl jacquard_common::IntoStatic for UnregisterPush<'_> {
+17
-1
crates/jacquard-api/src/app_bsky/notification/update_seen.rs
+17
-1
crates/jacquard-api/src/app_bsky/notification/update_seen.rs
···
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
8
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
9
+
#[derive(
10
+
serde::Serialize,
11
+
serde::Deserialize,
12
+
Debug,
13
+
Clone,
14
+
PartialEq,
15
+
Eq,
16
+
bon::Builder
17
+
)]
10
18
#[serde(rename_all = "camelCase")]
19
+
#[builder(start_fn = new)]
11
20
pub struct UpdateSeen<'a> {
12
21
pub seen_at: jacquard_common::types::string::Datetime,
22
+
#[serde(flatten)]
23
+
#[serde(borrow)]
24
+
#[builder(default)]
25
+
pub extra_data: ::std::collections::BTreeMap<
26
+
::jacquard_common::smol_str::SmolStr,
27
+
::jacquard_common::types::value::Data<'a>,
28
+
>,
13
29
}
14
30
15
31
impl jacquard_common::IntoStatic for UpdateSeen<'_> {
+12
-4
crates/jacquard-api/src/app_bsky/unspecced/get_onboarding_suggested_starter_packs.rs
+12
-4
crates/jacquard-api/src/app_bsky/unspecced/get_onboarding_suggested_starter_packs.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetOnboardingSuggestedStarterPacks {
11
20
///(default: 10, min: 1, max: 25)
···
40
49
41
50
impl jacquard_common::types::xrpc::XrpcRequest for GetOnboardingSuggestedStarterPacks {
42
51
const NSID: &'static str = "app.bsky.unspecced.getOnboardingSuggestedStarterPacks";
43
-
const METHOD: jacquard_common::types::xrpc::XrpcMethod =
44
-
jacquard_common::types::xrpc::XrpcMethod::Query;
52
+
const METHOD: jacquard_common::types::xrpc::XrpcMethod = jacquard_common::types::xrpc::XrpcMethod::Query;
45
53
const OUTPUT_ENCODING: &'static str = "application/json";
46
54
type Output<'de> = GetOnboardingSuggestedStarterPacksOutput<'de>;
47
55
type Err<'de> = jacquard_common::types::xrpc::GenericError<'de>;
48
-
}
56
+
}
+10
-1
crates/jacquard-api/src/app_bsky/unspecced/get_onboarding_suggested_starter_packs_skeleton.rs
+10
-1
crates/jacquard-api/src/app_bsky/unspecced/get_onboarding_suggested_starter_packs_skeleton.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetOnboardingSuggestedStarterPacksSkeleton<'a> {
11
20
///(default: 10, min: 1, max: 25)
+12
-1
crates/jacquard-api/src/app_bsky/unspecced/get_popular_feed_generators.rs
+12
-1
crates/jacquard-api/src/app_bsky/unspecced/get_popular_feed_generators.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetPopularFeedGenerators<'a> {
11
20
#[serde(skip_serializing_if = "std::option::Option::is_none")]
12
21
#[serde(borrow)]
22
+
#[builder(into)]
13
23
pub cursor: std::option::Option<jacquard_common::CowStr<'a>>,
14
24
///(default: 50, min: 1, max: 100)
15
25
#[serde(skip_serializing_if = "std::option::Option::is_none")]
16
26
pub limit: std::option::Option<i64>,
17
27
#[serde(skip_serializing_if = "std::option::Option::is_none")]
18
28
#[serde(borrow)]
29
+
#[builder(into)]
19
30
pub query: std::option::Option<jacquard_common::CowStr<'a>>,
20
31
}
21
32
+10
-1
crates/jacquard-api/src/app_bsky/unspecced/get_post_thread_other_v2.rs
+10
-1
crates/jacquard-api/src/app_bsky/unspecced/get_post_thread_other_v2.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetPostThreadOtherV2<'a> {
11
20
#[serde(borrow)]
+11
-1
crates/jacquard-api/src/app_bsky/unspecced/get_post_thread_v2.rs
+11
-1
crates/jacquard-api/src/app_bsky/unspecced/get_post_thread_v2.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetPostThreadV2<'a> {
11
20
///(default: true)
···
25
34
///(default: "oldest")
26
35
#[serde(skip_serializing_if = "std::option::Option::is_none")]
27
36
#[serde(borrow)]
37
+
#[builder(into)]
28
38
pub sort: std::option::Option<jacquard_common::CowStr<'a>>,
29
39
}
30
40
+10
-1
crates/jacquard-api/src/app_bsky/unspecced/get_suggested_feeds.rs
+10
-1
crates/jacquard-api/src/app_bsky/unspecced/get_suggested_feeds.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetSuggestedFeeds {
11
20
///(default: 10, min: 1, max: 25)
+10
-1
crates/jacquard-api/src/app_bsky/unspecced/get_suggested_feeds_skeleton.rs
+10
-1
crates/jacquard-api/src/app_bsky/unspecced/get_suggested_feeds_skeleton.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetSuggestedFeedsSkeleton<'a> {
11
20
///(default: 10, min: 1, max: 25)
+10
-1
crates/jacquard-api/src/app_bsky/unspecced/get_suggested_starter_packs.rs
+10
-1
crates/jacquard-api/src/app_bsky/unspecced/get_suggested_starter_packs.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetSuggestedStarterPacks {
11
20
///(default: 10, min: 1, max: 25)
+10
-1
crates/jacquard-api/src/app_bsky/unspecced/get_suggested_starter_packs_skeleton.rs
+10
-1
crates/jacquard-api/src/app_bsky/unspecced/get_suggested_starter_packs_skeleton.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetSuggestedStarterPacksSkeleton<'a> {
11
20
///(default: 10, min: 1, max: 25)
+11
-1
crates/jacquard-api/src/app_bsky/unspecced/get_suggested_users.rs
+11
-1
crates/jacquard-api/src/app_bsky/unspecced/get_suggested_users.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetSuggestedUsers<'a> {
11
20
#[serde(skip_serializing_if = "std::option::Option::is_none")]
12
21
#[serde(borrow)]
22
+
#[builder(into)]
13
23
pub category: std::option::Option<jacquard_common::CowStr<'a>>,
14
24
///(default: 25, min: 1, max: 50)
15
25
#[serde(skip_serializing_if = "std::option::Option::is_none")]
+11
-1
crates/jacquard-api/src/app_bsky/unspecced/get_suggested_users_skeleton.rs
+11
-1
crates/jacquard-api/src/app_bsky/unspecced/get_suggested_users_skeleton.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetSuggestedUsersSkeleton<'a> {
11
20
#[serde(skip_serializing_if = "std::option::Option::is_none")]
12
21
#[serde(borrow)]
22
+
#[builder(into)]
13
23
pub category: std::option::Option<jacquard_common::CowStr<'a>>,
14
24
///(default: 25, min: 1, max: 50)
15
25
#[serde(skip_serializing_if = "std::option::Option::is_none")]
+11
-1
crates/jacquard-api/src/app_bsky/unspecced/get_suggestions_skeleton.rs
+11
-1
crates/jacquard-api/src/app_bsky/unspecced/get_suggestions_skeleton.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetSuggestionsSkeleton<'a> {
11
20
#[serde(skip_serializing_if = "std::option::Option::is_none")]
12
21
#[serde(borrow)]
22
+
#[builder(into)]
13
23
pub cursor: std::option::Option<jacquard_common::CowStr<'a>>,
14
24
///(default: 50, min: 1, max: 100)
15
25
#[serde(skip_serializing_if = "std::option::Option::is_none")]
+10
-1
crates/jacquard-api/src/app_bsky/unspecced/get_tagged_suggestions.rs
+10
-1
crates/jacquard-api/src/app_bsky/unspecced/get_tagged_suggestions.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetTaggedSuggestions {}
11
20
impl jacquard_common::IntoStatic for GetTaggedSuggestions {
+10
-1
crates/jacquard-api/src/app_bsky/unspecced/get_trending_topics.rs
+10
-1
crates/jacquard-api/src/app_bsky/unspecced/get_trending_topics.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetTrendingTopics<'a> {
11
20
///(default: 10, min: 1, max: 25)
+10
-1
crates/jacquard-api/src/app_bsky/unspecced/get_trends.rs
+10
-1
crates/jacquard-api/src/app_bsky/unspecced/get_trends.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetTrends {
11
20
///(default: 10, min: 1, max: 25)
+10
-1
crates/jacquard-api/src/app_bsky/unspecced/get_trends_skeleton.rs
+10
-1
crates/jacquard-api/src/app_bsky/unspecced/get_trends_skeleton.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetTrendsSkeleton<'a> {
11
20
///(default: 10, min: 1, max: 25)
+20
-1
crates/jacquard-api/src/app_bsky/unspecced/init_age_assurance.rs
+20
-1
crates/jacquard-api/src/app_bsky/unspecced/init_age_assurance.rs
···
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
8
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
9
+
#[derive(
10
+
serde::Serialize,
11
+
serde::Deserialize,
12
+
Debug,
13
+
Clone,
14
+
PartialEq,
15
+
Eq,
16
+
bon::Builder
17
+
)]
10
18
#[serde(rename_all = "camelCase")]
19
+
#[builder(start_fn = new)]
11
20
pub struct InitAgeAssurance<'a> {
12
21
///An ISO 3166-1 alpha-2 code of the user's location.
13
22
#[serde(borrow)]
23
+
#[builder(into)]
14
24
pub country_code: jacquard_common::CowStr<'a>,
15
25
///The user's email address to receive assurance instructions.
16
26
#[serde(borrow)]
27
+
#[builder(into)]
17
28
pub email: jacquard_common::CowStr<'a>,
18
29
///The user's preferred language for communication during the assurance process.
19
30
#[serde(borrow)]
31
+
#[builder(into)]
20
32
pub language: jacquard_common::CowStr<'a>,
33
+
#[serde(flatten)]
34
+
#[serde(borrow)]
35
+
#[builder(default)]
36
+
pub extra_data: ::std::collections::BTreeMap<
37
+
::jacquard_common::smol_str::SmolStr,
38
+
::jacquard_common::types::value::Data<'a>,
39
+
>,
21
40
}
22
41
23
42
impl jacquard_common::IntoStatic for InitAgeAssurance<'_> {
+12
-1
crates/jacquard-api/src/app_bsky/unspecced/search_actors_skeleton.rs
+12
-1
crates/jacquard-api/src/app_bsky/unspecced/search_actors_skeleton.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct SearchActorsSkeleton<'a> {
11
20
#[serde(skip_serializing_if = "std::option::Option::is_none")]
12
21
#[serde(borrow)]
22
+
#[builder(into)]
13
23
pub cursor: std::option::Option<jacquard_common::CowStr<'a>>,
14
24
///(default: 25, min: 1, max: 100)
15
25
#[serde(skip_serializing_if = "std::option::Option::is_none")]
16
26
pub limit: std::option::Option<i64>,
17
27
#[serde(borrow)]
28
+
#[builder(into)]
18
29
pub q: jacquard_common::CowStr<'a>,
19
30
#[serde(skip_serializing_if = "std::option::Option::is_none")]
20
31
pub typeahead: std::option::Option<bool>,
+16
-1
crates/jacquard-api/src/app_bsky/unspecced/search_posts_skeleton.rs
+16
-1
crates/jacquard-api/src/app_bsky/unspecced/search_posts_skeleton.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct SearchPostsSkeleton<'a> {
11
20
#[serde(skip_serializing_if = "std::option::Option::is_none")]
···
13
22
pub author: std::option::Option<jacquard_common::types::ident::AtIdentifier<'a>>,
14
23
#[serde(skip_serializing_if = "std::option::Option::is_none")]
15
24
#[serde(borrow)]
25
+
#[builder(into)]
16
26
pub cursor: std::option::Option<jacquard_common::CowStr<'a>>,
17
27
#[serde(skip_serializing_if = "std::option::Option::is_none")]
18
28
#[serde(borrow)]
29
+
#[builder(into)]
19
30
pub domain: std::option::Option<jacquard_common::CowStr<'a>>,
20
31
#[serde(skip_serializing_if = "std::option::Option::is_none")]
21
32
pub lang: std::option::Option<jacquard_common::types::string::Language>,
···
26
37
#[serde(borrow)]
27
38
pub mentions: std::option::Option<jacquard_common::types::ident::AtIdentifier<'a>>,
28
39
#[serde(borrow)]
40
+
#[builder(into)]
29
41
pub q: jacquard_common::CowStr<'a>,
30
42
#[serde(skip_serializing_if = "std::option::Option::is_none")]
31
43
#[serde(borrow)]
44
+
#[builder(into)]
32
45
pub since: std::option::Option<jacquard_common::CowStr<'a>>,
33
46
///(default: "latest")
34
47
#[serde(skip_serializing_if = "std::option::Option::is_none")]
35
48
#[serde(borrow)]
49
+
#[builder(into)]
36
50
pub sort: std::option::Option<jacquard_common::CowStr<'a>>,
37
51
#[serde(skip_serializing_if = "std::option::Option::is_none")]
38
52
#[serde(borrow)]
39
53
pub tag: std::option::Option<Vec<jacquard_common::CowStr<'a>>>,
40
54
#[serde(skip_serializing_if = "std::option::Option::is_none")]
41
55
#[serde(borrow)]
56
+
#[builder(into)]
42
57
pub until: std::option::Option<jacquard_common::CowStr<'a>>,
43
58
#[serde(skip_serializing_if = "std::option::Option::is_none")]
44
59
#[serde(borrow)]
+12
-1
crates/jacquard-api/src/app_bsky/unspecced/search_starter_packs_skeleton.rs
+12
-1
crates/jacquard-api/src/app_bsky/unspecced/search_starter_packs_skeleton.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct SearchStarterPacksSkeleton<'a> {
11
20
#[serde(skip_serializing_if = "std::option::Option::is_none")]
12
21
#[serde(borrow)]
22
+
#[builder(into)]
13
23
pub cursor: std::option::Option<jacquard_common::CowStr<'a>>,
14
24
///(default: 25, min: 1, max: 100)
15
25
#[serde(skip_serializing_if = "std::option::Option::is_none")]
16
26
pub limit: std::option::Option<i64>,
17
27
#[serde(borrow)]
28
+
#[builder(into)]
18
29
pub q: jacquard_common::CowStr<'a>,
19
30
#[serde(skip_serializing_if = "std::option::Option::is_none")]
20
31
#[serde(borrow)]
+11
-1
crates/jacquard-api/src/app_bsky/video/get_job_status.rs
+11
-1
crates/jacquard-api/src/app_bsky/video/get_job_status.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetJobStatus<'a> {
11
20
#[serde(borrow)]
21
+
#[builder(into)]
12
22
pub job_id: jacquard_common::CowStr<'a>,
13
23
}
14
24
+21
-9
crates/jacquard-api/src/app_bsky/video/upload_video.rs
+21
-9
crates/jacquard-api/src/app_bsky/video/upload_video.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
10
18
#[serde(rename_all = "camelCase")]
11
-
pub struct UploadVideo<'a> {}
12
-
impl jacquard_common::IntoStatic for UploadVideo<'_> {
13
-
type Output = UploadVideo<'static>;
19
+
pub struct UploadVideo {
20
+
pub body: bytes::Bytes,
21
+
}
22
+
23
+
impl jacquard_common::IntoStatic for UploadVideo {
24
+
type Output = UploadVideo;
14
25
fn into_static(self) -> Self::Output {
15
-
UploadVideo {
16
-
extra_data: self.extra_data.into_static(),
17
-
}
26
+
self
18
27
}
19
28
}
20
29
···
36
45
}
37
46
}
38
47
39
-
impl jacquard_common::types::xrpc::XrpcRequest for UploadVideo<'_> {
48
+
impl jacquard_common::types::xrpc::XrpcRequest for UploadVideo {
40
49
const NSID: &'static str = "app.bsky.video.uploadVideo";
41
50
const METHOD: jacquard_common::types::xrpc::XrpcMethod = jacquard_common::types::xrpc::XrpcMethod::Procedure(
42
51
"video/mp4",
···
44
53
const OUTPUT_ENCODING: &'static str = "application/json";
45
54
type Output<'de> = UploadVideoOutput<'de>;
46
55
type Err<'de> = jacquard_common::types::xrpc::GenericError<'de>;
56
+
fn encode_body(&self) -> Result<Vec<u8>, jacquard_common::types::xrpc::EncodeError> {
57
+
Ok(self.body.to_vec())
58
+
}
47
59
}
+18
-1
crates/jacquard-api/src/chat_bsky/convo/accept_convo.rs
+18
-1
crates/jacquard-api/src/chat_bsky/convo/accept_convo.rs
···
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
8
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
9
+
#[derive(
10
+
serde::Serialize,
11
+
serde::Deserialize,
12
+
Debug,
13
+
Clone,
14
+
PartialEq,
15
+
Eq,
16
+
bon::Builder
17
+
)]
10
18
#[serde(rename_all = "camelCase")]
19
+
#[builder(start_fn = new)]
11
20
pub struct AcceptConvo<'a> {
12
21
#[serde(borrow)]
22
+
#[builder(into)]
13
23
pub convo_id: jacquard_common::CowStr<'a>,
24
+
#[serde(flatten)]
25
+
#[serde(borrow)]
26
+
#[builder(default)]
27
+
pub extra_data: ::std::collections::BTreeMap<
28
+
::jacquard_common::smol_str::SmolStr,
29
+
::jacquard_common::types::value::Data<'a>,
30
+
>,
14
31
}
15
32
16
33
impl jacquard_common::IntoStatic for AcceptConvo<'_> {
+20
-1
crates/jacquard-api/src/chat_bsky/convo/add_reaction.rs
+20
-1
crates/jacquard-api/src/chat_bsky/convo/add_reaction.rs
···
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
8
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
9
+
#[derive(
10
+
serde::Serialize,
11
+
serde::Deserialize,
12
+
Debug,
13
+
Clone,
14
+
PartialEq,
15
+
Eq,
16
+
bon::Builder
17
+
)]
10
18
#[serde(rename_all = "camelCase")]
19
+
#[builder(start_fn = new)]
11
20
pub struct AddReaction<'a> {
12
21
#[serde(borrow)]
22
+
#[builder(into)]
13
23
pub convo_id: jacquard_common::CowStr<'a>,
14
24
#[serde(borrow)]
25
+
#[builder(into)]
15
26
pub message_id: jacquard_common::CowStr<'a>,
16
27
#[serde(borrow)]
28
+
#[builder(into)]
17
29
pub value: jacquard_common::CowStr<'a>,
30
+
#[serde(flatten)]
31
+
#[serde(borrow)]
32
+
#[builder(default)]
33
+
pub extra_data: ::std::collections::BTreeMap<
34
+
::jacquard_common::smol_str::SmolStr,
35
+
::jacquard_common::types::value::Data<'a>,
36
+
>,
18
37
}
19
38
20
39
impl jacquard_common::IntoStatic for AddReaction<'_> {
+19
-1
crates/jacquard-api/src/chat_bsky/convo/delete_message_for_self.rs
+19
-1
crates/jacquard-api/src/chat_bsky/convo/delete_message_for_self.rs
···
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
8
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
9
+
#[derive(
10
+
serde::Serialize,
11
+
serde::Deserialize,
12
+
Debug,
13
+
Clone,
14
+
PartialEq,
15
+
Eq,
16
+
bon::Builder
17
+
)]
10
18
#[serde(rename_all = "camelCase")]
19
+
#[builder(start_fn = new)]
11
20
pub struct DeleteMessageForSelf<'a> {
12
21
#[serde(borrow)]
22
+
#[builder(into)]
13
23
pub convo_id: jacquard_common::CowStr<'a>,
14
24
#[serde(borrow)]
25
+
#[builder(into)]
15
26
pub message_id: jacquard_common::CowStr<'a>,
27
+
#[serde(flatten)]
28
+
#[serde(borrow)]
29
+
#[builder(default)]
30
+
pub extra_data: ::std::collections::BTreeMap<
31
+
::jacquard_common::smol_str::SmolStr,
32
+
::jacquard_common::types::value::Data<'a>,
33
+
>,
16
34
}
17
35
18
36
impl jacquard_common::IntoStatic for DeleteMessageForSelf<'_> {
+11
-1
crates/jacquard-api/src/chat_bsky/convo/get_convo.rs
+11
-1
crates/jacquard-api/src/chat_bsky/convo/get_convo.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetConvo<'a> {
11
20
#[serde(borrow)]
21
+
#[builder(into)]
12
22
pub convo_id: jacquard_common::CowStr<'a>,
13
23
}
14
24
+10
-1
crates/jacquard-api/src/chat_bsky/convo/get_convo_availability.rs
+10
-1
crates/jacquard-api/src/chat_bsky/convo/get_convo_availability.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetConvoAvailability<'a> {
11
20
#[serde(borrow)]
+10
-1
crates/jacquard-api/src/chat_bsky/convo/get_convo_for_members.rs
+10
-1
crates/jacquard-api/src/chat_bsky/convo/get_convo_for_members.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetConvoForMembers<'a> {
11
20
#[serde(borrow)]
+11
-1
crates/jacquard-api/src/chat_bsky/convo/get_log.rs
+11
-1
crates/jacquard-api/src/chat_bsky/convo/get_log.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetLog<'a> {
11
20
#[serde(skip_serializing_if = "std::option::Option::is_none")]
12
21
#[serde(borrow)]
22
+
#[builder(into)]
13
23
pub cursor: std::option::Option<jacquard_common::CowStr<'a>>,
14
24
}
15
25
+12
-1
crates/jacquard-api/src/chat_bsky/convo/get_messages.rs
+12
-1
crates/jacquard-api/src/chat_bsky/convo/get_messages.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetMessages<'a> {
11
20
#[serde(borrow)]
21
+
#[builder(into)]
12
22
pub convo_id: jacquard_common::CowStr<'a>,
13
23
#[serde(skip_serializing_if = "std::option::Option::is_none")]
14
24
#[serde(borrow)]
25
+
#[builder(into)]
15
26
pub cursor: std::option::Option<jacquard_common::CowStr<'a>>,
16
27
///(default: 50, min: 1, max: 100)
17
28
#[serde(skip_serializing_if = "std::option::Option::is_none")]
+18
-1
crates/jacquard-api/src/chat_bsky/convo/leave_convo.rs
+18
-1
crates/jacquard-api/src/chat_bsky/convo/leave_convo.rs
···
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
8
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
9
+
#[derive(
10
+
serde::Serialize,
11
+
serde::Deserialize,
12
+
Debug,
13
+
Clone,
14
+
PartialEq,
15
+
Eq,
16
+
bon::Builder
17
+
)]
10
18
#[serde(rename_all = "camelCase")]
19
+
#[builder(start_fn = new)]
11
20
pub struct LeaveConvo<'a> {
12
21
#[serde(borrow)]
22
+
#[builder(into)]
13
23
pub convo_id: jacquard_common::CowStr<'a>,
24
+
#[serde(flatten)]
25
+
#[serde(borrow)]
26
+
#[builder(default)]
27
+
pub extra_data: ::std::collections::BTreeMap<
28
+
::jacquard_common::smol_str::SmolStr,
29
+
::jacquard_common::types::value::Data<'a>,
30
+
>,
14
31
}
15
32
16
33
impl jacquard_common::IntoStatic for LeaveConvo<'_> {
+13
-1
crates/jacquard-api/src/chat_bsky/convo/list_convos.rs
+13
-1
crates/jacquard-api/src/chat_bsky/convo/list_convos.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct ListConvos<'a> {
11
20
#[serde(skip_serializing_if = "std::option::Option::is_none")]
12
21
#[serde(borrow)]
22
+
#[builder(into)]
13
23
pub cursor: std::option::Option<jacquard_common::CowStr<'a>>,
14
24
///(default: 50, min: 1, max: 100)
15
25
#[serde(skip_serializing_if = "std::option::Option::is_none")]
16
26
pub limit: std::option::Option<i64>,
17
27
#[serde(skip_serializing_if = "std::option::Option::is_none")]
18
28
#[serde(borrow)]
29
+
#[builder(into)]
19
30
pub read_state: std::option::Option<jacquard_common::CowStr<'a>>,
20
31
#[serde(skip_serializing_if = "std::option::Option::is_none")]
21
32
#[serde(borrow)]
33
+
#[builder(into)]
22
34
pub status: std::option::Option<jacquard_common::CowStr<'a>>,
23
35
}
24
36
+18
-1
crates/jacquard-api/src/chat_bsky/convo/mute_convo.rs
+18
-1
crates/jacquard-api/src/chat_bsky/convo/mute_convo.rs
···
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
8
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
9
+
#[derive(
10
+
serde::Serialize,
11
+
serde::Deserialize,
12
+
Debug,
13
+
Clone,
14
+
PartialEq,
15
+
Eq,
16
+
bon::Builder
17
+
)]
10
18
#[serde(rename_all = "camelCase")]
19
+
#[builder(start_fn = new)]
11
20
pub struct MuteConvo<'a> {
12
21
#[serde(borrow)]
22
+
#[builder(into)]
13
23
pub convo_id: jacquard_common::CowStr<'a>,
24
+
#[serde(flatten)]
25
+
#[serde(borrow)]
26
+
#[builder(default)]
27
+
pub extra_data: ::std::collections::BTreeMap<
28
+
::jacquard_common::smol_str::SmolStr,
29
+
::jacquard_common::types::value::Data<'a>,
30
+
>,
14
31
}
15
32
16
33
impl jacquard_common::IntoStatic for MuteConvo<'_> {
+20
-1
crates/jacquard-api/src/chat_bsky/convo/remove_reaction.rs
+20
-1
crates/jacquard-api/src/chat_bsky/convo/remove_reaction.rs
···
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
8
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
9
+
#[derive(
10
+
serde::Serialize,
11
+
serde::Deserialize,
12
+
Debug,
13
+
Clone,
14
+
PartialEq,
15
+
Eq,
16
+
bon::Builder
17
+
)]
10
18
#[serde(rename_all = "camelCase")]
19
+
#[builder(start_fn = new)]
11
20
pub struct RemoveReaction<'a> {
12
21
#[serde(borrow)]
22
+
#[builder(into)]
13
23
pub convo_id: jacquard_common::CowStr<'a>,
14
24
#[serde(borrow)]
25
+
#[builder(into)]
15
26
pub message_id: jacquard_common::CowStr<'a>,
16
27
#[serde(borrow)]
28
+
#[builder(into)]
17
29
pub value: jacquard_common::CowStr<'a>,
30
+
#[serde(flatten)]
31
+
#[serde(borrow)]
32
+
#[builder(default)]
33
+
pub extra_data: ::std::collections::BTreeMap<
34
+
::jacquard_common::smol_str::SmolStr,
35
+
::jacquard_common::types::value::Data<'a>,
36
+
>,
18
37
}
19
38
20
39
impl jacquard_common::IntoStatic for RemoveReaction<'_> {
+18
-1
crates/jacquard-api/src/chat_bsky/convo/send_message.rs
+18
-1
crates/jacquard-api/src/chat_bsky/convo/send_message.rs
···
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
8
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
9
+
#[derive(
10
+
serde::Serialize,
11
+
serde::Deserialize,
12
+
Debug,
13
+
Clone,
14
+
PartialEq,
15
+
Eq,
16
+
bon::Builder
17
+
)]
10
18
#[serde(rename_all = "camelCase")]
19
+
#[builder(start_fn = new)]
11
20
pub struct SendMessage<'a> {
12
21
#[serde(borrow)]
22
+
#[builder(into)]
13
23
pub convo_id: jacquard_common::CowStr<'a>,
14
24
#[serde(borrow)]
15
25
pub message: crate::chat_bsky::convo::MessageInput<'a>,
26
+
#[serde(flatten)]
27
+
#[serde(borrow)]
28
+
#[builder(default)]
29
+
pub extra_data: ::std::collections::BTreeMap<
30
+
::jacquard_common::smol_str::SmolStr,
31
+
::jacquard_common::types::value::Data<'a>,
32
+
>,
16
33
}
17
34
18
35
impl jacquard_common::IntoStatic for SendMessage<'_> {
+17
-1
crates/jacquard-api/src/chat_bsky/convo/send_message_batch.rs
+17
-1
crates/jacquard-api/src/chat_bsky/convo/send_message_batch.rs
···
27
27
}
28
28
29
29
#[jacquard_derive::lexicon]
30
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
30
+
#[derive(
31
+
serde::Serialize,
32
+
serde::Deserialize,
33
+
Debug,
34
+
Clone,
35
+
PartialEq,
36
+
Eq,
37
+
bon::Builder
38
+
)]
31
39
#[serde(rename_all = "camelCase")]
40
+
#[builder(start_fn = new)]
32
41
pub struct SendMessageBatch<'a> {
33
42
#[serde(borrow)]
34
43
pub items: Vec<jacquard_common::types::value::Data<'a>>,
44
+
#[serde(flatten)]
45
+
#[serde(borrow)]
46
+
#[builder(default)]
47
+
pub extra_data: ::std::collections::BTreeMap<
48
+
::jacquard_common::smol_str::SmolStr,
49
+
::jacquard_common::types::value::Data<'a>,
50
+
>,
35
51
}
36
52
37
53
impl jacquard_common::IntoStatic for SendMessageBatch<'_> {
+18
-1
crates/jacquard-api/src/chat_bsky/convo/unmute_convo.rs
+18
-1
crates/jacquard-api/src/chat_bsky/convo/unmute_convo.rs
···
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
8
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
9
+
#[derive(
10
+
serde::Serialize,
11
+
serde::Deserialize,
12
+
Debug,
13
+
Clone,
14
+
PartialEq,
15
+
Eq,
16
+
bon::Builder
17
+
)]
10
18
#[serde(rename_all = "camelCase")]
19
+
#[builder(start_fn = new)]
11
20
pub struct UnmuteConvo<'a> {
12
21
#[serde(borrow)]
22
+
#[builder(into)]
13
23
pub convo_id: jacquard_common::CowStr<'a>,
24
+
#[serde(flatten)]
25
+
#[serde(borrow)]
26
+
#[builder(default)]
27
+
pub extra_data: ::std::collections::BTreeMap<
28
+
::jacquard_common::smol_str::SmolStr,
29
+
::jacquard_common::types::value::Data<'a>,
30
+
>,
14
31
}
15
32
16
33
impl jacquard_common::IntoStatic for UnmuteConvo<'_> {
+18
-1
crates/jacquard-api/src/chat_bsky/convo/update_all_read.rs
+18
-1
crates/jacquard-api/src/chat_bsky/convo/update_all_read.rs
···
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
8
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
9
+
#[derive(
10
+
serde::Serialize,
11
+
serde::Deserialize,
12
+
Debug,
13
+
Clone,
14
+
PartialEq,
15
+
Eq,
16
+
bon::Builder
17
+
)]
10
18
#[serde(rename_all = "camelCase")]
19
+
#[builder(start_fn = new)]
11
20
pub struct UpdateAllRead<'a> {
12
21
#[serde(skip_serializing_if = "std::option::Option::is_none")]
13
22
#[serde(borrow)]
23
+
#[builder(into)]
14
24
pub status: std::option::Option<jacquard_common::CowStr<'a>>,
25
+
#[serde(flatten)]
26
+
#[serde(borrow)]
27
+
#[builder(default)]
28
+
pub extra_data: ::std::collections::BTreeMap<
29
+
::jacquard_common::smol_str::SmolStr,
30
+
::jacquard_common::types::value::Data<'a>,
31
+
>,
15
32
}
16
33
17
34
impl jacquard_common::IntoStatic for UpdateAllRead<'_> {
+19
-1
crates/jacquard-api/src/chat_bsky/convo/update_read.rs
+19
-1
crates/jacquard-api/src/chat_bsky/convo/update_read.rs
···
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
8
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
9
+
#[derive(
10
+
serde::Serialize,
11
+
serde::Deserialize,
12
+
Debug,
13
+
Clone,
14
+
PartialEq,
15
+
Eq,
16
+
bon::Builder
17
+
)]
10
18
#[serde(rename_all = "camelCase")]
19
+
#[builder(start_fn = new)]
11
20
pub struct UpdateRead<'a> {
12
21
#[serde(borrow)]
22
+
#[builder(into)]
13
23
pub convo_id: jacquard_common::CowStr<'a>,
14
24
#[serde(skip_serializing_if = "std::option::Option::is_none")]
15
25
#[serde(borrow)]
26
+
#[builder(into)]
16
27
pub message_id: std::option::Option<jacquard_common::CowStr<'a>>,
28
+
#[serde(flatten)]
29
+
#[serde(borrow)]
30
+
#[builder(default)]
31
+
pub extra_data: ::std::collections::BTreeMap<
32
+
::jacquard_common::smol_str::SmolStr,
33
+
::jacquard_common::types::value::Data<'a>,
34
+
>,
17
35
}
18
36
19
37
impl jacquard_common::IntoStatic for UpdateRead<'_> {
+10
-1
crates/jacquard-api/src/chat_bsky/moderation/get_actor_metadata.rs
+10
-1
crates/jacquard-api/src/chat_bsky/moderation/get_actor_metadata.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetActorMetadata<'a> {
11
20
#[serde(borrow)]
+12
-1
crates/jacquard-api/src/chat_bsky/moderation/get_message_context.rs
+12
-1
crates/jacquard-api/src/chat_bsky/moderation/get_message_context.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetMessageContext<'a> {
11
20
///(default: 5)
···
16
25
pub before: std::option::Option<i64>,
17
26
#[serde(skip_serializing_if = "std::option::Option::is_none")]
18
27
#[serde(borrow)]
28
+
#[builder(into)]
19
29
pub convo_id: std::option::Option<jacquard_common::CowStr<'a>>,
20
30
#[serde(borrow)]
31
+
#[builder(into)]
21
32
pub message_id: jacquard_common::CowStr<'a>,
22
33
}
23
34
+18
-1
crates/jacquard-api/src/chat_bsky/moderation/update_actor_access.rs
+18
-1
crates/jacquard-api/src/chat_bsky/moderation/update_actor_access.rs
···
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
8
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
9
+
#[derive(
10
+
serde::Serialize,
11
+
serde::Deserialize,
12
+
Debug,
13
+
Clone,
14
+
PartialEq,
15
+
Eq,
16
+
bon::Builder
17
+
)]
10
18
#[serde(rename_all = "camelCase")]
19
+
#[builder(start_fn = new)]
11
20
pub struct UpdateActorAccess<'a> {
12
21
#[serde(borrow)]
13
22
pub actor: jacquard_common::types::string::Did<'a>,
14
23
pub allow_access: bool,
15
24
#[serde(skip_serializing_if = "std::option::Option::is_none")]
16
25
#[serde(borrow)]
26
+
#[builder(into)]
17
27
pub r#ref: std::option::Option<jacquard_common::CowStr<'a>>,
28
+
#[serde(flatten)]
29
+
#[serde(borrow)]
30
+
#[builder(default)]
31
+
pub extra_data: ::std::collections::BTreeMap<
32
+
::jacquard_common::smol_str::SmolStr,
33
+
::jacquard_common::types::value::Data<'a>,
34
+
>,
18
35
}
19
36
20
37
impl jacquard_common::IntoStatic for UpdateActorAccess<'_> {
+17
-1
crates/jacquard-api/src/com_atproto/admin/delete_account.rs
+17
-1
crates/jacquard-api/src/com_atproto/admin/delete_account.rs
···
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
8
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
9
+
#[derive(
10
+
serde::Serialize,
11
+
serde::Deserialize,
12
+
Debug,
13
+
Clone,
14
+
PartialEq,
15
+
Eq,
16
+
bon::Builder
17
+
)]
10
18
#[serde(rename_all = "camelCase")]
19
+
#[builder(start_fn = new)]
11
20
pub struct DeleteAccount<'a> {
12
21
#[serde(borrow)]
13
22
pub did: jacquard_common::types::string::Did<'a>,
23
+
#[serde(flatten)]
24
+
#[serde(borrow)]
25
+
#[builder(default)]
26
+
pub extra_data: ::std::collections::BTreeMap<
27
+
::jacquard_common::smol_str::SmolStr,
28
+
::jacquard_common::types::value::Data<'a>,
29
+
>,
14
30
}
15
31
16
32
impl jacquard_common::IntoStatic for DeleteAccount<'_> {
+18
-1
crates/jacquard-api/src/com_atproto/admin/disable_account_invites.rs
+18
-1
crates/jacquard-api/src/com_atproto/admin/disable_account_invites.rs
···
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
8
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
9
+
#[derive(
10
+
serde::Serialize,
11
+
serde::Deserialize,
12
+
Debug,
13
+
Clone,
14
+
PartialEq,
15
+
Eq,
16
+
bon::Builder
17
+
)]
10
18
#[serde(rename_all = "camelCase")]
19
+
#[builder(start_fn = new)]
11
20
pub struct DisableAccountInvites<'a> {
12
21
#[serde(borrow)]
13
22
pub account: jacquard_common::types::string::Did<'a>,
14
23
///Optional reason for disabled invites.
15
24
#[serde(skip_serializing_if = "std::option::Option::is_none")]
16
25
#[serde(borrow)]
26
+
#[builder(into)]
17
27
pub note: std::option::Option<jacquard_common::CowStr<'a>>,
28
+
#[serde(flatten)]
29
+
#[serde(borrow)]
30
+
#[builder(default)]
31
+
pub extra_data: ::std::collections::BTreeMap<
32
+
::jacquard_common::smol_str::SmolStr,
33
+
::jacquard_common::types::value::Data<'a>,
34
+
>,
18
35
}
19
36
20
37
impl jacquard_common::IntoStatic for DisableAccountInvites<'_> {
+17
-1
crates/jacquard-api/src/com_atproto/admin/disable_invite_codes.rs
+17
-1
crates/jacquard-api/src/com_atproto/admin/disable_invite_codes.rs
···
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
8
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
9
+
#[derive(
10
+
serde::Serialize,
11
+
serde::Deserialize,
12
+
Debug,
13
+
Clone,
14
+
PartialEq,
15
+
Eq,
16
+
bon::Builder
17
+
)]
10
18
#[serde(rename_all = "camelCase")]
19
+
#[builder(start_fn = new)]
11
20
pub struct DisableInviteCodes<'a> {
12
21
#[serde(skip_serializing_if = "std::option::Option::is_none")]
13
22
#[serde(borrow)]
···
15
24
#[serde(skip_serializing_if = "std::option::Option::is_none")]
16
25
#[serde(borrow)]
17
26
pub codes: std::option::Option<Vec<jacquard_common::CowStr<'a>>>,
27
+
#[serde(flatten)]
28
+
#[serde(borrow)]
29
+
#[builder(default)]
30
+
pub extra_data: ::std::collections::BTreeMap<
31
+
::jacquard_common::smol_str::SmolStr,
32
+
::jacquard_common::types::value::Data<'a>,
33
+
>,
18
34
}
19
35
20
36
impl jacquard_common::IntoStatic for DisableInviteCodes<'_> {
+18
-1
crates/jacquard-api/src/com_atproto/admin/enable_account_invites.rs
+18
-1
crates/jacquard-api/src/com_atproto/admin/enable_account_invites.rs
···
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
8
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
9
+
#[derive(
10
+
serde::Serialize,
11
+
serde::Deserialize,
12
+
Debug,
13
+
Clone,
14
+
PartialEq,
15
+
Eq,
16
+
bon::Builder
17
+
)]
10
18
#[serde(rename_all = "camelCase")]
19
+
#[builder(start_fn = new)]
11
20
pub struct EnableAccountInvites<'a> {
12
21
#[serde(borrow)]
13
22
pub account: jacquard_common::types::string::Did<'a>,
14
23
///Optional reason for enabled invites.
15
24
#[serde(skip_serializing_if = "std::option::Option::is_none")]
16
25
#[serde(borrow)]
26
+
#[builder(into)]
17
27
pub note: std::option::Option<jacquard_common::CowStr<'a>>,
28
+
#[serde(flatten)]
29
+
#[serde(borrow)]
30
+
#[builder(default)]
31
+
pub extra_data: ::std::collections::BTreeMap<
32
+
::jacquard_common::smol_str::SmolStr,
33
+
::jacquard_common::types::value::Data<'a>,
34
+
>,
18
35
}
19
36
20
37
impl jacquard_common::IntoStatic for EnableAccountInvites<'_> {
+10
-1
crates/jacquard-api/src/com_atproto/admin/get_account_info.rs
+10
-1
crates/jacquard-api/src/com_atproto/admin/get_account_info.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetAccountInfo<'a> {
11
20
#[serde(borrow)]
+10
-1
crates/jacquard-api/src/com_atproto/admin/get_account_infos.rs
+10
-1
crates/jacquard-api/src/com_atproto/admin/get_account_infos.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetAccountInfos<'a> {
11
20
#[serde(borrow)]
+12
-1
crates/jacquard-api/src/com_atproto/admin/get_invite_codes.rs
+12
-1
crates/jacquard-api/src/com_atproto/admin/get_invite_codes.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetInviteCodes<'a> {
11
20
#[serde(skip_serializing_if = "std::option::Option::is_none")]
12
21
#[serde(borrow)]
22
+
#[builder(into)]
13
23
pub cursor: std::option::Option<jacquard_common::CowStr<'a>>,
14
24
///(default: 100, min: 1, max: 500)
15
25
#[serde(skip_serializing_if = "std::option::Option::is_none")]
···
17
27
///(default: "recent")
18
28
#[serde(skip_serializing_if = "std::option::Option::is_none")]
19
29
#[serde(borrow)]
30
+
#[builder(into)]
20
31
pub sort: std::option::Option<jacquard_common::CowStr<'a>>,
21
32
}
22
33
+10
-1
crates/jacquard-api/src/com_atproto/admin/get_subject_status.rs
+10
-1
crates/jacquard-api/src/com_atproto/admin/get_subject_status.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetSubjectStatus<'a> {
11
20
#[serde(skip_serializing_if = "std::option::Option::is_none")]
+12
-1
crates/jacquard-api/src/com_atproto/admin/search_accounts.rs
+12
-1
crates/jacquard-api/src/com_atproto/admin/search_accounts.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct SearchAccounts<'a> {
11
20
#[serde(skip_serializing_if = "std::option::Option::is_none")]
12
21
#[serde(borrow)]
22
+
#[builder(into)]
13
23
pub cursor: std::option::Option<jacquard_common::CowStr<'a>>,
14
24
#[serde(skip_serializing_if = "std::option::Option::is_none")]
15
25
#[serde(borrow)]
26
+
#[builder(into)]
16
27
pub email: std::option::Option<jacquard_common::CowStr<'a>>,
17
28
///(default: 50, min: 1, max: 100)
18
29
#[serde(skip_serializing_if = "std::option::Option::is_none")]
+20
-1
crates/jacquard-api/src/com_atproto/admin/send_email.rs
+20
-1
crates/jacquard-api/src/com_atproto/admin/send_email.rs
···
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
8
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
9
+
#[derive(
10
+
serde::Serialize,
11
+
serde::Deserialize,
12
+
Debug,
13
+
Clone,
14
+
PartialEq,
15
+
Eq,
16
+
bon::Builder
17
+
)]
10
18
#[serde(rename_all = "camelCase")]
19
+
#[builder(start_fn = new)]
11
20
pub struct SendEmail<'a> {
12
21
///Additional comment by the sender that won't be used in the email itself but helpful to provide more context for moderators/reviewers
13
22
#[serde(skip_serializing_if = "std::option::Option::is_none")]
14
23
#[serde(borrow)]
24
+
#[builder(into)]
15
25
pub comment: std::option::Option<jacquard_common::CowStr<'a>>,
16
26
#[serde(borrow)]
27
+
#[builder(into)]
17
28
pub content: jacquard_common::CowStr<'a>,
18
29
#[serde(borrow)]
19
30
pub recipient_did: jacquard_common::types::string::Did<'a>,
···
21
32
pub sender_did: jacquard_common::types::string::Did<'a>,
22
33
#[serde(skip_serializing_if = "std::option::Option::is_none")]
23
34
#[serde(borrow)]
35
+
#[builder(into)]
24
36
pub subject: std::option::Option<jacquard_common::CowStr<'a>>,
37
+
#[serde(flatten)]
38
+
#[serde(borrow)]
39
+
#[builder(default)]
40
+
pub extra_data: ::std::collections::BTreeMap<
41
+
::jacquard_common::smol_str::SmolStr,
42
+
::jacquard_common::types::value::Data<'a>,
43
+
>,
25
44
}
26
45
27
46
impl jacquard_common::IntoStatic for SendEmail<'_> {
+18
-1
crates/jacquard-api/src/com_atproto/admin/update_account_email.rs
+18
-1
crates/jacquard-api/src/com_atproto/admin/update_account_email.rs
···
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
8
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
9
+
#[derive(
10
+
serde::Serialize,
11
+
serde::Deserialize,
12
+
Debug,
13
+
Clone,
14
+
PartialEq,
15
+
Eq,
16
+
bon::Builder
17
+
)]
10
18
#[serde(rename_all = "camelCase")]
19
+
#[builder(start_fn = new)]
11
20
pub struct UpdateAccountEmail<'a> {
12
21
///The handle or DID of the repo.
13
22
#[serde(borrow)]
14
23
pub account: jacquard_common::types::ident::AtIdentifier<'a>,
15
24
#[serde(borrow)]
25
+
#[builder(into)]
16
26
pub email: jacquard_common::CowStr<'a>,
27
+
#[serde(flatten)]
28
+
#[serde(borrow)]
29
+
#[builder(default)]
30
+
pub extra_data: ::std::collections::BTreeMap<
31
+
::jacquard_common::smol_str::SmolStr,
32
+
::jacquard_common::types::value::Data<'a>,
33
+
>,
17
34
}
18
35
19
36
impl jacquard_common::IntoStatic for UpdateAccountEmail<'_> {
+17
-1
crates/jacquard-api/src/com_atproto/admin/update_account_handle.rs
+17
-1
crates/jacquard-api/src/com_atproto/admin/update_account_handle.rs
···
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
8
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
9
+
#[derive(
10
+
serde::Serialize,
11
+
serde::Deserialize,
12
+
Debug,
13
+
Clone,
14
+
PartialEq,
15
+
Eq,
16
+
bon::Builder
17
+
)]
10
18
#[serde(rename_all = "camelCase")]
19
+
#[builder(start_fn = new)]
11
20
pub struct UpdateAccountHandle<'a> {
12
21
#[serde(borrow)]
13
22
pub did: jacquard_common::types::string::Did<'a>,
14
23
#[serde(borrow)]
15
24
pub handle: jacquard_common::types::string::Handle<'a>,
25
+
#[serde(flatten)]
26
+
#[serde(borrow)]
27
+
#[builder(default)]
28
+
pub extra_data: ::std::collections::BTreeMap<
29
+
::jacquard_common::smol_str::SmolStr,
30
+
::jacquard_common::types::value::Data<'a>,
31
+
>,
16
32
}
17
33
18
34
impl jacquard_common::IntoStatic for UpdateAccountHandle<'_> {
+18
-1
crates/jacquard-api/src/com_atproto/admin/update_account_password.rs
+18
-1
crates/jacquard-api/src/com_atproto/admin/update_account_password.rs
···
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
8
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
9
+
#[derive(
10
+
serde::Serialize,
11
+
serde::Deserialize,
12
+
Debug,
13
+
Clone,
14
+
PartialEq,
15
+
Eq,
16
+
bon::Builder
17
+
)]
10
18
#[serde(rename_all = "camelCase")]
19
+
#[builder(start_fn = new)]
11
20
pub struct UpdateAccountPassword<'a> {
12
21
#[serde(borrow)]
13
22
pub did: jacquard_common::types::string::Did<'a>,
14
23
#[serde(borrow)]
24
+
#[builder(into)]
15
25
pub password: jacquard_common::CowStr<'a>,
26
+
#[serde(flatten)]
27
+
#[serde(borrow)]
28
+
#[builder(default)]
29
+
pub extra_data: ::std::collections::BTreeMap<
30
+
::jacquard_common::smol_str::SmolStr,
31
+
::jacquard_common::types::value::Data<'a>,
32
+
>,
16
33
}
17
34
18
35
impl jacquard_common::IntoStatic for UpdateAccountPassword<'_> {
+17
-1
crates/jacquard-api/src/com_atproto/admin/update_account_signing_key.rs
+17
-1
crates/jacquard-api/src/com_atproto/admin/update_account_signing_key.rs
···
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
8
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
9
+
#[derive(
10
+
serde::Serialize,
11
+
serde::Deserialize,
12
+
Debug,
13
+
Clone,
14
+
PartialEq,
15
+
Eq,
16
+
bon::Builder
17
+
)]
10
18
#[serde(rename_all = "camelCase")]
19
+
#[builder(start_fn = new)]
11
20
pub struct UpdateAccountSigningKey<'a> {
12
21
#[serde(borrow)]
13
22
pub did: jacquard_common::types::string::Did<'a>,
14
23
///Did-key formatted public key
15
24
#[serde(borrow)]
16
25
pub signing_key: jacquard_common::types::string::Did<'a>,
26
+
#[serde(flatten)]
27
+
#[serde(borrow)]
28
+
#[builder(default)]
29
+
pub extra_data: ::std::collections::BTreeMap<
30
+
::jacquard_common::smol_str::SmolStr,
31
+
::jacquard_common::types::value::Data<'a>,
32
+
>,
17
33
}
18
34
19
35
impl jacquard_common::IntoStatic for UpdateAccountSigningKey<'_> {
+17
-1
crates/jacquard-api/src/com_atproto/admin/update_subject_status.rs
+17
-1
crates/jacquard-api/src/com_atproto/admin/update_subject_status.rs
···
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
8
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
9
+
#[derive(
10
+
serde::Serialize,
11
+
serde::Deserialize,
12
+
Debug,
13
+
Clone,
14
+
PartialEq,
15
+
Eq,
16
+
bon::Builder
17
+
)]
10
18
#[serde(rename_all = "camelCase")]
19
+
#[builder(start_fn = new)]
11
20
pub struct UpdateSubjectStatus<'a> {
12
21
#[serde(skip_serializing_if = "std::option::Option::is_none")]
13
22
#[serde(borrow)]
···
17
26
#[serde(skip_serializing_if = "std::option::Option::is_none")]
18
27
#[serde(borrow)]
19
28
pub takedown: std::option::Option<crate::com_atproto::admin::StatusAttr<'a>>,
29
+
#[serde(flatten)]
30
+
#[serde(borrow)]
31
+
#[builder(default)]
32
+
pub extra_data: ::std::collections::BTreeMap<
33
+
::jacquard_common::smol_str::SmolStr,
34
+
::jacquard_common::types::value::Data<'a>,
35
+
>,
20
36
}
21
37
22
38
#[jacquard_derive::open_union]
+17
-1
crates/jacquard-api/src/com_atproto/identity/refresh_identity.rs
+17
-1
crates/jacquard-api/src/com_atproto/identity/refresh_identity.rs
···
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
8
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
9
+
#[derive(
10
+
serde::Serialize,
11
+
serde::Deserialize,
12
+
Debug,
13
+
Clone,
14
+
PartialEq,
15
+
Eq,
16
+
bon::Builder
17
+
)]
10
18
#[serde(rename_all = "camelCase")]
19
+
#[builder(start_fn = new)]
11
20
pub struct RefreshIdentity<'a> {
12
21
#[serde(borrow)]
13
22
pub identifier: jacquard_common::types::ident::AtIdentifier<'a>,
23
+
#[serde(flatten)]
24
+
#[serde(borrow)]
25
+
#[builder(default)]
26
+
pub extra_data: ::std::collections::BTreeMap<
27
+
::jacquard_common::smol_str::SmolStr,
28
+
::jacquard_common::types::value::Data<'a>,
29
+
>,
14
30
}
15
31
16
32
impl jacquard_common::IntoStatic for RefreshIdentity<'_> {
+10
-1
crates/jacquard-api/src/com_atproto/identity/resolve_did.rs
+10
-1
crates/jacquard-api/src/com_atproto/identity/resolve_did.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct ResolveDid<'a> {
11
20
#[serde(borrow)]
+10
-1
crates/jacquard-api/src/com_atproto/identity/resolve_handle.rs
+10
-1
crates/jacquard-api/src/com_atproto/identity/resolve_handle.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct ResolveHandle<'a> {
11
20
#[serde(borrow)]
+10
-1
crates/jacquard-api/src/com_atproto/identity/resolve_identity.rs
+10
-1
crates/jacquard-api/src/com_atproto/identity/resolve_identity.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct ResolveIdentity<'a> {
11
20
#[serde(borrow)]
+18
-1
crates/jacquard-api/src/com_atproto/identity/sign_plc_operation.rs
+18
-1
crates/jacquard-api/src/com_atproto/identity/sign_plc_operation.rs
···
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
8
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
9
+
#[derive(
10
+
serde::Serialize,
11
+
serde::Deserialize,
12
+
Debug,
13
+
Clone,
14
+
PartialEq,
15
+
Eq,
16
+
bon::Builder
17
+
)]
10
18
#[serde(rename_all = "camelCase")]
19
+
#[builder(start_fn = new)]
11
20
pub struct SignPlcOperation<'a> {
12
21
#[serde(skip_serializing_if = "std::option::Option::is_none")]
13
22
#[serde(borrow)]
···
21
30
///A token received through com.atproto.identity.requestPlcOperationSignature
22
31
#[serde(skip_serializing_if = "std::option::Option::is_none")]
23
32
#[serde(borrow)]
33
+
#[builder(into)]
24
34
pub token: std::option::Option<jacquard_common::CowStr<'a>>,
25
35
#[serde(skip_serializing_if = "std::option::Option::is_none")]
26
36
#[serde(borrow)]
27
37
pub verification_methods: std::option::Option<
28
38
jacquard_common::types::value::Data<'a>,
39
+
>,
40
+
#[serde(flatten)]
41
+
#[serde(borrow)]
42
+
#[builder(default)]
43
+
pub extra_data: ::std::collections::BTreeMap<
44
+
::jacquard_common::smol_str::SmolStr,
45
+
::jacquard_common::types::value::Data<'a>,
29
46
>,
30
47
}
31
48
+17
-1
crates/jacquard-api/src/com_atproto/identity/submit_plc_operation.rs
+17
-1
crates/jacquard-api/src/com_atproto/identity/submit_plc_operation.rs
···
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
8
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
9
+
#[derive(
10
+
serde::Serialize,
11
+
serde::Deserialize,
12
+
Debug,
13
+
Clone,
14
+
PartialEq,
15
+
Eq,
16
+
bon::Builder
17
+
)]
10
18
#[serde(rename_all = "camelCase")]
19
+
#[builder(start_fn = new)]
11
20
pub struct SubmitPlcOperation<'a> {
12
21
#[serde(borrow)]
13
22
pub operation: jacquard_common::types::value::Data<'a>,
23
+
#[serde(flatten)]
24
+
#[serde(borrow)]
25
+
#[builder(default)]
26
+
pub extra_data: ::std::collections::BTreeMap<
27
+
::jacquard_common::smol_str::SmolStr,
28
+
::jacquard_common::types::value::Data<'a>,
29
+
>,
14
30
}
15
31
16
32
impl jacquard_common::IntoStatic for SubmitPlcOperation<'_> {
+17
-1
crates/jacquard-api/src/com_atproto/identity/update_handle.rs
+17
-1
crates/jacquard-api/src/com_atproto/identity/update_handle.rs
···
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
8
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
9
+
#[derive(
10
+
serde::Serialize,
11
+
serde::Deserialize,
12
+
Debug,
13
+
Clone,
14
+
PartialEq,
15
+
Eq,
16
+
bon::Builder
17
+
)]
10
18
#[serde(rename_all = "camelCase")]
19
+
#[builder(start_fn = new)]
11
20
pub struct UpdateHandle<'a> {
12
21
///The new handle.
13
22
#[serde(borrow)]
14
23
pub handle: jacquard_common::types::string::Handle<'a>,
24
+
#[serde(flatten)]
25
+
#[serde(borrow)]
26
+
#[builder(default)]
27
+
pub extra_data: ::std::collections::BTreeMap<
28
+
::jacquard_common::smol_str::SmolStr,
29
+
::jacquard_common::types::value::Data<'a>,
30
+
>,
15
31
}
16
32
17
33
impl jacquard_common::IntoStatic for UpdateHandle<'_> {
+11
-1
crates/jacquard-api/src/com_atproto/label/query_labels.rs
+11
-1
crates/jacquard-api/src/com_atproto/label/query_labels.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct QueryLabels<'a> {
11
20
#[serde(skip_serializing_if = "std::option::Option::is_none")]
12
21
#[serde(borrow)]
22
+
#[builder(into)]
13
23
pub cursor: std::option::Option<jacquard_common::CowStr<'a>>,
14
24
///(default: 50, min: 1, max: 250)
15
25
#[serde(skip_serializing_if = "std::option::Option::is_none")]
+10
-1
crates/jacquard-api/src/com_atproto/label/subscribe_labels.rs
+10
-1
crates/jacquard-api/src/com_atproto/label/subscribe_labels.rs
···
47
47
}
48
48
}
49
49
50
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
50
+
#[derive(
51
+
serde::Serialize,
52
+
serde::Deserialize,
53
+
Debug,
54
+
Clone,
55
+
PartialEq,
56
+
Eq,
57
+
bon::Builder
58
+
)]
59
+
#[builder(start_fn = new)]
51
60
#[serde(rename_all = "camelCase")]
52
61
pub struct SubscribeLabels {
53
62
#[serde(skip_serializing_if = "std::option::Option::is_none")]
+18
-1
crates/jacquard-api/src/com_atproto/moderation/create_report.rs
+18
-1
crates/jacquard-api/src/com_atproto/moderation/create_report.rs
···
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
8
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
9
+
#[derive(
10
+
serde::Serialize,
11
+
serde::Deserialize,
12
+
Debug,
13
+
Clone,
14
+
PartialEq,
15
+
Eq,
16
+
bon::Builder
17
+
)]
10
18
#[serde(rename_all = "camelCase")]
19
+
#[builder(start_fn = new)]
11
20
pub struct CreateReport<'a> {
12
21
#[serde(skip_serializing_if = "std::option::Option::is_none")]
13
22
#[serde(borrow)]
···
15
24
///Additional context about the content and violation.
16
25
#[serde(skip_serializing_if = "std::option::Option::is_none")]
17
26
#[serde(borrow)]
27
+
#[builder(into)]
18
28
pub reason: std::option::Option<jacquard_common::CowStr<'a>>,
19
29
///Indicates the broad category of violation the report is for.
20
30
#[serde(borrow)]
21
31
pub reason_type: crate::com_atproto::moderation::ReasonType<'a>,
22
32
#[serde(borrow)]
23
33
pub subject: CreateReportRecordSubject<'a>,
34
+
#[serde(flatten)]
35
+
#[serde(borrow)]
36
+
#[builder(default)]
37
+
pub extra_data: ::std::collections::BTreeMap<
38
+
::jacquard_common::smol_str::SmolStr,
39
+
::jacquard_common::types::value::Data<'a>,
40
+
>,
24
41
}
25
42
26
43
#[jacquard_derive::open_union]
+17
-1
crates/jacquard-api/src/com_atproto/repo/apply_writes.rs
+17
-1
crates/jacquard-api/src/com_atproto/repo/apply_writes.rs
···
99
99
}
100
100
101
101
#[jacquard_derive::lexicon]
102
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
102
+
#[derive(
103
+
serde::Serialize,
104
+
serde::Deserialize,
105
+
Debug,
106
+
Clone,
107
+
PartialEq,
108
+
Eq,
109
+
bon::Builder
110
+
)]
103
111
#[serde(rename_all = "camelCase")]
112
+
#[builder(start_fn = new)]
104
113
pub struct ApplyWrites<'a> {
105
114
///The handle or DID of the repo (aka, current account).
106
115
#[serde(borrow)]
···
114
123
pub validate: std::option::Option<bool>,
115
124
#[serde(borrow)]
116
125
pub writes: Vec<jacquard_common::types::value::Data<'a>>,
126
+
#[serde(flatten)]
127
+
#[serde(borrow)]
128
+
#[builder(default)]
129
+
pub extra_data: ::std::collections::BTreeMap<
130
+
::jacquard_common::smol_str::SmolStr,
131
+
::jacquard_common::types::value::Data<'a>,
132
+
>,
117
133
}
118
134
119
135
impl jacquard_common::IntoStatic for ApplyWrites<'_> {
+17
-1
crates/jacquard-api/src/com_atproto/repo/create_record.rs
+17
-1
crates/jacquard-api/src/com_atproto/repo/create_record.rs
···
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
8
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
9
+
#[derive(
10
+
serde::Serialize,
11
+
serde::Deserialize,
12
+
Debug,
13
+
Clone,
14
+
PartialEq,
15
+
Eq,
16
+
bon::Builder
17
+
)]
10
18
#[serde(rename_all = "camelCase")]
19
+
#[builder(start_fn = new)]
11
20
pub struct CreateRecord<'a> {
12
21
///The NSID of the record collection.
13
22
#[serde(borrow)]
···
33
42
///Can be set to 'false' to skip Lexicon schema validation of record data, 'true' to require it, or leave unset to validate only for known Lexicons.
34
43
#[serde(skip_serializing_if = "std::option::Option::is_none")]
35
44
pub validate: std::option::Option<bool>,
45
+
#[serde(flatten)]
46
+
#[serde(borrow)]
47
+
#[builder(default)]
48
+
pub extra_data: ::std::collections::BTreeMap<
49
+
::jacquard_common::smol_str::SmolStr,
50
+
::jacquard_common::types::value::Data<'a>,
51
+
>,
36
52
}
37
53
38
54
impl jacquard_common::IntoStatic for CreateRecord<'_> {
+17
-1
crates/jacquard-api/src/com_atproto/repo/delete_record.rs
+17
-1
crates/jacquard-api/src/com_atproto/repo/delete_record.rs
···
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
8
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
9
+
#[derive(
10
+
serde::Serialize,
11
+
serde::Deserialize,
12
+
Debug,
13
+
Clone,
14
+
PartialEq,
15
+
Eq,
16
+
bon::Builder
17
+
)]
10
18
#[serde(rename_all = "camelCase")]
19
+
#[builder(start_fn = new)]
11
20
pub struct DeleteRecord<'a> {
12
21
///The NSID of the record collection.
13
22
#[serde(borrow)]
···
28
37
#[serde(skip_serializing_if = "std::option::Option::is_none")]
29
38
#[serde(borrow)]
30
39
pub swap_record: std::option::Option<jacquard_common::types::string::Cid<'a>>,
40
+
#[serde(flatten)]
41
+
#[serde(borrow)]
42
+
#[builder(default)]
43
+
pub extra_data: ::std::collections::BTreeMap<
44
+
::jacquard_common::smol_str::SmolStr,
45
+
::jacquard_common::types::value::Data<'a>,
46
+
>,
31
47
}
32
48
33
49
impl jacquard_common::IntoStatic for DeleteRecord<'_> {
+10
-1
crates/jacquard-api/src/com_atproto/repo/describe_repo.rs
+10
-1
crates/jacquard-api/src/com_atproto/repo/describe_repo.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct DescribeRepo<'a> {
11
20
#[serde(borrow)]
+10
-1
crates/jacquard-api/src/com_atproto/repo/get_record.rs
+10
-1
crates/jacquard-api/src/com_atproto/repo/get_record.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetRecord<'a> {
11
20
#[serde(skip_serializing_if = "std::option::Option::is_none")]
+21
-9
crates/jacquard-api/src/com_atproto/repo/import_repo.rs
+21
-9
crates/jacquard-api/src/com_atproto/repo/import_repo.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
10
18
#[serde(rename_all = "camelCase")]
11
-
pub struct ImportRepo<'a> {}
12
-
impl jacquard_common::IntoStatic for ImportRepo<'_> {
13
-
type Output = ImportRepo<'static>;
19
+
pub struct ImportRepo {
20
+
pub body: bytes::Bytes,
21
+
}
22
+
23
+
impl jacquard_common::IntoStatic for ImportRepo {
24
+
type Output = ImportRepo;
14
25
fn into_static(self) -> Self::Output {
15
-
ImportRepo {
16
-
extra_data: self.extra_data.into_static(),
17
-
}
26
+
self
18
27
}
19
28
}
20
29
21
-
impl jacquard_common::types::xrpc::XrpcRequest for ImportRepo<'_> {
30
+
impl jacquard_common::types::xrpc::XrpcRequest for ImportRepo {
22
31
const NSID: &'static str = "com.atproto.repo.importRepo";
23
32
const METHOD: jacquard_common::types::xrpc::XrpcMethod = jacquard_common::types::xrpc::XrpcMethod::Procedure(
24
33
"application/vnd.ipld.car",
···
26
35
const OUTPUT_ENCODING: &'static str = "application/json";
27
36
type Output<'de> = ();
28
37
type Err<'de> = jacquard_common::types::xrpc::GenericError<'de>;
38
+
fn encode_body(&self) -> Result<Vec<u8>, jacquard_common::types::xrpc::EncodeError> {
39
+
Ok(self.body.to_vec())
40
+
}
29
41
}
+11
-1
crates/jacquard-api/src/com_atproto/repo/list_missing_blobs.rs
+11
-1
crates/jacquard-api/src/com_atproto/repo/list_missing_blobs.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct ListMissingBlobs<'a> {
11
20
#[serde(skip_serializing_if = "std::option::Option::is_none")]
12
21
#[serde(borrow)]
22
+
#[builder(into)]
13
23
pub cursor: std::option::Option<jacquard_common::CowStr<'a>>,
14
24
///(default: 500, min: 1, max: 1000)
15
25
#[serde(skip_serializing_if = "std::option::Option::is_none")]
+11
-1
crates/jacquard-api/src/com_atproto/repo/list_records.rs
+11
-1
crates/jacquard-api/src/com_atproto/repo/list_records.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct ListRecords<'a> {
11
20
#[serde(borrow)]
12
21
pub collection: jacquard_common::types::string::Nsid<'a>,
13
22
#[serde(skip_serializing_if = "std::option::Option::is_none")]
14
23
#[serde(borrow)]
24
+
#[builder(into)]
15
25
pub cursor: std::option::Option<jacquard_common::CowStr<'a>>,
16
26
///(default: 50, min: 1, max: 100)
17
27
#[serde(skip_serializing_if = "std::option::Option::is_none")]
+17
-1
crates/jacquard-api/src/com_atproto/repo/put_record.rs
+17
-1
crates/jacquard-api/src/com_atproto/repo/put_record.rs
···
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
8
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
9
+
#[derive(
10
+
serde::Serialize,
11
+
serde::Deserialize,
12
+
Debug,
13
+
Clone,
14
+
PartialEq,
15
+
Eq,
16
+
bon::Builder
17
+
)]
10
18
#[serde(rename_all = "camelCase")]
19
+
#[builder(start_fn = new)]
11
20
pub struct PutRecord<'a> {
12
21
///The NSID of the record collection.
13
22
#[serde(borrow)]
···
34
43
///Can be set to 'false' to skip Lexicon schema validation of record data, 'true' to require it, or leave unset to validate only for known Lexicons.
35
44
#[serde(skip_serializing_if = "std::option::Option::is_none")]
36
45
pub validate: std::option::Option<bool>,
46
+
#[serde(flatten)]
47
+
#[serde(borrow)]
48
+
#[builder(default)]
49
+
pub extra_data: ::std::collections::BTreeMap<
50
+
::jacquard_common::smol_str::SmolStr,
51
+
::jacquard_common::types::value::Data<'a>,
52
+
>,
37
53
}
38
54
39
55
impl jacquard_common::IntoStatic for PutRecord<'_> {
+21
-9
crates/jacquard-api/src/com_atproto/repo/upload_blob.rs
+21
-9
crates/jacquard-api/src/com_atproto/repo/upload_blob.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
10
18
#[serde(rename_all = "camelCase")]
11
-
pub struct UploadBlob<'a> {}
12
-
impl jacquard_common::IntoStatic for UploadBlob<'_> {
13
-
type Output = UploadBlob<'static>;
19
+
pub struct UploadBlob {
20
+
pub body: bytes::Bytes,
21
+
}
22
+
23
+
impl jacquard_common::IntoStatic for UploadBlob {
24
+
type Output = UploadBlob;
14
25
fn into_static(self) -> Self::Output {
15
-
UploadBlob {
16
-
extra_data: self.extra_data.into_static(),
17
-
}
26
+
self
18
27
}
19
28
}
20
29
···
36
45
}
37
46
}
38
47
39
-
impl jacquard_common::types::xrpc::XrpcRequest for UploadBlob<'_> {
48
+
impl jacquard_common::types::xrpc::XrpcRequest for UploadBlob {
40
49
const NSID: &'static str = "com.atproto.repo.uploadBlob";
41
50
const METHOD: jacquard_common::types::xrpc::XrpcMethod = jacquard_common::types::xrpc::XrpcMethod::Procedure(
42
51
"*/*",
···
44
53
const OUTPUT_ENCODING: &'static str = "application/json";
45
54
type Output<'de> = UploadBlobOutput<'de>;
46
55
type Err<'de> = jacquard_common::types::xrpc::GenericError<'de>;
56
+
fn encode_body(&self) -> Result<Vec<u8>, jacquard_common::types::xrpc::EncodeError> {
57
+
Ok(self.body.to_vec())
58
+
}
47
59
}
+19
-1
crates/jacquard-api/src/com_atproto/server/confirm_email.rs
+19
-1
crates/jacquard-api/src/com_atproto/server/confirm_email.rs
···
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
8
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
9
+
#[derive(
10
+
serde::Serialize,
11
+
serde::Deserialize,
12
+
Debug,
13
+
Clone,
14
+
PartialEq,
15
+
Eq,
16
+
bon::Builder
17
+
)]
10
18
#[serde(rename_all = "camelCase")]
19
+
#[builder(start_fn = new)]
11
20
pub struct ConfirmEmail<'a> {
12
21
#[serde(borrow)]
22
+
#[builder(into)]
13
23
pub email: jacquard_common::CowStr<'a>,
14
24
#[serde(borrow)]
25
+
#[builder(into)]
15
26
pub token: jacquard_common::CowStr<'a>,
27
+
#[serde(flatten)]
28
+
#[serde(borrow)]
29
+
#[builder(default)]
30
+
pub extra_data: ::std::collections::BTreeMap<
31
+
::jacquard_common::smol_str::SmolStr,
32
+
::jacquard_common::types::value::Data<'a>,
33
+
>,
16
34
}
17
35
18
36
impl jacquard_common::IntoStatic for ConfirmEmail<'_> {
+23
-1
crates/jacquard-api/src/com_atproto/server/create_account.rs
+23
-1
crates/jacquard-api/src/com_atproto/server/create_account.rs
···
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
8
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
9
+
#[derive(
10
+
serde::Serialize,
11
+
serde::Deserialize,
12
+
Debug,
13
+
Clone,
14
+
PartialEq,
15
+
Eq,
16
+
bon::Builder
17
+
)]
10
18
#[serde(rename_all = "camelCase")]
19
+
#[builder(start_fn = new)]
11
20
pub struct CreateAccount<'a> {
12
21
///Pre-existing atproto DID, being imported to a new account.
13
22
#[serde(skip_serializing_if = "std::option::Option::is_none")]
···
15
24
pub did: std::option::Option<jacquard_common::types::string::Did<'a>>,
16
25
#[serde(skip_serializing_if = "std::option::Option::is_none")]
17
26
#[serde(borrow)]
27
+
#[builder(into)]
18
28
pub email: std::option::Option<jacquard_common::CowStr<'a>>,
19
29
///Requested handle for the account.
20
30
#[serde(borrow)]
21
31
pub handle: jacquard_common::types::string::Handle<'a>,
22
32
#[serde(skip_serializing_if = "std::option::Option::is_none")]
23
33
#[serde(borrow)]
34
+
#[builder(into)]
24
35
pub invite_code: std::option::Option<jacquard_common::CowStr<'a>>,
25
36
///Initial account password. May need to meet instance-specific password strength requirements.
26
37
#[serde(skip_serializing_if = "std::option::Option::is_none")]
27
38
#[serde(borrow)]
39
+
#[builder(into)]
28
40
pub password: std::option::Option<jacquard_common::CowStr<'a>>,
29
41
///A signed DID PLC operation to be submitted as part of importing an existing account to this instance. NOTE: this optional field may be updated when full account migration is implemented.
30
42
#[serde(skip_serializing_if = "std::option::Option::is_none")]
···
33
45
///DID PLC rotation key (aka, recovery key) to be included in PLC creation operation.
34
46
#[serde(skip_serializing_if = "std::option::Option::is_none")]
35
47
#[serde(borrow)]
48
+
#[builder(into)]
36
49
pub recovery_key: std::option::Option<jacquard_common::CowStr<'a>>,
37
50
#[serde(skip_serializing_if = "std::option::Option::is_none")]
38
51
#[serde(borrow)]
52
+
#[builder(into)]
39
53
pub verification_code: std::option::Option<jacquard_common::CowStr<'a>>,
40
54
#[serde(skip_serializing_if = "std::option::Option::is_none")]
41
55
#[serde(borrow)]
56
+
#[builder(into)]
42
57
pub verification_phone: std::option::Option<jacquard_common::CowStr<'a>>,
58
+
#[serde(flatten)]
59
+
#[serde(borrow)]
60
+
#[builder(default)]
61
+
pub extra_data: ::std::collections::BTreeMap<
62
+
::jacquard_common::smol_str::SmolStr,
63
+
::jacquard_common::types::value::Data<'a>,
64
+
>,
43
65
}
44
66
45
67
impl jacquard_common::IntoStatic for CreateAccount<'_> {
+18
-1
crates/jacquard-api/src/com_atproto/server/create_app_password.rs
+18
-1
crates/jacquard-api/src/com_atproto/server/create_app_password.rs
···
32
32
}
33
33
34
34
#[jacquard_derive::lexicon]
35
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
35
+
#[derive(
36
+
serde::Serialize,
37
+
serde::Deserialize,
38
+
Debug,
39
+
Clone,
40
+
PartialEq,
41
+
Eq,
42
+
bon::Builder
43
+
)]
36
44
#[serde(rename_all = "camelCase")]
45
+
#[builder(start_fn = new)]
37
46
pub struct CreateAppPassword<'a> {
38
47
///A short name for the App Password, to help distinguish them.
39
48
#[serde(borrow)]
49
+
#[builder(into)]
40
50
pub name: jacquard_common::CowStr<'a>,
41
51
///If an app password has 'privileged' access to possibly sensitive account state. Meant for use with trusted clients.
42
52
#[serde(skip_serializing_if = "std::option::Option::is_none")]
43
53
pub privileged: std::option::Option<bool>,
54
+
#[serde(flatten)]
55
+
#[serde(borrow)]
56
+
#[builder(default)]
57
+
pub extra_data: ::std::collections::BTreeMap<
58
+
::jacquard_common::smol_str::SmolStr,
59
+
::jacquard_common::types::value::Data<'a>,
60
+
>,
44
61
}
45
62
46
63
impl jacquard_common::IntoStatic for CreateAppPassword<'_> {
+17
-1
crates/jacquard-api/src/com_atproto/server/create_invite_code.rs
+17
-1
crates/jacquard-api/src/com_atproto/server/create_invite_code.rs
···
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
8
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
9
+
#[derive(
10
+
serde::Serialize,
11
+
serde::Deserialize,
12
+
Debug,
13
+
Clone,
14
+
PartialEq,
15
+
Eq,
16
+
bon::Builder
17
+
)]
10
18
#[serde(rename_all = "camelCase")]
19
+
#[builder(start_fn = new)]
11
20
pub struct CreateInviteCode<'a> {
12
21
#[serde(skip_serializing_if = "std::option::Option::is_none")]
13
22
#[serde(borrow)]
14
23
pub for_account: std::option::Option<jacquard_common::types::string::Did<'a>>,
15
24
pub use_count: i64,
25
+
#[serde(flatten)]
26
+
#[serde(borrow)]
27
+
#[builder(default)]
28
+
pub extra_data: ::std::collections::BTreeMap<
29
+
::jacquard_common::smol_str::SmolStr,
30
+
::jacquard_common::types::value::Data<'a>,
31
+
>,
16
32
}
17
33
18
34
impl jacquard_common::IntoStatic for CreateInviteCode<'_> {
+17
-1
crates/jacquard-api/src/com_atproto/server/create_invite_codes.rs
+17
-1
crates/jacquard-api/src/com_atproto/server/create_invite_codes.rs
···
27
27
}
28
28
29
29
#[jacquard_derive::lexicon]
30
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
30
+
#[derive(
31
+
serde::Serialize,
32
+
serde::Deserialize,
33
+
Debug,
34
+
Clone,
35
+
PartialEq,
36
+
Eq,
37
+
bon::Builder
38
+
)]
31
39
#[serde(rename_all = "camelCase")]
40
+
#[builder(start_fn = new)]
32
41
pub struct CreateInviteCodes<'a> {
33
42
pub code_count: i64,
34
43
#[serde(skip_serializing_if = "std::option::Option::is_none")]
35
44
#[serde(borrow)]
36
45
pub for_accounts: std::option::Option<Vec<jacquard_common::types::string::Did<'a>>>,
37
46
pub use_count: i64,
47
+
#[serde(flatten)]
48
+
#[serde(borrow)]
49
+
#[builder(default)]
50
+
pub extra_data: ::std::collections::BTreeMap<
51
+
::jacquard_common::smol_str::SmolStr,
52
+
::jacquard_common::types::value::Data<'a>,
53
+
>,
38
54
}
39
55
40
56
impl jacquard_common::IntoStatic for CreateInviteCodes<'_> {
+20
-1
crates/jacquard-api/src/com_atproto/server/create_session.rs
+20
-1
crates/jacquard-api/src/com_atproto/server/create_session.rs
···
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
8
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
9
+
#[derive(
10
+
serde::Serialize,
11
+
serde::Deserialize,
12
+
Debug,
13
+
Clone,
14
+
PartialEq,
15
+
Eq,
16
+
bon::Builder
17
+
)]
10
18
#[serde(rename_all = "camelCase")]
19
+
#[builder(start_fn = new)]
11
20
pub struct CreateSession<'a> {
12
21
///When true, instead of throwing error for takendown accounts, a valid response with a narrow scoped token will be returned
13
22
#[serde(skip_serializing_if = "std::option::Option::is_none")]
14
23
pub allow_takendown: std::option::Option<bool>,
15
24
#[serde(skip_serializing_if = "std::option::Option::is_none")]
16
25
#[serde(borrow)]
26
+
#[builder(into)]
17
27
pub auth_factor_token: std::option::Option<jacquard_common::CowStr<'a>>,
18
28
///Handle or other identifier supported by the server for the authenticating user.
19
29
#[serde(borrow)]
30
+
#[builder(into)]
20
31
pub identifier: jacquard_common::CowStr<'a>,
21
32
#[serde(borrow)]
33
+
#[builder(into)]
22
34
pub password: jacquard_common::CowStr<'a>,
35
+
#[serde(flatten)]
36
+
#[serde(borrow)]
37
+
#[builder(default)]
38
+
pub extra_data: ::std::collections::BTreeMap<
39
+
::jacquard_common::smol_str::SmolStr,
40
+
::jacquard_common::types::value::Data<'a>,
41
+
>,
23
42
}
24
43
25
44
impl jacquard_common::IntoStatic for CreateSession<'_> {
+17
-1
crates/jacquard-api/src/com_atproto/server/deactivate_account.rs
+17
-1
crates/jacquard-api/src/com_atproto/server/deactivate_account.rs
···
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
8
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
9
+
#[derive(
10
+
serde::Serialize,
11
+
serde::Deserialize,
12
+
Debug,
13
+
Clone,
14
+
PartialEq,
15
+
Eq,
16
+
bon::Builder
17
+
)]
10
18
#[serde(rename_all = "camelCase")]
19
+
#[builder(start_fn = new)]
11
20
pub struct DeactivateAccount<'a> {
12
21
///A recommendation to server as to how long they should hold onto the deactivated account before deleting.
13
22
#[serde(skip_serializing_if = "std::option::Option::is_none")]
14
23
pub delete_after: std::option::Option<jacquard_common::types::string::Datetime>,
24
+
#[serde(flatten)]
25
+
#[serde(borrow)]
26
+
#[builder(default)]
27
+
pub extra_data: ::std::collections::BTreeMap<
28
+
::jacquard_common::smol_str::SmolStr,
29
+
::jacquard_common::types::value::Data<'a>,
30
+
>,
15
31
}
16
32
17
33
impl jacquard_common::IntoStatic for DeactivateAccount<'_> {
+19
-1
crates/jacquard-api/src/com_atproto/server/delete_account.rs
+19
-1
crates/jacquard-api/src/com_atproto/server/delete_account.rs
···
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
8
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
9
+
#[derive(
10
+
serde::Serialize,
11
+
serde::Deserialize,
12
+
Debug,
13
+
Clone,
14
+
PartialEq,
15
+
Eq,
16
+
bon::Builder
17
+
)]
10
18
#[serde(rename_all = "camelCase")]
19
+
#[builder(start_fn = new)]
11
20
pub struct DeleteAccount<'a> {
12
21
#[serde(borrow)]
13
22
pub did: jacquard_common::types::string::Did<'a>,
14
23
#[serde(borrow)]
24
+
#[builder(into)]
15
25
pub password: jacquard_common::CowStr<'a>,
16
26
#[serde(borrow)]
27
+
#[builder(into)]
17
28
pub token: jacquard_common::CowStr<'a>,
29
+
#[serde(flatten)]
30
+
#[serde(borrow)]
31
+
#[builder(default)]
32
+
pub extra_data: ::std::collections::BTreeMap<
33
+
::jacquard_common::smol_str::SmolStr,
34
+
::jacquard_common::types::value::Data<'a>,
35
+
>,
18
36
}
19
37
20
38
impl jacquard_common::IntoStatic for DeleteAccount<'_> {
+10
-1
crates/jacquard-api/src/com_atproto/server/get_account_invite_codes.rs
+10
-1
crates/jacquard-api/src/com_atproto/server/get_account_invite_codes.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetAccountInviteCodes {
11
20
///(default: true)
+10
-1
crates/jacquard-api/src/com_atproto/server/get_service_auth.rs
+10
-1
crates/jacquard-api/src/com_atproto/server/get_service_auth.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetServiceAuth<'a> {
11
20
#[serde(borrow)]
+18
-1
crates/jacquard-api/src/com_atproto/server/request_password_reset.rs
+18
-1
crates/jacquard-api/src/com_atproto/server/request_password_reset.rs
···
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
8
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
9
+
#[derive(
10
+
serde::Serialize,
11
+
serde::Deserialize,
12
+
Debug,
13
+
Clone,
14
+
PartialEq,
15
+
Eq,
16
+
bon::Builder
17
+
)]
10
18
#[serde(rename_all = "camelCase")]
19
+
#[builder(start_fn = new)]
11
20
pub struct RequestPasswordReset<'a> {
12
21
#[serde(borrow)]
22
+
#[builder(into)]
13
23
pub email: jacquard_common::CowStr<'a>,
24
+
#[serde(flatten)]
25
+
#[serde(borrow)]
26
+
#[builder(default)]
27
+
pub extra_data: ::std::collections::BTreeMap<
28
+
::jacquard_common::smol_str::SmolStr,
29
+
::jacquard_common::types::value::Data<'a>,
30
+
>,
14
31
}
15
32
16
33
impl jacquard_common::IntoStatic for RequestPasswordReset<'_> {
+17
-1
crates/jacquard-api/src/com_atproto/server/reserve_signing_key.rs
+17
-1
crates/jacquard-api/src/com_atproto/server/reserve_signing_key.rs
···
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
8
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
9
+
#[derive(
10
+
serde::Serialize,
11
+
serde::Deserialize,
12
+
Debug,
13
+
Clone,
14
+
PartialEq,
15
+
Eq,
16
+
bon::Builder
17
+
)]
10
18
#[serde(rename_all = "camelCase")]
19
+
#[builder(start_fn = new)]
11
20
pub struct ReserveSigningKey<'a> {
12
21
///The DID to reserve a key for.
13
22
#[serde(skip_serializing_if = "std::option::Option::is_none")]
14
23
#[serde(borrow)]
15
24
pub did: std::option::Option<jacquard_common::types::string::Did<'a>>,
25
+
#[serde(flatten)]
26
+
#[serde(borrow)]
27
+
#[builder(default)]
28
+
pub extra_data: ::std::collections::BTreeMap<
29
+
::jacquard_common::smol_str::SmolStr,
30
+
::jacquard_common::types::value::Data<'a>,
31
+
>,
16
32
}
17
33
18
34
impl jacquard_common::IntoStatic for ReserveSigningKey<'_> {
+19
-1
crates/jacquard-api/src/com_atproto/server/reset_password.rs
+19
-1
crates/jacquard-api/src/com_atproto/server/reset_password.rs
···
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
8
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
9
+
#[derive(
10
+
serde::Serialize,
11
+
serde::Deserialize,
12
+
Debug,
13
+
Clone,
14
+
PartialEq,
15
+
Eq,
16
+
bon::Builder
17
+
)]
10
18
#[serde(rename_all = "camelCase")]
19
+
#[builder(start_fn = new)]
11
20
pub struct ResetPassword<'a> {
12
21
#[serde(borrow)]
22
+
#[builder(into)]
13
23
pub password: jacquard_common::CowStr<'a>,
14
24
#[serde(borrow)]
25
+
#[builder(into)]
15
26
pub token: jacquard_common::CowStr<'a>,
27
+
#[serde(flatten)]
28
+
#[serde(borrow)]
29
+
#[builder(default)]
30
+
pub extra_data: ::std::collections::BTreeMap<
31
+
::jacquard_common::smol_str::SmolStr,
32
+
::jacquard_common::types::value::Data<'a>,
33
+
>,
16
34
}
17
35
18
36
impl jacquard_common::IntoStatic for ResetPassword<'_> {
+18
-1
crates/jacquard-api/src/com_atproto/server/revoke_app_password.rs
+18
-1
crates/jacquard-api/src/com_atproto/server/revoke_app_password.rs
···
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
8
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
9
+
#[derive(
10
+
serde::Serialize,
11
+
serde::Deserialize,
12
+
Debug,
13
+
Clone,
14
+
PartialEq,
15
+
Eq,
16
+
bon::Builder
17
+
)]
10
18
#[serde(rename_all = "camelCase")]
19
+
#[builder(start_fn = new)]
11
20
pub struct RevokeAppPassword<'a> {
12
21
#[serde(borrow)]
22
+
#[builder(into)]
13
23
pub name: jacquard_common::CowStr<'a>,
24
+
#[serde(flatten)]
25
+
#[serde(borrow)]
26
+
#[builder(default)]
27
+
pub extra_data: ::std::collections::BTreeMap<
28
+
::jacquard_common::smol_str::SmolStr,
29
+
::jacquard_common::types::value::Data<'a>,
30
+
>,
14
31
}
15
32
16
33
impl jacquard_common::IntoStatic for RevokeAppPassword<'_> {
+19
-1
crates/jacquard-api/src/com_atproto/server/update_email.rs
+19
-1
crates/jacquard-api/src/com_atproto/server/update_email.rs
···
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
8
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
9
+
#[derive(
10
+
serde::Serialize,
11
+
serde::Deserialize,
12
+
Debug,
13
+
Clone,
14
+
PartialEq,
15
+
Eq,
16
+
bon::Builder
17
+
)]
10
18
#[serde(rename_all = "camelCase")]
19
+
#[builder(start_fn = new)]
11
20
pub struct UpdateEmail<'a> {
12
21
#[serde(borrow)]
22
+
#[builder(into)]
13
23
pub email: jacquard_common::CowStr<'a>,
14
24
#[serde(skip_serializing_if = "std::option::Option::is_none")]
15
25
pub email_auth_factor: std::option::Option<bool>,
16
26
///Requires a token from com.atproto.sever.requestEmailUpdate if the account's email has been confirmed.
17
27
#[serde(skip_serializing_if = "std::option::Option::is_none")]
18
28
#[serde(borrow)]
29
+
#[builder(into)]
19
30
pub token: std::option::Option<jacquard_common::CowStr<'a>>,
31
+
#[serde(flatten)]
32
+
#[serde(borrow)]
33
+
#[builder(default)]
34
+
pub extra_data: ::std::collections::BTreeMap<
35
+
::jacquard_common::smol_str::SmolStr,
36
+
::jacquard_common::types::value::Data<'a>,
37
+
>,
20
38
}
21
39
22
40
impl jacquard_common::IntoStatic for UpdateEmail<'_> {
+10
-1
crates/jacquard-api/src/com_atproto/sync/get_blob.rs
+10
-1
crates/jacquard-api/src/com_atproto/sync/get_blob.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetBlob<'a> {
11
20
#[serde(borrow)]
+10
-1
crates/jacquard-api/src/com_atproto/sync/get_blocks.rs
+10
-1
crates/jacquard-api/src/com_atproto/sync/get_blocks.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetBlocks<'a> {
11
20
#[serde(borrow)]
+10
-1
crates/jacquard-api/src/com_atproto/sync/get_checkout.rs
+10
-1
crates/jacquard-api/src/com_atproto/sync/get_checkout.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetCheckout<'a> {
11
20
#[serde(borrow)]
+10
-1
crates/jacquard-api/src/com_atproto/sync/get_head.rs
+10
-1
crates/jacquard-api/src/com_atproto/sync/get_head.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetHead<'a> {
11
20
#[serde(borrow)]
+11
-1
crates/jacquard-api/src/com_atproto/sync/get_host_status.rs
+11
-1
crates/jacquard-api/src/com_atproto/sync/get_host_status.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetHostStatus<'a> {
11
20
#[serde(borrow)]
21
+
#[builder(into)]
12
22
pub hostname: jacquard_common::CowStr<'a>,
13
23
}
14
24
+10
-1
crates/jacquard-api/src/com_atproto/sync/get_latest_commit.rs
+10
-1
crates/jacquard-api/src/com_atproto/sync/get_latest_commit.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetLatestCommit<'a> {
11
20
#[serde(borrow)]
+10
-1
crates/jacquard-api/src/com_atproto/sync/get_record.rs
+10
-1
crates/jacquard-api/src/com_atproto/sync/get_record.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetRecord<'a> {
11
20
#[serde(borrow)]
+10
-1
crates/jacquard-api/src/com_atproto/sync/get_repo.rs
+10
-1
crates/jacquard-api/src/com_atproto/sync/get_repo.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetRepo<'a> {
11
20
#[serde(borrow)]
+10
-1
crates/jacquard-api/src/com_atproto/sync/get_repo_status.rs
+10
-1
crates/jacquard-api/src/com_atproto/sync/get_repo_status.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetRepoStatus<'a> {
11
20
#[serde(borrow)]
+11
-1
crates/jacquard-api/src/com_atproto/sync/list_blobs.rs
+11
-1
crates/jacquard-api/src/com_atproto/sync/list_blobs.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct ListBlobs<'a> {
11
20
#[serde(skip_serializing_if = "std::option::Option::is_none")]
12
21
#[serde(borrow)]
22
+
#[builder(into)]
13
23
pub cursor: std::option::Option<jacquard_common::CowStr<'a>>,
14
24
#[serde(borrow)]
15
25
pub did: jacquard_common::types::string::Did<'a>,
+11
-1
crates/jacquard-api/src/com_atproto/sync/list_hosts.rs
+11
-1
crates/jacquard-api/src/com_atproto/sync/list_hosts.rs
···
35
35
}
36
36
}
37
37
38
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
38
+
#[derive(
39
+
serde::Serialize,
40
+
serde::Deserialize,
41
+
Debug,
42
+
Clone,
43
+
PartialEq,
44
+
Eq,
45
+
bon::Builder
46
+
)]
47
+
#[builder(start_fn = new)]
39
48
#[serde(rename_all = "camelCase")]
40
49
pub struct ListHosts<'a> {
41
50
#[serde(skip_serializing_if = "std::option::Option::is_none")]
42
51
#[serde(borrow)]
52
+
#[builder(into)]
43
53
pub cursor: std::option::Option<jacquard_common::CowStr<'a>>,
44
54
///(default: 200, min: 1, max: 1000)
45
55
#[serde(skip_serializing_if = "std::option::Option::is_none")]
+11
-1
crates/jacquard-api/src/com_atproto/sync/list_repos.rs
+11
-1
crates/jacquard-api/src/com_atproto/sync/list_repos.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct ListRepos<'a> {
11
20
#[serde(skip_serializing_if = "std::option::Option::is_none")]
12
21
#[serde(borrow)]
22
+
#[builder(into)]
13
23
pub cursor: std::option::Option<jacquard_common::CowStr<'a>>,
14
24
///(default: 500, min: 1, max: 1000)
15
25
#[serde(skip_serializing_if = "std::option::Option::is_none")]
+11
-1
crates/jacquard-api/src/com_atproto/sync/list_repos_by_collection.rs
+11
-1
crates/jacquard-api/src/com_atproto/sync/list_repos_by_collection.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct ListReposByCollection<'a> {
11
20
#[serde(borrow)]
12
21
pub collection: jacquard_common::types::string::Nsid<'a>,
13
22
#[serde(skip_serializing_if = "std::option::Option::is_none")]
14
23
#[serde(borrow)]
24
+
#[builder(into)]
15
25
pub cursor: std::option::Option<jacquard_common::CowStr<'a>>,
16
26
///(default: 500, min: 1, max: 2000)
17
27
#[serde(skip_serializing_if = "std::option::Option::is_none")]
+18
-1
crates/jacquard-api/src/com_atproto/sync/notify_of_update.rs
+18
-1
crates/jacquard-api/src/com_atproto/sync/notify_of_update.rs
···
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
8
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
9
+
#[derive(
10
+
serde::Serialize,
11
+
serde::Deserialize,
12
+
Debug,
13
+
Clone,
14
+
PartialEq,
15
+
Eq,
16
+
bon::Builder
17
+
)]
10
18
#[serde(rename_all = "camelCase")]
19
+
#[builder(start_fn = new)]
11
20
pub struct NotifyOfUpdate<'a> {
12
21
///Hostname of the current service (usually a PDS) that is notifying of update.
13
22
#[serde(borrow)]
23
+
#[builder(into)]
14
24
pub hostname: jacquard_common::CowStr<'a>,
25
+
#[serde(flatten)]
26
+
#[serde(borrow)]
27
+
#[builder(default)]
28
+
pub extra_data: ::std::collections::BTreeMap<
29
+
::jacquard_common::smol_str::SmolStr,
30
+
::jacquard_common::types::value::Data<'a>,
31
+
>,
15
32
}
16
33
17
34
impl jacquard_common::IntoStatic for NotifyOfUpdate<'_> {
+18
-1
crates/jacquard-api/src/com_atproto/sync/request_crawl.rs
+18
-1
crates/jacquard-api/src/com_atproto/sync/request_crawl.rs
···
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
8
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
9
+
#[derive(
10
+
serde::Serialize,
11
+
serde::Deserialize,
12
+
Debug,
13
+
Clone,
14
+
PartialEq,
15
+
Eq,
16
+
bon::Builder
17
+
)]
10
18
#[serde(rename_all = "camelCase")]
19
+
#[builder(start_fn = new)]
11
20
pub struct RequestCrawl<'a> {
12
21
///Hostname of the current service (eg, PDS) that is requesting to be crawled.
13
22
#[serde(borrow)]
23
+
#[builder(into)]
14
24
pub hostname: jacquard_common::CowStr<'a>,
25
+
#[serde(flatten)]
26
+
#[serde(borrow)]
27
+
#[builder(default)]
28
+
pub extra_data: ::std::collections::BTreeMap<
29
+
::jacquard_common::smol_str::SmolStr,
30
+
::jacquard_common::types::value::Data<'a>,
31
+
>,
15
32
}
16
33
17
34
impl jacquard_common::IntoStatic for RequestCrawl<'_> {
+10
-1
crates/jacquard-api/src/com_atproto/sync/subscribe_repos.rs
+10
-1
crates/jacquard-api/src/com_atproto/sync/subscribe_repos.rs
···
142
142
}
143
143
}
144
144
145
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
145
+
#[derive(
146
+
serde::Serialize,
147
+
serde::Deserialize,
148
+
Debug,
149
+
Clone,
150
+
PartialEq,
151
+
Eq,
152
+
bon::Builder
153
+
)]
154
+
#[builder(start_fn = new)]
146
155
#[serde(rename_all = "camelCase")]
147
156
pub struct SubscribeRepos {
148
157
#[serde(skip_serializing_if = "std::option::Option::is_none")]
+18
-1
crates/jacquard-api/src/com_atproto/temp/add_reserved_handle.rs
+18
-1
crates/jacquard-api/src/com_atproto/temp/add_reserved_handle.rs
···
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
8
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
9
+
#[derive(
10
+
serde::Serialize,
11
+
serde::Deserialize,
12
+
Debug,
13
+
Clone,
14
+
PartialEq,
15
+
Eq,
16
+
bon::Builder
17
+
)]
10
18
#[serde(rename_all = "camelCase")]
19
+
#[builder(start_fn = new)]
11
20
pub struct AddReservedHandle<'a> {
12
21
#[serde(borrow)]
22
+
#[builder(into)]
13
23
pub handle: jacquard_common::CowStr<'a>,
24
+
#[serde(flatten)]
25
+
#[serde(borrow)]
26
+
#[builder(default)]
27
+
pub extra_data: ::std::collections::BTreeMap<
28
+
::jacquard_common::smol_str::SmolStr,
29
+
::jacquard_common::types::value::Data<'a>,
30
+
>,
14
31
}
15
32
16
33
impl jacquard_common::IntoStatic for AddReservedHandle<'_> {
+11
-1
crates/jacquard-api/src/com_atproto/temp/check_handle_availability.rs
+11
-1
crates/jacquard-api/src/com_atproto/temp/check_handle_availability.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct CheckHandleAvailability<'a> {
11
20
#[serde(skip_serializing_if = "std::option::Option::is_none")]
12
21
pub birth_date: std::option::Option<jacquard_common::types::string::Datetime>,
13
22
#[serde(skip_serializing_if = "std::option::Option::is_none")]
14
23
#[serde(borrow)]
24
+
#[builder(into)]
15
25
pub email: std::option::Option<jacquard_common::CowStr<'a>>,
16
26
#[serde(borrow)]
17
27
pub handle: jacquard_common::types::string::Handle<'a>,
+11
-1
crates/jacquard-api/src/com_atproto/temp/dereference_scope.rs
+11
-1
crates/jacquard-api/src/com_atproto/temp/dereference_scope.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct DereferenceScope<'a> {
11
20
#[serde(borrow)]
21
+
#[builder(into)]
12
22
pub scope: jacquard_common::CowStr<'a>,
13
23
}
14
24
+10
-1
crates/jacquard-api/src/com_atproto/temp/fetch_labels.rs
+10
-1
crates/jacquard-api/src/com_atproto/temp/fetch_labels.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct FetchLabels {
11
20
///(default: 50, min: 1, max: 250)
+18
-1
crates/jacquard-api/src/com_atproto/temp/request_phone_verification.rs
+18
-1
crates/jacquard-api/src/com_atproto/temp/request_phone_verification.rs
···
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
8
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
9
+
#[derive(
10
+
serde::Serialize,
11
+
serde::Deserialize,
12
+
Debug,
13
+
Clone,
14
+
PartialEq,
15
+
Eq,
16
+
bon::Builder
17
+
)]
10
18
#[serde(rename_all = "camelCase")]
19
+
#[builder(start_fn = new)]
11
20
pub struct RequestPhoneVerification<'a> {
12
21
#[serde(borrow)]
22
+
#[builder(into)]
13
23
pub phone_number: jacquard_common::CowStr<'a>,
24
+
#[serde(flatten)]
25
+
#[serde(borrow)]
26
+
#[builder(default)]
27
+
pub extra_data: ::std::collections::BTreeMap<
28
+
::jacquard_common::smol_str::SmolStr,
29
+
::jacquard_common::types::value::Data<'a>,
30
+
>,
14
31
}
15
32
16
33
impl jacquard_common::IntoStatic for RequestPhoneVerification<'_> {
+17
-1
crates/jacquard-api/src/com_atproto/temp/revoke_account_credentials.rs
+17
-1
crates/jacquard-api/src/com_atproto/temp/revoke_account_credentials.rs
···
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
8
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
9
+
#[derive(
10
+
serde::Serialize,
11
+
serde::Deserialize,
12
+
Debug,
13
+
Clone,
14
+
PartialEq,
15
+
Eq,
16
+
bon::Builder
17
+
)]
10
18
#[serde(rename_all = "camelCase")]
19
+
#[builder(start_fn = new)]
11
20
pub struct RevokeAccountCredentials<'a> {
12
21
#[serde(borrow)]
13
22
pub account: jacquard_common::types::ident::AtIdentifier<'a>,
23
+
#[serde(flatten)]
24
+
#[serde(borrow)]
25
+
#[builder(default)]
26
+
pub extra_data: ::std::collections::BTreeMap<
27
+
::jacquard_common::smol_str::SmolStr,
28
+
::jacquard_common::types::value::Data<'a>,
29
+
>,
14
30
}
15
31
16
32
impl jacquard_common::IntoStatic for RevokeAccountCredentials<'_> {
+7
crates/jacquard-api/src/lib.rs
+7
crates/jacquard-api/src/lib.rs
···
3
3
// This file was automatically generated from Lexicon schemas.
4
4
// Any manual changes will be overwritten on the next regeneration.
5
5
6
+
#[cfg(feature = "app_bsky")]
6
7
pub mod app_bsky;
8
+
9
+
#[cfg(feature = "chat_bsky")]
7
10
pub mod chat_bsky;
11
+
12
+
#[cfg(feature = "com_atproto")]
8
13
pub mod com_atproto;
14
+
15
+
#[cfg(feature = "tools_ozone")]
9
16
pub mod tools_ozone;
+20
-1
crates/jacquard-api/src/tools_ozone/communication/create_template.rs
+20
-1
crates/jacquard-api/src/tools_ozone/communication/create_template.rs
···
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
8
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
9
+
#[derive(
10
+
serde::Serialize,
11
+
serde::Deserialize,
12
+
Debug,
13
+
Clone,
14
+
PartialEq,
15
+
Eq,
16
+
bon::Builder
17
+
)]
10
18
#[serde(rename_all = "camelCase")]
19
+
#[builder(start_fn = new)]
11
20
pub struct CreateTemplate<'a> {
12
21
///Content of the template, markdown supported, can contain variable placeholders.
13
22
#[serde(borrow)]
23
+
#[builder(into)]
14
24
pub content_markdown: jacquard_common::CowStr<'a>,
15
25
///DID of the user who is creating the template.
16
26
#[serde(skip_serializing_if = "std::option::Option::is_none")]
···
21
31
pub lang: std::option::Option<jacquard_common::types::string::Language>,
22
32
///Name of the template.
23
33
#[serde(borrow)]
34
+
#[builder(into)]
24
35
pub name: jacquard_common::CowStr<'a>,
25
36
///Subject of the message, used in emails.
26
37
#[serde(borrow)]
38
+
#[builder(into)]
27
39
pub subject: jacquard_common::CowStr<'a>,
40
+
#[serde(flatten)]
41
+
#[serde(borrow)]
42
+
#[builder(default)]
43
+
pub extra_data: ::std::collections::BTreeMap<
44
+
::jacquard_common::smol_str::SmolStr,
45
+
::jacquard_common::types::value::Data<'a>,
46
+
>,
28
47
}
29
48
30
49
impl jacquard_common::IntoStatic for CreateTemplate<'_> {
+18
-1
crates/jacquard-api/src/tools_ozone/communication/delete_template.rs
+18
-1
crates/jacquard-api/src/tools_ozone/communication/delete_template.rs
···
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
8
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
9
+
#[derive(
10
+
serde::Serialize,
11
+
serde::Deserialize,
12
+
Debug,
13
+
Clone,
14
+
PartialEq,
15
+
Eq,
16
+
bon::Builder
17
+
)]
10
18
#[serde(rename_all = "camelCase")]
19
+
#[builder(start_fn = new)]
11
20
pub struct DeleteTemplate<'a> {
12
21
#[serde(borrow)]
22
+
#[builder(into)]
13
23
pub id: jacquard_common::CowStr<'a>,
24
+
#[serde(flatten)]
25
+
#[serde(borrow)]
26
+
#[builder(default)]
27
+
pub extra_data: ::std::collections::BTreeMap<
28
+
::jacquard_common::smol_str::SmolStr,
29
+
::jacquard_common::types::value::Data<'a>,
30
+
>,
14
31
}
15
32
16
33
impl jacquard_common::IntoStatic for DeleteTemplate<'_> {
+21
-1
crates/jacquard-api/src/tools_ozone/communication/update_template.rs
+21
-1
crates/jacquard-api/src/tools_ozone/communication/update_template.rs
···
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
8
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
9
+
#[derive(
10
+
serde::Serialize,
11
+
serde::Deserialize,
12
+
Debug,
13
+
Clone,
14
+
PartialEq,
15
+
Eq,
16
+
bon::Builder
17
+
)]
10
18
#[serde(rename_all = "camelCase")]
19
+
#[builder(start_fn = new)]
11
20
pub struct UpdateTemplate<'a> {
12
21
///Content of the template, markdown supported, can contain variable placeholders.
13
22
#[serde(skip_serializing_if = "std::option::Option::is_none")]
14
23
#[serde(borrow)]
24
+
#[builder(into)]
15
25
pub content_markdown: std::option::Option<jacquard_common::CowStr<'a>>,
16
26
#[serde(skip_serializing_if = "std::option::Option::is_none")]
17
27
pub disabled: std::option::Option<bool>,
18
28
///ID of the template to be updated.
19
29
#[serde(borrow)]
30
+
#[builder(into)]
20
31
pub id: jacquard_common::CowStr<'a>,
21
32
///Message language.
22
33
#[serde(skip_serializing_if = "std::option::Option::is_none")]
···
24
35
///Name of the template.
25
36
#[serde(skip_serializing_if = "std::option::Option::is_none")]
26
37
#[serde(borrow)]
38
+
#[builder(into)]
27
39
pub name: std::option::Option<jacquard_common::CowStr<'a>>,
28
40
///Subject of the message, used in emails.
29
41
#[serde(skip_serializing_if = "std::option::Option::is_none")]
30
42
#[serde(borrow)]
43
+
#[builder(into)]
31
44
pub subject: std::option::Option<jacquard_common::CowStr<'a>>,
32
45
///DID of the user who is updating the template.
33
46
#[serde(skip_serializing_if = "std::option::Option::is_none")]
34
47
#[serde(borrow)]
35
48
pub updated_by: std::option::Option<jacquard_common::types::string::Did<'a>>,
49
+
#[serde(flatten)]
50
+
#[serde(borrow)]
51
+
#[builder(default)]
52
+
pub extra_data: ::std::collections::BTreeMap<
53
+
::jacquard_common::smol_str::SmolStr,
54
+
::jacquard_common::types::value::Data<'a>,
55
+
>,
36
56
}
37
57
38
58
impl jacquard_common::IntoStatic for UpdateTemplate<'_> {
+11
-1
crates/jacquard-api/src/tools_ozone/hosting/get_account_history.rs
+11
-1
crates/jacquard-api/src/tools_ozone/hosting/get_account_history.rs
···
121
121
}
122
122
}
123
123
124
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
124
+
#[derive(
125
+
serde::Serialize,
126
+
serde::Deserialize,
127
+
Debug,
128
+
Clone,
129
+
PartialEq,
130
+
Eq,
131
+
bon::Builder
132
+
)]
133
+
#[builder(start_fn = new)]
125
134
#[serde(rename_all = "camelCase")]
126
135
pub struct GetAccountHistory<'a> {
127
136
#[serde(skip_serializing_if = "std::option::Option::is_none")]
128
137
#[serde(borrow)]
138
+
#[builder(into)]
129
139
pub cursor: std::option::Option<jacquard_common::CowStr<'a>>,
130
140
#[serde(borrow)]
131
141
pub did: jacquard_common::types::string::Did<'a>,
+18
-1
crates/jacquard-api/src/tools_ozone/moderation/emit_event.rs
+18
-1
crates/jacquard-api/src/tools_ozone/moderation/emit_event.rs
···
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
8
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
9
+
#[derive(
10
+
serde::Serialize,
11
+
serde::Deserialize,
12
+
Debug,
13
+
Clone,
14
+
PartialEq,
15
+
Eq,
16
+
bon::Builder
17
+
)]
10
18
#[serde(rename_all = "camelCase")]
19
+
#[builder(start_fn = new)]
11
20
pub struct EmitEvent<'a> {
12
21
#[serde(borrow)]
13
22
pub created_by: jacquard_common::types::string::Did<'a>,
···
16
25
///An optional external ID for the event, used to deduplicate events from external systems. Fails when an event of same type with the same external ID exists for the same subject.
17
26
#[serde(skip_serializing_if = "std::option::Option::is_none")]
18
27
#[serde(borrow)]
28
+
#[builder(into)]
19
29
pub external_id: std::option::Option<jacquard_common::CowStr<'a>>,
20
30
#[serde(skip_serializing_if = "std::option::Option::is_none")]
21
31
#[serde(borrow)]
···
26
36
#[serde(borrow)]
27
37
pub subject_blob_cids: std::option::Option<
28
38
Vec<jacquard_common::types::string::Cid<'a>>,
39
+
>,
40
+
#[serde(flatten)]
41
+
#[serde(borrow)]
42
+
#[builder(default)]
43
+
pub extra_data: ::std::collections::BTreeMap<
44
+
::jacquard_common::smol_str::SmolStr,
45
+
::jacquard_common::types::value::Data<'a>,
29
46
>,
30
47
}
31
48
+10
-1
crates/jacquard-api/src/tools_ozone/moderation/get_account_timeline.rs
+10
-1
crates/jacquard-api/src/tools_ozone/moderation/get_account_timeline.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetAccountTimeline<'a> {
11
20
#[serde(borrow)]
+10
-1
crates/jacquard-api/src/tools_ozone/moderation/get_event.rs
+10
-1
crates/jacquard-api/src/tools_ozone/moderation/get_event.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetEvent {
11
20
pub id: i64,
+10
-1
crates/jacquard-api/src/tools_ozone/moderation/get_record.rs
+10
-1
crates/jacquard-api/src/tools_ozone/moderation/get_record.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetRecord<'a> {
11
20
#[serde(skip_serializing_if = "std::option::Option::is_none")]
+10
-1
crates/jacquard-api/src/tools_ozone/moderation/get_records.rs
+10
-1
crates/jacquard-api/src/tools_ozone/moderation/get_records.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetRecords<'a> {
11
20
#[serde(borrow)]
+10
-1
crates/jacquard-api/src/tools_ozone/moderation/get_repo.rs
+10
-1
crates/jacquard-api/src/tools_ozone/moderation/get_repo.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetRepo<'a> {
11
20
#[serde(borrow)]
+10
-1
crates/jacquard-api/src/tools_ozone/moderation/get_reporter_stats.rs
+10
-1
crates/jacquard-api/src/tools_ozone/moderation/get_reporter_stats.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetReporterStats<'a> {
11
20
#[serde(borrow)]
+10
-1
crates/jacquard-api/src/tools_ozone/moderation/get_repos.rs
+10
-1
crates/jacquard-api/src/tools_ozone/moderation/get_repos.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetRepos<'a> {
11
20
#[serde(borrow)]
+10
-1
crates/jacquard-api/src/tools_ozone/moderation/get_subjects.rs
+10
-1
crates/jacquard-api/src/tools_ozone/moderation/get_subjects.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetSubjects<'a> {
11
20
#[serde(borrow)]
+16
-1
crates/jacquard-api/src/tools_ozone/moderation/query_events.rs
+16
-1
crates/jacquard-api/src/tools_ozone/moderation/query_events.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct QueryEvents<'a> {
11
20
#[serde(skip_serializing_if = "std::option::Option::is_none")]
···
16
25
pub added_tags: std::option::Option<Vec<jacquard_common::CowStr<'a>>>,
17
26
#[serde(skip_serializing_if = "std::option::Option::is_none")]
18
27
#[serde(borrow)]
28
+
#[builder(into)]
19
29
pub age_assurance_state: std::option::Option<jacquard_common::CowStr<'a>>,
20
30
#[serde(skip_serializing_if = "std::option::Option::is_none")]
21
31
#[serde(borrow)]
32
+
#[builder(into)]
22
33
pub batch_id: std::option::Option<jacquard_common::CowStr<'a>>,
23
34
#[serde(skip_serializing_if = "std::option::Option::is_none")]
24
35
#[serde(borrow)]
25
36
pub collections: std::option::Option<Vec<jacquard_common::types::string::Nsid<'a>>>,
26
37
#[serde(skip_serializing_if = "std::option::Option::is_none")]
27
38
#[serde(borrow)]
39
+
#[builder(into)]
28
40
pub comment: std::option::Option<jacquard_common::CowStr<'a>>,
29
41
#[serde(skip_serializing_if = "std::option::Option::is_none")]
30
42
pub created_after: std::option::Option<jacquard_common::types::string::Datetime>,
···
35
47
pub created_by: std::option::Option<jacquard_common::types::string::Did<'a>>,
36
48
#[serde(skip_serializing_if = "std::option::Option::is_none")]
37
49
#[serde(borrow)]
50
+
#[builder(into)]
38
51
pub cursor: std::option::Option<jacquard_common::CowStr<'a>>,
39
52
#[serde(skip_serializing_if = "std::option::Option::is_none")]
40
53
pub has_comment: std::option::Option<bool>,
···
62
75
///(default: "desc")
63
76
#[serde(skip_serializing_if = "std::option::Option::is_none")]
64
77
#[serde(borrow)]
78
+
#[builder(into)]
65
79
pub sort_direction: std::option::Option<jacquard_common::CowStr<'a>>,
66
80
#[serde(skip_serializing_if = "std::option::Option::is_none")]
67
81
#[serde(borrow)]
68
82
pub subject: std::option::Option<jacquard_common::types::string::Uri<'a>>,
69
83
#[serde(skip_serializing_if = "std::option::Option::is_none")]
70
84
#[serde(borrow)]
85
+
#[builder(into)]
71
86
pub subject_type: std::option::Option<jacquard_common::CowStr<'a>>,
72
87
#[serde(skip_serializing_if = "std::option::Option::is_none")]
73
88
#[serde(borrow)]
+18
-1
crates/jacquard-api/src/tools_ozone/moderation/query_statuses.rs
+18
-1
crates/jacquard-api/src/tools_ozone/moderation/query_statuses.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct QueryStatuses<'a> {
11
20
#[serde(skip_serializing_if = "std::option::Option::is_none")]
12
21
#[serde(borrow)]
22
+
#[builder(into)]
13
23
pub age_assurance_state: std::option::Option<jacquard_common::CowStr<'a>>,
14
24
#[serde(skip_serializing_if = "std::option::Option::is_none")]
15
25
pub appealed: std::option::Option<bool>,
···
18
28
pub collections: std::option::Option<Vec<jacquard_common::types::string::Nsid<'a>>>,
19
29
#[serde(skip_serializing_if = "std::option::Option::is_none")]
20
30
#[serde(borrow)]
31
+
#[builder(into)]
21
32
pub comment: std::option::Option<jacquard_common::CowStr<'a>>,
22
33
#[serde(skip_serializing_if = "std::option::Option::is_none")]
23
34
#[serde(borrow)]
35
+
#[builder(into)]
24
36
pub cursor: std::option::Option<jacquard_common::CowStr<'a>>,
25
37
#[serde(skip_serializing_if = "std::option::Option::is_none")]
26
38
#[serde(borrow)]
···
76
88
pub queue_index: std::option::Option<i64>,
77
89
#[serde(skip_serializing_if = "std::option::Option::is_none")]
78
90
#[serde(borrow)]
91
+
#[builder(into)]
79
92
pub queue_seed: std::option::Option<jacquard_common::CowStr<'a>>,
80
93
#[serde(skip_serializing_if = "std::option::Option::is_none")]
81
94
pub reported_after: std::option::Option<jacquard_common::types::string::Datetime>,
···
83
96
pub reported_before: std::option::Option<jacquard_common::types::string::Datetime>,
84
97
#[serde(skip_serializing_if = "std::option::Option::is_none")]
85
98
#[serde(borrow)]
99
+
#[builder(into)]
86
100
pub review_state: std::option::Option<jacquard_common::CowStr<'a>>,
87
101
#[serde(skip_serializing_if = "std::option::Option::is_none")]
88
102
pub reviewed_after: std::option::Option<jacquard_common::types::string::Datetime>,
···
91
105
///(default: "desc")
92
106
#[serde(skip_serializing_if = "std::option::Option::is_none")]
93
107
#[serde(borrow)]
108
+
#[builder(into)]
94
109
pub sort_direction: std::option::Option<jacquard_common::CowStr<'a>>,
95
110
///(default: "lastReportedAt")
96
111
#[serde(skip_serializing_if = "std::option::Option::is_none")]
97
112
#[serde(borrow)]
113
+
#[builder(into)]
98
114
pub sort_field: std::option::Option<jacquard_common::CowStr<'a>>,
99
115
#[serde(skip_serializing_if = "std::option::Option::is_none")]
100
116
#[serde(borrow)]
101
117
pub subject: std::option::Option<jacquard_common::types::string::Uri<'a>>,
102
118
#[serde(skip_serializing_if = "std::option::Option::is_none")]
103
119
#[serde(borrow)]
120
+
#[builder(into)]
104
121
pub subject_type: std::option::Option<jacquard_common::CowStr<'a>>,
105
122
#[serde(skip_serializing_if = "std::option::Option::is_none")]
106
123
#[serde(borrow)]
+13
-1
crates/jacquard-api/src/tools_ozone/moderation/search_repos.rs
+13
-1
crates/jacquard-api/src/tools_ozone/moderation/search_repos.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct SearchRepos<'a> {
11
20
#[serde(skip_serializing_if = "std::option::Option::is_none")]
12
21
#[serde(borrow)]
22
+
#[builder(into)]
13
23
pub cursor: std::option::Option<jacquard_common::CowStr<'a>>,
14
24
///(default: 50, min: 1, max: 100)
15
25
#[serde(skip_serializing_if = "std::option::Option::is_none")]
16
26
pub limit: std::option::Option<i64>,
17
27
#[serde(skip_serializing_if = "std::option::Option::is_none")]
18
28
#[serde(borrow)]
29
+
#[builder(into)]
19
30
pub q: std::option::Option<jacquard_common::CowStr<'a>>,
20
31
#[serde(skip_serializing_if = "std::option::Option::is_none")]
21
32
#[serde(borrow)]
33
+
#[builder(into)]
22
34
pub term: std::option::Option<jacquard_common::CowStr<'a>>,
23
35
}
24
36
+19
-1
crates/jacquard-api/src/tools_ozone/safelink/add_rule.rs
+19
-1
crates/jacquard-api/src/tools_ozone/safelink/add_rule.rs
···
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
8
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
9
+
#[derive(
10
+
serde::Serialize,
11
+
serde::Deserialize,
12
+
Debug,
13
+
Clone,
14
+
PartialEq,
15
+
Eq,
16
+
bon::Builder
17
+
)]
10
18
#[serde(rename_all = "camelCase")]
19
+
#[builder(start_fn = new)]
11
20
pub struct AddRule<'a> {
12
21
#[serde(borrow)]
13
22
pub action: crate::tools_ozone::safelink::ActionType<'a>,
14
23
///Optional comment about the decision
15
24
#[serde(skip_serializing_if = "std::option::Option::is_none")]
16
25
#[serde(borrow)]
26
+
#[builder(into)]
17
27
pub comment: std::option::Option<jacquard_common::CowStr<'a>>,
18
28
///Author DID. Only respected when using admin auth
19
29
#[serde(skip_serializing_if = "std::option::Option::is_none")]
···
25
35
pub reason: crate::tools_ozone::safelink::ReasonType<'a>,
26
36
///The URL or domain to apply the rule to
27
37
#[serde(borrow)]
38
+
#[builder(into)]
28
39
pub url: jacquard_common::CowStr<'a>,
40
+
#[serde(flatten)]
41
+
#[serde(borrow)]
42
+
#[builder(default)]
43
+
pub extra_data: ::std::collections::BTreeMap<
44
+
::jacquard_common::smol_str::SmolStr,
45
+
::jacquard_common::types::value::Data<'a>,
46
+
>,
29
47
}
30
48
31
49
impl jacquard_common::IntoStatic for AddRule<'_> {
+20
-1
crates/jacquard-api/src/tools_ozone/safelink/query_events.rs
+20
-1
crates/jacquard-api/src/tools_ozone/safelink/query_events.rs
···
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
8
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
9
+
#[derive(
10
+
serde::Serialize,
11
+
serde::Deserialize,
12
+
Debug,
13
+
Clone,
14
+
PartialEq,
15
+
Eq,
16
+
bon::Builder
17
+
)]
10
18
#[serde(rename_all = "camelCase")]
19
+
#[builder(start_fn = new)]
11
20
pub struct QueryEvents<'a> {
12
21
///Cursor for pagination
13
22
#[serde(skip_serializing_if = "std::option::Option::is_none")]
14
23
#[serde(borrow)]
24
+
#[builder(into)]
15
25
pub cursor: std::option::Option<jacquard_common::CowStr<'a>>,
16
26
///Maximum number of results to return
17
27
#[serde(skip_serializing_if = "std::option::Option::is_none")]
···
19
29
///Filter by pattern type
20
30
#[serde(skip_serializing_if = "std::option::Option::is_none")]
21
31
#[serde(borrow)]
32
+
#[builder(into)]
22
33
pub pattern_type: std::option::Option<jacquard_common::CowStr<'a>>,
23
34
///Sort direction
24
35
#[serde(skip_serializing_if = "std::option::Option::is_none")]
25
36
#[serde(borrow)]
37
+
#[builder(into)]
26
38
pub sort_direction: std::option::Option<jacquard_common::CowStr<'a>>,
27
39
///Filter by specific URLs or domains
28
40
#[serde(skip_serializing_if = "std::option::Option::is_none")]
29
41
#[serde(borrow)]
30
42
pub urls: std::option::Option<Vec<jacquard_common::CowStr<'a>>>,
43
+
#[serde(flatten)]
44
+
#[serde(borrow)]
45
+
#[builder(default)]
46
+
pub extra_data: ::std::collections::BTreeMap<
47
+
::jacquard_common::smol_str::SmolStr,
48
+
::jacquard_common::types::value::Data<'a>,
49
+
>,
31
50
}
32
51
33
52
impl jacquard_common::IntoStatic for QueryEvents<'_> {
+21
-1
crates/jacquard-api/src/tools_ozone/safelink/query_rules.rs
+21
-1
crates/jacquard-api/src/tools_ozone/safelink/query_rules.rs
···
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
8
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
9
+
#[derive(
10
+
serde::Serialize,
11
+
serde::Deserialize,
12
+
Debug,
13
+
Clone,
14
+
PartialEq,
15
+
Eq,
16
+
bon::Builder
17
+
)]
10
18
#[serde(rename_all = "camelCase")]
19
+
#[builder(start_fn = new)]
11
20
pub struct QueryRules<'a> {
12
21
///Filter by action types
13
22
#[serde(skip_serializing_if = "std::option::Option::is_none")]
···
20
29
///Cursor for pagination
21
30
#[serde(skip_serializing_if = "std::option::Option::is_none")]
22
31
#[serde(borrow)]
32
+
#[builder(into)]
23
33
pub cursor: std::option::Option<jacquard_common::CowStr<'a>>,
24
34
///Maximum number of results to return
25
35
#[serde(skip_serializing_if = "std::option::Option::is_none")]
···
27
37
///Filter by pattern type
28
38
#[serde(skip_serializing_if = "std::option::Option::is_none")]
29
39
#[serde(borrow)]
40
+
#[builder(into)]
30
41
pub pattern_type: std::option::Option<jacquard_common::CowStr<'a>>,
31
42
///Filter by reason type
32
43
#[serde(skip_serializing_if = "std::option::Option::is_none")]
33
44
#[serde(borrow)]
45
+
#[builder(into)]
34
46
pub reason: std::option::Option<jacquard_common::CowStr<'a>>,
35
47
///Sort direction
36
48
#[serde(skip_serializing_if = "std::option::Option::is_none")]
37
49
#[serde(borrow)]
50
+
#[builder(into)]
38
51
pub sort_direction: std::option::Option<jacquard_common::CowStr<'a>>,
39
52
///Filter by specific URLs or domains
40
53
#[serde(skip_serializing_if = "std::option::Option::is_none")]
41
54
#[serde(borrow)]
42
55
pub urls: std::option::Option<Vec<jacquard_common::CowStr<'a>>>,
56
+
#[serde(flatten)]
57
+
#[serde(borrow)]
58
+
#[builder(default)]
59
+
pub extra_data: ::std::collections::BTreeMap<
60
+
::jacquard_common::smol_str::SmolStr,
61
+
::jacquard_common::types::value::Data<'a>,
62
+
>,
43
63
}
44
64
45
65
impl jacquard_common::IntoStatic for QueryRules<'_> {
+19
-1
crates/jacquard-api/src/tools_ozone/safelink/remove_rule.rs
+19
-1
crates/jacquard-api/src/tools_ozone/safelink/remove_rule.rs
···
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
8
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
9
+
#[derive(
10
+
serde::Serialize,
11
+
serde::Deserialize,
12
+
Debug,
13
+
Clone,
14
+
PartialEq,
15
+
Eq,
16
+
bon::Builder
17
+
)]
10
18
#[serde(rename_all = "camelCase")]
19
+
#[builder(start_fn = new)]
11
20
pub struct RemoveRule<'a> {
12
21
///Optional comment about why the rule is being removed
13
22
#[serde(skip_serializing_if = "std::option::Option::is_none")]
14
23
#[serde(borrow)]
24
+
#[builder(into)]
15
25
pub comment: std::option::Option<jacquard_common::CowStr<'a>>,
16
26
///Optional DID of the user. Only respected when using admin auth.
17
27
#[serde(skip_serializing_if = "std::option::Option::is_none")]
···
21
31
pub pattern: crate::tools_ozone::safelink::PatternType<'a>,
22
32
///The URL or domain to remove the rule for
23
33
#[serde(borrow)]
34
+
#[builder(into)]
24
35
pub url: jacquard_common::CowStr<'a>,
36
+
#[serde(flatten)]
37
+
#[serde(borrow)]
38
+
#[builder(default)]
39
+
pub extra_data: ::std::collections::BTreeMap<
40
+
::jacquard_common::smol_str::SmolStr,
41
+
::jacquard_common::types::value::Data<'a>,
42
+
>,
25
43
}
26
44
27
45
impl jacquard_common::IntoStatic for RemoveRule<'_> {
+19
-1
crates/jacquard-api/src/tools_ozone/safelink/update_rule.rs
+19
-1
crates/jacquard-api/src/tools_ozone/safelink/update_rule.rs
···
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
8
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
9
+
#[derive(
10
+
serde::Serialize,
11
+
serde::Deserialize,
12
+
Debug,
13
+
Clone,
14
+
PartialEq,
15
+
Eq,
16
+
bon::Builder
17
+
)]
10
18
#[serde(rename_all = "camelCase")]
19
+
#[builder(start_fn = new)]
11
20
pub struct UpdateRule<'a> {
12
21
#[serde(borrow)]
13
22
pub action: crate::tools_ozone::safelink::ActionType<'a>,
14
23
///Optional comment about the update
15
24
#[serde(skip_serializing_if = "std::option::Option::is_none")]
16
25
#[serde(borrow)]
26
+
#[builder(into)]
17
27
pub comment: std::option::Option<jacquard_common::CowStr<'a>>,
18
28
///Optional DID to credit as the creator. Only respected for admin_token authentication.
19
29
#[serde(skip_serializing_if = "std::option::Option::is_none")]
···
25
35
pub reason: crate::tools_ozone::safelink::ReasonType<'a>,
26
36
///The URL or domain to update the rule for
27
37
#[serde(borrow)]
38
+
#[builder(into)]
28
39
pub url: jacquard_common::CowStr<'a>,
40
+
#[serde(flatten)]
41
+
#[serde(borrow)]
42
+
#[builder(default)]
43
+
pub extra_data: ::std::collections::BTreeMap<
44
+
::jacquard_common::smol_str::SmolStr,
45
+
::jacquard_common::types::value::Data<'a>,
46
+
>,
29
47
}
30
48
31
49
impl jacquard_common::IntoStatic for UpdateRule<'_> {
+18
-1
crates/jacquard-api/src/tools_ozone/set/add_values.rs
+18
-1
crates/jacquard-api/src/tools_ozone/set/add_values.rs
···
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
8
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
9
+
#[derive(
10
+
serde::Serialize,
11
+
serde::Deserialize,
12
+
Debug,
13
+
Clone,
14
+
PartialEq,
15
+
Eq,
16
+
bon::Builder
17
+
)]
10
18
#[serde(rename_all = "camelCase")]
19
+
#[builder(start_fn = new)]
11
20
pub struct AddValues<'a> {
12
21
///Name of the set to add values to
13
22
#[serde(borrow)]
23
+
#[builder(into)]
14
24
pub name: jacquard_common::CowStr<'a>,
15
25
///Array of string values to add to the set
16
26
#[serde(borrow)]
17
27
pub values: Vec<jacquard_common::CowStr<'a>>,
28
+
#[serde(flatten)]
29
+
#[serde(borrow)]
30
+
#[builder(default)]
31
+
pub extra_data: ::std::collections::BTreeMap<
32
+
::jacquard_common::smol_str::SmolStr,
33
+
::jacquard_common::types::value::Data<'a>,
34
+
>,
18
35
}
19
36
20
37
impl jacquard_common::IntoStatic for AddValues<'_> {
+18
-1
crates/jacquard-api/src/tools_ozone/set/delete_set.rs
+18
-1
crates/jacquard-api/src/tools_ozone/set/delete_set.rs
···
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
8
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
9
+
#[derive(
10
+
serde::Serialize,
11
+
serde::Deserialize,
12
+
Debug,
13
+
Clone,
14
+
PartialEq,
15
+
Eq,
16
+
bon::Builder
17
+
)]
10
18
#[serde(rename_all = "camelCase")]
19
+
#[builder(start_fn = new)]
11
20
pub struct DeleteSet<'a> {
12
21
///Name of the set to delete
13
22
#[serde(borrow)]
23
+
#[builder(into)]
14
24
pub name: jacquard_common::CowStr<'a>,
25
+
#[serde(flatten)]
26
+
#[serde(borrow)]
27
+
#[builder(default)]
28
+
pub extra_data: ::std::collections::BTreeMap<
29
+
::jacquard_common::smol_str::SmolStr,
30
+
::jacquard_common::types::value::Data<'a>,
31
+
>,
15
32
}
16
33
17
34
impl jacquard_common::IntoStatic for DeleteSet<'_> {
+18
-1
crates/jacquard-api/src/tools_ozone/set/delete_values.rs
+18
-1
crates/jacquard-api/src/tools_ozone/set/delete_values.rs
···
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
8
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
9
+
#[derive(
10
+
serde::Serialize,
11
+
serde::Deserialize,
12
+
Debug,
13
+
Clone,
14
+
PartialEq,
15
+
Eq,
16
+
bon::Builder
17
+
)]
10
18
#[serde(rename_all = "camelCase")]
19
+
#[builder(start_fn = new)]
11
20
pub struct DeleteValues<'a> {
12
21
///Name of the set to delete values from
13
22
#[serde(borrow)]
23
+
#[builder(into)]
14
24
pub name: jacquard_common::CowStr<'a>,
15
25
///Array of string values to delete from the set
16
26
#[serde(borrow)]
17
27
pub values: Vec<jacquard_common::CowStr<'a>>,
28
+
#[serde(flatten)]
29
+
#[serde(borrow)]
30
+
#[builder(default)]
31
+
pub extra_data: ::std::collections::BTreeMap<
32
+
::jacquard_common::smol_str::SmolStr,
33
+
::jacquard_common::types::value::Data<'a>,
34
+
>,
18
35
}
19
36
20
37
impl jacquard_common::IntoStatic for DeleteValues<'_> {
+12
-1
crates/jacquard-api/src/tools_ozone/set/get_values.rs
+12
-1
crates/jacquard-api/src/tools_ozone/set/get_values.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct GetValues<'a> {
11
20
#[serde(skip_serializing_if = "std::option::Option::is_none")]
12
21
#[serde(borrow)]
22
+
#[builder(into)]
13
23
pub cursor: std::option::Option<jacquard_common::CowStr<'a>>,
14
24
///(default: 100, min: 1, max: 1000)
15
25
#[serde(skip_serializing_if = "std::option::Option::is_none")]
16
26
pub limit: std::option::Option<i64>,
17
27
#[serde(borrow)]
28
+
#[builder(into)]
18
29
pub name: jacquard_common::CowStr<'a>,
19
30
}
20
31
+14
-1
crates/jacquard-api/src/tools_ozone/set/query_sets.rs
+14
-1
crates/jacquard-api/src/tools_ozone/set/query_sets.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct QuerySets<'a> {
11
20
#[serde(skip_serializing_if = "std::option::Option::is_none")]
12
21
#[serde(borrow)]
22
+
#[builder(into)]
13
23
pub cursor: std::option::Option<jacquard_common::CowStr<'a>>,
14
24
///(default: 50, min: 1, max: 100)
15
25
#[serde(skip_serializing_if = "std::option::Option::is_none")]
16
26
pub limit: std::option::Option<i64>,
17
27
#[serde(skip_serializing_if = "std::option::Option::is_none")]
18
28
#[serde(borrow)]
29
+
#[builder(into)]
19
30
pub name_prefix: std::option::Option<jacquard_common::CowStr<'a>>,
20
31
///(default: "name")
21
32
#[serde(skip_serializing_if = "std::option::Option::is_none")]
22
33
#[serde(borrow)]
34
+
#[builder(into)]
23
35
pub sort_by: std::option::Option<jacquard_common::CowStr<'a>>,
24
36
///(default: "asc")
25
37
#[serde(skip_serializing_if = "std::option::Option::is_none")]
26
38
#[serde(borrow)]
39
+
#[builder(into)]
27
40
pub sort_direction: std::option::Option<jacquard_common::CowStr<'a>>,
28
41
}
29
42
+17
-1
crates/jacquard-api/src/tools_ozone/set/upsert_set.rs
+17
-1
crates/jacquard-api/src/tools_ozone/set/upsert_set.rs
···
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
8
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
9
+
#[derive(
10
+
serde::Serialize,
11
+
serde::Deserialize,
12
+
Debug,
13
+
Clone,
14
+
PartialEq,
15
+
Eq,
16
+
bon::Builder
17
+
)]
10
18
#[serde(rename_all = "camelCase")]
19
+
#[builder(start_fn = new)]
11
20
pub struct UpsertSet<'a> {
12
21
#[serde(flatten)]
13
22
#[serde(borrow)]
14
23
pub value: crate::tools_ozone::set::Set<'a>,
24
+
#[serde(flatten)]
25
+
#[serde(borrow)]
26
+
#[builder(default)]
27
+
pub extra_data: ::std::collections::BTreeMap<
28
+
::jacquard_common::smol_str::SmolStr,
29
+
::jacquard_common::types::value::Data<'a>,
30
+
>,
15
31
}
16
32
17
33
impl jacquard_common::IntoStatic for UpsertSet<'_> {
+13
-1
crates/jacquard-api/src/tools_ozone/setting/list_options.rs
+13
-1
crates/jacquard-api/src/tools_ozone/setting/list_options.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct ListOptions<'a> {
11
20
#[serde(skip_serializing_if = "std::option::Option::is_none")]
12
21
#[serde(borrow)]
22
+
#[builder(into)]
13
23
pub cursor: std::option::Option<jacquard_common::CowStr<'a>>,
14
24
#[serde(skip_serializing_if = "std::option::Option::is_none")]
15
25
#[serde(borrow)]
···
19
29
pub limit: std::option::Option<i64>,
20
30
#[serde(skip_serializing_if = "std::option::Option::is_none")]
21
31
#[serde(borrow)]
32
+
#[builder(into)]
22
33
pub prefix: std::option::Option<jacquard_common::CowStr<'a>>,
23
34
///(default: "instance")
24
35
#[serde(skip_serializing_if = "std::option::Option::is_none")]
25
36
#[serde(borrow)]
37
+
#[builder(into)]
26
38
pub scope: std::option::Option<jacquard_common::CowStr<'a>>,
27
39
}
28
40
+18
-1
crates/jacquard-api/src/tools_ozone/setting/remove_options.rs
+18
-1
crates/jacquard-api/src/tools_ozone/setting/remove_options.rs
···
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
8
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
9
+
#[derive(
10
+
serde::Serialize,
11
+
serde::Deserialize,
12
+
Debug,
13
+
Clone,
14
+
PartialEq,
15
+
Eq,
16
+
bon::Builder
17
+
)]
10
18
#[serde(rename_all = "camelCase")]
19
+
#[builder(start_fn = new)]
11
20
pub struct RemoveOptions<'a> {
12
21
#[serde(borrow)]
13
22
pub keys: Vec<jacquard_common::types::string::Nsid<'a>>,
14
23
#[serde(borrow)]
24
+
#[builder(into)]
15
25
pub scope: jacquard_common::CowStr<'a>,
26
+
#[serde(flatten)]
27
+
#[serde(borrow)]
28
+
#[builder(default)]
29
+
pub extra_data: ::std::collections::BTreeMap<
30
+
::jacquard_common::smol_str::SmolStr,
31
+
::jacquard_common::types::value::Data<'a>,
32
+
>,
16
33
}
17
34
18
35
impl jacquard_common::IntoStatic for RemoveOptions<'_> {
+20
-1
crates/jacquard-api/src/tools_ozone/setting/upsert_option.rs
+20
-1
crates/jacquard-api/src/tools_ozone/setting/upsert_option.rs
···
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
8
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
9
+
#[derive(
10
+
serde::Serialize,
11
+
serde::Deserialize,
12
+
Debug,
13
+
Clone,
14
+
PartialEq,
15
+
Eq,
16
+
bon::Builder
17
+
)]
10
18
#[serde(rename_all = "camelCase")]
19
+
#[builder(start_fn = new)]
11
20
pub struct UpsertOption<'a> {
12
21
#[serde(skip_serializing_if = "std::option::Option::is_none")]
13
22
#[serde(borrow)]
23
+
#[builder(into)]
14
24
pub description: std::option::Option<jacquard_common::CowStr<'a>>,
15
25
#[serde(borrow)]
16
26
pub key: jacquard_common::types::string::Nsid<'a>,
17
27
#[serde(skip_serializing_if = "std::option::Option::is_none")]
18
28
#[serde(borrow)]
29
+
#[builder(into)]
19
30
pub manager_role: std::option::Option<jacquard_common::CowStr<'a>>,
20
31
#[serde(borrow)]
32
+
#[builder(into)]
21
33
pub scope: jacquard_common::CowStr<'a>,
22
34
#[serde(borrow)]
23
35
pub value: jacquard_common::types::value::Data<'a>,
36
+
#[serde(flatten)]
37
+
#[serde(borrow)]
38
+
#[builder(default)]
39
+
pub extra_data: ::std::collections::BTreeMap<
40
+
::jacquard_common::smol_str::SmolStr,
41
+
::jacquard_common::types::value::Data<'a>,
42
+
>,
24
43
}
25
44
26
45
impl jacquard_common::IntoStatic for UpsertOption<'_> {
+10
-1
crates/jacquard-api/src/tools_ozone/signature/find_correlation.rs
+10
-1
crates/jacquard-api/src/tools_ozone/signature/find_correlation.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct FindCorrelation<'a> {
11
20
#[serde(borrow)]
+11
-1
crates/jacquard-api/src/tools_ozone/signature/search_accounts.rs
+11
-1
crates/jacquard-api/src/tools_ozone/signature/search_accounts.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct SearchAccounts<'a> {
11
20
#[serde(skip_serializing_if = "std::option::Option::is_none")]
12
21
#[serde(borrow)]
22
+
#[builder(into)]
13
23
pub cursor: std::option::Option<jacquard_common::CowStr<'a>>,
14
24
///(default: 50, min: 1, max: 100)
15
25
#[serde(skip_serializing_if = "std::option::Option::is_none")]
+18
-1
crates/jacquard-api/src/tools_ozone/team/add_member.rs
+18
-1
crates/jacquard-api/src/tools_ozone/team/add_member.rs
···
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
8
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
9
+
#[derive(
10
+
serde::Serialize,
11
+
serde::Deserialize,
12
+
Debug,
13
+
Clone,
14
+
PartialEq,
15
+
Eq,
16
+
bon::Builder
17
+
)]
10
18
#[serde(rename_all = "camelCase")]
19
+
#[builder(start_fn = new)]
11
20
pub struct AddMember<'a> {
12
21
#[serde(borrow)]
13
22
pub did: jacquard_common::types::string::Did<'a>,
14
23
#[serde(borrow)]
24
+
#[builder(into)]
15
25
pub role: jacquard_common::CowStr<'a>,
26
+
#[serde(flatten)]
27
+
#[serde(borrow)]
28
+
#[builder(default)]
29
+
pub extra_data: ::std::collections::BTreeMap<
30
+
::jacquard_common::smol_str::SmolStr,
31
+
::jacquard_common::types::value::Data<'a>,
32
+
>,
16
33
}
17
34
18
35
impl jacquard_common::IntoStatic for AddMember<'_> {
+17
-1
crates/jacquard-api/src/tools_ozone/team/delete_member.rs
+17
-1
crates/jacquard-api/src/tools_ozone/team/delete_member.rs
···
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
8
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
9
+
#[derive(
10
+
serde::Serialize,
11
+
serde::Deserialize,
12
+
Debug,
13
+
Clone,
14
+
PartialEq,
15
+
Eq,
16
+
bon::Builder
17
+
)]
10
18
#[serde(rename_all = "camelCase")]
19
+
#[builder(start_fn = new)]
11
20
pub struct DeleteMember<'a> {
12
21
#[serde(borrow)]
13
22
pub did: jacquard_common::types::string::Did<'a>,
23
+
#[serde(flatten)]
24
+
#[serde(borrow)]
25
+
#[builder(default)]
26
+
pub extra_data: ::std::collections::BTreeMap<
27
+
::jacquard_common::smol_str::SmolStr,
28
+
::jacquard_common::types::value::Data<'a>,
29
+
>,
14
30
}
15
31
16
32
impl jacquard_common::IntoStatic for DeleteMember<'_> {
+12
-1
crates/jacquard-api/src/tools_ozone/team/list_members.rs
+12
-1
crates/jacquard-api/src/tools_ozone/team/list_members.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct ListMembers<'a> {
11
20
#[serde(skip_serializing_if = "std::option::Option::is_none")]
12
21
#[serde(borrow)]
22
+
#[builder(into)]
13
23
pub cursor: std::option::Option<jacquard_common::CowStr<'a>>,
14
24
#[serde(skip_serializing_if = "std::option::Option::is_none")]
15
25
pub disabled: std::option::Option<bool>,
···
18
28
pub limit: std::option::Option<i64>,
19
29
#[serde(skip_serializing_if = "std::option::Option::is_none")]
20
30
#[serde(borrow)]
31
+
#[builder(into)]
21
32
pub q: std::option::Option<jacquard_common::CowStr<'a>>,
22
33
#[serde(skip_serializing_if = "std::option::Option::is_none")]
23
34
#[serde(borrow)]
+18
-1
crates/jacquard-api/src/tools_ozone/team/update_member.rs
+18
-1
crates/jacquard-api/src/tools_ozone/team/update_member.rs
···
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
8
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
9
+
#[derive(
10
+
serde::Serialize,
11
+
serde::Deserialize,
12
+
Debug,
13
+
Clone,
14
+
PartialEq,
15
+
Eq,
16
+
bon::Builder
17
+
)]
10
18
#[serde(rename_all = "camelCase")]
19
+
#[builder(start_fn = new)]
11
20
pub struct UpdateMember<'a> {
12
21
#[serde(borrow)]
13
22
pub did: jacquard_common::types::string::Did<'a>,
···
15
24
pub disabled: std::option::Option<bool>,
16
25
#[serde(skip_serializing_if = "std::option::Option::is_none")]
17
26
#[serde(borrow)]
27
+
#[builder(into)]
18
28
pub role: std::option::Option<jacquard_common::CowStr<'a>>,
29
+
#[serde(flatten)]
30
+
#[serde(borrow)]
31
+
#[builder(default)]
32
+
pub extra_data: ::std::collections::BTreeMap<
33
+
::jacquard_common::smol_str::SmolStr,
34
+
::jacquard_common::types::value::Data<'a>,
35
+
>,
19
36
}
20
37
21
38
impl jacquard_common::IntoStatic for UpdateMember<'_> {
+17
-1
crates/jacquard-api/src/tools_ozone/verification/grant_verifications.rs
+17
-1
crates/jacquard-api/src/tools_ozone/verification/grant_verifications.rs
···
30
30
}
31
31
32
32
#[jacquard_derive::lexicon]
33
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
33
+
#[derive(
34
+
serde::Serialize,
35
+
serde::Deserialize,
36
+
Debug,
37
+
Clone,
38
+
PartialEq,
39
+
Eq,
40
+
bon::Builder
41
+
)]
34
42
#[serde(rename_all = "camelCase")]
43
+
#[builder(start_fn = new)]
35
44
pub struct GrantVerifications<'a> {
36
45
///Array of verification requests to process
37
46
#[serde(borrow)]
38
47
pub verifications: Vec<jacquard_common::types::value::Data<'a>>,
48
+
#[serde(flatten)]
49
+
#[serde(borrow)]
50
+
#[builder(default)]
51
+
pub extra_data: ::std::collections::BTreeMap<
52
+
::jacquard_common::smol_str::SmolStr,
53
+
::jacquard_common::types::value::Data<'a>,
54
+
>,
39
55
}
40
56
41
57
impl jacquard_common::IntoStatic for GrantVerifications<'_> {
+12
-1
crates/jacquard-api/src/tools_ozone/verification/list_verifications.rs
+12
-1
crates/jacquard-api/src/tools_ozone/verification/list_verifications.rs
···
5
5
// This file was automatically generated from Lexicon schemas.
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
+
#[derive(
9
+
serde::Serialize,
10
+
serde::Deserialize,
11
+
Debug,
12
+
Clone,
13
+
PartialEq,
14
+
Eq,
15
+
bon::Builder
16
+
)]
17
+
#[builder(start_fn = new)]
9
18
#[serde(rename_all = "camelCase")]
10
19
pub struct ListVerifications<'a> {
11
20
#[serde(skip_serializing_if = "std::option::Option::is_none")]
···
14
23
pub created_before: std::option::Option<jacquard_common::types::string::Datetime>,
15
24
#[serde(skip_serializing_if = "std::option::Option::is_none")]
16
25
#[serde(borrow)]
26
+
#[builder(into)]
17
27
pub cursor: std::option::Option<jacquard_common::CowStr<'a>>,
18
28
#[serde(skip_serializing_if = "std::option::Option::is_none")]
19
29
pub is_revoked: std::option::Option<bool>,
···
26
36
///(default: "desc")
27
37
#[serde(skip_serializing_if = "std::option::Option::is_none")]
28
38
#[serde(borrow)]
39
+
#[builder(into)]
29
40
pub sort_direction: std::option::Option<jacquard_common::CowStr<'a>>,
30
41
#[serde(skip_serializing_if = "std::option::Option::is_none")]
31
42
#[serde(borrow)]
+18
-1
crates/jacquard-api/src/tools_ozone/verification/revoke_verifications.rs
+18
-1
crates/jacquard-api/src/tools_ozone/verification/revoke_verifications.rs
···
6
6
// Any manual changes will be overwritten on the next regeneration.
7
7
8
8
#[jacquard_derive::lexicon]
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
9
+
#[derive(
10
+
serde::Serialize,
11
+
serde::Deserialize,
12
+
Debug,
13
+
Clone,
14
+
PartialEq,
15
+
Eq,
16
+
bon::Builder
17
+
)]
10
18
#[serde(rename_all = "camelCase")]
19
+
#[builder(start_fn = new)]
11
20
pub struct RevokeVerifications<'a> {
12
21
///Reason for revoking the verification. This is optional and can be omitted if not needed.
13
22
#[serde(skip_serializing_if = "std::option::Option::is_none")]
14
23
#[serde(borrow)]
24
+
#[builder(into)]
15
25
pub revoke_reason: std::option::Option<jacquard_common::CowStr<'a>>,
16
26
///Array of verification record uris to revoke
17
27
#[serde(borrow)]
18
28
pub uris: Vec<jacquard_common::types::string::AtUri<'a>>,
29
+
#[serde(flatten)]
30
+
#[serde(borrow)]
31
+
#[builder(default)]
32
+
pub extra_data: ::std::collections::BTreeMap<
33
+
::jacquard_common::smol_str::SmolStr,
34
+
::jacquard_common::types::value::Data<'a>,
35
+
>,
19
36
}
20
37
21
38
impl jacquard_common::IntoStatic for RevokeVerifications<'_> {
+11
-12
crates/jacquard-common/Cargo.toml
+11
-12
crates/jacquard-common/Cargo.toml
···
1
1
[package]
2
2
name = "jacquard-common"
3
+
description = "Core AT Protocol types and utilities for Jacquard"
3
4
edition.workspace = true
4
5
version.workspace = true
5
6
authors.workspace = true
···
7
8
keywords.workspace = true
8
9
categories.workspace = true
9
10
readme.workspace = true
10
-
documentation.workspace = true
11
11
exclude.workspace = true
12
-
description.workspace = true
13
-
12
+
license-file.workspace = true
14
13
15
14
16
15
[dependencies]
17
16
base64 = "0.22.1"
18
-
bytes = "1.10.1"
17
+
bytes.workspace = true
19
18
chrono = "0.4.42"
20
19
cid = { version = "0.11.1", features = ["serde", "std"] }
21
20
enum_dispatch = "0.3.13"
22
21
ipld-core = { version = "0.4.2", features = ["serde"] }
23
22
langtag = { version = "0.4.0", features = ["serde"] }
24
-
miette = "7.6.0"
23
+
miette.workspace = true
25
24
multibase = "0.9.1"
26
25
multihash = "0.19.3"
27
26
num-traits = "0.2.19"
28
27
ouroboros = "0.18.5"
29
28
rand = "0.9.2"
30
29
regex = "1.11.3"
31
-
serde = { version = "1.0.227", features = ["derive"] }
32
-
serde_html_form = "0.2.8"
33
-
serde_json = "1.0.145"
34
-
serde_with = "3.14.1"
35
-
smol_str = { version = "0.3.2", features = ["serde"] }
36
-
thiserror = "2.0.16"
37
-
url = "2.5.7"
30
+
serde.workspace = true
31
+
serde_html_form.workspace = true
32
+
serde_json.workspace = true
33
+
serde_with.workspace = true
34
+
smol_str.workspace = true
35
+
thiserror.workspace = true
36
+
url.workspace = true
+11
-5
crates/jacquard-common/src/cowstr.rs
+11
-5
crates/jacquard-common/src/cowstr.rs
···
9
9
10
10
use crate::IntoStatic;
11
11
12
-
/// Shamelessly copied from https://github.com/bearcove/merde
12
+
/// Shamelessly copied from [](https://github.com/bearcove/merde)
13
13
/// A copy-on-write immutable string type that uses [`SmolStr`] for
14
14
/// the "owned" variant.
15
15
///
···
17
17
/// `<str as ToOwned>::Owned` is `String`, and not `SmolStr`.
18
18
#[derive(Clone)]
19
19
pub enum CowStr<'s> {
20
+
/// &str varaiant
20
21
Borrowed(&'s str),
22
+
/// Smolstr variant
21
23
Owned(SmolStr),
22
24
}
23
25
24
26
impl CowStr<'static> {
25
27
/// Create a new `CowStr` by copying from a `&str` โ this might allocate
26
-
/// if the `compact_str` feature is disabled, or if the string is longer
27
-
/// than `MAX_INLINE_SIZE`.
28
+
/// if the string is longer than `MAX_INLINE_SIZE`.
28
29
pub fn copy_from_str(s: &str) -> Self {
29
30
Self::Owned(SmolStr::from(s))
30
31
}
31
32
33
+
/// Create a new owned `CowStr` from a static &str without allocating
32
34
pub fn new_static(s: &'static str) -> Self {
33
35
Self::Owned(SmolStr::new_static(s))
34
36
}
···
36
38
37
39
impl<'s> CowStr<'s> {
38
40
#[inline]
41
+
/// Borrow and decode a byte slice as utf8 into a CowStr
39
42
pub fn from_utf8(s: &'s [u8]) -> Result<Self, std::str::Utf8Error> {
40
43
Ok(Self::Borrowed(std::str::from_utf8(s)?))
41
44
}
42
45
43
46
#[inline]
44
-
pub fn from_utf8_owned(s: Vec<u8>) -> Result<Self, std::str::Utf8Error> {
45
-
Ok(Self::Owned(SmolStr::new(std::str::from_utf8(&s)?)))
47
+
/// Take bytes and decode them as utf8 into an owned CowStr. Might allocate.
48
+
pub fn from_utf8_owned(s: impl AsRef<[u8]>) -> Result<Self, std::str::Utf8Error> {
49
+
Ok(Self::Owned(SmolStr::new(std::str::from_utf8(&s.as_ref())?)))
46
50
}
47
51
48
52
#[inline]
53
+
/// Take bytes and decode them as utf8, skipping invalid characters, taking ownership.
54
+
/// Will allocate, uses String::from_utf8_lossy() internally for now.
49
55
pub fn from_utf8_lossy(s: &'s [u8]) -> Self {
50
56
Self::Owned(String::from_utf8_lossy(&s).into())
51
57
}
+1
-1
crates/jacquard-common/src/into_static.rs
+1
-1
crates/jacquard-common/src/into_static.rs
···
7
7
use std::hash::Hash;
8
8
use std::sync::Arc;
9
9
10
-
/// Shamelessly copied from https://github.com/bearcove/merde
10
+
/// Shamelessly copied from [](https://github.com/bearcove/merde)
11
11
/// Allow turning a value into an "owned" variant, which can then be
12
12
/// returned, moved, etc.
13
13
///
+12
-5
crates/jacquard-common/src/lib.rs
+12
-5
crates/jacquard-common/src/lib.rs
···
1
+
//! Common types for the jacquard implementation of atproto
2
+
3
+
#![warn(missing_docs)]
4
+
pub use cowstr::CowStr;
5
+
pub use into_static::IntoStatic;
6
+
pub use smol_str;
7
+
pub use url;
8
+
9
+
/// A copy-on-write immutable string type that uses [`SmolStr`] for
10
+
/// the "owned" variant.
1
11
#[macro_use]
2
12
pub mod cowstr;
3
13
#[macro_use]
14
+
/// Trait for taking ownership of most borrowed types in jacquard.
4
15
pub mod into_static;
5
16
pub mod macros;
17
+
/// Baseline fundamental AT Protocol data types.
6
18
pub mod types;
7
-
8
-
pub use cowstr::CowStr;
9
-
pub use into_static::IntoStatic;
10
-
pub use smol_str;
11
-
pub use url;
+50
-23
crates/jacquard-common/src/types/aturi.rs
+50
-23
crates/jacquard-common/src/types/aturi.rs
···
12
12
use std::sync::LazyLock;
13
13
use std::{ops::Deref, str::FromStr};
14
14
15
-
/// at:// URI type
15
+
/// AT Protocol URI (`at://`) for referencing records in repositories
16
+
///
17
+
/// AT URIs provide a way to reference records using either a DID or handle as the authority.
18
+
/// They're not content-addressed, so the record's contents can change over time.
19
+
///
20
+
/// Format: `at://AUTHORITY[/COLLECTION[/RKEY]][#FRAGMENT]`
21
+
/// - Authority: DID or handle identifying the repository (required)
22
+
/// - Collection: NSID of the record type (optional)
23
+
/// - Record key (rkey): specific record identifier (optional)
24
+
/// - Fragment: sub-resource identifier (optional, limited support)
16
25
///
17
-
/// based on the regex here: https://github.com/bluesky-social/atproto/blob/main/packages/syntax/src/aturi_validation.ts
26
+
/// Examples:
27
+
/// - `at://alice.bsky.social`
28
+
/// - `at://did:plc:abc123/app.bsky.feed.post/3jk5`
18
29
///
19
-
/// Doesn't support the query segment, but then neither does the Typescript SDK.
30
+
/// See: <https://atproto.com/specs/at-uri-scheme>
20
31
#[derive(PartialEq, Eq, Debug)]
21
32
pub struct AtUri<'u> {
22
33
inner: Inner<'u>,
···
31
42
pub authority: AtIdentifier<'this>,
32
43
#[borrows(uri)]
33
44
#[covariant]
34
-
pub path: Option<UriPath<'this>>,
45
+
pub path: Option<RepoPath<'this>>,
35
46
#[borrows(uri)]
36
47
#[covariant]
37
48
pub fragment: Option<CowStr<'this>>,
···
58
69
} else {
59
70
None
60
71
};
61
-
Some(UriPath { collection, rkey })
72
+
Some(RepoPath { collection, rkey })
62
73
} else {
63
74
None
64
75
}
···
81
92
}
82
93
}
83
94
84
-
/// at:// URI path component (current subset)
95
+
/// Path component of an AT URI (collection and optional record key)
96
+
///
97
+
/// Represents the `/COLLECTION[/RKEY]` portion of an AT URI.
85
98
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
86
-
pub struct UriPath<'u> {
99
+
pub struct RepoPath<'u> {
100
+
/// Collection NSID (e.g., `app.bsky.feed.post`)
87
101
pub collection: Nsid<'u>,
102
+
/// Optional record key identifying a specific record
88
103
pub rkey: Option<RecordKey<Rkey<'u>>>,
89
104
}
90
105
91
-
impl IntoStatic for UriPath<'_> {
92
-
type Output = UriPath<'static>;
106
+
impl IntoStatic for RepoPath<'_> {
107
+
type Output = RepoPath<'static>;
93
108
94
109
fn into_static(self) -> Self::Output {
95
-
UriPath {
110
+
RepoPath {
96
111
collection: self.collection.into_static(),
97
112
rkey: self.rkey.map(|rkey| rkey.into_static()),
98
113
}
99
114
}
100
115
}
101
116
102
-
pub type UriPathBuf = UriPath<'static>;
117
+
/// Owned (static lifetime) version of `RepoPath`
118
+
pub type UriPathBuf = RepoPath<'static>;
103
119
120
+
/// Regex for AT URI validation per AT Protocol spec
104
121
pub static ATURI_REGEX: LazyLock<Regex> = LazyLock::new(|| {
105
122
// Fragment allows: / and \ and other special chars. In raw string, backslashes are literal.
106
123
Regex::new(r##"^at://(?<authority>[a-zA-Z0-9._:%-]+)(/(?<collection>[a-zA-Z0-9-.]+)(/(?<rkey>[a-zA-Z0-9._~:@!$&%')(*+,;=-]+))?)?(#(?<fragment>/[a-zA-Z0-9._~:@!$&%')(*+,;=\-\[\]/\\]*))?$"##).unwrap()
···
125
142
} else {
126
143
None
127
144
};
128
-
Some(UriPath { collection, rkey })
145
+
Some(RepoPath { collection, rkey })
129
146
} else {
130
147
None
131
148
};
···
154
171
}
155
172
}
156
173
174
+
/// Infallible constructor for when you know the URI is valid
175
+
///
176
+
/// Panics on invalid URIs. Use this when manually constructing URIs from trusted sources.
157
177
pub fn raw(uri: &'u str) -> Self {
158
178
if let Some(parts) = ATURI_REGEX.captures(uri) {
159
179
if let Some(authority) = parts.name("authority") {
···
166
186
} else {
167
187
None
168
188
};
169
-
Some(UriPath { collection, rkey })
189
+
Some(RepoPath { collection, rkey })
170
190
} else {
171
191
None
172
192
};
···
207
227
} else {
208
228
None
209
229
};
210
-
Some(UriPath { collection, rkey })
230
+
Some(RepoPath { collection, rkey })
211
231
} else {
212
232
None
213
233
};
···
275
295
})
276
296
}
277
297
298
+
/// Get the full URI as a string slice
278
299
pub fn as_str(&self) -> &str {
279
300
{
280
301
let this = &self.inner.borrow_uri();
···
282
303
}
283
304
}
284
305
306
+
/// Get the authority component (DID or handle)
285
307
pub fn authority(&self) -> &AtIdentifier<'_> {
286
308
self.inner.borrow_authority()
287
309
}
288
310
289
-
pub fn path(&self) -> &Option<UriPath<'_>> {
311
+
/// Get the path component (collection and optional rkey)
312
+
pub fn path(&self) -> &Option<RepoPath<'_>> {
290
313
self.inner.borrow_path()
291
314
}
292
315
316
+
/// Get the fragment component if present
293
317
pub fn fragment(&self) -> &Option<CowStr<'_>> {
294
318
self.inner.borrow_fragment()
295
319
}
296
320
321
+
/// Get the collection NSID from the path, if present
297
322
pub fn collection(&self) -> Option<&Nsid<'_>> {
298
323
self.inner.borrow_path().as_ref().map(|p| &p.collection)
299
324
}
300
325
326
+
/// Get the record key from the path, if present
301
327
pub fn rkey(&self) -> Option<&RecordKey<Rkey<'_>>> {
302
328
self.inner
303
329
.borrow_path()
···
339
365
} else {
340
366
None
341
367
};
342
-
Some(UriPath { collection, rkey })
368
+
Some(RepoPath { collection, rkey })
343
369
} else {
344
370
None
345
371
};
···
367
393
} else {
368
394
None
369
395
};
370
-
Some(UriPath { collection, rkey })
396
+
Some(RepoPath { collection, rkey })
371
397
} else {
372
398
None
373
399
}
···
400
426
}
401
427
}
402
428
429
+
/// Fallible constructor, validates, doesn't allocate (static lifetime)
403
430
pub fn new_static(uri: &'static str) -> Result<Self, AtStrError> {
404
431
let uri = uri.as_ref();
405
432
if let Some(parts) = ATURI_REGEX.captures(uri) {
···
418
445
} else {
419
446
None
420
447
};
421
-
Some(UriPath { collection, rkey })
448
+
Some(RepoPath { collection, rkey })
422
449
} else {
423
450
None
424
451
};
···
470
497
} else {
471
498
None
472
499
};
473
-
Some(UriPath { collection, rkey })
500
+
Some(RepoPath { collection, rkey })
474
501
} else {
475
502
None
476
503
};
···
498
525
} else {
499
526
None
500
527
};
501
-
Some(UriPath { collection, rkey })
528
+
Some(RepoPath { collection, rkey })
502
529
} else {
503
530
None
504
531
}
···
555
582
} else {
556
583
None
557
584
};
558
-
Some(UriPath { collection, rkey })
585
+
Some(RepoPath { collection, rkey })
559
586
} else {
560
587
None
561
588
}
···
646
673
} else {
647
674
None
648
675
};
649
-
Some(UriPath { collection, rkey })
676
+
Some(RepoPath { collection, rkey })
650
677
} else {
651
678
None
652
679
};
···
672
699
} else {
673
700
None
674
701
};
675
-
Some(UriPath { collection, rkey })
702
+
Some(RepoPath { collection, rkey })
676
703
} else {
677
704
None
678
705
}
+25
-7
crates/jacquard-common/src/types/blob.rs
+25
-7
crates/jacquard-common/src/types/blob.rs
···
12
12
str::FromStr,
13
13
};
14
14
15
+
/// Blob reference for binary data in AT Protocol
16
+
///
17
+
/// Blobs represent uploaded binary data (images, videos, etc.) stored separately from records.
18
+
/// They include a CID reference, MIME type, and size information.
19
+
///
20
+
/// Serialization differs between formats:
21
+
/// - JSON: `ref` is serialized as `{"$link": "cid_string"}`
22
+
/// - CBOR: `ref` is the raw CID
15
23
#[derive(Deserialize, Debug, Clone, PartialEq, Eq, Hash)]
16
24
#[serde(rename_all = "camelCase")]
17
25
pub struct Blob<'b> {
26
+
/// CID (Content Identifier) reference to the blob data
18
27
pub r#ref: Cid<'b>,
28
+
/// MIME type of the blob (e.g., "image/png", "video/mp4")
19
29
#[serde(borrow)]
20
30
pub mime_type: MimeType<'b>,
31
+
/// Size of the blob in bytes
21
32
pub size: usize,
22
33
}
23
34
···
65
76
}
66
77
}
67
78
68
-
/// Current, typed blob reference.
69
-
/// Quite dislike this nesting, but it serves the same purpose as it did in Atrium
70
-
/// Couple of helper methods and conversions to make it less annoying.
71
-
/// TODO: revisit nesting and maybe hand-roll a serde impl that supports this sans nesting
79
+
/// Tagged blob reference with `$type` field for serde
80
+
///
81
+
/// This enum provides the `{"$type": "blob"}` wrapper expected by AT Protocol's JSON format.
82
+
/// Currently only contains the `Blob` variant, but the enum structure supports future extensions.
72
83
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
73
84
#[serde(tag = "$type", rename_all = "lowercase")]
74
85
pub enum BlobRef<'r> {
86
+
/// Blob variant with embedded blob data
75
87
#[serde(borrow)]
76
88
Blob(Blob<'r>),
77
89
}
78
90
79
91
impl<'r> BlobRef<'r> {
92
+
/// Get the inner blob reference
80
93
pub fn blob(&self) -> &Blob<'r> {
81
94
match self {
82
95
BlobRef::Blob(blob) => blob,
···
108
121
}
109
122
}
110
123
111
-
/// Wrapper for file type
124
+
/// MIME type identifier for blob data
125
+
///
126
+
/// Used to specify the content type of blobs. Supports patterns like "image/*" and "*/*".
112
127
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize)]
113
128
#[serde(transparent)]
114
129
#[repr(transparent)]
···
120
135
Ok(Self(CowStr::Borrowed(mime_type)))
121
136
}
122
137
138
+
/// Fallible constructor, validates, takes ownership
123
139
pub fn new_owned(mime_type: impl AsRef<str>) -> Self {
124
140
Self(CowStr::Owned(mime_type.as_ref().to_smolstr()))
125
141
}
126
142
143
+
/// Fallible constructor, validates, doesn't allocate
127
144
pub fn new_static(mime_type: &'static str) -> Self {
128
145
Self(CowStr::new_static(mime_type))
129
146
}
130
147
131
-
/// Fallible constructor from an existing CowStr, borrows
148
+
/// Fallible constructor from an existing CowStr
132
149
pub fn from_cowstr(mime_type: CowStr<'m>) -> Result<MimeType<'m>, &'static str> {
133
150
Ok(Self(mime_type))
134
151
}
135
152
136
-
/// Infallible constructor
153
+
/// Infallible constructor for trusted MIME type strings
137
154
pub fn raw(mime_type: &'m str) -> Self {
138
155
Self(CowStr::Borrowed(mime_type))
139
156
}
140
157
158
+
/// Get the MIME type as a string slice
141
159
pub fn as_str(&self) -> &str {
142
160
{
143
161
let this = &self.0;
+44
-10
crates/jacquard-common/src/types/cid.rs
+44
-10
crates/jacquard-common/src/types/cid.rs
···
4
4
use smol_str::ToSmolStr;
5
5
use std::{convert::Infallible, fmt, marker::PhantomData, ops::Deref, str::FromStr};
6
6
7
-
/// raw
7
+
/// CID codec for AT Protocol (raw)
8
8
pub const ATP_CID_CODEC: u64 = 0x55;
9
9
10
-
/// SHA-256
10
+
/// CID hash function for AT Protocol (SHA-256)
11
11
pub const ATP_CID_HASH: u64 = 0x12;
12
12
13
-
/// base 32
13
+
/// CID encoding base for AT Protocol (base32 lowercase)
14
14
pub const ATP_CID_BASE: multibase::Base = multibase::Base::Base32Lower;
15
15
16
-
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
17
-
/// Either the string form of a cid or the ipld form
18
-
/// For the IPLD form we also cache the string representation for later use.
16
+
/// Content Identifier (CID) for IPLD data in AT Protocol
17
+
///
18
+
/// CIDs are self-describing content addresses used to reference IPLD data.
19
+
/// This type supports both string and parsed IPLD forms, with string caching
20
+
/// for the parsed form to optimize serialization.
19
21
///
20
-
/// Default on deserialization matches the format (if we get bytes, we try to decode)
22
+
/// Deserialization automatically detects the format (bytes trigger IPLD parsing).
23
+
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
21
24
pub enum Cid<'c> {
22
-
Ipld { cid: IpldCid, s: CowStr<'c> },
25
+
/// Parsed IPLD CID with cached string representation
26
+
Ipld {
27
+
/// Parsed CID structure
28
+
cid: IpldCid,
29
+
/// Cached base32 string form
30
+
s: CowStr<'c>,
31
+
},
32
+
/// String-only form (not yet parsed)
23
33
Str(CowStr<'c>),
24
34
}
25
35
36
+
/// Errors that can occur when working with CIDs
26
37
#[derive(Debug, thiserror::Error, miette::Diagnostic)]
27
38
pub enum Error {
39
+
/// Invalid IPLD CID structure
28
40
#[error("Invalid IPLD CID {:?}", 0)]
29
41
Ipld(#[from] cid::Error),
42
+
/// Invalid UTF-8 in CID string
30
43
#[error("{:?}", 0)]
31
44
Utf8(#[from] std::str::Utf8Error),
32
45
}
33
46
34
47
impl<'c> Cid<'c> {
48
+
/// Parse a CID from bytes (tries IPLD first, falls back to UTF-8 string)
35
49
pub fn new(cid: &'c [u8]) -> Result<Self, Error> {
36
50
if let Ok(cid) = IpldCid::try_from(cid.as_ref()) {
37
51
Ok(Self::ipld(cid))
···
41
55
}
42
56
}
43
57
58
+
/// Parse a CID from bytes into an owned (static lifetime) value
44
59
pub fn new_owned(cid: &[u8]) -> Result<Cid<'static>, Error> {
45
60
if let Ok(cid) = IpldCid::try_from(cid.as_ref()) {
46
61
Ok(Self::ipld(cid))
···
50
65
}
51
66
}
52
67
68
+
/// Construct a CID from a parsed IPLD CID
53
69
pub fn ipld(cid: IpldCid) -> Cid<'static> {
54
70
let s = CowStr::Owned(
55
71
cid.to_string_of_base(ATP_CID_BASE)
···
59
75
Cid::Ipld { cid, s }
60
76
}
61
77
78
+
/// Construct a CID from a string slice (borrows)
62
79
pub fn str(cid: &'c str) -> Self {
63
80
Self::Str(CowStr::Borrowed(cid))
64
81
}
65
82
83
+
/// Construct a CID from a CowStr
66
84
pub fn cow_str(cid: CowStr<'c>) -> Self {
67
85
Self::Str(cid)
68
86
}
69
87
88
+
/// Convert to a parsed IPLD CID (parses if needed)
70
89
pub fn to_ipld(&self) -> Result<IpldCid, cid::Error> {
71
90
match self {
72
91
Cid::Ipld { cid, s: _ } => Ok(cid.clone()),
···
74
93
}
75
94
}
76
95
96
+
/// Get the CID as a string slice
77
97
pub fn as_str(&self) -> &str {
78
98
match self {
79
99
Cid::Ipld { cid: _, s } => s.as_ref(),
···
218
238
}
219
239
}
220
240
221
-
/// CID link wrapper that serializes as {"$link": "cid"} in JSON
222
-
/// and as raw CID in CBOR
241
+
/// CID link wrapper for JSON `{"$link": "cid"}` serialization
242
+
///
243
+
/// Wraps a `Cid` and handles format-specific serialization:
244
+
/// - JSON: `{"$link": "cid_string"}`
245
+
/// - CBOR: raw CID bytes
246
+
///
247
+
/// Used in the AT Protocol data model to represent IPLD links in JSON.
223
248
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
224
249
#[repr(transparent)]
225
250
pub struct CidLink<'c>(pub Cid<'c>);
226
251
227
252
impl<'c> CidLink<'c> {
253
+
/// Parse a CID link from bytes
228
254
pub fn new(cid: &'c [u8]) -> Result<Self, Error> {
229
255
Ok(Self(Cid::new(cid)?))
230
256
}
231
257
258
+
/// Parse a CID link from bytes into an owned value
232
259
pub fn new_owned(cid: &[u8]) -> Result<CidLink<'static>, Error> {
233
260
Ok(CidLink(Cid::new_owned(cid)?))
234
261
}
235
262
263
+
/// Construct a CID link from a static string
236
264
pub fn new_static(cid: &'static str) -> Self {
237
265
Self(Cid::str(cid))
238
266
}
239
267
268
+
/// Construct a CID link from a parsed IPLD CID
240
269
pub fn ipld(cid: IpldCid) -> CidLink<'static> {
241
270
CidLink(Cid::ipld(cid))
242
271
}
243
272
273
+
/// Construct a CID link from a string slice
244
274
pub fn str(cid: &'c str) -> Self {
245
275
Self(Cid::str(cid))
246
276
}
247
277
278
+
/// Construct a CID link from a CowStr
248
279
pub fn cow_str(cid: CowStr<'c>) -> Self {
249
280
Self(Cid::cow_str(cid))
250
281
}
251
282
283
+
/// Get the CID as a string slice
252
284
pub fn as_str(&self) -> &str {
253
285
self.0.as_str()
254
286
}
255
287
288
+
/// Convert to a parsed IPLD CID
256
289
pub fn to_ipld(&self) -> Result<IpldCid, cid::Error> {
257
290
self.0.to_ipld()
258
291
}
259
292
293
+
/// Unwrap into the inner Cid
260
294
pub fn into_inner(self) -> Cid<'c> {
261
295
self.0
262
296
}
+5
-5
crates/jacquard-common/src/types/collection.rs
+5
-5
crates/jacquard-common/src/types/collection.rs
···
3
3
use serde::Serialize;
4
4
5
5
use crate::types::{
6
-
aturi::UriPath,
6
+
aturi::RepoPath,
7
7
nsid::Nsid,
8
8
recordkey::{RecordKey, RecordKeyType, Rkey},
9
9
};
···
26
26
///
27
27
/// Panics if [`Self::NSID`] is not a valid NSID.
28
28
///
29
-
/// [`Nsid`]: string::Nsid
29
+
/// [`Nsid`]: crate::types::string::Nsid
30
30
fn nsid() -> crate::types::nsid::Nsid<'static> {
31
31
Nsid::new_static(Self::NSID).expect("should be valid NSID")
32
32
}
···
39
39
/// > [`RecordKey`].
40
40
///
41
41
/// [Repo Data Structure v3]: https://atproto.com/specs/repository#repo-data-structure-v3
42
-
/// [`Nsid`]: string::Nsid
42
+
/// [`Nsid`]: crate::types::string::Nsid
43
43
fn repo_path<'u, T: RecordKeyType>(
44
44
rkey: &'u crate::types::recordkey::RecordKey<T>,
45
-
) -> UriPath<'u> {
46
-
UriPath {
45
+
) -> RepoPath<'u> {
46
+
RepoPath {
47
47
collection: Self::nsid(),
48
48
rkey: Some(RecordKey::from(Rkey::raw(rkey.as_ref()))),
49
49
}
+14
-3
crates/jacquard-common/src/types/datetime.rs
+14
-3
crates/jacquard-common/src/types/datetime.rs
···
9
9
use crate::{CowStr, IntoStatic};
10
10
use regex::Regex;
11
11
12
+
/// Regex for ISO 8601 datetime validation per AT Protocol spec
12
13
pub static ISO8601_REGEX: LazyLock<Regex> = LazyLock::new(|| {
13
14
Regex::new(r"^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(\.[0-9]+)?(Z|(\+[0-9]{2}|\-[0-9][1-9]):[0-9]{2})$").unwrap()
14
15
});
15
16
16
-
/// A Lexicon timestamp.
17
+
/// AT Protocol datetime (ISO 8601 with specific requirements)
18
+
///
19
+
/// Lexicon datetimes use ISO 8601 format with these requirements:
20
+
/// - Must include timezone (strongly prefer UTC with 'Z')
21
+
/// - Requires whole seconds precision minimum
22
+
/// - Supports millisecond and microsecond precision
23
+
/// - Uses uppercase 'T' to separate date and time
24
+
///
25
+
/// Examples: `"1985-04-12T23:20:50.123Z"`, `"2023-01-01T00:00:00+00:00"`
26
+
///
27
+
/// The serialized form is preserved during parsing to ensure exact round-trip serialization.
17
28
#[derive(Clone, Debug, Eq, Hash)]
18
29
pub struct Datetime {
19
-
/// Serialized form. Preserved during parsing to ensure round-trip re-serialization.
30
+
/// Serialized form preserved from parsing for round-trip consistency
20
31
serialized: CowStr<'static>,
21
-
/// Parsed form.
32
+
/// Parsed datetime value for comparisons and operations
22
33
dt: chrono::DateTime<chrono::FixedOffset>,
23
34
}
24
35
+16
-1
crates/jacquard-common/src/types/did.rs
+16
-1
crates/jacquard-common/src/types/did.rs
···
7
7
use std::sync::LazyLock;
8
8
use std::{ops::Deref, str::FromStr};
9
9
10
+
/// Decentralized Identifier (DID) for AT Protocol accounts
11
+
///
12
+
/// DIDs are the persistent, long-term account identifiers in AT Protocol. Unlike handles,
13
+
/// which can change, a DID permanently identifies an account across the network.
14
+
///
15
+
/// Supported DID methods:
16
+
/// - `did:plc` - Bluesky's novel DID method
17
+
/// - `did:web` - Based on HTTPS and DNS
18
+
///
19
+
/// Validation enforces a maximum length of 2048 characters and uses the pattern:
20
+
/// `did:[method]:[method-specific-id]` where the method is lowercase ASCII and the
21
+
/// method-specific-id allows alphanumerics, dots, colons, hyphens, underscores, and percent signs.
22
+
///
23
+
/// See: <https://atproto.com/specs/did>
10
24
#[derive(Clone, PartialEq, Eq, Serialize, Hash)]
11
25
#[serde(transparent)]
12
26
#[repr(transparent)]
···
76
90
/// Infallible constructor for when you *know* the string is a valid DID.
77
91
/// Will panic on invalid DIDs. If you're manually decoding atproto records
78
92
/// or API values you know are valid (rather than using serde), this is the one to use.
79
-
/// The From<String> and From<CowStr> impls use the same logic.
93
+
/// The `From<String>` and `From<CowStr>` impls use the same logic.
80
94
pub fn raw(did: &'d str) -> Self {
81
95
let did = did.strip_prefix("at://").unwrap_or(did);
82
96
if did.len() > 2048 {
···
94
108
Self(CowStr::Borrowed(did))
95
109
}
96
110
111
+
/// Get the DID as a string slice
97
112
pub fn as_str(&self) -> &str {
98
113
{
99
114
let this = &self.0;
+20
-3
crates/jacquard-common/src/types/handle.rs
+20
-3
crates/jacquard-common/src/types/handle.rs
···
8
8
use std::sync::LazyLock;
9
9
use std::{ops::Deref, str::FromStr};
10
10
11
+
/// AT Protocol handle (human-readable account identifier)
12
+
///
13
+
/// Handles are user-friendly account identifiers that must resolve to a DID through DNS
14
+
/// or HTTPS. Unlike DIDs, handles can change over time, though they remain an important
15
+
/// part of user identity.
16
+
///
17
+
/// Format rules:
18
+
/// - Maximum 253 characters
19
+
/// - At least two segments separated by dots (e.g., "alice.bsky.social")
20
+
/// - Each segment is 1-63 characters of ASCII letters, numbers, and hyphens
21
+
/// - Segments cannot start or end with a hyphen
22
+
/// - Final segment (TLD) cannot start with a digit
23
+
/// - Case-insensitive (normalized to lowercase)
24
+
///
25
+
/// Certain TLDs are disallowed (.local, .localhost, .arpa, .invalid, .internal, .example, .alt, .onion).
26
+
///
27
+
/// See: <https://atproto.com/specs/handle>
11
28
#[derive(Clone, PartialEq, Eq, Serialize, Hash)]
12
29
#[serde(transparent)]
13
30
#[repr(transparent)]
14
31
pub struct Handle<'h>(CowStr<'h>);
15
32
33
+
/// Regex for handle validation per AT Protocol spec
16
34
pub static HANDLE_REGEX: LazyLock<Regex> = LazyLock::new(|| {
17
35
Regex::new(r"^([a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?$").unwrap()
18
36
});
19
-
20
-
/// AT Protocol handle
21
37
impl<'h> Handle<'h> {
22
38
/// Fallible constructor, validates, borrows from input
23
39
///
···
95
111
/// Infallible constructor for when you *know* the string is a valid handle.
96
112
/// Will panic on invalid handles. If you're manually decoding atproto records
97
113
/// or API values you know are valid (rather than using serde), this is the one to use.
98
-
/// The From<String> and From<CowStr> impls use the same logic.
114
+
/// The `From<String>` and `From<CowStr>` impls use the same logic.
99
115
///
100
116
/// Accepts (and strips) preceding '@' or 'at://' if present
101
117
pub fn raw(handle: &'h str) -> Self {
···
127
143
Self(CowStr::Borrowed(stripped))
128
144
}
129
145
146
+
/// Get the handle as a string slice
130
147
pub fn as_str(&self) -> &str {
131
148
{
132
149
let this = &self.0;
+11
-2
crates/jacquard-common/src/types/ident.rs
+11
-2
crates/jacquard-common/src/types/ident.rs
···
8
8
9
9
use crate::CowStr;
10
10
11
-
/// An AT Protocol identifier.
11
+
/// AT Protocol identifier (either a DID or handle)
12
+
///
13
+
/// Represents the union of DIDs and handles, which can both be used to identify
14
+
/// accounts in AT Protocol. DIDs are permanent identifiers, while handles are
15
+
/// human-friendly and can change.
16
+
///
17
+
/// Automatically determines whether a string is a DID or a handle during parsing.
12
18
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize, Hash)]
13
19
#[serde(untagged)]
14
20
pub enum AtIdentifier<'i> {
21
+
/// DID variant
15
22
#[serde(borrow)]
16
23
Did(Did<'i>),
24
+
/// Handle variant
17
25
Handle(Handle<'i>),
18
26
}
19
27
···
49
57
/// Infallible constructor for when you *know* the string is a valid identifier.
50
58
/// Will panic on invalid identifiers. If you're manually decoding atproto records
51
59
/// or API values you know are valid (rather than using serde), this is the one to use.
52
-
/// The From<String> and From<CowStr> impls use the same logic.
60
+
/// The `From<String>` and `From<CowStr>` impls use the same logic.
53
61
pub fn raw(ident: &'i str) -> Self {
54
62
if let Ok(did) = ident.parse() {
55
63
AtIdentifier::Did(did)
···
73
81
}
74
82
}
75
83
84
+
/// Get the identifier as a string slice
76
85
pub fn as_str(&self) -> &str {
77
86
match self {
78
87
AtIdentifier::Did(did) => did.as_str(),
+8
-3
crates/jacquard-common/src/types/language.rs
+8
-3
crates/jacquard-common/src/types/language.rs
···
5
5
6
6
use crate::CowStr;
7
7
8
-
/// An IETF language tag.
8
+
/// IETF BCP 47 language tag for AT Protocol
9
+
///
10
+
/// Language tags identify natural languages following the BCP 47 standard. They consist of
11
+
/// a 2-3 character language code (e.g., "en", "ja") with optional regional subtags (e.g., "pt-BR").
9
12
///
10
-
/// Uses langtag crate for validation, but is stored as a SmolStr for size/avoiding allocations
13
+
/// Examples: `"ja"` (Japanese), `"pt-BR"` (Brazilian Portuguese), `"en-US"` (US English)
11
14
///
15
+
/// Language tags require semantic parsing rather than simple string comparison.
16
+
/// Uses the `langtag` crate for validation but stores as `SmolStr` for efficiency.
12
17
/// TODO: Implement langtag-style semantic matching for this type, delegating to langtag
13
18
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Hash)]
14
19
#[serde(transparent)]
···
34
39
/// Infallible constructor for when you *know* the string is a valid IETF language tag.
35
40
/// Will panic on invalid tag. If you're manually decoding atproto records
36
41
/// or API values you know are valid (rather than using serde), this is the one to use.
37
-
/// The From<String> and From<CowStr> impls use the same logic.
42
+
/// The `From<String>` and `From<CowStr>` impls use the same logic.
38
43
pub fn raw(lang: impl AsRef<str>) -> Self {
39
44
let lang = lang.as_ref();
40
45
let tag = langtag::LangTag::new(lang).expect("valid IETF language tag");
+18
-4
crates/jacquard-common/src/types/nsid.rs
+18
-4
crates/jacquard-common/src/types/nsid.rs
···
8
8
use std::sync::LazyLock;
9
9
use std::{ops::Deref, str::FromStr};
10
10
11
-
/// Namespaced Identifier (NSID)
11
+
/// Namespaced Identifier (NSID) for Lexicon schemas and XRPC endpoints
12
+
///
13
+
/// NSIDs provide globally unique identifiers for Lexicon schemas, record types, and XRPC methods.
14
+
/// They're structured as reversed domain names with a camelCase name segment.
15
+
///
16
+
/// Format: `domain.authority.name` (e.g., `com.example.fooBar`)
17
+
/// - Domain authority: reversed domain name (โค253 chars, lowercase, dots separate segments)
18
+
/// - Name: camelCase identifier (letters and numbers only, cannot start with a digit)
19
+
///
20
+
/// Validation rules:
21
+
/// - Minimum 3 segments
22
+
/// - Maximum 317 characters total
23
+
/// - Each domain segment is 1-63 characters
24
+
/// - Case-sensitive
12
25
///
13
-
/// Stored as SmolStr to ease lifetime issues and because, despite the fact that NSIDs *can* be 317 characters, most are quite short
14
-
/// TODO: consider if this should go back to CowStr, or be broken up into segments
26
+
/// See: <https://atproto.com/specs/nsid>
15
27
#[derive(Clone, PartialEq, Eq, Serialize, Hash)]
16
28
#[serde(transparent)]
17
29
#[repr(transparent)]
18
30
pub struct Nsid<'n>(CowStr<'n>);
19
31
32
+
/// Regex for NSID validation per AT Protocol spec
20
33
pub static NSID_REGEX: LazyLock<Regex> = LazyLock::new(|| {
21
34
Regex::new(r"^[a-zA-Z]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(\.[a-zA-Z][a-zA-Z0-9]{0,62})$").unwrap()
22
35
});
···
71
84
/// Infallible constructor for when you *know* the string is a valid NSID.
72
85
/// Will panic on invalid NSIDs. If you're manually decoding atproto records
73
86
/// or API values you know are valid (rather than using serde), this is the one to use.
74
-
/// The From<String> and From<CowStr> impls use the same logic.
87
+
/// The `From<String>` and `From<CowStr>` impls use the same logic.
75
88
pub fn raw(nsid: &'n str) -> Self {
76
89
if nsid.len() > 317 {
77
90
panic!("NSID too long")
···
100
113
&self.0[split + 1..]
101
114
}
102
115
116
+
/// Get the NSID as a string slice
103
117
pub fn as_str(&self) -> &str {
104
118
{
105
119
let this = &self.0;
+31
-11
crates/jacquard-common/src/types/recordkey.rs
+31
-11
crates/jacquard-common/src/types/recordkey.rs
···
9
9
use std::sync::LazyLock;
10
10
use std::{ops::Deref, str::FromStr};
11
11
12
-
/// Trait for generic typed record keys
12
+
/// Trait for typed record key implementations
13
13
///
14
-
/// This is deliberately public (so that consumers can develop specialized record key types),
15
-
/// but is marked as unsafe, because the implementer is expected to uphold the invariants
16
-
/// required by this trait, namely compliance with the [spec](https://atproto.com/specs/record-key)
17
-
/// as described by [`RKEY_REGEX`](RKEY_REGEX).
14
+
/// Allows different record key types (TID, NSID, literals, generic strings) while
15
+
/// maintaining validation guarantees. Implementers must ensure compliance with the
16
+
/// AT Protocol [record key specification](https://atproto.com/specs/record-key).
18
17
///
19
-
/// This crate provides implementations for TID, NSID, literals, and generic strings
18
+
/// # Safety
19
+
/// Implementations must ensure the string representation matches [`RKEY_REGEX`] and
20
+
/// is not "." or "..". Built-in implementations: `Tid`, `Nsid`, `Literal<T>`, `Rkey<'_>`.
20
21
pub unsafe trait RecordKeyType: Clone + Serialize {
22
+
/// Get the record key as a string slice
21
23
fn as_str(&self) -> &str;
22
24
}
23
25
26
+
/// Wrapper for typed record keys
27
+
///
28
+
/// Provides a generic container for different record key types while preserving their
29
+
/// specific validation guarantees through the `RecordKeyType` trait.
24
30
#[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Hash, Debug)]
25
31
#[serde(transparent)]
26
32
#[repr(transparent)]
···
56
62
}
57
63
}
58
64
59
-
/// ATProto Record Key (type `any`)
60
-
/// Catch-all for any string meeting the overall Record Key requirements detailed https://atproto.com/specs/record-key
65
+
/// AT Protocol record key (generic "any" type)
66
+
///
67
+
/// Record keys uniquely identify records within a collection. This is the catch-all
68
+
/// type for any valid record key string (1-512 characters of alphanumerics, dots,
69
+
/// hyphens, underscores, colons, tildes).
70
+
///
71
+
/// Common record key types:
72
+
/// - TID: timestamp-based (most common)
73
+
/// - Literal: fixed keys like "self"
74
+
/// - NSID: namespaced identifiers
75
+
/// - Any: flexible strings matching the validation rules
76
+
///
77
+
/// See: <https://atproto.com/specs/record-key>
61
78
#[derive(Clone, PartialEq, Eq, Serialize, Hash)]
62
79
#[serde(transparent)]
63
80
#[repr(transparent)]
···
69
86
}
70
87
}
71
88
89
+
/// Regex for record key validation per AT Protocol spec
72
90
pub static RKEY_REGEX: LazyLock<Regex> =
73
91
LazyLock::new(|| Regex::new(r"^[a-zA-Z0-9.\-_:~]{1,512}$").unwrap());
74
92
75
-
/// AT Protocol rkey
76
93
impl<'r> Rkey<'r> {
77
94
/// Fallible constructor, validates, borrows from input
78
95
pub fn new(rkey: &'r str) -> Result<Self, AtStrError> {
···
89
106
}
90
107
}
91
108
92
-
/// Fallible constructor, validates, borrows from input
109
+
/// Fallible constructor, validates, takes ownership
93
110
pub fn new_owned(rkey: impl AsRef<str>) -> Result<Self, AtStrError> {
94
111
let rkey = rkey.as_ref();
95
112
if [".", ".."].contains(&rkey) {
···
140
157
Self(CowStr::Borrowed(rkey))
141
158
}
142
159
160
+
/// Get the record key as a string slice
143
161
pub fn as_str(&self) -> &str {
144
162
{
145
163
let this = &self.0;
···
265
283
}
266
284
267
285
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
286
+
/// Key for a record where only one of an NSID is supposed to exist
268
287
pub struct SelfRecord;
269
288
270
289
impl Literal for SelfRecord {
···
298
317
/// Infallible constructor for when you *know* the string is a valid rkey.
299
318
/// Will panic on invalid rkeys. If you're manually decoding atproto records
300
319
/// or API values you know are valid (rather than using serde), this is the one to use.
301
-
/// The From<String> and From<CowStr> impls use the same logic.
320
+
/// The `From<String>` and `From<CowStr>` impls use the same logic.
302
321
pub fn raw(rkey: &str) -> Self {
303
322
if !rkey.eq_ignore_ascii_case(T::LITERAL) {
304
323
panic!(
···
326
345
}
327
346
}
328
347
348
+
/// Get the literal record key as a string slice
329
349
pub fn as_str(&self) -> &str {
330
350
T::LITERAL
331
351
}
+57
-3
crates/jacquard-common/src/types/string.rs
+57
-3
crates/jacquard-common/src/types/string.rs
···
21
21
},
22
22
};
23
23
24
-
/// ATProto string value
24
+
/// Polymorphic AT Protocol string value
25
+
///
26
+
/// Represents any AT Protocol string type, automatically detecting and parsing
27
+
/// into the appropriate variant. Used internally for generic value handling.
28
+
///
29
+
/// Variants are checked in order from most specific to least specific. Note that
30
+
/// record keys are intentionally NOT parsed from bare strings as the validation
31
+
/// is too permissive and would catch too many values.
25
32
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
26
33
pub enum AtprotoStr<'s> {
34
+
/// ISO 8601 datetime
27
35
Datetime(Datetime),
36
+
/// BCP 47 language tag
28
37
Language(Language),
38
+
/// Timestamp identifier
29
39
Tid(Tid),
40
+
/// Namespaced identifier
30
41
Nsid(Nsid<'s>),
42
+
/// Decentralized identifier
31
43
Did(Did<'s>),
44
+
/// Account handle
32
45
Handle(Handle<'s>),
46
+
/// Identifier (DID or handle)
33
47
AtIdentifier(AtIdentifier<'s>),
48
+
/// AT URI
34
49
AtUri(AtUri<'s>),
50
+
/// Generic URI
35
51
Uri(Uri<'s>),
52
+
/// Content identifier
36
53
Cid(Cid<'s>),
54
+
/// Record key
37
55
RecordKey(RecordKey<Rkey<'s>>),
56
+
/// Plain string (fallback)
38
57
String(CowStr<'s>),
39
58
}
40
59
···
77
96
}
78
97
}
79
98
99
+
/// Get the string value regardless of variant
80
100
pub fn as_str(&self) -> &str {
81
101
match self {
82
102
Self::Datetime(datetime) => datetime.as_str(),
···
238
258
help("if something doesn't match the spec, contact the crate author")
239
259
)]
240
260
pub struct AtStrError {
261
+
/// AT Protocol spec name this error relates to
241
262
pub spec: SmolStr,
263
+
/// The source string that failed to parse
242
264
#[source_code]
243
265
pub source: String,
266
+
/// The specific kind of parsing error
244
267
#[source]
245
268
#[diagnostic_source]
246
269
pub kind: StrParseKind,
247
270
}
248
271
249
272
impl AtStrError {
273
+
/// Create a new AT string parsing error
250
274
pub fn new(spec: &'static str, source: String, kind: StrParseKind) -> Self {
251
275
Self {
252
276
spec: SmolStr::new_static(spec),
···
255
279
}
256
280
}
257
281
282
+
/// Wrap an existing error with a new spec context
258
283
pub fn wrap(spec: &'static str, source: String, error: AtStrError) -> Self {
259
284
if let Some(span) = match &error.kind {
260
285
StrParseKind::Disallowed { problem, .. } => problem,
···
309
334
}
310
335
}
311
336
337
+
/// Create an error for a string that exceeds the maximum length
312
338
pub fn too_long(spec: &'static str, source: &str, max: usize, actual: usize) -> Self {
313
339
Self {
314
340
spec: SmolStr::new_static(spec),
···
317
343
}
318
344
}
319
345
346
+
/// Create an error for a string below the minimum length
320
347
pub fn too_short(spec: &'static str, source: &str, min: usize, actual: usize) -> Self {
321
348
Self {
322
349
spec: SmolStr::new_static(spec),
···
348
375
}
349
376
350
377
/// missing component, with the span where it was expected to be founf
378
+
/// Create an error for a missing component at a specific span
351
379
pub fn missing_from(
352
380
spec: &'static str,
353
381
source: &str,
···
364
392
}
365
393
}
366
394
395
+
/// Create an error for a regex validation failure
367
396
pub fn regex(spec: &'static str, source: &str, message: SmolStr) -> Self {
368
397
Self {
369
398
spec: SmolStr::new_static(spec),
···
376
405
}
377
406
}
378
407
408
+
/// Kinds of parsing errors for AT Protocol string types
379
409
#[derive(Debug, thiserror::Error, miette::Diagnostic)]
380
410
pub enum StrParseKind {
411
+
/// Regex pattern validation failed
381
412
#[error("regex failure - {message}")]
382
413
#[diagnostic(code(jacquard::types::string::regex_fail))]
383
414
RegexFail {
415
+
/// Optional span highlighting the problem area
384
416
#[label]
385
417
span: Option<SourceSpan>,
418
+
/// Help message explaining the failure
386
419
#[help]
387
420
message: SmolStr,
388
421
},
422
+
/// String exceeds maximum allowed length
389
423
#[error("string too long (allowed: {max}, actual: {actual})")]
390
424
#[diagnostic(code(jacquard::types::string::wrong_length))]
391
-
TooLong { max: usize, actual: usize },
425
+
TooLong {
426
+
/// Maximum allowed length
427
+
max: usize,
428
+
/// Actual string length
429
+
actual: usize,
430
+
},
392
431
432
+
/// String is below minimum required length
393
433
#[error("string too short (allowed: {min}, actual: {actual})")]
394
434
#[diagnostic(code(jacquard::types::string::wrong_length))]
395
-
TooShort { min: usize, actual: usize },
435
+
TooShort {
436
+
/// Minimum required length
437
+
min: usize,
438
+
/// Actual string length
439
+
actual: usize,
440
+
},
441
+
/// String contains disallowed values
396
442
#[error("disallowed - {message}")]
397
443
#[diagnostic(code(jacquard::types::string::disallowed))]
398
444
Disallowed {
445
+
/// Optional span highlighting the disallowed content
399
446
#[label]
400
447
problem: Option<SourceSpan>,
448
+
/// Help message about what's disallowed
401
449
#[help]
402
450
message: SmolStr,
403
451
},
452
+
/// Required component is missing
404
453
#[error("missing - {message}")]
405
454
#[diagnostic(code(jacquard::atstr::missing_component))]
406
455
MissingComponent {
456
+
/// Optional span where the component should be
407
457
#[label]
408
458
span: Option<SourceSpan>,
459
+
/// Help message about what's missing
409
460
#[help]
410
461
message: SmolStr,
411
462
},
463
+
/// Wraps another error with additional context
412
464
#[error("{err:?}")]
413
465
#[diagnostic(code(jacquard::atstr::inner))]
414
466
Wrap {
467
+
/// Optional span in the outer context
415
468
#[label]
416
469
span: Option<SourceSpan>,
470
+
/// The wrapped inner error
417
471
#[source]
418
472
err: Arc<AtStrError>,
419
473
},
+27
-4
crates/jacquard-common/src/types/tid.rs
+27
-4
crates/jacquard-common/src/types/tid.rs
···
28
28
builder.finish()
29
29
}
30
30
31
+
/// Regex for TID validation per AT Protocol spec
31
32
static TID_REGEX: LazyLock<Regex> = LazyLock::new(|| {
32
33
Regex::new(r"^[234567abcdefghij][234567abcdefghijklmnopqrstuvwxyz]{12}$").unwrap()
33
34
});
34
35
35
-
/// A [Timestamp Identifier].
36
+
/// Timestamp Identifier (TID) for record keys and commit revisions
36
37
///
37
-
/// [Timestamp Identifier]: https://atproto.com/specs/tid
38
+
/// TIDs are compact, sortable identifiers based on timestamps. They're used as record keys
39
+
/// and repository commit revision numbers in AT Protocol.
40
+
///
41
+
/// Format:
42
+
/// - Always 13 ASCII characters
43
+
/// - Base32-sortable encoding (`234567abcdefghijklmnopqrstuvwxyz`)
44
+
/// - First 53 bits: microseconds since UNIX epoch
45
+
/// - Final 10 bits: random clock identifier for collision resistance
46
+
///
47
+
/// TIDs are sortable by timestamp and suitable for use in URLs. Generate new TIDs with
48
+
/// `Tid::now()` or `Tid::now_with_clock_id()`.
49
+
///
50
+
/// See: <https://atproto.com/specs/tid>
38
51
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Hash)]
39
52
#[serde(transparent)]
40
53
#[repr(transparent)]
···
71
84
/// Infallible constructor for when you *know* the string is a valid TID.
72
85
/// Will panic on invalid TID. If you're manually decoding atproto records
73
86
/// or API values you know are valid (rather than using serde), this is the one to use.
74
-
/// The From<String> and From<CowStr> impls use the same logic.
87
+
/// The `From<String>` and `From<CowStr>` impls use the same logic.
75
88
pub fn raw(tid: impl AsRef<str>) -> Self {
76
89
let tid = tid.as_ref();
77
90
if tid.len() != 13 {
···
105
118
Self(s32_encode(tid))
106
119
}
107
120
121
+
/// Construct a TID from a timestamp (in microseconds) and clock ID
108
122
pub fn from_time(timestamp: usize, clkid: u32) -> Self {
109
123
let str = smol_str::format_smolstr!(
110
124
"{0}{1:2>2}",
···
114
128
Self(str)
115
129
}
116
130
131
+
/// Extract the timestamp component (microseconds since UNIX epoch)
117
132
pub fn timestamp(&self) -> usize {
118
133
s32decode(self.0[0..11].to_owned())
119
134
}
120
135
121
-
// newer > older
136
+
/// Compare two TIDs chronologically (newer > older)
137
+
///
138
+
/// Returns 1 if self is newer, -1 if older, 0 if equal
122
139
pub fn compare_to(&self, other: &Tid) -> i8 {
123
140
if self.0 > other.0 {
124
141
return 1;
···
129
146
0
130
147
}
131
148
149
+
/// Check if this TID is newer than another
132
150
pub fn newer_than(&self, other: &Tid) -> bool {
133
151
self.compare_to(other) > 0
134
152
}
135
153
154
+
/// Check if this TID is older than another
136
155
pub fn older_than(&self, other: &Tid) -> bool {
137
156
self.compare_to(other) < 0
138
157
}
139
158
159
+
/// Generate the next TID in sequence after the given TID
140
160
pub fn next_str(prev: Option<Tid>) -> Result<Self, AtStrError> {
141
161
let prev = match prev {
142
162
None => None,
···
173
193
}
174
194
}
175
195
196
+
/// Decode a base32-sortable string into a usize
176
197
pub fn s32decode(s: String) -> usize {
177
198
let mut i: usize = 0;
178
199
for c in s.chars() {
···
273
294
}
274
295
275
296
impl Ticker {
297
+
/// Create a new TID generator with random clock ID
276
298
pub fn new() -> Self {
277
299
let mut ticker = Self {
278
300
last_timestamp: 0,
···
284
306
ticker
285
307
}
286
308
309
+
/// Generate the next TID, optionally ensuring it's after the given TID
287
310
pub fn next(&mut self, prev: Option<Tid>) -> Tid {
288
311
let now = SystemTime::now()
289
312
.duration_since(SystemTime::UNIX_EPOCH)
+19
-2
crates/jacquard-common/src/types/uri.rs
+19
-2
crates/jacquard-common/src/types/uri.rs
···
7
7
types::{aturi::AtUri, cid::Cid, did::Did, string::AtStrError},
8
8
};
9
9
10
-
/// URI with best-available contextual type
11
-
/// TODO: figure out wtf a DNS uri should look like
10
+
/// Generic URI with type-specific parsing
11
+
///
12
+
/// Automatically detects and parses URIs into the appropriate variant based on
13
+
/// the scheme prefix. Used in lexicon where URIs can be of various types.
14
+
///
15
+
/// Variants are checked by prefix: `did:`, `at://`, `https://`, `wss://`, `ipld://`
12
16
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
13
17
pub enum Uri<'u> {
18
+
/// DID URI (did:)
14
19
Did(Did<'u>),
20
+
/// AT Protocol URI (at://)
15
21
At(AtUri<'u>),
22
+
/// HTTPS URL
16
23
Https(Url),
24
+
/// WebSocket Secure URL
17
25
Wss(Url),
26
+
/// IPLD CID URI
18
27
Cid(Cid<'u>),
28
+
/// Unrecognized URI scheme (catch-all)
19
29
Any(CowStr<'u>),
20
30
}
21
31
32
+
/// Errors that can occur when parsing URIs
22
33
#[derive(Debug, thiserror::Error, miette::Diagnostic)]
23
34
pub enum UriParseError {
35
+
/// AT Protocol string parsing error
24
36
#[error("Invalid atproto string: {0}")]
25
37
At(#[from] AtStrError),
38
+
/// Generic URL parsing error
26
39
#[error(transparent)]
27
40
Url(#[from] url::ParseError),
41
+
/// CID parsing error
28
42
#[error(transparent)]
29
43
Cid(#[from] crate::types::cid::Error),
30
44
}
31
45
32
46
impl<'u> Uri<'u> {
47
+
/// Parse a URI from a string slice, borrowing
33
48
pub fn new(uri: &'u str) -> Result<Self, UriParseError> {
34
49
if uri.starts_with("did:") {
35
50
Ok(Uri::Did(Did::new(uri)?))
···
46
61
}
47
62
}
48
63
64
+
/// Parse a URI from a string, taking ownership
49
65
pub fn new_owned(uri: impl AsRef<str>) -> Result<Uri<'static>, UriParseError> {
50
66
let uri = uri.as_ref();
51
67
if uri.starts_with("did:") {
···
63
79
}
64
80
}
65
81
82
+
/// Get the URI as a string slice
66
83
pub fn as_str(&self) -> &str {
67
84
match self {
68
85
Uri::Did(did) => did.as_str(),
+6
crates/jacquard-common/src/types/value/parsing.rs
+6
crates/jacquard-common/src/types/value/parsing.rs
···
17
17
use std::{collections::BTreeMap, str::FromStr};
18
18
use url::Url;
19
19
20
+
/// Insert a string into an at:// `Data<'_>` map, inferring its type.
20
21
pub fn insert_string<'s>(
21
22
map: &mut BTreeMap<SmolStr, Data<'s>>,
22
23
key: &'s str,
···
231
232
}
232
233
}
233
234
235
+
/// Convert an ipld map to a atproto data model blob if it matches the format
234
236
pub fn cbor_to_blob<'b>(blob: &'b BTreeMap<String, Ipld>) -> Option<Blob<'b>> {
235
237
let mime_type = blob.get("mimeType").and_then(|o| {
236
238
if let Ipld::String(string) = o {
···
267
269
None
268
270
}
269
271
272
+
/// convert a JSON object to an atproto data model blob if it matches the format
270
273
pub fn json_to_blob<'b>(blob: &'b serde_json::Map<String, serde_json::Value>) -> Option<Blob<'b>> {
271
274
let mime_type = blob.get("mimeType").and_then(|v| v.as_str());
272
275
if let Some(value) = blob.get("ref") {
···
297
300
None
298
301
}
299
302
303
+
/// Infer if something with a "$type" field is a blob or an object
300
304
pub fn infer_from_type(type_field: &str) -> DataModelType {
301
305
match type_field {
302
306
"blob" => DataModelType::Blob,
···
304
308
}
305
309
}
306
310
311
+
/// decode a base64 byte string into atproto data
307
312
pub fn decode_bytes<'s>(bytes: &str) -> Data<'s> {
308
313
// First one should just work. rest are insurance.
309
314
if let Ok(bytes) = BASE64_STANDARD.decode(bytes) {
···
319
324
}
320
325
}
321
326
327
+
/// decode a base64 byte string into atproto raw unvalidated data
322
328
pub fn decode_raw_bytes<'s>(bytes: &str) -> RawData<'s> {
323
329
// First one should just work. rest are insurance.
324
330
if let Ok(bytes) = BASE64_STANDARD.decode(bytes) {
+47
crates/jacquard-common/src/types/value.rs
+47
crates/jacquard-common/src/types/value.rs
···
7
7
use smol_str::{SmolStr, ToSmolStr};
8
8
use std::collections::BTreeMap;
9
9
10
+
/// Conversion utilities for Data types
10
11
pub mod convert;
12
+
/// String parsing for AT Protocol types
11
13
pub mod parsing;
14
+
/// Serde implementations for Data types
12
15
pub mod serde_impl;
13
16
14
17
#[cfg(test)]
15
18
mod tests;
16
19
20
+
/// AT Protocol data model value
21
+
///
22
+
/// Represents any valid value in the AT Protocol data model, which supports JSON and CBOR
23
+
/// serialization with specific constraints (no floats, CID links, blobs with metadata).
24
+
///
25
+
/// This is the generic "unknown data" type used for lexicon values, extra fields captured
26
+
/// by `#[lexicon]`, and IPLD data structures.
17
27
#[derive(Debug, Clone, PartialEq, Eq)]
18
28
pub enum Data<'s> {
29
+
/// Null value
19
30
Null,
31
+
/// Boolean value
20
32
Boolean(bool),
33
+
/// Integer value (no floats in AT Protocol)
21
34
Integer(i64),
35
+
/// String value (parsed into specific AT Protocol types when possible)
22
36
String(AtprotoStr<'s>),
37
+
/// Raw bytes
23
38
Bytes(Bytes),
39
+
/// CID link reference
24
40
CidLink(Cid<'s>),
41
+
/// Array of values
25
42
Array(Array<'s>),
43
+
/// Object/map of values
26
44
Object(Object<'s>),
45
+
/// Blob reference with metadata
27
46
Blob(Blob<'s>),
28
47
}
29
48
49
+
/// Errors that can occur when working with AT Protocol data
30
50
#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error, miette::Diagnostic)]
31
51
pub enum AtDataError {
52
+
/// Floating point numbers are not allowed in AT Protocol
32
53
#[error("floating point numbers not allowed in AT protocol data")]
33
54
FloatNotAllowed,
34
55
}
35
56
36
57
impl<'s> Data<'s> {
58
+
/// Get the data model type of this value
37
59
pub fn data_type(&self) -> DataModelType {
38
60
match self {
39
61
Data::Null => DataModelType::Null,
···
69
91
Data::Blob(_) => DataModelType::Blob,
70
92
}
71
93
}
94
+
/// Parse a Data value from a JSON value
72
95
pub fn from_json(json: &'s serde_json::Value) -> Result<Self, AtDataError> {
73
96
Ok(if let Some(value) = json.as_bool() {
74
97
Self::Boolean(value)
···
87
110
})
88
111
}
89
112
113
+
/// Parse a Data value from an IPLD value (CBOR)
90
114
pub fn from_cbor(cbor: &'s Ipld) -> Result<Self, AtDataError> {
91
115
Ok(match cbor {
92
116
Ipld::Null => Data::Null,
···
121
145
}
122
146
}
123
147
148
+
/// Array of AT Protocol data values
124
149
#[derive(Debug, Clone, PartialEq, Eq)]
125
150
pub struct Array<'s>(pub Vec<Data<'s>>);
126
151
···
132
157
}
133
158
134
159
impl<'s> Array<'s> {
160
+
/// Parse an array from JSON values
135
161
pub fn from_json(json: &'s Vec<serde_json::Value>) -> Result<Self, AtDataError> {
136
162
let mut array = Vec::with_capacity(json.len());
137
163
for item in json {
···
139
165
}
140
166
Ok(Self(array))
141
167
}
168
+
/// Parse an array from IPLD values (CBOR)
142
169
pub fn from_cbor(cbor: &'s Vec<Ipld>) -> Result<Self, AtDataError> {
143
170
let mut array = Vec::with_capacity(cbor.len());
144
171
for item in cbor {
···
148
175
}
149
176
}
150
177
178
+
/// Object/map of AT Protocol data values
151
179
#[derive(Debug, Clone, PartialEq, Eq)]
152
180
pub struct Object<'s>(pub BTreeMap<SmolStr, Data<'s>>);
153
181
···
159
187
}
160
188
161
189
impl<'s> Object<'s> {
190
+
/// Parse an object from a JSON map with type inference
191
+
///
192
+
/// Uses key names to infer the appropriate AT Protocol types for values.
162
193
pub fn from_json(
163
194
json: &'s serde_json::Map<String, serde_json::Value>,
164
195
) -> Result<Data<'s>, AtDataError> {
···
232
263
Ok(Data::Object(Object(map)))
233
264
}
234
265
266
+
/// Parse an object from IPLD (CBOR) with type inference
267
+
///
268
+
/// Uses key names to infer the appropriate AT Protocol types for values.
235
269
pub fn from_cbor(cbor: &'s BTreeMap<String, Ipld>) -> Result<Data<'s>, AtDataError> {
236
270
if let Some(Ipld::String(type_field)) = cbor.get("$type") {
237
271
if parsing::infer_from_type(type_field) == DataModelType::Blob {
···
288
322
/// E.g. lower-level services, PDS implementations, firehose indexers, relay implementations.
289
323
#[derive(Debug, Clone, PartialEq, Eq)]
290
324
pub enum RawData<'s> {
325
+
/// Null value
291
326
Null,
327
+
/// Boolean value
292
328
Boolean(bool),
329
+
/// Signed integer
293
330
SignedInt(i64),
331
+
/// Unsigned integer
294
332
UnsignedInt(u64),
333
+
/// String value (no type inference)
295
334
String(CowStr<'s>),
335
+
/// Raw bytes
296
336
Bytes(Bytes),
337
+
/// CID link reference
297
338
CidLink(Cid<'s>),
339
+
/// Array of raw values
298
340
Array(Vec<RawData<'s>>),
341
+
/// Object/map of raw values
299
342
Object(BTreeMap<SmolStr, RawData<'s>>),
343
+
/// Valid blob reference
300
344
Blob(Blob<'s>),
345
+
/// Invalid blob structure (captured for debugging)
301
346
InvalidBlob(Box<RawData<'s>>),
347
+
/// Invalid number format, generally a floating point number (captured as bytes)
302
348
InvalidNumber(Bytes),
349
+
/// Invalid/unknown data (captured as bytes)
303
350
InvalidData(Bytes),
304
351
}
+30
-1
crates/jacquard-common/src/types/xrpc.rs
+30
-1
crates/jacquard-common/src/types/xrpc.rs
···
1
-
use serde::de::DeserializeOwned;
2
1
use serde::{Deserialize, Serialize};
3
2
use std::error::Error;
4
3
use std::fmt::{self, Debug};
···
6
5
use crate::IntoStatic;
7
6
use crate::types::value::Data;
8
7
8
+
/// Error type for encoding XRPC requests
9
+
#[derive(Debug, thiserror::Error, miette::Diagnostic)]
10
+
pub enum EncodeError {
11
+
/// Failed to serialize query parameters
12
+
#[error("Failed to serialize query: {0}")]
13
+
Query(
14
+
#[from]
15
+
#[source]
16
+
serde_html_form::ser::Error,
17
+
),
18
+
/// Failed to serialize JSON body
19
+
#[error("Failed to serialize JSON: {0}")]
20
+
Json(
21
+
#[from]
22
+
#[source]
23
+
serde_json::Error,
24
+
),
25
+
/// Other encoding error
26
+
#[error("Encoding error: {0}")]
27
+
Other(String),
28
+
}
29
+
9
30
/// XRPC method type
10
31
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
11
32
pub enum XrpcMethod {
···
24
45
}
25
46
}
26
47
48
+
/// Get the body encoding type for this method (procedures only)
27
49
pub const fn body_encoding(&self) -> Option<&'static str> {
28
50
match self {
29
51
Self::Query => None,
···
53
75
54
76
/// Error type for this request
55
77
type Err<'de>: Error + Deserialize<'de> + IntoStatic;
78
+
79
+
/// Encode the request body for procedures.
80
+
///
81
+
/// Default implementation serializes to JSON. Override for non-JSON encodings.
82
+
fn encode_body(&self) -> Result<Vec<u8>, EncodeError> {
83
+
Ok(serde_json::to_vec(self)?)
84
+
}
56
85
}
57
86
58
87
/// Error type for XRPC endpoints that don't define any errors
+51
-16
crates/jacquard-common/src/types.rs
+51
-16
crates/jacquard-common/src/types.rs
···
1
1
use serde::{Deserialize, Serialize};
2
2
3
+
/// AT Protocol URI (at://) types and validation
3
4
pub mod aturi;
5
+
/// Blob references for binary data
4
6
pub mod blob;
7
+
/// Content Identifier (CID) types for IPLD
5
8
pub mod cid;
9
+
/// Repository collection trait for records
6
10
pub mod collection;
11
+
/// AT Protocol datetime string type
7
12
pub mod datetime;
13
+
/// Decentralized Identifier (DID) types and validation
8
14
pub mod did;
15
+
/// AT Protocol handle types and validation
9
16
pub mod handle;
17
+
/// AT Protocol identifier types (handle or DID)
10
18
pub mod ident;
19
+
/// Integer type with validation
11
20
pub mod integer;
21
+
/// Language tag types per BCP 47
12
22
pub mod language;
23
+
/// CID link wrapper for JSON serialization
13
24
pub mod link;
25
+
/// Namespaced Identifier (NSID) types and validation
14
26
pub mod nsid;
27
+
/// Record key types and validation
15
28
pub mod recordkey;
29
+
/// String types with format validation
16
30
pub mod string;
31
+
/// Timestamp Identifier (TID) types and generation
17
32
pub mod tid;
33
+
/// URI types with scheme validation
18
34
pub mod uri;
35
+
/// Generic data value types for lexicon data model
19
36
pub mod value;
37
+
/// XRPC protocol types and traits
20
38
pub mod xrpc;
21
39
22
40
/// Trait for a constant string literal type
···
25
43
const LITERAL: &'static str;
26
44
}
27
45
46
+
/// top-level domains which are not allowed in at:// handles or dids
28
47
pub const DISALLOWED_TLDS: &[&str] = &[
29
48
".local",
30
49
".arpa",
···
39
58
// "should" "never" actually resolve and get registered in production
40
59
];
41
60
61
+
/// checks if a string ends with anything from the provided list of strings.
42
62
pub fn ends_with(string: impl AsRef<str>, list: &[&str]) -> bool {
43
63
let string = string.as_ref();
44
64
for item in list {
···
51
71
52
72
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Hash)]
53
73
#[serde(rename_all = "kebab-case")]
74
+
/// Valid types in the AT protocol [data model](https://atproto.com/specs/data-model). Type marker only, used in concert with `[Data<'_>]`.
54
75
pub enum DataModelType {
76
+
/// Null type. IPLD type `null`, JSON type `Null`, CBOR Special Value (major 7)
55
77
Null,
78
+
/// Boolean type. IPLD type `boolean`, JSON type Boolean, CBOR Special Value (major 7)
56
79
Boolean,
80
+
/// Integer type. IPLD type `integer`, JSON type Number, CBOR Special Value (major 7)
57
81
Integer,
82
+
/// Byte type. IPLD type `bytes`, in JSON a `{ "$bytes": bytes }` Object, CBOR Byte String (major 2)
58
83
Bytes,
84
+
/// CID (content identifier) link. IPLD type `link`, in JSON a `{ "$link": cid }` Object, CBOR CID (tag 42)
59
85
CidLink,
86
+
/// Blob type. No special IPLD type. in JSON a `{ "$type": "blob" }` Object. in CBOR a `{ "$type": "blob" }` Map.
60
87
Blob,
88
+
/// Array type. IPLD type `list`. JSON type `Array`, CBOR type Array (major 4)
61
89
Array,
90
+
/// Object type. IPLD type `map`. JSON type `Object`, CBOR type Map (major 5). keys are always SmolStr.
62
91
Object,
63
92
#[serde(untagged)]
93
+
/// String type (lots of variants). JSON String, CBOR UTF-8 String (major 3)
64
94
String(LexiconStringType),
65
95
}
66
96
67
-
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Hash)]
68
-
#[serde(rename_all = "kebab-case")]
69
-
pub enum LexiconType {
70
-
Params,
71
-
Token,
72
-
Ref,
73
-
Union,
74
-
Unknown,
75
-
Record,
76
-
Query,
77
-
Procedure,
78
-
Subscription,
79
-
#[serde(untagged)]
80
-
DataModel(DataModelType),
81
-
}
82
-
97
+
/// Lexicon string format types for typed strings in the AT Protocol data model
83
98
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Hash)]
84
99
#[serde(rename_all = "kebab-case")]
85
100
pub enum LexiconStringType {
101
+
/// ISO 8601 datetime string
86
102
Datetime,
103
+
/// AT Protocol URI (at://)
87
104
AtUri,
105
+
/// Decentralized Identifier
88
106
Did,
107
+
/// AT Protocol handle
89
108
Handle,
109
+
/// Handle or DID
90
110
AtIdentifier,
111
+
/// Namespaced Identifier
91
112
Nsid,
113
+
/// Content Identifier
92
114
Cid,
115
+
/// BCP 47 language tag
93
116
Language,
117
+
/// Timestamp Identifier
94
118
Tid,
119
+
/// Record key
95
120
RecordKey,
121
+
/// URI with type constraint
96
122
Uri(UriType),
123
+
/// Plain string
97
124
#[serde(untagged)]
98
125
String,
99
126
}
100
127
128
+
/// URI scheme types for lexicon URI format constraints
101
129
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
102
130
#[serde(tag = "type")]
103
131
pub enum UriType {
132
+
/// DID URI (did:)
104
133
Did,
134
+
/// AT Protocol URI (at://)
105
135
At,
136
+
/// HTTPS URI
106
137
Https,
138
+
/// WebSocket Secure URI
107
139
Wss,
140
+
/// CID URI
108
141
Cid,
142
+
/// DNS name
109
143
Dns,
144
+
/// Any valid URI
110
145
Any,
111
146
}
+12
-12
crates/jacquard-derive/Cargo.toml
+12
-12
crates/jacquard-derive/Cargo.toml
···
1
1
[package]
2
2
name = "jacquard-derive"
3
+
description = "Procedural macros for Jacquard lexicon types"
3
4
edition.workspace = true
4
5
version.workspace = true
5
6
authors.workspace = true
···
7
8
keywords.workspace = true
8
9
categories.workspace = true
9
10
readme.workspace = true
10
-
documentation.workspace = true
11
11
exclude.workspace = true
12
-
description.workspace = true
12
+
license-file.workspace = true
13
13
14
14
[lib]
15
15
proc-macro = true
16
16
17
17
[dependencies]
18
-
heck = "0.5.0"
19
-
itertools = "0.14.0"
20
-
prettyplease = "0.2.37"
21
-
proc-macro2 = "1.0.101"
22
-
quote = "1.0.41"
23
-
serde = { version = "1.0.228", features = ["derive"] }
24
-
serde_json = "1.0.145"
25
-
serde_repr = "0.1.20"
26
-
serde_with = "3.14.1"
27
-
syn = "2.0.106"
18
+
heck.workspace = true
19
+
itertools.workspace = true
20
+
prettyplease.workspace = true
21
+
proc-macro2.workspace = true
22
+
quote.workspace = true
23
+
serde.workspace = true
24
+
serde_json.workspace = true
25
+
serde_repr.workspace = true
26
+
serde_with.workspace = true
27
+
syn.workspace = true
28
28
29
29
30
30
[dev-dependencies]
+1
-1
crates/jacquard-derive/tests/open_union.rs
+1
-1
crates/jacquard-derive/tests/open_union.rs
···
24
24
25
25
#[test]
26
26
fn test_open_union_unknown_variant() {
27
-
use jacquard_common::types::value::{Data, Object};
27
+
use jacquard_common::types::value::Data;
28
28
29
29
let json = r#"{"$type":"com.example.unknown","data":"something"}"#;
30
30
let union: TestUnion = serde_json::from_str(json).unwrap();
+18
-15
crates/jacquard-lexicon/Cargo.toml
+18
-15
crates/jacquard-lexicon/Cargo.toml
···
1
1
[package]
2
2
name = "jacquard-lexicon"
3
+
description = "Lexicon schema parsing and code generation for Jacquard"
3
4
edition.workspace = true
4
5
version.workspace = true
5
6
authors.workspace = true
···
7
8
keywords.workspace = true
8
9
categories.workspace = true
9
10
readme.workspace = true
10
-
documentation.workspace = true
11
11
exclude.workspace = true
12
-
description.workspace = true
12
+
license-file.workspace = true
13
13
14
14
[[bin]]
15
15
name = "jacquard-codegen"
16
16
path = "src/bin/codegen.rs"
17
17
18
18
[dependencies]
19
-
clap = { workspace = true }
20
-
heck = "0.5.0"
21
-
itertools = "0.14.0"
19
+
clap.workspace = true
20
+
heck.workspace = true
21
+
itertools.workspace = true
22
22
jacquard-common = { version = "0.1.0", path = "../jacquard-common" }
23
-
miette = { version = "7.6.0", features = ["fancy"] }
24
-
prettyplease = "0.2.37"
25
-
proc-macro2 = "1.0.101"
26
-
quote = "1.0.41"
27
-
serde = { version = "1.0.228", features = ["derive"] }
28
-
serde_json = "1.0.145"
29
-
serde_repr = "0.1.20"
30
-
serde_with = "3.14.1"
31
-
syn = "2.0.106"
32
-
thiserror = "2.0.17"
23
+
miette = { workspace = true, features = ["fancy"] }
24
+
prettyplease.workspace = true
25
+
proc-macro2.workspace = true
26
+
quote.workspace = true
27
+
serde.workspace = true
28
+
serde_json.workspace = true
29
+
serde_repr.workspace = true
30
+
serde_with.workspace = true
31
+
syn.workspace = true
32
+
thiserror.workspace = true
33
+
34
+
[dev-dependencies]
35
+
tempfile = { version = "3.23.0" }
+150
-74
crates/jacquard-lexicon/src/codegen.rs
+150
-74
crates/jacquard-lexicon/src/codegen.rs
···
152
152
let ident = syn::Ident::new(&type_name, proc_macro2::Span::call_site());
153
153
154
154
// Generate main struct fields
155
-
let fields = self.generate_object_fields(nsid, &type_name, obj)?;
155
+
let fields = self.generate_object_fields(nsid, &type_name, obj, false)?;
156
156
let doc = self.generate_doc_comment(record.description.as_ref());
157
157
158
158
// Records always get a lifetime since they have the #[lexicon] attribute
···
213
213
let type_name = self.def_to_type_name(nsid, def_name);
214
214
let ident = syn::Ident::new(&type_name, proc_macro2::Span::call_site());
215
215
216
-
let fields = self.generate_object_fields(nsid, &type_name, obj)?;
216
+
let fields = self.generate_object_fields(nsid, &type_name, obj, false)?;
217
217
let doc = self.generate_doc_comment(obj.description.as_ref());
218
218
219
219
// Objects always get a lifetime since they have the #[lexicon] attribute
···
257
257
nsid: &str,
258
258
parent_type_name: &str,
259
259
obj: &LexObject<'static>,
260
+
is_builder: bool,
260
261
) -> Result<TokenStream> {
261
262
let required = obj.required.as_ref().map(|r| r.as_slice()).unwrap_or(&[]);
262
263
263
264
let mut fields = Vec::new();
264
265
for (field_name, field_type) in &obj.properties {
265
266
let is_required = required.contains(field_name);
266
-
let field_tokens =
267
-
self.generate_field(nsid, parent_type_name, field_name, field_type, is_required)?;
267
+
let field_tokens = self.generate_field(
268
+
nsid,
269
+
parent_type_name,
270
+
field_name,
271
+
field_type,
272
+
is_required,
273
+
is_builder,
274
+
)?;
268
275
fields.push(field_tokens);
269
276
}
270
277
···
279
286
field_name: &str,
280
287
field_type: &LexObjectProperty<'static>,
281
288
is_required: bool,
289
+
is_builder: bool,
282
290
) -> Result<TokenStream> {
283
291
let field_ident = make_ident(&field_name.to_snake_case());
284
292
···
286
294
self.property_to_rust_type(nsid, parent_type_name, field_name, field_type)?;
287
295
let needs_lifetime = self.property_needs_lifetime(field_type);
288
296
297
+
// Check if this is a CowStr field for builder(into) attribute
298
+
let is_cowstr = matches!(field_type, LexObjectProperty::String(s) if s.format.is_none());
299
+
289
300
let rust_type = if is_required {
290
301
rust_type
291
302
} else {
···
316
327
// Add serde(borrow) to all fields with lifetimes
317
328
if needs_lifetime {
318
329
attrs.push(quote! { #[serde(borrow)] });
330
+
}
331
+
332
+
// Add builder(into) for CowStr fields to allow String, &str, etc., but only for builder structs
333
+
if is_builder && is_cowstr {
334
+
attrs.push(quote! { #[builder(into)] });
319
335
}
320
336
321
337
Ok(quote! {
···
662
678
params_has_lifetime,
663
679
has_output,
664
680
has_errors,
681
+
false, // queries never have binary inputs
665
682
)?;
666
683
output.push(xrpc_impl);
667
684
···
680
697
let type_base = self.def_to_type_name(nsid, def_name);
681
698
let mut output = Vec::new();
682
699
683
-
// Input bodies always have lifetimes (they get #[lexicon] attribute)
684
-
let params_has_lifetime = proc.input.is_some();
700
+
// Check if input is a binary body (no schema)
701
+
let is_binary_input = proc
702
+
.input
703
+
.as_ref()
704
+
.map(|i| i.schema.is_none())
705
+
.unwrap_or(false);
706
+
707
+
// Input bodies with schemas have lifetimes (they get #[lexicon] attribute)
708
+
// Binary inputs don't have lifetimes
709
+
let params_has_lifetime = proc.input.is_some() && !is_binary_input;
685
710
let has_input = proc.input.is_some();
686
711
let has_output = proc.output.is_some();
687
712
let has_errors = proc.errors.is_some();
···
726
751
params_has_lifetime,
727
752
has_output,
728
753
has_errors,
754
+
is_binary_input,
729
755
)?;
730
756
output.push(xrpc_impl);
731
757
···
855
881
let struct_name = format!("{}Message", type_base);
856
882
let struct_ident = syn::Ident::new(&struct_name, proc_macro2::Span::call_site());
857
883
858
-
let fields = self.generate_object_fields("", &struct_name, obj)?;
884
+
let fields = self.generate_object_fields("", &struct_name, obj, false)?;
859
885
let doc = self.generate_doc_comment(obj.description.as_ref());
860
886
861
887
// Subscription message structs always get a lifetime since they have the #[lexicon] attribute
···
1069
1095
path
1070
1096
};
1071
1097
1098
+
let is_root = dir.components().count() == 0;
1072
1099
let mods: Vec<_> = module_names
1073
1100
.iter()
1074
1101
.map(|name| {
1075
1102
let ident = syn::Ident::new(name, proc_macro2::Span::call_site());
1076
-
quote! { pub mod #ident; }
1103
+
if is_root {
1104
+
// Top-level modules get feature gates
1105
+
quote! {
1106
+
#[cfg(feature = #name)]
1107
+
pub mod #ident;
1108
+
}
1109
+
} else {
1110
+
quote! { pub mod #ident; }
1111
+
}
1077
1112
})
1078
1113
.collect();
1079
1114
···
1253
1288
let doc = self.generate_doc_comment(p.description.as_ref());
1254
1289
let needs_lifetime = self.params_need_lifetime(p);
1255
1290
1256
-
let derives =
1257
-
quote! { #[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)] };
1291
+
let derives = quote! {
1292
+
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq, bon::Builder)]
1293
+
#[builder(start_fn = new)]
1294
+
};
1258
1295
1259
1296
// Generate IntoStatic impl
1260
1297
let field_names: Vec<&str> = p.properties.keys().map(|k| k.as_str()).collect();
···
1424
1461
) -> Result<TokenStream> {
1425
1462
let ident = syn::Ident::new(type_base, proc_macro2::Span::call_site());
1426
1463
1464
+
// Check if this is a binary body (no schema, just raw bytes)
1465
+
let is_binary_body = body.schema.is_none();
1466
+
1427
1467
let fields = if let Some(schema) = &body.schema {
1428
-
self.generate_body_fields("", type_base, schema)?
1468
+
self.generate_body_fields("", type_base, schema, true)?
1429
1469
} else {
1430
-
quote! {}
1470
+
// Binary body: just a bytes field
1471
+
quote! {
1472
+
pub body: bytes::Bytes,
1473
+
}
1431
1474
};
1432
1475
1433
1476
let doc = self.generate_doc_comment(body.description.as_ref());
1434
1477
1435
-
// Input structs always get a lifetime since they have the #[lexicon] attribute
1436
-
// which adds extra_data: BTreeMap<..., Data<'a>>
1437
-
let struct_def = quote! {
1438
-
#doc
1439
-
#[jacquard_derive::lexicon]
1440
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
1441
-
#[serde(rename_all = "camelCase")]
1442
-
pub struct #ident<'a> {
1443
-
#fields
1478
+
// Binary bodies don't need #[lexicon] attribute or lifetime
1479
+
let struct_def = if is_binary_body {
1480
+
quote! {
1481
+
#doc
1482
+
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq, bon::Builder)]
1483
+
#[builder(start_fn = new)]
1484
+
#[serde(rename_all = "camelCase")]
1485
+
pub struct #ident {
1486
+
#fields
1487
+
}
1488
+
}
1489
+
} else {
1490
+
// Input structs with schemas: manually add extra_data field with #[builder(default)]
1491
+
// for bon compatibility. The #[lexicon] macro will see it exists and skip adding it.
1492
+
quote! {
1493
+
#doc
1494
+
#[jacquard_derive::lexicon]
1495
+
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq, bon::Builder)]
1496
+
#[serde(rename_all = "camelCase")]
1497
+
#[builder(start_fn = new)]
1498
+
pub struct #ident<'a> {
1499
+
#fields
1500
+
#[serde(flatten)]
1501
+
#[serde(borrow)]
1502
+
#[builder(default)]
1503
+
pub extra_data: ::std::collections::BTreeMap<
1504
+
::jacquard_common::smol_str::SmolStr,
1505
+
::jacquard_common::types::value::Data<'a>
1506
+
>,
1507
+
}
1444
1508
}
1445
1509
};
1446
1510
···
1458
1522
}
1459
1523
1460
1524
// Generate IntoStatic impl
1461
-
let field_names: Vec<&str> = match &body.schema {
1462
-
Some(crate::lexicon::LexXrpcBodySchema::Object(obj)) => {
1463
-
obj.properties.keys().map(|k| k.as_str()).collect()
1464
-
}
1465
-
Some(_) => {
1466
-
// For Ref or Union schemas, there's just a single flattened field
1467
-
vec!["value"]
1468
-
}
1469
-
None => {
1470
-
// No schema means no fields, just extra_data
1471
-
vec![]
1525
+
let into_static_impl = if is_binary_body {
1526
+
// Binary bodies: simple clone of the Bytes field
1527
+
quote! {
1528
+
impl jacquard_common::IntoStatic for #ident {
1529
+
type Output = #ident;
1530
+
fn into_static(self) -> Self::Output {
1531
+
self
1532
+
}
1533
+
}
1472
1534
}
1535
+
} else {
1536
+
let field_names: Vec<&str> = match &body.schema {
1537
+
Some(crate::lexicon::LexXrpcBodySchema::Object(obj)) => {
1538
+
obj.properties.keys().map(|k| k.as_str()).collect()
1539
+
}
1540
+
Some(_) => {
1541
+
// For Ref or Union schemas, there's just a single flattened field
1542
+
vec!["value"]
1543
+
}
1544
+
None => {
1545
+
// No schema means no fields, just extra_data
1546
+
vec![]
1547
+
}
1548
+
};
1549
+
self.generate_into_static_for_struct(type_base, &field_names, true, true)
1473
1550
};
1474
-
let into_static_impl =
1475
-
self.generate_into_static_for_struct(type_base, &field_names, true, true);
1476
1551
1477
1552
Ok(quote! {
1478
1553
#struct_def
···
1491
1566
let ident = syn::Ident::new(&struct_name, proc_macro2::Span::call_site());
1492
1567
1493
1568
let fields = if let Some(schema) = &body.schema {
1494
-
self.generate_body_fields("", &struct_name, schema)?
1569
+
self.generate_body_fields("", &struct_name, schema, false)?
1495
1570
} else {
1496
1571
quote! {}
1497
1572
};
···
1554
1629
nsid: &str,
1555
1630
parent_type_name: &str,
1556
1631
schema: &LexXrpcBodySchema<'static>,
1632
+
is_builder: bool,
1557
1633
) -> Result<TokenStream> {
1558
1634
use crate::lexicon::LexXrpcBodySchema;
1559
1635
1560
1636
match schema {
1561
1637
LexXrpcBodySchema::Object(obj) => {
1562
-
self.generate_object_fields(nsid, parent_type_name, obj)
1638
+
self.generate_object_fields(nsid, parent_type_name, obj, is_builder)
1563
1639
}
1564
1640
LexXrpcBodySchema::Ref(ref_type) => {
1565
1641
let rust_type = self.ref_to_rust_type(&ref_type.r#ref)?;
···
1592
1668
1593
1669
let field_ident = make_ident(&field_name.to_snake_case());
1594
1670
1595
-
let (rust_type, needs_lifetime) = match field_type {
1596
-
LexXrpcParametersProperty::Boolean(_) => (quote! { bool }, false),
1597
-
LexXrpcParametersProperty::Integer(_) => (quote! { i64 }, false),
1671
+
let (rust_type, needs_lifetime, is_cowstr) = match field_type {
1672
+
LexXrpcParametersProperty::Boolean(_) => (quote! { bool }, false, false),
1673
+
LexXrpcParametersProperty::Integer(_) => (quote! { i64 }, false, false),
1598
1674
LexXrpcParametersProperty::String(s) => {
1599
-
(self.string_to_rust_type(s), self.string_needs_lifetime(s))
1600
-
}
1601
-
LexXrpcParametersProperty::Unknown(_) => {
1602
-
(quote! { jacquard_common::types::value::Data<'a> }, true)
1675
+
let is_cowstr = s.format.is_none(); // CowStr for plain strings
1676
+
(
1677
+
self.string_to_rust_type(s),
1678
+
self.string_needs_lifetime(s),
1679
+
is_cowstr,
1680
+
)
1603
1681
}
1682
+
LexXrpcParametersProperty::Unknown(_) => (
1683
+
quote! { jacquard_common::types::value::Data<'a> },
1684
+
true,
1685
+
false,
1686
+
),
1604
1687
LexXrpcParametersProperty::Array(arr) => {
1605
1688
let needs_lifetime = match &arr.items {
1606
1689
crate::lexicon::LexPrimitiveArrayItem::Boolean(_)
···
1618
1701
quote! { jacquard_common::types::value::Data<'a> }
1619
1702
}
1620
1703
};
1621
-
(quote! { Vec<#item_type> }, needs_lifetime)
1704
+
(quote! { Vec<#item_type> }, needs_lifetime, false)
1622
1705
}
1623
1706
};
1624
1707
···
1637
1720
// Add serde(borrow) to all fields with lifetimes
1638
1721
if needs_lifetime {
1639
1722
attrs.push(quote! { #[serde(borrow)] });
1723
+
}
1724
+
1725
+
// Add builder(into) for CowStr fields to allow String, &str, etc.
1726
+
if is_cowstr {
1727
+
attrs.push(quote! { #[builder(into)] });
1640
1728
}
1641
1729
1642
1730
Ok(quote! {
···
1923
2011
params_has_lifetime: bool,
1924
2012
has_output: bool,
1925
2013
has_errors: bool,
2014
+
is_binary_input: bool,
1926
2015
) -> Result<TokenStream> {
1927
2016
let output_type = if has_output {
1928
2017
let output_ident = syn::Ident::new(
···
1944
2033
quote! { jacquard_common::types::xrpc::GenericError<'de> }
1945
2034
};
1946
2035
2036
+
// Generate encode_body() method for binary inputs
2037
+
let encode_body_method = if is_binary_input {
2038
+
quote! {
2039
+
fn encode_body(&self) -> Result<Vec<u8>, jacquard_common::types::xrpc::EncodeError> {
2040
+
Ok(self.body.to_vec())
2041
+
}
2042
+
}
2043
+
} else {
2044
+
quote! {}
2045
+
};
2046
+
1947
2047
if has_params {
1948
2048
// Implement on the params/input struct itself
1949
2049
let request_ident = syn::Ident::new(type_base, proc_macro2::Span::call_site());
···
1961
2061
1962
2062
type Output<'de> = #output_type;
1963
2063
type Err<'de> = #error_type;
2064
+
2065
+
#encode_body_method
1964
2066
}
1965
2067
})
1966
2068
} else {
···
2311
2413
println!("\n{}\n", formatted);
2312
2414
2313
2415
// Check structure
2314
-
assert!(formatted.contains("struct GetAuthorFeedParams"));
2416
+
assert!(formatted.contains("struct GetAuthorFeed"));
2315
2417
assert!(formatted.contains("struct GetAuthorFeedOutput"));
2316
2418
assert!(formatted.contains("enum GetAuthorFeedError"));
2317
2419
assert!(formatted.contains("pub actor"));
···
2382
2484
LexiconCorpus::load_from_dir("tests/fixtures/test_lexicons").expect("load corpus");
2383
2485
let codegen = CodeGenerator::new(&corpus, "test_generated");
2384
2486
2385
-
let output_dir = std::path::PathBuf::from("target/test_codegen_output");
2487
+
let tmp_dir =
2488
+
tempfile::tempdir().expect("should be able to create temp directory for output");
2489
+
let output_dir = std::path::PathBuf::from(tmp_dir.path());
2386
2490
2387
2491
// Clean up any previous test output
2388
2492
let _ = std::fs::remove_dir_all(&output_dir);
···
2404
2508
.expect("read post.rs");
2405
2509
assert!(post_content.contains("pub struct Post"));
2406
2510
assert!(post_content.contains("jacquard_common"));
2407
-
}
2408
-
2409
-
#[test]
2410
-
#[ignore] // run manually: cargo test test_generate_full_atproto -- --ignored
2411
-
fn test_generate_full_atproto() {
2412
-
let corpus = LexiconCorpus::load_from_dir("tests/fixtures/lexicons/atproto/lexicons")
2413
-
.expect("load atproto corpus");
2414
-
let codegen = CodeGenerator::new(&corpus, "crate");
2415
-
2416
-
let output_dir = std::path::PathBuf::from("../jacquard-api/src");
2417
-
2418
-
// Clean up existing generated code
2419
-
if output_dir.exists() {
2420
-
for entry in std::fs::read_dir(&output_dir).expect("read output dir") {
2421
-
let entry = entry.expect("dir entry");
2422
-
let path = entry.path();
2423
-
if path.is_dir() {
2424
-
std::fs::remove_dir_all(&path).ok();
2425
-
} else if path.extension().map_or(false, |e| e == "rs") {
2426
-
std::fs::remove_file(&path).ok();
2427
-
}
2428
-
}
2429
-
}
2430
-
2431
-
// Generate and write
2432
-
codegen.write_to_disk(&output_dir).expect("write to disk");
2433
-
2434
-
println!("\nโจ Generated full atproto API to {:?}", output_dir);
2435
2511
}
2436
2512
}
-47
crates/jacquard-lexicon/src/lib.rs
-47
crates/jacquard-lexicon/src/lib.rs
···
4
4
pub mod fs;
5
5
pub mod lexicon;
6
6
pub mod union_registry;
7
-
8
-
// #[lexicon]
9
-
// #[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
10
-
// #[serde(rename_all = "camelCase")]
11
-
// pub struct Post<'s> {
12
-
// ///Client-declared timestamp when this post was originally created.
13
-
// pub created_at: jacquard_common::types::string::Datetime,
14
-
// #[serde(skip_serializing_if = "core::option::Option::is_none")]
15
-
// pub embed: core::option::Option<RecordEmbed<'s>>,
16
-
// ///DEPRECATED: replaced by app.bsky.richtext.facet.
17
-
// #[serde(skip_serializing_if = "core::option::Option::is_none")]
18
-
// pub entities: core::option::Option<Vec<Entity<'s>>>,
19
-
// ///Annotations of text (mentions, URLs, hashtags, etc)
20
-
// #[serde(skip_serializing_if = "core::option::Option::is_none")]
21
-
// pub facets: core::option::Option<Vec<jacquard_api::app_bsky::richtext::Facet<'s>>>,
22
-
// ///Self-label values for this post. Effectively content warnings.
23
-
// #[serde(skip_serializing_if = "core::option::Option::is_none")]
24
-
// pub labels: core::option::Option<RecordLabels<'s>>,
25
-
// ///Indicates human language of post primary text content.
26
-
// #[serde(skip_serializing_if = "core::option::Option::is_none")]
27
-
// pub langs: core::option::Option<Vec<jacquard_common::types::string::Language>>,
28
-
// #[serde(skip_serializing_if = "core::option::Option::is_none")]
29
-
// pub reply: core::option::Option<ReplyRef<'s>>,
30
-
// ///Additional hashtags, in addition to any included in post text and facets.
31
-
// #[serde(skip_serializing_if = "core::option::Option::is_none")]
32
-
// pub tags: core::option::Option<Vec<jacquard_common::CowStr<'s>>>,
33
-
// ///The primary post content. May be an empty string, if there are embeds.
34
-
// #[serde(borrow)]
35
-
// pub text: jacquard_common::CowStr<'s>,
36
-
// }
37
-
38
-
// #[open_union]
39
-
// #[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
40
-
// #[serde(tag = "$type")]
41
-
// pub enum RecordEmbed<'s> {
42
-
// #[serde(borrow)]
43
-
// #[serde(rename = "app.bsky.embed.images")]
44
-
// EmbedImages(Box<jacquard_api::app_bsky::embed::Images<'s>>),
45
-
// #[serde(rename = "app.bsky.embed.video")]
46
-
// EmbedVideo(Box<jacquard_api::app_bsky::embed::Video<'s>>),
47
-
// #[serde(rename = "app.bsky.embed.external")]
48
-
// EmbedExternal(Box<jacquard_api::app_bsky::embed::External<'s>>),
49
-
// #[serde(rename = "app.bsky.embed.record")]
50
-
// EmbedRecord(Box<jacquard_api::app_bsky::embed::Record<'s>>),
51
-
// #[serde(rename = "app.bsky.embed.recordWithMedia")]
52
-
// EmbedRecordWithMedia(Box<jacquard_api::app_bsky::embed::RecordWithMedia<'s>>),
53
-
// }
-29
crates/jacquard-lexicon/target/test_codegen_output/app_bsky/embed/external.rs
-29
crates/jacquard-lexicon/target/test_codegen_output/app_bsky/embed/external.rs
···
1
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
2
-
#[serde(rename_all = "camelCase")]
3
-
pub struct External<'a> {
4
-
pub description: jacquard_common::CowStr<'a>,
5
-
#[serde(skip_serializing_if = "Option::is_none")]
6
-
pub thumb: Option<jacquard_common::types::blob::Blob<'a>>,
7
-
pub title: jacquard_common::CowStr<'a>,
8
-
pub uri: jacquard_common::types::string::Uri<'a>,
9
-
}
10
-
///A representation of some externally linked content (eg, a URL and 'card'), embedded in a Bluesky record (eg, a post).
11
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
12
-
#[serde(rename_all = "camelCase")]
13
-
pub struct External<'a> {
14
-
pub external: jacquard_common::types::value::Data<'a>,
15
-
}
16
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
17
-
#[serde(rename_all = "camelCase")]
18
-
pub struct View<'a> {
19
-
pub external: jacquard_common::types::value::Data<'a>,
20
-
}
21
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
22
-
#[serde(rename_all = "camelCase")]
23
-
pub struct ViewExternal<'a> {
24
-
pub description: jacquard_common::CowStr<'a>,
25
-
#[serde(skip_serializing_if = "Option::is_none")]
26
-
pub thumb: Option<jacquard_common::types::string::Uri<'a>>,
27
-
pub title: jacquard_common::CowStr<'a>,
28
-
pub uri: jacquard_common::types::string::Uri<'a>,
29
-
}
-27
crates/jacquard-lexicon/target/test_codegen_output/app_bsky/embed/images.rs
-27
crates/jacquard-lexicon/target/test_codegen_output/app_bsky/embed/images.rs
···
1
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
2
-
#[serde(rename_all = "camelCase")]
3
-
pub struct Image<'a> {
4
-
pub alt: jacquard_common::CowStr<'a>,
5
-
#[serde(skip_serializing_if = "Option::is_none")]
6
-
pub aspect_ratio: Option<jacquard_common::types::value::Data<'a>>,
7
-
pub image: jacquard_common::types::blob::Blob<'a>,
8
-
}
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
10
-
#[serde(rename_all = "camelCase")]
11
-
pub struct Images<'a> {
12
-
pub images: Vec<jacquard_common::types::value::Data<'a>>,
13
-
}
14
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
15
-
#[serde(rename_all = "camelCase")]
16
-
pub struct View<'a> {
17
-
pub images: Vec<jacquard_common::types::value::Data<'a>>,
18
-
}
19
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
20
-
#[serde(rename_all = "camelCase")]
21
-
pub struct ViewImage<'a> {
22
-
pub alt: jacquard_common::CowStr<'a>,
23
-
#[serde(skip_serializing_if = "Option::is_none")]
24
-
pub aspect_ratio: Option<jacquard_common::types::value::Data<'a>>,
25
-
pub fullsize: jacquard_common::types::string::Uri<'a>,
26
-
pub thumb: jacquard_common::types::string::Uri<'a>,
27
-
}
-50
crates/jacquard-lexicon/target/test_codegen_output/app_bsky/embed/record.rs
-50
crates/jacquard-lexicon/target/test_codegen_output/app_bsky/embed/record.rs
···
1
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
2
-
#[serde(rename_all = "camelCase")]
3
-
pub struct Record<'a> {
4
-
pub record: test_generated::com_atproto::repo::StrongRef<'a>,
5
-
}
6
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
7
-
#[serde(rename_all = "camelCase")]
8
-
pub struct View<'a> {
9
-
pub record: RecordRecord<'a>,
10
-
}
11
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
12
-
#[serde(rename_all = "camelCase")]
13
-
pub struct ViewBlocked<'a> {
14
-
pub author: jacquard_common::types::value::Data<'a>,
15
-
pub blocked: bool,
16
-
pub uri: jacquard_common::types::string::AtUri<'a>,
17
-
}
18
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
19
-
#[serde(rename_all = "camelCase")]
20
-
pub struct ViewDetached<'a> {
21
-
pub detached: bool,
22
-
pub uri: jacquard_common::types::string::AtUri<'a>,
23
-
}
24
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
25
-
#[serde(rename_all = "camelCase")]
26
-
pub struct ViewNotFound<'a> {
27
-
pub not_found: bool,
28
-
pub uri: jacquard_common::types::string::AtUri<'a>,
29
-
}
30
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
31
-
#[serde(rename_all = "camelCase")]
32
-
pub struct ViewRecord<'a> {
33
-
pub author: jacquard_common::types::value::Data<'a>,
34
-
pub cid: jacquard_common::types::string::Cid<'a>,
35
-
#[serde(skip_serializing_if = "Option::is_none")]
36
-
pub embeds: Option<Vec<jacquard_common::types::value::Data<'a>>>,
37
-
pub indexed_at: jacquard_common::types::string::Datetime,
38
-
#[serde(skip_serializing_if = "Option::is_none")]
39
-
pub labels: Option<Vec<test_generated::com_atproto::label::Label<'a>>>,
40
-
#[serde(skip_serializing_if = "Option::is_none")]
41
-
pub like_count: Option<i64>,
42
-
#[serde(skip_serializing_if = "Option::is_none")]
43
-
pub quote_count: Option<i64>,
44
-
#[serde(skip_serializing_if = "Option::is_none")]
45
-
pub reply_count: Option<i64>,
46
-
#[serde(skip_serializing_if = "Option::is_none")]
47
-
pub repost_count: Option<i64>,
48
-
pub uri: jacquard_common::types::string::AtUri<'a>,
49
-
pub value: jacquard_common::types::value::Data<'a>,
50
-
}
-12
crates/jacquard-lexicon/target/test_codegen_output/app_bsky/embed/record_with_media.rs
-12
crates/jacquard-lexicon/target/test_codegen_output/app_bsky/embed/record_with_media.rs
···
1
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
2
-
#[serde(rename_all = "camelCase")]
3
-
pub struct RecordWithMedia<'a> {
4
-
pub media: RecordMedia<'a>,
5
-
pub record: test_generated::app_bsky::embed::Record<'a>,
6
-
}
7
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
-
#[serde(rename_all = "camelCase")]
9
-
pub struct View<'a> {
10
-
pub media: RecordMedia<'a>,
11
-
pub record: test_generated::app_bsky::embed::View<'a>,
12
-
}
-29
crates/jacquard-lexicon/target/test_codegen_output/app_bsky/embed/video.rs
-29
crates/jacquard-lexicon/target/test_codegen_output/app_bsky/embed/video.rs
···
1
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
2
-
#[serde(rename_all = "camelCase")]
3
-
pub struct Caption<'a> {
4
-
pub file: jacquard_common::types::blob::Blob<'a>,
5
-
pub lang: jacquard_common::types::string::Language,
6
-
}
7
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
8
-
#[serde(rename_all = "camelCase")]
9
-
pub struct Video<'a> {
10
-
#[serde(skip_serializing_if = "Option::is_none")]
11
-
pub alt: Option<jacquard_common::CowStr<'a>>,
12
-
#[serde(skip_serializing_if = "Option::is_none")]
13
-
pub aspect_ratio: Option<jacquard_common::types::value::Data<'a>>,
14
-
#[serde(skip_serializing_if = "Option::is_none")]
15
-
pub captions: Option<Vec<jacquard_common::types::value::Data<'a>>>,
16
-
pub video: jacquard_common::types::blob::Blob<'a>,
17
-
}
18
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
19
-
#[serde(rename_all = "camelCase")]
20
-
pub struct View<'a> {
21
-
#[serde(skip_serializing_if = "Option::is_none")]
22
-
pub alt: Option<jacquard_common::CowStr<'a>>,
23
-
#[serde(skip_serializing_if = "Option::is_none")]
24
-
pub aspect_ratio: Option<jacquard_common::types::value::Data<'a>>,
25
-
pub cid: jacquard_common::types::string::Cid<'a>,
26
-
pub playlist: jacquard_common::types::string::Uri<'a>,
27
-
#[serde(skip_serializing_if = "Option::is_none")]
28
-
pub thumbnail: Option<jacquard_common::types::string::Uri<'a>>,
29
-
}
-5
crates/jacquard-lexicon/target/test_codegen_output/app_bsky/embed.rs
-5
crates/jacquard-lexicon/target/test_codegen_output/app_bsky/embed.rs
-65
crates/jacquard-lexicon/target/test_codegen_output/app_bsky/feed/post.rs
-65
crates/jacquard-lexicon/target/test_codegen_output/app_bsky/feed/post.rs
···
1
-
///Deprecated: use facets instead.
2
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
3
-
#[serde(rename_all = "camelCase")]
4
-
pub struct Entity<'a> {
5
-
pub index: jacquard_common::types::value::Data<'a>,
6
-
pub r#type: jacquard_common::CowStr<'a>,
7
-
pub value: jacquard_common::CowStr<'a>,
8
-
}
9
-
///Record containing a Bluesky post.
10
-
#[jacquard_derive::lexicon]
11
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
12
-
#[serde(rename_all = "camelCase")]
13
-
pub struct Post<'a> {
14
-
pub created_at: jacquard_common::types::string::Datetime,
15
-
#[serde(skip_serializing_if = "Option::is_none")]
16
-
pub embed: Option<RecordEmbed<'a>>,
17
-
#[serde(skip_serializing_if = "Option::is_none")]
18
-
pub entities: Option<Vec<jacquard_common::types::value::Data<'a>>>,
19
-
#[serde(skip_serializing_if = "Option::is_none")]
20
-
pub facets: Option<Vec<test_generated::app_bsky::richtext::Facet<'a>>>,
21
-
#[serde(skip_serializing_if = "Option::is_none")]
22
-
pub labels: Option<RecordLabels<'a>>,
23
-
#[serde(skip_serializing_if = "Option::is_none")]
24
-
pub langs: Option<Vec<jacquard_common::types::string::Language>>,
25
-
#[serde(skip_serializing_if = "Option::is_none")]
26
-
pub reply: Option<jacquard_common::types::value::Data<'a>>,
27
-
#[serde(skip_serializing_if = "Option::is_none")]
28
-
pub tags: Option<Vec<jacquard_common::CowStr<'a>>>,
29
-
pub text: jacquard_common::CowStr<'a>,
30
-
}
31
-
#[jacquard_derive::open_union]
32
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
33
-
#[serde(tag = "$type")]
34
-
pub enum RecordEmbed<'a> {
35
-
#[serde(rename = "app.bsky.embed.images")]
36
-
Images(Box<test_generated::app_bsky::embed::Images<'a>>),
37
-
#[serde(rename = "app.bsky.embed.video")]
38
-
Video(Box<test_generated::app_bsky::embed::Video<'a>>),
39
-
#[serde(rename = "app.bsky.embed.external")]
40
-
External(Box<test_generated::app_bsky::embed::External<'a>>),
41
-
#[serde(rename = "app.bsky.embed.record")]
42
-
Record(Box<test_generated::app_bsky::embed::Record<'a>>),
43
-
#[serde(rename = "app.bsky.embed.recordWithMedia")]
44
-
RecordWithMedia(Box<test_generated::app_bsky::embed::RecordWithMedia<'a>>),
45
-
}
46
-
#[jacquard_derive::open_union]
47
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
48
-
#[serde(tag = "$type")]
49
-
pub enum RecordLabels<'a> {
50
-
#[serde(rename = "com.atproto.label.defs#selfLabels")]
51
-
SelfLabels(Box<test_generated::com_atproto::label::SelfLabels<'a>>),
52
-
}
53
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
54
-
#[serde(rename_all = "camelCase")]
55
-
pub struct ReplyRef<'a> {
56
-
pub parent: test_generated::com_atproto::repo::StrongRef<'a>,
57
-
pub root: test_generated::com_atproto::repo::StrongRef<'a>,
58
-
}
59
-
///Deprecated. Use app.bsky.richtext instead -- A text segment. Start is inclusive, end is exclusive. Indices are for utf16-encoded strings.
60
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
61
-
#[serde(rename_all = "camelCase")]
62
-
pub struct TextSlice<'a> {
63
-
pub end: i64,
64
-
pub start: i64,
65
-
}
-2
crates/jacquard-lexicon/target/test_codegen_output/app_bsky/feed.rs
-2
crates/jacquard-lexicon/target/test_codegen_output/app_bsky/feed.rs
-32
crates/jacquard-lexicon/target/test_codegen_output/app_bsky/richtext/facet.rs
-32
crates/jacquard-lexicon/target/test_codegen_output/app_bsky/richtext/facet.rs
···
1
-
///Specifies the sub-string range a facet feature applies to. Start index is inclusive, end index is exclusive. Indices are zero-indexed, counting bytes of the UTF-8 encoded text. NOTE: some languages, like Javascript, use UTF-16 or Unicode codepoints for string slice indexing; in these languages, convert to byte arrays before working with facets.
2
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
3
-
#[serde(rename_all = "camelCase")]
4
-
pub struct ByteSlice<'a> {
5
-
pub byte_end: i64,
6
-
pub byte_start: i64,
7
-
}
8
-
///Facet feature for a URL. The text URL may have been simplified or truncated, but the facet reference should be a complete URL.
9
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
10
-
#[serde(rename_all = "camelCase")]
11
-
pub struct Link<'a> {
12
-
pub uri: jacquard_common::types::string::Uri<'a>,
13
-
}
14
-
///Annotation of a sub-string within rich text.
15
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
16
-
#[serde(rename_all = "camelCase")]
17
-
pub struct Facet<'a> {
18
-
pub features: Vec<jacquard_common::types::value::Data<'a>>,
19
-
pub index: jacquard_common::types::value::Data<'a>,
20
-
}
21
-
///Facet feature for mention of another account. The text is usually a handle, including a '@' prefix, but the facet reference is a DID.
22
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
23
-
#[serde(rename_all = "camelCase")]
24
-
pub struct Mention<'a> {
25
-
pub did: jacquard_common::types::string::Did<'a>,
26
-
}
27
-
///Facet feature for a hashtag. The text usually includes a '#' prefix, but the facet reference should not (except in the case of 'double hash tags').
28
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
29
-
#[serde(rename_all = "camelCase")]
30
-
pub struct Tag<'a> {
31
-
pub tag: jacquard_common::CowStr<'a>,
32
-
}
-1
crates/jacquard-lexicon/target/test_codegen_output/app_bsky/richtext.rs
-1
crates/jacquard-lexicon/target/test_codegen_output/app_bsky/richtext.rs
···
1
-
pub mod facet;
-3
crates/jacquard-lexicon/target/test_codegen_output/app_bsky.rs
-3
crates/jacquard-lexicon/target/test_codegen_output/app_bsky.rs
-158
crates/jacquard-lexicon/target/test_codegen_output/com_atproto/label.rs
-158
crates/jacquard-lexicon/target/test_codegen_output/com_atproto/label.rs
···
1
-
///Metadata tag on an atproto resource (eg, repo or record).
2
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
3
-
#[serde(rename_all = "camelCase")]
4
-
pub struct Label<'a> {
5
-
#[serde(skip_serializing_if = "Option::is_none")]
6
-
pub cid: Option<jacquard_common::types::string::Cid<'a>>,
7
-
pub cts: jacquard_common::types::string::Datetime,
8
-
#[serde(skip_serializing_if = "Option::is_none")]
9
-
pub exp: Option<jacquard_common::types::string::Datetime>,
10
-
#[serde(skip_serializing_if = "Option::is_none")]
11
-
pub neg: Option<bool>,
12
-
#[serde(skip_serializing_if = "Option::is_none")]
13
-
pub sig: Option<jacquard_common::types::value::Bytes>,
14
-
pub src: jacquard_common::types::string::Did<'a>,
15
-
pub uri: jacquard_common::types::string::Uri<'a>,
16
-
pub val: jacquard_common::CowStr<'a>,
17
-
#[serde(skip_serializing_if = "Option::is_none")]
18
-
pub ver: Option<i64>,
19
-
}
20
-
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
21
-
pub enum LabelValue<'a> {
22
-
#[serde(rename = "!hide")]
23
-
Hide,
24
-
#[serde(rename = "!no-promote")]
25
-
NoPromote,
26
-
#[serde(rename = "!warn")]
27
-
Warn,
28
-
#[serde(rename = "!no-unauthenticated")]
29
-
NoUnauthenticated,
30
-
#[serde(rename = "dmca-violation")]
31
-
DmcaViolation,
32
-
#[serde(rename = "doxxing")]
33
-
Doxxing,
34
-
#[serde(rename = "porn")]
35
-
Porn,
36
-
#[serde(rename = "sexual")]
37
-
Sexual,
38
-
#[serde(rename = "nudity")]
39
-
Nudity,
40
-
#[serde(rename = "nsfl")]
41
-
Nsfl,
42
-
#[serde(rename = "gore")]
43
-
Gore,
44
-
#[serde(untagged)]
45
-
Other(jacquard_common::CowStr<'a>),
46
-
}
47
-
impl<'a> LabelValue<'a> {
48
-
pub fn as_str(&self) -> &str {
49
-
match self {
50
-
Self::Hide => "!hide",
51
-
Self::NoPromote => "!no-promote",
52
-
Self::Warn => "!warn",
53
-
Self::NoUnauthenticated => "!no-unauthenticated",
54
-
Self::DmcaViolation => "dmca-violation",
55
-
Self::Doxxing => "doxxing",
56
-
Self::Porn => "porn",
57
-
Self::Sexual => "sexual",
58
-
Self::Nudity => "nudity",
59
-
Self::Nsfl => "nsfl",
60
-
Self::Gore => "gore",
61
-
Self::Other(s) => s.as_ref(),
62
-
}
63
-
}
64
-
}
65
-
impl<'a> From<&'a str> for LabelValue<'a> {
66
-
fn from(s: &'a str) -> Self {
67
-
match s {
68
-
"!hide" => Self::Hide,
69
-
"!no-promote" => Self::NoPromote,
70
-
"!warn" => Self::Warn,
71
-
"!no-unauthenticated" => Self::NoUnauthenticated,
72
-
"dmca-violation" => Self::DmcaViolation,
73
-
"doxxing" => Self::Doxxing,
74
-
"porn" => Self::Porn,
75
-
"sexual" => Self::Sexual,
76
-
"nudity" => Self::Nudity,
77
-
"nsfl" => Self::Nsfl,
78
-
"gore" => Self::Gore,
79
-
_ => Self::Other(jacquard_common::CowStr::from(s)),
80
-
}
81
-
}
82
-
}
83
-
impl<'a> From<String> for LabelValue<'a> {
84
-
fn from(s: String) -> Self {
85
-
match s.as_str() {
86
-
"!hide" => Self::Hide,
87
-
"!no-promote" => Self::NoPromote,
88
-
"!warn" => Self::Warn,
89
-
"!no-unauthenticated" => Self::NoUnauthenticated,
90
-
"dmca-violation" => Self::DmcaViolation,
91
-
"doxxing" => Self::Doxxing,
92
-
"porn" => Self::Porn,
93
-
"sexual" => Self::Sexual,
94
-
"nudity" => Self::Nudity,
95
-
"nsfl" => Self::Nsfl,
96
-
"gore" => Self::Gore,
97
-
_ => Self::Other(jacquard_common::CowStr::from(s)),
98
-
}
99
-
}
100
-
}
101
-
impl<'a> AsRef<str> for LabelValue<'a> {
102
-
fn as_ref(&self) -> &str {
103
-
self.as_str()
104
-
}
105
-
}
106
-
impl<'a> serde::Serialize for LabelValue<'a> {
107
-
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
108
-
where
109
-
S: serde::Serializer,
110
-
{
111
-
serializer.serialize_str(self.as_str())
112
-
}
113
-
}
114
-
impl<'de, 'a> serde::Deserialize<'de> for LabelValue<'a>
115
-
where
116
-
'de: 'a,
117
-
{
118
-
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
119
-
where
120
-
D: serde::Deserializer<'de>,
121
-
{
122
-
let s = <&'de str>::deserialize(deserializer)?;
123
-
Ok(Self::from(s))
124
-
}
125
-
}
126
-
///Declares a label value and its expected interpretations and behaviors.
127
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
128
-
#[serde(rename_all = "camelCase")]
129
-
pub struct LabelValueDefinition<'a> {
130
-
#[serde(skip_serializing_if = "Option::is_none")]
131
-
pub adult_only: Option<bool>,
132
-
pub blurs: jacquard_common::CowStr<'a>,
133
-
#[serde(skip_serializing_if = "Option::is_none")]
134
-
pub default_setting: Option<jacquard_common::CowStr<'a>>,
135
-
pub identifier: jacquard_common::CowStr<'a>,
136
-
pub locales: Vec<jacquard_common::types::value::Data<'a>>,
137
-
pub severity: jacquard_common::CowStr<'a>,
138
-
}
139
-
///Strings which describe the label in the UI, localized into a specific language.
140
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
141
-
#[serde(rename_all = "camelCase")]
142
-
pub struct LabelValueDefinitionStrings<'a> {
143
-
pub description: jacquard_common::CowStr<'a>,
144
-
pub lang: jacquard_common::types::string::Language,
145
-
pub name: jacquard_common::CowStr<'a>,
146
-
}
147
-
///Metadata tag on an atproto record, published by the author within the record. Note that schemas should use #selfLabels, not #selfLabel.
148
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
149
-
#[serde(rename_all = "camelCase")]
150
-
pub struct SelfLabel<'a> {
151
-
pub val: jacquard_common::CowStr<'a>,
152
-
}
153
-
///Metadata tags on an atproto record, published by the author within the record.
154
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
155
-
#[serde(rename_all = "camelCase")]
156
-
pub struct SelfLabels<'a> {
157
-
pub values: Vec<jacquard_common::types::value::Data<'a>>,
158
-
}
-6
crates/jacquard-lexicon/target/test_codegen_output/com_atproto/repo/strong_ref.rs
-6
crates/jacquard-lexicon/target/test_codegen_output/com_atproto/repo/strong_ref.rs
-1
crates/jacquard-lexicon/target/test_codegen_output/com_atproto/repo.rs
-1
crates/jacquard-lexicon/target/test_codegen_output/com_atproto/repo.rs
···
1
-
pub mod strong_ref;
-2
crates/jacquard-lexicon/target/test_codegen_output/com_atproto.rs
-2
crates/jacquard-lexicon/target/test_codegen_output/com_atproto.rs
-2
crates/jacquard-lexicon/target/test_codegen_output/lib.rs
-2
crates/jacquard-lexicon/target/test_codegen_output/lib.rs
-15
crates/jacquard-lexicon/tests/regen_api.rs
-15
crates/jacquard-lexicon/tests/regen_api.rs
···
1
-
use jacquard_lexicon::codegen::CodeGenerator;
2
-
use jacquard_lexicon::corpus::LexiconCorpus;
3
-
4
-
#[test]
5
-
#[ignore] // Run with: cargo test --test regen_api -- --ignored
6
-
fn regenerate_api() {
7
-
let corpus = LexiconCorpus::load_from_dir("tests/fixtures/lexicons/atproto/lexicons").expect("load corpus");
8
-
let codegen = CodeGenerator::new(&corpus, "crate");
9
-
10
-
codegen
11
-
.write_to_disk(std::path::Path::new("../jacquard-api/src"))
12
-
.expect("write to disk");
13
-
14
-
println!("Generated {} lexicons", corpus.len());
15
-
}
+1
nix/modules/devshell.nix
+1
nix/modules/devshell.nix
-120
regen.rs
-120
regen.rs
···
1
-
use jacquard_lexicon::codegen::CodeGenerator;
2
-
use jacquard_lexicon::corpus::LexiconCorpus;
3
-
use prettyplease;
4
-
use std::collections::BTreeMap;
5
-
use std::fs;
6
-
use std::path::Path;
7
-
8
-
fn main() -> Result<(), Box<dyn std::error::Error>> {
9
-
let lexicons_path = "lexicons/atproto";
10
-
let output_path = "crates/jacquard-api/src";
11
-
let root_module = "crate";
12
-
13
-
println!("Loading lexicons from {}...", lexicons_path);
14
-
let corpus = LexiconCorpus::load_from_dir(lexicons_path)?;
15
-
println!("Loaded {} lexicons", corpus.len());
16
-
17
-
println!("Generating code...");
18
-
let generator = CodeGenerator::new(&corpus, root_module);
19
-
20
-
// Group by module
21
-
let mut modules: BTreeMap<String, Vec<(String, String)>> = BTreeMap::new();
22
-
23
-
for (nsid, doc) in corpus.iter() {
24
-
let nsid_str = nsid.as_str();
25
-
26
-
// Get module path: app.bsky.feed.post -> app_bsky/feed
27
-
let parts: Vec<&str> = nsid_str.split('.').collect();
28
-
let module_path = if parts.len() >= 3 {
29
-
let first_two = format!("{}_{}", parts[0], parts[1]);
30
-
if parts.len() > 3 {
31
-
let middle: Vec<&str> = parts[2..parts.len() - 1].iter().copied().collect();
32
-
format!("{}/{}", first_two, middle.join("/"))
33
-
} else {
34
-
first_two
35
-
}
36
-
} else {
37
-
parts.join("_")
38
-
};
39
-
40
-
let file_name = parts.last().unwrap().to_string();
41
-
42
-
for (def_name, def) in &doc.defs {
43
-
match generator.generate_def(nsid_str, def_name, def) {
44
-
Ok(tokens) => {
45
-
let code = prettyplease::unparse(&syn::parse_file(&tokens.to_string())?);
46
-
modules
47
-
.entry(format!("{}/{}.rs", module_path, file_name))
48
-
.or_default()
49
-
.push((def_name.to_string(), code));
50
-
}
51
-
Err(e) => {
52
-
eprintln!("Error generating {}.{}: {:?}", nsid_str, def_name, e);
53
-
}
54
-
}
55
-
}
56
-
}
57
-
58
-
// Write files
59
-
for (file_path, defs) in modules {
60
-
let full_path = Path::new(output_path).join(&file_path);
61
-
62
-
// Create parent directory
63
-
if let Some(parent) = full_path.parent() {
64
-
fs::create_dir_all(parent)?;
65
-
}
66
-
67
-
let content = defs.iter().map(|(_, code)| code.as_str()).collect::<Vec<_>>().join("\n");
68
-
fs::write(&full_path, content)?;
69
-
println!("Wrote {}", file_path);
70
-
}
71
-
72
-
// Generate mod.rs files
73
-
println!("Generating mod.rs files...");
74
-
generate_mod_files(Path::new(output_path))?;
75
-
76
-
println!("Done!");
77
-
Ok(())
78
-
}
79
-
80
-
fn generate_mod_files(root: &Path) -> Result<(), Box<dyn std::error::Error>> {
81
-
// Find all directories
82
-
for entry in fs::read_dir(root)? {
83
-
let entry = entry?;
84
-
let path = entry.path();
85
-
86
-
if path.is_dir() {
87
-
let dir_name = path.file_name().unwrap().to_str().unwrap();
88
-
89
-
// Recursively generate for subdirectories
90
-
generate_mod_files(&path)?;
91
-
92
-
// Generate mod.rs for this directory
93
-
let mut mods = Vec::new();
94
-
for sub_entry in fs::read_dir(&path)? {
95
-
let sub_entry = sub_entry?;
96
-
let sub_path = sub_entry.path();
97
-
98
-
if sub_path.is_file() {
99
-
if let Some(name) = sub_path.file_stem() {
100
-
let name_str = name.to_str().unwrap();
101
-
if name_str != "mod" {
102
-
mods.push(format!("pub mod {};", name_str));
103
-
}
104
-
}
105
-
} else if sub_path.is_dir() {
106
-
if let Some(name) = sub_path.file_name() {
107
-
mods.push(format!("pub mod {};", name.to_str().unwrap()));
108
-
}
109
-
}
110
-
}
111
-
112
-
if !mods.is_empty() {
113
-
let mod_content = mods.join("\n") + "\n";
114
-
fs::write(path.join("mod.rs"), mod_content)?;
115
-
}
116
-
}
117
-
}
118
-
119
-
Ok(())
120
-
}