use super::*;
#[derive(Debug, Clone, Serialize, Deserialize, Getters, MutGetters, PartialEq)]
pub struct SparseRefRaw<S> {
#[serde(skip)]
#[getset(get = "pub", get_mut)]
#[serde(default = "SparsePointedValue::<S>::default")]
val: SparsePointedValue<S>,
#[serde(rename = "$ref")]
#[getset(get = "pub")]
raw_pointer: String,
#[serde(skip)]
#[getset(get = "pub", get_mut = "pub")]
base_path: PathBuf,
}
impl<S> SparsableTrait for SparseRefRaw<S>
where
S: DeserializeOwned + Serialize + SparsableTrait,
{
fn sparse_init<'a>(
&mut self,
state: &mut SparseState,
metadata: &SparseMetadata,
depth: u32,
) -> Result<(), SparseError> {
self.check_depth(depth)?;
match self.val {
SparsePointedValue::Null => self.self_reset(state, metadata, depth)?,
_ => {
if let Some(SparseError::OutdatedPointer) = self.check_version(state).err() {
self.self_reset(state, metadata, depth)?;
self.val.sparse_init(state, metadata, depth + 1)?
}
}
}
self.val.sparse_init(state, metadata, depth + 1)
}
fn sparse_updt<'a>(
&mut self,
state: &mut SparseState,
metadata: &SparseMetadata,
depth: u32,
) -> Result<(), SparseError> {
self.check_depth(depth)?;
let vcheck = self.check_version(state);
match vcheck {
Ok(()) => (),
Err(SparseError::OutdatedPointer) => self.sparse_init(state, metadata, depth)?,
Err(_) => return vcheck,
};
self.val.sparse_updt(state, metadata, depth + 1)
}
}
impl<S> SparsePointerRaw<S> for SparseRefRaw<S>
where
S: DeserializeOwned + Serialize + SparsableTrait,
{
fn check_version(&self, state: &SparseState) -> Result<(), SparseError> {
self.val.check_version(state)
}
fn get<'a>(
&'a self,
metadata: Option<&'a SparseMetadata>,
) -> Result<SparseValue<'a, S>, SparseError> {
self.val().get(metadata)
}
fn get_mut<'a>(
&'a mut self,
state_cell: Rc<RefCell<SparseState>>,
metadata: Option<&'a SparseMetadata>,
) -> Result<SparseValueMut<'a, S>, SparseError> {
{
let state = state_cell
.try_borrow()
.map_err(|_e| SparseError::StateAlreadyBorrowed)?;
self.check_version(&state)?;
}
self.val_mut().get_mut(state_cell, metadata)
}
fn self_reset<'a>(
&mut self,
state: &mut SparseState,
metadata: &SparseMetadata,
depth: u32,
) -> Result<(), SparseError> {
self.check_depth(depth)?;
self._self_reset(state, metadata, depth)
}
}
impl<S> SparseRefRaw<S>
where
S: DeserializeOwned + Serialize + SparsableTrait,
{
pub(crate) fn init_val(
&mut self,
state: &mut SparseState,
metadata: &SparseMetadata,
depth: u32,
) -> Result<(), SparseError> {
match self.val {
SparsePointedValue::Null => {
let val = &mut self.val;
let path = match self.base_path.is_absolute() {
true => self.base_path.clone(),
false => metadata.pfile_path().clone(),
};
*val = SparsePointedValue::Ref(SparseRef::new(
state,
path,
self.raw_pointer.clone(),
depth,
)?);
Ok(())
}
_ => Ok(()),
}
}
fn _self_reset(
&mut self,
state: &mut SparseState,
metadata: &SparseMetadata,
depth: u32,
) -> Result<(), SparseError> {
self.val = SparsePointedValue::Null;
self.init_val(state, metadata, depth)
}
pub fn new(raw_pointer: String) -> Self {
SparseRefRaw {
val: SparsePointedValue::Null,
raw_pointer,
base_path: PathBuf::new(),
}
}
}