sq3_rs/file_header/
write_library_version.rs

1use std::ops::Deref;
2
3use sq3_derive::Name;
4use sq3_parser::TypeName;
5
6use crate::{result::SqliteResult, traits::ParseBytes, VERSION_NUMBER};
7
8/// # Write library version number (4 Bytes)
9///
10///  The 4-byte big-endian integer at offset 96 stores the SQLITE_VERSION_NUMBER
11/// value for the Sqlite library that most recently modified the database file.
12///
13/// >  The entries at offsets 92 and 96 were added in later version of the
14/// > SQLite library.
15/// >
16/// >  When an older version modifies the file, it will change the change
17/// > counter (offset 24), but not adjust the version-valid-for number or the
18/// > write library version number. So the library version number is no longer
19/// > correct, because a different version last wrote to the file.
20/// >
21/// >  The version-valid-for number allows a new library to detect this case: if
22/// > the change counter and the version-valid-for number do not match, then the
23/// > write library version number is outdated, and must be ignored.
24/// >
25/// >  **Reference:** https://stackoverflow.com/a/45420823
26#[derive(Debug, Name)]
27pub struct WriteLibraryVersion(u32);
28impl Default for WriteLibraryVersion {
29    fn default() -> Self {
30        Self(*VERSION_NUMBER.get().unwrap_or(&0))
31    }
32}
33impl Deref for WriteLibraryVersion {
34    type Target = u32;
35
36    fn deref(&self) -> &Self::Target {
37        &self.0
38    }
39}
40
41impl ParseBytes for WriteLibraryVersion {
42    const LENGTH_BYTES: usize = 4;
43
44    fn parsing_handler(bytes: &[u8]) -> SqliteResult<Self> {
45        let buf: [u8; Self::LENGTH_BYTES] = bytes.try_into()?;
46
47        let database_size = u32::from_be_bytes(buf);
48
49        Ok(Self(database_size))
50    }
51}