1pub mod core;
7
8pub mod builder;
10
11pub mod export;
13
14pub mod error;
16pub mod storage;
17
18pub use crate::core::{
20 AnkiConfig, Card, Deck, DeckConfig, Error, Field, FieldDefaults, Model, ModelConfig, ModelIds,
21 ModelType, Note, Result, Template, guid_for,
22};
23
24pub use crate::storage::{
26 AnkiSchema, COL_SQL, Collection, CollectionManager, DeckDbEntry, ModelDbEntry, SCHEMA_SQL,
27};
28
29pub use crate::builder::{
31 BasicModels, DeckBuilder, FieldBuilder, ModelBuilder, NoteBuilder, TemplateBuilder,
32};
33
34pub use crate::export::{MediaFiles, Package, PackageWriter};
36
37pub mod builders {
41 pub use crate::builder::{FieldBuilder, TemplateBuilder};
42 pub use crate::core::{Field, Template};
43}
44
45pub mod constants {
46 pub use crate::storage::{COL_SQL as APKG_COL, SCHEMA_SQL as APKG_SCHEMA};
47 pub static MEDIA_DIRNAME: &str = "media";
48
49 pub static MEDIA_MAPPING_FILENAME: &str = "collection.media";
50
51 pub static DATABASE_FILENAME: &str = "collection.anki2";
52}
53
54pub fn basic_model() -> Model {
56 BasicModels::basic()
57}
58
59pub fn basic_and_reversed_card_model() -> Model {
61 Model::with_options(
62 1485830179,
63 "Basic (and reversed card) (genanki)",
64 vec![
65 Field::new("Front").font("Arial"),
66 Field::new("Back").font("Arial"),
67 ],
68 vec![
69 Template::new("Card 1")
70 .qfmt("{{Front}}")
71 .afmt("{{FrontSide}}\n\n<hr id=answer>\n\n{{Back}}"),
72 Template::new("Card 2")
73 .qfmt("{{Back}}")
74 .afmt("{{FrontSide}}\n\n<hr id=answer>\n\n{{Front}}"),
75 ],
76 Some(
77 ".card {\n font-family: arial;\n font-size: 20px;\n text-align: center;\n color: black;\n background-color: white;\n}\n",
78 ),
79 None,
80 None,
81 None,
82 None,
83 )
84}
85
86pub fn basic_optional_reversed_card_model() -> Model {
88 Model::with_options(
89 1382232460,
90 "Basic (optional reversed card) (genanki)",
91 vec![
92 Field::new("Front").font("Arial"),
93 Field::new("Back").font("Arial"),
94 Field::new("AddReverse").font("Arial"),
95 ],
96 vec![
97 Template::new("Card 1")
98 .qfmt("{{Front}}")
99 .afmt("{{FrontSide}}\n\n<hr id=answer>\n\n{{Back}}"),
100 Template::new("Card 2")
101 .qfmt("{{#AddReverse}}{{Back}}{{/AddReverse}}")
102 .afmt("{{FrontSide}}\n\n<hr id=answer>\n\n{{Front}}"),
103 ],
104 Some(
105 ".card {\n font-family: arial;\n font-size: 20px;\n text-align: center;\n color: black;\n background-color: white;\n}\n",
106 ),
107 None,
108 None,
109 None,
110 None,
111 )
112}
113
114pub fn basic_type_in_the_answer_model() -> Model {
116 Model::with_options(
117 1305534440,
118 "Basic (type in the answer) (genanki)",
119 vec![
120 Field::new("Front").font("Arial"),
121 Field::new("Back").font("Arial"),
122 ],
123 vec![
124 Template::new("Card 1")
125 .qfmt("{{Front}}\n\n{{type:Back}}")
126 .afmt("{{Front}}\n\n<hr id=answer>\n\n{{type:Back}}"),
127 ],
128 Some(
129 ".card {\n font-family: arial;\n font-size: 20px;\n text-align: center;\n color: black;\n background-color: white;\n}\n",
130 ),
131 None,
132 None,
133 None,
134 None,
135 )
136}
137
138pub fn cloze_model() -> Model {
140 BasicModels::cloze()
141}
142
143#[cfg(test)]
144mod tests {
145 use super::*;
146
147 #[test]
148 fn test_basic_model() {
149 let model = basic_model();
150 assert_eq!(model.id, 1559383000);
151 assert_eq!(model.num_fields(), 2);
152 }
153
154 #[test]
155 fn test_cloze_model() {
156 let model = cloze_model();
157 assert_eq!(model.id, 1122529321);
158 assert_eq!(model.num_fields(), 1);
159 }
160
161 #[test]
162 fn test_deck_creation() {
163 let deck = Deck::new(1234, "Test", "Description");
164 assert_eq!(deck.id, 1234);
165 assert!(deck.is_empty());
166 }
167
168 #[test]
169 fn test_note_creation() {
170 let model = basic_model();
171 let note = Note::new(model, vec!["Question", "Answer"]).unwrap();
172 assert_eq!(note.fields().len(), 2);
173 }
174}