genanki_rs_rev/
lib.rs

1//! Genanki-rs - Create Anki flashcard decks
2//!
3//! This is the main library crate that re-exports all functionality.
4
5// Core module - data structures and types
6pub mod core;
7
8// Builder module - enhanced builder patterns
9pub mod builder;
10
11// Export module - APKG export functionality
12pub mod export;
13
14// Storage module - database operations
15pub mod error;
16pub mod storage;
17
18// Re-export core types and functions
19pub use crate::core::{
20    AnkiConfig, Card, Deck, DeckConfig, Error, Field, FieldDefaults, Model, ModelConfig, ModelIds,
21    ModelType, Note, Result, Template, guid_for,
22};
23
24// Re-export storage types
25pub use crate::storage::{
26    AnkiSchema, COL_SQL, Collection, CollectionManager, DeckDbEntry, ModelDbEntry, SCHEMA_SQL,
27};
28
29// Re-export builder types
30pub use crate::builder::{
31    BasicModels, DeckBuilder, FieldBuilder, ModelBuilder, NoteBuilder, TemplateBuilder,
32};
33
34// Re-export export types
35pub use crate::export::{MediaFiles, Package, PackageWriter};
36
37// ===== BACKWARD COMPATIBILITY =====
38// Re-export old API for compatibility
39
40pub 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
54/// Basic model (backward compatible)
55pub fn basic_model() -> Model {
56    BasicModels::basic()
57}
58
59/// Basic and reversed card model (backward compatible)
60pub 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
86/// Basic optional reversed card model (backward compatible)
87pub 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
114/// Basic type in the answer model (backward compatible)
115pub 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
138/// Cloze model (backward compatible)
139pub 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}