sqlite_rs/header/
file_format_version_numbers.rs

1use crate::traits::{Name, ParseBytes};
2use crate::{field_parsing_error, impl_name, result::SqliteResult};
3use core::fmt::Display;
4
5/// # File format version numbers (2 Bytes)
6///
7///  The file format write version and file format read version at offsets 18
8/// and 19 are intended to allow for enhancements of the file format in future
9/// versions of Sqlite. In current versions of Sqlite, both of these values
10/// are:
11///   - `1` for rollback journalling modes; and
12///   - `2` for WAL journalling mode.
13///
14///  If a version of Sqlite coded to the current file format specification
15/// encounters a database file where the read version is 1 or 2 but the write
16/// version is greater than 2, then the database file must be treated as
17/// read-only. If a database file with a read version greater than 2 is
18/// encountered, then that database cannot be read or written.
19#[derive(Debug, Default)]
20pub struct FileFormatVersionNumbers {
21  /// File format write version. 1 for legacy; 2 for WAL.
22  write_version: FileFormatWriteVersion,
23  /// File format read version. 1 for legacy; 2 for WAL.
24  read_version: FileFormatReadVersion,
25}
26
27impl FileFormatVersionNumbers {
28  pub fn write_version(&self) -> &FileFormatWriteVersion {
29    &self.write_version
30  }
31
32  pub fn read_version(&self) -> &FileFormatReadVersion {
33    &self.read_version
34  }
35}
36impl_name! {FileFormatVersionNumbers}
37impl ParseBytes for FileFormatVersionNumbers {
38  const LENGTH_BYTES: usize = 2;
39
40  fn parsing_handler(bytes: &[u8]) -> SqliteResult<Self> {
41    let write_version = FileFormatWriteVersion::parsing_handler(&[bytes[0]])?;
42    let read_version = FileFormatReadVersion::parsing_handler(&[bytes[1]])?;
43    Ok(Self {
44      write_version,
45      read_version,
46    })
47  }
48}
49
50#[derive(Debug, Default)]
51pub enum FileFormatWriteVersion {
52  #[default]
53  Legacy,
54  /// Write-Ahead Log
55  ///
56  /// Reference: https://www.sqlite.org/wal.html
57  WAL,
58}
59
60impl From<&FileFormatWriteVersion> for u8 {
61  fn from(value: &FileFormatWriteVersion) -> Self {
62    match value {
63      FileFormatWriteVersion::Legacy => 1,
64      FileFormatWriteVersion::WAL => 2,
65    }
66  }
67}
68
69impl_name! {FileFormatWriteVersion}
70
71impl ParseBytes for FileFormatWriteVersion {
72  const LENGTH_BYTES: usize = 1;
73
74  fn parsing_handler(bytes: &[u8]) -> SqliteResult<Self> {
75    let one_byte = *bytes
76      .first()
77      .ok_or(field_parsing_error! {Self::NAME.into()})?;
78    match one_byte {
79      1 => Ok(Self::Legacy),
80      2 => Ok(Self::WAL),
81      _ => Err(field_parsing_error! {Self::NAME.into()}),
82    }
83  }
84}
85
86impl Display for FileFormatWriteVersion {
87  fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
88    write!(f, "{}", u8::from(self))
89  }
90}
91
92#[derive(Debug, Default)]
93pub enum FileFormatReadVersion {
94  #[default]
95  Legacy,
96  /// Write-Ahead Log
97  ///
98  /// Reference: https://www.sqlite.org/wal.html
99  WAL,
100}
101
102impl From<&FileFormatReadVersion> for u8 {
103  fn from(value: &FileFormatReadVersion) -> Self {
104    match value {
105      FileFormatReadVersion::Legacy => 1,
106      FileFormatReadVersion::WAL => 2,
107    }
108  }
109}
110
111impl_name! {FileFormatReadVersion}
112
113impl ParseBytes for FileFormatReadVersion {
114  const LENGTH_BYTES: usize = 1;
115
116  fn parsing_handler(bytes: &[u8]) -> SqliteResult<Self> {
117    let one_byte = *bytes
118      .first()
119      .ok_or(field_parsing_error! {Self::NAME.into()})?;
120    match one_byte {
121      1 => Ok(Self::Legacy),
122      2 => Ok(Self::WAL),
123      _ => Err(field_parsing_error! {Self::NAME.into()}),
124    }
125  }
126}
127
128impl Display for FileFormatReadVersion {
129  fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
130    write!(f, "{}", u8::from(self))
131  }
132}