use std::{fs, num::NonZeroU32, ops::Deref, sync::Arc};
use hashbrown::HashMap;
use idx_binary::IdxBinary;
use crate::Data;
pub type Field = IdxBinary;
#[derive(Debug, Clone, Hash, Eq, PartialEq)]
pub struct FieldName(Arc<String>);
impl<T: Into<String>> From<T> for FieldName {
fn from(value: T) -> Self {
Self(Arc::new(value.into()))
}
}
impl Deref for FieldName {
type Target = Arc<String>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
pub type Fields = HashMap<FieldName, Field>;
impl Data {
pub fn field_bytes(&self, row: NonZeroU32, name: &FieldName) -> &[u8] {
self.fields
.get(name)
.and_then(|v| v.bytes(row))
.unwrap_or(b"")
}
pub fn field_num(&self, row: NonZeroU32, name: &FieldName) -> f64 {
self.fields
.get(name)
.and_then(|v| v.bytes(row))
.and_then(|v| unsafe { std::str::from_utf8_unchecked(v) }.parse().ok())
.unwrap_or(0.0)
}
pub(crate) fn create_field(&mut self, name: &FieldName) {
if !self.fields.contains_key(name) {
let mut fields_dir = self.fields_dir.clone();
fields_dir.push(name.as_ref().to_string());
fs::create_dir_all(&fields_dir).unwrap();
let field = Field::new(fields_dir, self.option.allocation_lot);
self.fields.insert(name.clone(), field);
}
}
pub fn fields(&self) -> &Fields {
&self.fields
}
}