mod apply;
pub use apply::{ApplyReport, SkippedPatch};
mod read;
mod write;
use indexmap::IndexMap;
use ltk_hash::BinHash;
use crate::{
path::PropertyPath,
property::{Kind, NoMeta},
BinObject, PropertyValueEnum,
};
#[cfg_attr(
feature = "serde",
derive(serde::Serialize, serde::Deserialize),
serde(bound = "for <'dee> M: serde::Serialize + serde::Deserialize<'dee>")
)]
#[derive(Debug, Clone, PartialEq)]
pub struct BinOverride<M = NoMeta> {
pub deleted: Vec<BinHash>,
pub objects: IndexMap<BinHash, BinObject<M>>,
pub patches: Vec<PropertyPatch<M>>,
}
impl Default for BinOverride {
fn default() -> Self {
Self::new()
}
}
impl<M> BinOverride<M> {
#[must_use]
pub fn new() -> Self {
Self {
deleted: Vec::new(),
objects: IndexMap::new(),
patches: Vec::new(),
}
}
#[must_use]
pub fn builder() -> Builder<M> {
Builder::new()
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.deleted.is_empty() && self.objects.is_empty() && self.patches.is_empty()
}
}
#[cfg_attr(
feature = "serde",
derive(serde::Serialize, serde::Deserialize),
serde(bound = "for <'dee> M: serde::Serialize + serde::Deserialize<'dee>")
)]
#[derive(Debug, Clone, PartialEq)]
pub struct PropertyPatch<M = NoMeta> {
pub object_hash: BinHash,
pub path: PropertyPath,
pub value: PropertyValueEnum<M>,
}
impl<M> PropertyPatch<M> {
pub fn new(
object_hash: impl Into<BinHash>,
path: PropertyPath,
value: impl Into<PropertyValueEnum<M>>,
) -> Self {
Self {
object_hash: object_hash.into(),
path,
value: value.into(),
}
}
#[must_use]
#[inline]
pub fn kind(&self) -> Kind {
self.value.kind()
}
}
#[derive(Debug, Clone)]
pub struct Builder<M = NoMeta> {
deleted: Vec<BinHash>,
objects: Vec<BinObject<M>>,
patches: Vec<PropertyPatch<M>>,
}
impl<M> Default for Builder<M> {
fn default() -> Self {
Self {
deleted: Vec::new(),
objects: Vec::new(),
patches: Vec::new(),
}
}
}
impl<M> Builder<M> {
#[must_use]
pub fn new() -> Self {
Self::default()
}
#[must_use]
pub fn delete(mut self, object_hash: impl Into<BinHash>) -> Self {
self.deleted.push(object_hash.into());
self
}
#[must_use]
pub fn deletions(mut self, hashes: impl IntoIterator<Item = impl Into<BinHash>>) -> Self {
self.deleted.extend(hashes.into_iter().map(Into::into));
self
}
#[must_use]
pub fn object(mut self, object: BinObject<M>) -> Self {
self.objects.push(object);
self
}
#[must_use]
pub fn objects(mut self, objects: impl IntoIterator<Item = BinObject<M>>) -> Self {
self.objects.extend(objects);
self
}
#[must_use]
pub fn set(
self,
object_hash: impl Into<BinHash>,
path: PropertyPath,
value: impl Into<PropertyValueEnum<M>>,
) -> Self {
self.patch(PropertyPatch::new(object_hash, path, value))
}
#[must_use]
pub fn patch(mut self, patch: PropertyPatch<M>) -> Self {
self.patches.push(patch);
self
}
#[must_use]
pub fn patches(mut self, patches: impl IntoIterator<Item = PropertyPatch<M>>) -> Self {
self.patches.extend(patches);
self
}
#[must_use]
pub fn build(self) -> BinOverride<M> {
BinOverride {
deleted: self.deleted,
objects: self
.objects
.into_iter()
.map(|object| (object.path_hash, object))
.collect(),
patches: self.patches,
}
}
}