ankiconnect_rs/client/
request.rs

1//! Request and response types for the AnkiConnect API
2//!
3//! These are internal types used for serializing requests to and from AnkiConnect.
4
5use serde::{Deserialize, Serialize};
6use std::collections::HashMap;
7use std::path::PathBuf;
8
9// -------------------
10// Card-related params
11// -------------------
12
13/// Parameters for finding cards
14#[derive(Serialize, Debug)]
15pub(crate) struct FindCardsParams<'a> {
16    pub query: &'a str,
17}
18
19/// Parameters for finding notes
20#[derive(Serialize, Debug)]
21pub(crate) struct FindNotesParams {
22    pub query: String,
23}
24
25/// Parameters for browsing cards in the GUI
26#[derive(Serialize, Debug)]
27#[serde(rename_all = "camelCase")]
28pub(crate) struct GuiBrowseParams {
29    pub query: String,
30    #[serde(skip_serializing_if = "Option::is_none")]
31    pub reorder_cards: Option<CardsReordering>,
32}
33
34/// Card reordering options for browse
35#[derive(Serialize, Debug)]
36pub(crate) struct CardsReordering {
37    #[serde(rename = "order")]
38    pub order: SortOrder,
39    #[serde(rename = "columnId")]
40    pub column_id: ColumnIdentifier,
41}
42
43/// Sort order for cards
44#[derive(Serialize, Debug)]
45#[serde(rename_all = "camelCase")]
46pub(crate) enum SortOrder {
47    Ascending,
48    Descending,
49}
50
51/// Column identifier for sorting
52#[derive(Serialize, Debug)]
53#[serde(rename_all = "camelCase")]
54pub(crate) enum ColumnIdentifier {
55    #[serde(rename = "")]
56    Custom,
57    Answer,
58    CardMod,
59    #[serde(rename = "template")]
60    Cards,
61    Deck,
62    #[serde(rename = "cardDue")]
63    Due,
64    #[serde(rename = "cardEase")]
65    Ease,
66    #[serde(rename = "cardLapses")]
67    Lapses,
68    #[serde(rename = "cardIvl")]
69    Interval,
70    #[serde(rename = "noteCrt")]
71    NoteCreation,
72    NoteMod,
73    #[serde(rename = "note")]
74    Notetype,
75    OriginalPosition,
76    Question,
77    #[serde(rename = "cardReps")]
78    Reps,
79    #[serde(rename = "noteFld")]
80    SortField,
81    #[serde(rename = "noteTags")]
82    Tags,
83    Stability,
84    Difficulty,
85    Retrievability,
86}
87
88/// Parameters for deleting notes
89#[derive(Serialize, Debug)]
90pub(crate) struct DeleteNotesParams {
91    pub notes: Vec<u64>,
92}
93
94/// Parameters for operations that use card IDs
95#[derive(Serialize, Debug)]
96pub(crate) struct CardIdsParams {
97    pub cards: Vec<u64>,
98}
99
100/// Parameters for setting a flag
101#[derive(Serialize, Debug)]
102pub(crate) struct SetFlagParams {
103    pub cards: Vec<u64>,
104    pub flag: u8,
105}
106
107/// Parameters for note info
108#[derive(Serialize, Debug)]
109pub(crate) struct NoteIdParam {
110    pub note: u64,
111}
112
113/// Response for note info
114#[derive(Deserialize, Debug)]
115#[serde(rename_all = "camelCase")]
116pub struct NoteInfo {
117    pub note_id: u64,
118    pub model_name: String,
119    pub tags: Vec<String>,
120    pub fields: HashMap<String, FieldInfo>,
121}
122
123/// Field info in note info
124#[derive(Deserialize, Debug)]
125pub struct FieldInfo {
126    pub value: String,
127    pub order: u32,
128}
129
130/// Parameters for updating a note
131#[derive(Serialize, Debug)]
132pub(crate) struct UpdateNoteFieldsParams {
133    note: NoteDto,
134}
135
136// ------------------
137// Deck-related params
138// ------------------
139
140/// Parameters for creating a deck
141#[derive(Serialize, Debug)]
142pub(crate) struct CreateDeckParams<'a> {
143    pub deck: &'a str,
144}
145
146/// Parameters for renaming a deck
147#[derive(Serialize, Debug)]
148pub(crate) struct RenameDeckParams<'a> {
149    pub deck: &'a str,
150    pub new_name: &'a str,
151}
152
153/// Parameters for deleting a deck
154#[derive(Serialize, Debug)]
155#[serde(rename_all = "camelCase")]
156pub(crate) struct DeleteDeckParams<'a> {
157    pub decks: &'a [&'a str],
158    pub cards_too: bool,
159}
160
161/// Parameters for deck stats
162#[derive(Serialize, Debug)]
163pub(crate) struct DeckStatsParams<'a> {
164    pub decks: &'a [&'a str],
165}
166
167/// Response for deck stats
168#[derive(Deserialize, Debug)]
169pub struct DeckStatsDto {
170    pub deck_id: u64,
171    pub new_count: u32,
172    pub learn_count: u32,
173    pub review_count: u32,
174    pub total_in_deck: u32,
175}
176
177/// Response for deck configuration
178#[derive(Deserialize, Debug)]
179pub struct DeckConfigsResult {
180    pub current_deck_id: u64,
181    pub current_config_id: u64,
182    pub all_config_id: Vec<u64>,
183    pub config_list: Vec<DeckConfigDto>,
184}
185
186/// Deck configuration
187#[derive(Deserialize, Debug)]
188pub struct DeckConfigDto {
189    pub id: u64,
190    pub name: String,
191    pub reuse_if_possible: bool,
192    pub disable_auto_qe: bool,
193}
194
195/// Parameters for finding cards in a deck
196#[derive(Serialize, Debug)]
197pub(crate) struct DeckCardParams<'a> {
198    pub deck: &'a str,
199}
200
201/// Deck tree node
202#[derive(Deserialize, Debug)]
203pub struct DeckTreeNode {
204    pub id: u64,
205    pub name: String,
206    pub level: u32,
207    pub collapsed: bool,
208    pub has_children: bool,
209    pub children: Vec<DeckTreeNode>,
210}
211
212// ------------------
213// Media-related params
214// ------------------
215
216/// Parameters for storing media files
217#[derive(Serialize, Debug)]
218#[serde(rename_all = "camelCase")]
219pub(crate) struct StoreMediaFileParams {
220    #[serde(skip_serializing_if = "Option::is_none")]
221    pub path: Option<PathBuf>,
222    #[serde(skip_serializing_if = "Option::is_none")]
223    pub url: Option<String>,
224    #[serde(skip_serializing_if = "Option::is_none")]
225    pub data: Option<String>,
226    pub filename: String,
227    pub delete_existing: bool,
228}
229
230/// Parameters for retrieving media files
231#[derive(Serialize, Debug)]
232pub(crate) struct RetrieveMediaParams {
233    pub filename: String,
234}
235
236/// Parameters for deleting media files
237#[derive(Serialize, Debug)]
238pub(crate) struct DeleteMediaParams {
239    pub filename: String,
240}
241
242// -------------------
243// Model-related params
244// -------------------
245
246/// Parameters for getting model field names
247#[derive(Serialize, Debug)]
248#[serde(rename_all = "camelCase")]
249pub(crate) struct ModelFieldNamesParams<'a> {
250    pub model_name: &'a str,
251}
252
253/// Parameters for finding models by ID
254#[derive(Serialize, Debug)]
255#[serde(rename_all = "camelCase")]
256pub(crate) struct FindModelsByIdParams<'a> {
257    pub model_ids: &'a [u64],
258}
259
260/// Parameters for getting model templates
261#[derive(Serialize, Debug)]
262#[serde(rename_all = "camelCase")]
263pub(crate) struct ModelTemplatesParams<'a> {
264    pub model_name: &'a str,
265}
266
267/// Parameters for getting model styling
268#[derive(Serialize, Debug)]
269pub(crate) struct ModelStylingParams<'a> {
270    pub model_name: &'a str,
271}
272
273/// Parameters for updating model styling
274#[derive(Serialize, Debug)]
275pub(crate) struct UpdateModelStylingParams<'a> {
276    pub model: &'a str,
277    pub css: &'a str,
278}
279
280/// Parameters for creating a model
281#[derive(Serialize, Debug)]
282#[serde(rename_all = "camelCase")]
283pub(crate) struct CreateModelParams<'a> {
284    pub model_name: &'a str,
285    pub in_order_fields: &'a [&'a str],
286    pub css: &'a str,
287    pub card_templates: HashMap<String, CardTemplate>,
288}
289
290/// Card template for model creation
291#[derive(Serialize, Debug)]
292pub(crate) struct CardTemplate {
293    pub front: String,
294    pub back: String,
295}
296
297/// Model details from API response
298#[derive(Deserialize, Debug)]
299#[serde(rename_all = "camelCase")]
300pub struct ModelDetails {
301    pub id: u64,
302    pub name: String,
303    #[serde(rename = "type")]
304    pub type_: u64,
305    #[serde(rename = "mod")]
306    pub mod_: u64,
307    pub usn: i64,
308    pub sortf: i64,
309    pub did: Option<i64>,
310    pub tmpls: Vec<Template>,
311    pub flds: Vec<Field>,
312    pub css: String,
313    pub latex_pre: String,
314    pub latex_post: String,
315    pub latexsvg: bool,
316    pub req: Vec<Requirement>,
317    pub original_stock_kind: i64,
318}
319
320/// Template in model details
321#[derive(Deserialize, Debug)]
322#[serde(rename_all = "camelCase")]
323pub struct Template {
324    pub name: String,
325    pub ord: i64,
326    pub qfmt: String,
327    pub afmt: String,
328    pub bqfmt: String,
329    pub bafmt: String,
330    pub did: Option<i64>,
331    pub bfont: String,
332    pub bsize: i64,
333    pub id: u64,
334}
335
336/// Field in model details
337#[derive(Deserialize, Debug)]
338#[serde(rename_all = "camelCase")]
339pub struct Field {
340    pub name: String,
341    pub ord: i64,
342    pub sticky: bool,
343    pub rtl: bool,
344    pub font: String,
345    pub size: i64,
346    pub description: String,
347    pub plain_text: bool,
348    pub collapsed: bool,
349    pub exclude_from_search: bool,
350    pub id: i64,
351    pub tag: Option<String>,
352    pub prevent_deletion: bool,
353}
354
355/// Requirement in model details
356#[derive(Deserialize, Debug)]
357pub struct Requirement(pub i64, pub String, pub Vec<i64>);
358
359// -------------------
360// Note-related params
361// -------------------
362
363/// Parameters for adding a note
364#[derive(Serialize, Debug)]
365#[serde(rename_all = "camelCase")]
366pub(crate) struct AddNoteParams {
367    pub note: NoteDto,
368}
369
370/// Note data for adding to Anki
371#[derive(Serialize, Debug)]
372#[serde(rename_all = "camelCase")]
373pub(crate) struct NoteDto {
374    // TODO Or id?
375    pub deck_name: String,
376    pub model_name: String,
377    /// field -> content mapping
378    pub fields: HashMap<String, String>,
379    pub options: AddNoteOptions,
380    pub tags: Vec<String>,
381    #[serde(skip_serializing_if = "Vec::is_empty")]
382    pub audio: Vec<Media>,
383    #[serde(skip_serializing_if = "Vec::is_empty")]
384    pub video: Vec<Media>,
385    #[serde(skip_serializing_if = "Vec::is_empty")]
386    pub picture: Vec<Media>,
387}
388
389/// Media data for notes
390#[derive(Serialize, Debug)]
391#[serde(rename_all = "camelCase")]
392pub(crate) struct Media {
393    #[serde(skip_serializing_if = "Option::is_none")]
394    pub path: Option<PathBuf>,
395    #[serde(skip_serializing_if = "Option::is_none")]
396    pub url: Option<String>,
397    #[serde(skip_serializing_if = "Option::is_none")]
398    pub data: Option<String>,
399    pub filename: String,
400    #[serde(skip_serializing_if = "Vec::is_empty")]
401    pub fields: Vec<String>,
402}
403
404/// Options for adding notes
405#[derive(Serialize, Debug)]
406#[serde(rename_all = "camelCase")]
407pub(crate) struct AddNoteOptions {
408    pub allow_duplicate: bool,
409    #[serde(skip_serializing_if = "Option::is_none")]
410    pub duplicate_scope: Option<DuplicateScopeDto>,
411    #[serde(skip_serializing_if = "Option::is_none")]
412    pub duplicate_scope_options: Option<DuplicateScopeOptionsDto>,
413}
414
415/// Scope for duplicate checking
416#[derive(Serialize, Debug)]
417#[serde(rename_all = "camelCase")]
418pub(crate) enum DuplicateScopeDto {
419    Deck,
420    Collection,
421}
422
423/// Options for duplicate scope
424#[derive(Serialize, Debug)]
425#[serde(rename_all = "camelCase")]
426pub(crate) struct DuplicateScopeOptionsDto {
427    #[serde(skip_serializing_if = "Option::is_none")]
428    pub deck_name: Option<String>,
429    pub check_children: bool,
430    pub check_all_models: bool,
431}