use std::collections::HashMap;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct Note {
pub deck_name: String,
pub model_name: String,
pub fields: HashMap<String, String>,
#[serde(skip_serializing_if = "Vec::is_empty")]
pub tags: Vec<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub audio: Option<Vec<MediaAttachment>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub video: Option<Vec<MediaAttachment>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub picture: Option<Vec<MediaAttachment>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub options: Option<NoteOptions>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct MediaAttachment {
#[serde(skip_serializing_if = "Option::is_none")]
pub url: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub data: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub path: Option<String>,
pub filename: String,
pub fields: Vec<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub skip_hash: Option<String>,
}
#[derive(Debug, Clone, Default, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct NoteOptions {
#[serde(skip_serializing_if = "Option::is_none")]
pub allow_duplicate: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub duplicate_scope: Option<DuplicateScope>,
#[serde(skip_serializing_if = "Option::is_none")]
pub duplicate_scope_options: Option<DuplicateScopeOptions>,
}
#[derive(Debug, Clone, Copy, Serialize)]
#[serde(rename_all = "camelCase")]
pub enum DuplicateScope {
Deck,
DeckRoot,
}
#[derive(Debug, Clone, Default, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct DuplicateScopeOptions {
#[serde(skip_serializing_if = "Option::is_none")]
pub deck_name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub check_children: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub check_all_models: Option<bool>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct NoteInfo {
pub note_id: i64,
pub model_name: String,
pub tags: Vec<String>,
pub fields: HashMap<String, NoteField>,
#[serde(default)]
pub cards: Vec<i64>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct NoteField {
pub value: String,
pub order: i32,
}
#[derive(Debug, Clone, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct CanAddResult {
pub can_add: bool,
#[serde(default)]
pub error: Option<String>,
}
#[derive(Debug, Clone, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct NoteModTime {
pub note_id: i64,
#[serde(rename = "mod")]
pub mod_time: i64,
}
#[derive(Debug, Clone, Default)]
pub struct NoteBuilder {
deck_name: String,
model_name: String,
fields: HashMap<String, String>,
tags: Vec<String>,
audio: Option<Vec<MediaAttachment>>,
video: Option<Vec<MediaAttachment>>,
picture: Option<Vec<MediaAttachment>>,
options: Option<NoteOptions>,
}
impl NoteBuilder {
pub fn new(deck: impl Into<String>, model: impl Into<String>) -> Self {
Self {
deck_name: deck.into(),
model_name: model.into(),
..Default::default()
}
}
pub fn field(mut self, name: impl Into<String>, value: impl Into<String>) -> Self {
self.fields.insert(name.into(), value.into());
self
}
pub fn tag(mut self, tag: impl Into<String>) -> Self {
self.tags.push(tag.into());
self
}
pub fn tags(mut self, tags: impl IntoIterator<Item = impl Into<String>>) -> Self {
self.tags.extend(tags.into_iter().map(Into::into));
self
}
pub fn audio(mut self, attachment: MediaAttachment) -> Self {
self.audio.get_or_insert_with(Vec::new).push(attachment);
self
}
pub fn video(mut self, attachment: MediaAttachment) -> Self {
self.video.get_or_insert_with(Vec::new).push(attachment);
self
}
pub fn picture(mut self, attachment: MediaAttachment) -> Self {
self.picture.get_or_insert_with(Vec::new).push(attachment);
self
}
pub fn allow_duplicate(mut self, allow: bool) -> Self {
self.options
.get_or_insert_with(NoteOptions::default)
.allow_duplicate = Some(allow);
self
}
pub fn duplicate_scope(mut self, scope: DuplicateScope) -> Self {
self.options
.get_or_insert_with(NoteOptions::default)
.duplicate_scope = Some(scope);
self
}
pub fn duplicate_scope_deck(mut self, deck: impl Into<String>) -> Self {
let options = self.options.get_or_insert_with(NoteOptions::default);
options
.duplicate_scope_options
.get_or_insert_with(DuplicateScopeOptions::default)
.deck_name = Some(deck.into());
self
}
pub fn build(self) -> Note {
Note {
deck_name: self.deck_name,
model_name: self.model_name,
fields: self.fields,
tags: self.tags,
audio: self.audio,
video: self.video,
picture: self.picture,
options: self.options,
}
}
}