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
use assembly_core::displaydoc::Display;
use thiserror::Error;
use super::{DatabaseBufReader, DatabaseReader};
use crate::fdb::{
common::{UnknownValueType, ValueType},
core::Field,
file::FDBFieldData,
};
use std::{
convert::TryFrom,
io::{self, BufRead, Seek},
};
#[derive(Debug, Display, Error)]
pub enum BuilderError {
IO(#[from] io::Error),
UnknownValueType(#[from] UnknownValueType),
}
pub type Result<T> = std::result::Result<T, BuilderError>;
impl<T: ?Sized> DatabaseBuilder for T where T: DatabaseBufReader + DatabaseReader + Seek + BufRead {}
pub trait DatabaseBuilder
where
Self: Seek + BufRead + DatabaseBufReader + DatabaseReader,
{
fn try_load_field(&mut self, data: &FDBFieldData) -> Result<Field> {
let bytes = data.value;
match ValueType::try_from(data.data_type)? {
ValueType::Nothing => Ok(Field::Nothing),
ValueType::Integer => Ok(bytes).map(i32::from_le_bytes).map(Field::Integer),
ValueType::Float => Ok(bytes)
.map(u32::from_le_bytes)
.map(f32::from_bits)
.map(Field::Float),
ValueType::Text => Ok(bytes)
.map(u32::from_le_bytes)
.and_then(|addr| self.get_string(addr))
.map(Field::Text)
.map_err(Into::into),
ValueType::Boolean => Ok(bytes).map(|v| v != [0; 4]).map(Field::Boolean),
ValueType::BigInt => Ok(bytes)
.map(u32::from_le_bytes)
.and_then(|addr| self.get_i64(addr))
.map(Field::BigInt)
.map_err(Into::into),
ValueType::VarChar => Ok(bytes)
.map(u32::from_le_bytes)
.and_then(|addr| self.get_string(addr))
.map(Field::VarChar)
.map_err(Into::into),
}
}
}