sq3_rs/file_header/
payload_fractions.rs

1use std::ops::Deref;
2
3use sq3_derive::Name;
4use sq3_parser::TypeName;
5
6use crate::traits::ParseBytes;
7use crate::{
8    field_parsing_error,
9    result::{SqliteError, SqliteResult},
10};
11
12/// # Payload Fractions (3 Bytes)
13///
14///  The maximum and minimum embedded payload fractions and the leaf payload
15/// fraction values must be 64, 32, and 32. These values were originally
16/// intended to be tunable parameters that could be used to modify the storage
17/// format of the b-tree algorithm. However, that functionality is not
18/// supported and there are no current plans to add support in the future.
19/// Hence, these three bytes are fixed at the values specified.
20#[derive(Debug, Default, Name)]
21pub struct PayloadFractions {
22    /// Maximum embedded payload fraction. Must be 64.
23    maximum: MaximumEmbeddedPayloadFraction,
24    /// Minimum embedded payload fraction. Must be 32.
25    minimum: MinimumEmbeddedPayloadFraction,
26    /// Leaf payload fraction. Must be 32.
27    leaf: LeafPayloadFraction,
28}
29
30impl PayloadFractions {
31    pub fn maximum(&self) -> &MaximumEmbeddedPayloadFraction {
32        &self.maximum
33    }
34
35    pub fn minimum(&self) -> &MinimumEmbeddedPayloadFraction {
36        &self.minimum
37    }
38
39    pub fn leaf(&self) -> &LeafPayloadFraction {
40        &self.leaf
41    }
42}
43
44impl ParseBytes for PayloadFractions {
45    const LENGTH_BYTES: usize = 3;
46
47    fn parsing_handler(bytes: &[u8]) -> SqliteResult<Self> {
48        let maximum = MaximumEmbeddedPayloadFraction::parse_bytes(&[bytes[0]])?;
49        let minimum = MinimumEmbeddedPayloadFraction::parse_bytes(&[bytes[1]])?;
50        let leaf = LeafPayloadFraction::parse_bytes(&[bytes[2]])?;
51        Ok(Self {
52            maximum,
53            minimum,
54            leaf,
55        })
56    }
57}
58
59/// Maximum embedded payload fraction. Must be 64.
60#[derive(Debug, Name)]
61pub struct MaximumEmbeddedPayloadFraction(u8);
62impl Default for MaximumEmbeddedPayloadFraction {
63    fn default() -> Self {
64        Self(64)
65    }
66}
67impl Deref for MaximumEmbeddedPayloadFraction {
68    type Target = u8;
69
70    fn deref(&self) -> &Self::Target {
71        &self.0
72    }
73}
74
75impl ParseBytes for MaximumEmbeddedPayloadFraction {
76    const LENGTH_BYTES: usize = 1;
77
78    fn parsing_handler(bytes: &[u8]) -> SqliteResult<Self> {
79        let maximum = *bytes
80            .first()
81            .ok_or(field_parsing_error! {Self::NAME.into()})?;
82        if maximum == 64 {
83            Ok(Self(maximum))
84        } else {
85            Err(SqliteError::Custom(
86                "MaximumEmbeddedPayloadFraction must be 64.".into(),
87            ))
88        }
89    }
90}
91
92/// Minimum embedded payload fraction. Must be 32.
93#[derive(Debug, Name)]
94pub struct MinimumEmbeddedPayloadFraction(u8);
95impl Default for MinimumEmbeddedPayloadFraction {
96    fn default() -> Self {
97        Self(32)
98    }
99}
100impl Deref for MinimumEmbeddedPayloadFraction {
101    type Target = u8;
102
103    fn deref(&self) -> &Self::Target {
104        &self.0
105    }
106}
107
108impl ParseBytes for MinimumEmbeddedPayloadFraction {
109    const LENGTH_BYTES: usize = 1;
110
111    fn parsing_handler(bytes: &[u8]) -> SqliteResult<Self> {
112        let minimum = *bytes
113            .first()
114            .ok_or(field_parsing_error! {Self::NAME.into()})?;
115        if minimum == 32 {
116            Ok(Self(minimum))
117        } else {
118            Err(SqliteError::Custom(
119                "MinimumEmbeddedPayloadFraction must be 32.".into(),
120            ))
121        }
122    }
123}
124
125/// Leaf payload fraction. Must be 32.
126#[derive(Debug, Name)]
127pub struct LeafPayloadFraction(u8);
128impl Default for LeafPayloadFraction {
129    fn default() -> Self {
130        Self(32)
131    }
132}
133impl Deref for LeafPayloadFraction {
134    type Target = u8;
135
136    fn deref(&self) -> &Self::Target {
137        &self.0
138    }
139}
140
141impl ParseBytes for LeafPayloadFraction {
142    const LENGTH_BYTES: usize = 1;
143
144    fn parsing_handler(bytes: &[u8]) -> SqliteResult<Self> {
145        let leaf = *bytes
146            .first()
147            .ok_or(field_parsing_error! {Self::NAME.into()})?;
148        if leaf == 32 {
149            Ok(Self(leaf))
150        } else {
151            Err(SqliteError::Custom(
152                "LeafPayloadFraction must be 32.".into(),
153            ))
154        }
155    }
156}