sqlite_rs/header/
payload_fractions.rs

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