1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
use super::traits::ParseBytes;
use crate::{impl_name, result::SQLiteResult};
use core::ops::Deref;

/// # Free page list (8 Bytes) => First(4 Bytes) + TotalPages (4 Bytes)
///  Unused pages in the database file are stored on a freelist.
#[derive(Debug)]
pub struct FreeListPages {
  /// Page number of the first freelist trunk page. (4 Bytes)
  first: FreeListPagesFirstTrunkPage,
  /// Total number of freelist pages. (4 Bytes)
  total: FreeListPagesTotalPages,
}

impl FreeListPages {
  pub fn first(&self) -> &FreeListPagesFirstTrunkPage {
    &self.first
  }

  pub fn total(&self) -> &FreeListPagesTotalPages {
    &self.total
  }
}
impl_name! {FreeListPages}

impl ParseBytes for FreeListPages {
  const LENGTH_BYTES: usize = 8;

  fn parsing_handler(bytes: &[u8]) -> SQLiteResult<Self> {
    let first = FreeListPagesFirstTrunkPage::parse_bytes(&bytes[0..=3])?;
    let total = FreeListPagesTotalPages::parse_bytes(&bytes[4..=7])?;

    Ok(Self { first, total })
  }
}

///  FreeListPagesFirstTrunkPage: The 4-byte big-endian integer at offset 32
/// stores the page number of the first page of the freelist, or zero if the
/// freelist is empty.
#[derive(Debug)]
pub struct FreeListPagesFirstTrunkPage(u32);

impl Deref for FreeListPagesFirstTrunkPage {
  type Target = u32;

  fn deref(&self) -> &Self::Target {
    &self.0
  }
}

impl_name! {FreeListPagesFirstTrunkPage}

impl ParseBytes for FreeListPagesFirstTrunkPage {
  const LENGTH_BYTES: usize = 4;

  fn parsing_handler(bytes: &[u8]) -> SQLiteResult<Self> {
    let buf: [u8; Self::LENGTH_BYTES] = bytes.try_into()?;
    let first_page_trunk = u32::from_be_bytes(buf);
    Ok(Self(first_page_trunk))
  }
}

///  FreeListPagesTotalPages: The 4-byte big-endian integer at offset 36
/// stores the total number of pages on the freelist.
#[derive(Debug)]
pub struct FreeListPagesTotalPages(u32);

impl Deref for FreeListPagesTotalPages {
  type Target = u32;

  fn deref(&self) -> &Self::Target {
    &self.0
  }
}

impl_name! {FreeListPagesTotalPages}

impl ParseBytes for FreeListPagesTotalPages {
  const LENGTH_BYTES: usize = 4;

  fn parsing_handler(bytes: &[u8]) -> SQLiteResult<Self> {
    let buf: [u8; Self::LENGTH_BYTES] = bytes.try_into()?;
    let total_pages = u32::from_be_bytes(buf);
    Ok(Self(total_pages))
  }
}