use std::collections::HashMap;
use std::path::Path;
use crate::core::{BuildReport, FuseResult, WriterCore};
#[cfg(feature = "msgpack")]
use serde::Serialize;
#[derive(Default)]
pub struct FuseWriter {
core: WriterCore,
dedup: HashMap<Vec<u8>, usize>,
}
impl FuseWriter {
pub fn new() -> Self {
Self {
core: WriterCore::new(),
dedup: HashMap::new(),
}
}
pub fn add_object_raw(&mut self, raw: impl AsRef<[u8]>) -> usize {
self.core.add_object(raw.as_ref())
}
pub fn add_object_raw_deduped(&mut self, raw: impl AsRef<[u8]>) -> usize {
let raw = raw.as_ref();
if let Some(&id) = self.dedup.get(raw) {
return id;
}
let id = self.core.add_object(raw);
self.dedup.insert(raw.to_vec(), id);
id
}
pub fn add_key(&mut self, key: impl AsRef<[u8]>, obj_id: usize) -> FuseResult<()> {
self.core.add_key(key.as_ref(), obj_id)
}
pub fn add_raw(&mut self, key: impl AsRef<[u8]>, raw: impl AsRef<[u8]>) -> FuseResult<usize> {
let oid = self.add_object_raw(raw);
self.add_key(key, oid)?;
Ok(oid)
}
#[cfg(feature = "msgpack")]
pub fn add_object<T: Serialize + ?Sized>(&mut self, value: &T) -> FuseResult<usize> {
let raw = super::codec::encode(value)?;
Ok(self.core.add_object(&raw))
}
#[cfg(feature = "msgpack")]
pub fn add_object_deduped<T: Serialize + ?Sized>(&mut self, value: &T) -> FuseResult<usize> {
let raw = super::codec::encode(value)?;
Ok(self.add_object_raw_deduped(raw))
}
#[cfg(feature = "msgpack")]
pub fn add<T: Serialize + ?Sized>(
&mut self,
key: impl AsRef<[u8]>,
value: &T,
) -> FuseResult<usize> {
let oid = self.add_object(value)?;
self.add_key(key, oid)?;
Ok(oid)
}
pub fn build(&self, path: impl AsRef<Path>) -> FuseResult<BuildReport> {
self.core.build(path)
}
#[inline]
pub fn num_objects(&self) -> usize {
self.core.num_objects()
}
#[inline]
pub fn num_keys(&self) -> usize {
self.core.num_keys()
}
#[inline]
pub fn is_empty(&self) -> bool {
self.core.num_objects() == 0 && self.core.num_keys() == 0
}
}
impl std::fmt::Debug for FuseWriter {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("FuseWriter")
.field("objects", &self.num_objects())
.field("keys", &self.num_keys())
.finish()
}
}