Skip to main content

bible_io/
loading.rs

1//! Bible loading, validation, and search-index options.
2
3use serde::{Deserialize, Serialize};
4
5use crate::errors::ModelError;
6
7/// Current version of the serialized Bible content contract.
8pub const CURRENT_BIBLE_SCHEMA_VERSION: u32 = 1;
9
10/// Stable phases reported while loading a Bible from external storage.
11#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
12#[serde(rename_all = "snake_case")]
13pub enum BibleLoadPhase {
14    /// Reading bytes from storage.
15    Reading,
16    /// Decoding and validating the content model.
17    Processing,
18    /// The Bible is ready for use.
19    Complete,
20}
21
22/// Snapshot delivered to a load-progress callback.
23#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
24#[serde(rename_all = "camelCase")]
25pub struct BibleLoadProgress {
26    /// Current phase.
27    pub phase: BibleLoadPhase,
28    /// Overall completion fraction in the inclusive range `0.0..=1.0`.
29    pub fraction: f32,
30    /// Completion fraction within the current phase.
31    pub phase_fraction: f32,
32}
33
34impl BibleLoadProgress {
35    /// Construct a validated progress snapshot.
36    pub fn new(
37        phase: BibleLoadPhase,
38        fraction: f32,
39        phase_fraction: f32,
40    ) -> Result<Self, ModelError> {
41        if !fraction.is_finite() || !(0.0..=1.0).contains(&fraction) {
42            return Err(ModelError::new(
43                "fraction",
44                "must be finite and between 0 and 1",
45            ));
46        }
47        if !phase_fraction.is_finite() || !(0.0..=1.0).contains(&phase_fraction) {
48            return Err(ModelError::new(
49                "phase_fraction",
50                "must be finite and between 0 and 1",
51            ));
52        }
53        Ok(Self {
54            phase,
55            fraction,
56            phase_fraction,
57        })
58    }
59}
60
61/// Strictness controls for decoded Bible content.
62#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
63#[serde(rename_all = "camelCase")]
64pub struct BibleDataValidationOptions {
65    /// Require at least one book.
66    pub require_books: bool,
67    /// Require at least one chapter per book.
68    pub require_chapters: bool,
69    /// Require at least one verse per chapter.
70    pub require_verses: bool,
71    /// Require every verse text to contain a non-whitespace character.
72    pub require_verse_text: bool,
73}
74
75impl BibleDataValidationOptions {
76    /// Compatibility policy for intentionally skeletal data.
77    pub const PERMISSIVE: Self = Self {
78        require_books: false,
79        require_chapters: false,
80        require_verses: false,
81        require_verse_text: false,
82    };
83}
84
85impl Default for BibleDataValidationOptions {
86    fn default() -> Self {
87        Self {
88            require_books: true,
89            require_chapters: true,
90            require_verses: true,
91            require_verse_text: true,
92        }
93    }
94}
95
96/// Options shared by all Bible construction methods.
97#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default, Serialize, Deserialize)]
98#[serde(rename_all = "camelCase")]
99pub struct BibleLoadOptions {
100    /// Content presence requirements.
101    pub validation: BibleDataValidationOptions,
102    /// Search index construction policy.
103    pub search_index_mode: crate::search::SearchIndexMode,
104}