assembly_data/fdb/reader/
builder.rs

1//! # Extension for constructing Rustic values
2use assembly_core::displaydoc::Display;
3use thiserror::Error;
4
5use super::{DatabaseBufReader, DatabaseReader};
6use crate::fdb::{
7    common::{UnknownValueType, ValueType},
8    core::Field,
9    file::FDBFieldData,
10};
11
12use std::{
13    convert::TryFrom,
14    io::{self, BufRead, Seek},
15};
16
17/// Errors generated by the builder module
18#[derive(Debug, Display, Error)]
19pub enum BuilderError {
20    /// Failed IO
21    Io(#[from] io::Error),
22    /// Unknown Value Type
23    UnknownValueType(#[from] UnknownValueType),
24}
25
26/// Results for this module
27pub type Result<T> = std::result::Result<T, BuilderError>;
28
29impl<T: ?Sized> DatabaseBuilder for T where T: DatabaseBufReader + DatabaseReader + Seek + BufRead {}
30
31/// Extension trait for `Seek + BufRead + DatabaseBufReader + DatabaseReader`
32pub trait DatabaseBuilder
33where
34    Self: Seek + BufRead + DatabaseBufReader + DatabaseReader,
35{
36    /// Try to load a field value
37    fn try_load_field(&mut self, data: &FDBFieldData) -> Result<Field> {
38        let bytes = data.value;
39        match ValueType::try_from(data.data_type)? {
40            ValueType::Nothing => Ok(Field::Nothing),
41            ValueType::Integer => Ok(bytes).map(i32::from_le_bytes).map(Field::Integer),
42            ValueType::Float => Ok(bytes)
43                .map(u32::from_le_bytes)
44                .map(f32::from_bits)
45                .map(Field::Float),
46            ValueType::Text => Ok(bytes)
47                .map(u32::from_le_bytes)
48                .and_then(|addr| self.get_string(addr))
49                .map(Field::Text)
50                .map_err(Into::into),
51            ValueType::Boolean => Ok(bytes).map(|v| v != [0; 4]).map(Field::Boolean),
52            ValueType::BigInt => Ok(bytes)
53                .map(u32::from_le_bytes)
54                .and_then(|addr| self.get_i64(addr))
55                .map(Field::BigInt)
56                .map_err(Into::into),
57            ValueType::VarChar => Ok(bytes)
58                .map(u32::from_le_bytes)
59                .and_then(|addr| self.get_string(addr))
60                .map(Field::VarChar)
61                .map_err(Into::into),
62        }
63    }
64}