Struct den::Difference
source · [−]Expand description
A delta between the local data and the data the Signature
represents.
Implementations
sourceimpl Difference
impl Difference
sourcepub fn minify(&self, block_size: usize, base: &[u8]) -> Result<Self, MinifyError>
pub fn minify(&self, block_size: usize, base: &[u8]) -> Result<Self, MinifyError>
Changes the block size to block_size
, shrinking the Segment::Unknown
s in the process.
This results in a smaller diff.
Consider Self::minify_with_builder
for using custom signature settings.
Errors
tl;dr, you can Option::unwrap
this if it comes straight from Signature::diff
or
this very function. If it’s untrusted data, handle the errors.
Returns MinifyError::NewLarger
if block_size
>= Self::block_size
and
MinifyError::NotMultiple
if Self::block_size
is not a multiple of block_size
.
MinifyError::SuccessiveUnknowns
is returned if two Segment::Unknown
are after
each other.
Returns MinifyError::Zero
if block_size == 0
.
sourcepub fn minify_with_builder(
&self,
block_size: usize,
base: &[u8],
signature_builder: impl FnMut(usize) -> SignatureBuilder
) -> Result<Self, MinifyError>
pub fn minify_with_builder(
&self,
block_size: usize,
base: &[u8],
signature_builder: impl FnMut(usize) -> SignatureBuilder
) -> Result<Self, MinifyError>
Changes the block size to block_size
, shrinking the Segment::Unknown
s in the process.
This results in a smaller diff.
signature_builder
takes the block size and gives the signature builder to use.
Panics
Panics if signature_builder
returns a SignatureBuilder
with a different block_size
from what’s supplied.
Errors
tl;dr, you can Option::unwrap
this if it comes straight from Signature::diff
or
this very function. If it’s untrusted data, handle the errors.
Returns MinifyError::NewLarger
if block_size
>= Self::block_size
and
MinifyError::NotMultiple
if Self::block_size
is not a multiple of block_size
.
MinifyError::SuccessiveUnknowns
is returned if two Segment::Unknown
are after
each other.
Returns MinifyError::Zero
if block_size == 0
.
sourceimpl<S: ExtendVec> Difference<S>
impl<S: ExtendVec> Difference<S>
sourcepub fn empty(len: usize, block_size: usize) -> Self
pub fn empty(len: usize, block_size: usize) -> Self
Create an empty diff that does nothing when applied.
len
is the length of the data, both before and after.
If this is smaller than the target, it’ll truncate it
(in whole block_size
segments). If len
is longer,
applying will return an error.
block_size
is simply the size of the blocks.
Not that relevant here, but used by other methods on Difference
.
Panics
Panics if block_size
is 0
.
sourcepub fn segments(&self) -> &[Segment<S>]
pub fn segments(&self) -> &[Segment<S>]
Returns a reference to all the internal Segment
s.
This can be used for implementing algorithms other than Self::apply
to apply the data.
agde
uses this to convert from this format to theirSection
style.
sourcepub fn segments_mut(&mut self) -> &mut Vec<Segment<S>>
pub fn segments_mut(&mut self) -> &mut Vec<Segment<S>>
Returns a mutable reference to all the internal Segment
s.
Don’t use this unless you know what you’re doing.
Using this function, you can change the building blocks of the diff.
This can be useful for transforming it to use another ExtendVec
for compact metadata
storage (which can later be used to revert).
sourcepub fn into_segments(self) -> Vec<Segment<S>>
pub fn into_segments(self) -> Vec<Segment<S>>
Turns this difference into it’s list of segments.
Prefer to use Self::segments
if you don’t plan on consuming the internal data.
sourcepub fn map_ref<NS: ExtendVec + 'static>(
&self,
f: impl FnMut(&S, usize) -> NS
) -> Difference<NS>
pub fn map_ref<NS: ExtendVec + 'static>(
&self,
f: impl FnMut(&S, usize) -> NS
) -> Difference<NS>
Map the ExtendVec
s of the Segment::Unknown
s with f
.
The second argument of f
is the start of S
the applied data.
Creates a new difference with the same length and values.
Consider using Difference::map
.
Panics
Panics if NS
doesn’t have the same ExtendVec::len
as S
.
sourcepub fn map<NS: ExtendVec + 'static>(
self,
f: impl FnMut(S, usize) -> NS
) -> Difference<NS>
pub fn map<NS: ExtendVec + 'static>(
self,
f: impl FnMut(S, usize) -> NS
) -> Difference<NS>
Map the ExtendVec
s of the Segment::Unknown
s with f
.
The second argument of f
is the start of S
the applied data.
Creates a new difference with the same length and values.
Still allocates Difference::segments
vector.
Consider using Difference::map_ref
.
Panics
Panics if NS
doesn’t have the same ExtendVec::len
as S
.
sourcepub fn block_size(&self) -> usize
pub fn block_size(&self) -> usize
The block size used by this diff.
sourcepub fn approximate_binary_size(&self) -> usize
pub fn approximate_binary_size(&self) -> usize
Approximates the size this takes up in memory or when serializing it with a binary serializer. The returned value is in bytes.
sourcepub fn original_data_len(&self) -> usize
pub fn original_data_len(&self) -> usize
Get the length of the original data - the data fed to SignatureBuilder::write
.
sourcepub fn set_original_data_len(&mut self, original_data_len: usize)
pub fn set_original_data_len(&mut self, original_data_len: usize)
Set the length of the original data.
See Self::original_data_len
for more details.
sourcepub fn with_block_size(&mut self, block_size: usize) -> Result<(), MinifyError>
pub fn with_block_size(&mut self, block_size: usize) -> Result<(), MinifyError>
Set the block size.
Use Difference::minify
to also trim down the size of the contained data.
block_size
must be small than Self::block_size
.
Self::block_size
must also be dividable by it.
Errors
Returns MinifyError::NewLarger
if block_size
>= Self::block_size
and
MinifyError::NotMultiple
if Self::block_size
is not a multiple of block_size
.
Returns MinifyError::Zero
if block_size == 0
.
sourcepub fn apply_overlaps(&self, base_len: usize) -> bool
pub fn apply_overlaps(&self, base_len: usize) -> bool
Returns whether or not applying this diff is impossible to do on a single Vec
.
base_len
is the length of base
passed to Self::apply
or Self::apply_in_place
.
If the returned value is true
, the apply function will try to read data from parts of the
Vec
already overridden.
You should be able to use a single Vec
if the returned value is false
.
Examples
let base_data = b"This is a document everyone has. It's about some new difference library.";
let target_data = b"This is a document only I have. It's about some new difference library.";
let mut base_data = base_data.to_vec();
let mut signature = Signature::new(128);
signature.write(&base_data);
let signature = signature.finish();
let diff = signature.diff(target_data);
// This is the small diff you could serialize with Serde and send.
let minified = diff.minify(8, &base_data)
.expect("This won't panic, as the data hasn't changed from calling the other functions.");
let data = if minified.apply_overlaps(base_data.len()) {
let mut data = Vec::new();
minified.apply(&base_data, &mut data);
data
} else {
minified.apply_in_place(&mut base_data);
base_data
};
assert_eq!(data, target_data);
sourcepub fn apply_overlaps_adaptive_end(&self, base_len: usize) -> bool
pub fn apply_overlaps_adaptive_end(&self, base_len: usize) -> bool
Returns whether or not applying this diff is impossible to do on a single Vec
.
base_len
is the length of base
passed to Self::apply
or Self::apply_in_place
.
If the returned value is true
, the apply function will try to read data from parts of the
Vec
already overridden.
You should be able to use a single Vec
if the returned value is false
.
The adaptive end part means that if base
isn’t the same as fed to
SignatureBuilder::write
, we’ll try to write any additional written data to the end.
This makes it feasible to apply diffs after modifying base
, without all
modifications being overridden.
Examples
See Self::apply_overlaps
.
sourcepub fn apply(&self, base: &[u8], out: &mut Vec<u8>) -> Result<(), ApplyError>
pub fn apply(&self, base: &[u8], out: &mut Vec<u8>) -> Result<(), ApplyError>
Apply diff
to the base
data base, appending the result to out
.
Consider checking Self::apply_overlaps
and calling Self::apply_in_place
to remove the need for the Vec
.
Security
The diff
should be sanitized if input is suspected to be malicious.
Errors
Returns ApplyError::RefOutOfBounds
if a reference is out of bounds of the base
.
If base
is the same data written to SignatureBuilder::write
, this error will not
occur, granted this diff is derived from that Signature
.
Ok to unwrap if Self::in_bounds
.
sourcepub fn apply_adaptive_end(
&self,
base: &[u8],
out: &mut Vec<u8>
) -> Result<(), ApplyError>
pub fn apply_adaptive_end(
&self,
base: &[u8],
out: &mut Vec<u8>
) -> Result<(), ApplyError>
Apply diff
to the base
data base, appending the result to out
.
Consider checking Self::apply_overlaps
and calling Self::apply_in_place
to remove the need for the Vec
.
The adaptive end part means that if base
isn’t the same as fed to
SignatureBuilder::write
, we’ll try to write any additional written data to the end.
This makes it feasible to apply diffs after modifying base
, without all
modifications being overridden.
Security
The diff
should be sanitized if input is suspected to be malicious.
Errors
Returns ApplyError::RefOutOfBounds
if a reference is out of bounds of the base
.
If base
is the same data written to SignatureBuilder::write
, this error will not
occur, granted this diff is derived from that Signature
.
Ok to unwrap if Self::in_bounds
.
sourcepub fn apply_in_place(&self, base: &mut Vec<u8>) -> Result<(), ApplyError>
pub fn apply_in_place(&self, base: &mut Vec<u8>) -> Result<(), ApplyError>
Apply diff
to the base
data base, mutating the base
data.
You MUST check that this is possible using Self::apply_overlaps
.
Neglecting that step will result in data loss and erroneous data.
This WILL NOT give an error in case of breaking that contract.
Security
The diff
should be sanitized if input is suspected to be malicious.
Errors
If this returns an error, consider base
to be bogus data.
Returns ApplyError::RefOutOfBounds
if a reference is out of bounds of the base
.
Ok to unwrap if Self::in_bounds
.
Examples
See Self::apply_overlaps
.
sourcepub fn apply_in_place_adaptive_end(
&self,
base: &mut Vec<u8>
) -> Result<(), ApplyError>
pub fn apply_in_place_adaptive_end(
&self,
base: &mut Vec<u8>
) -> Result<(), ApplyError>
Apply diff
to the base
data base, mutating the base
data.
You MUST check that this is possible using Self::apply_overlaps_adaptive_end
.
Neglecting that step will result in data loss and erroneous data.
This WILL NOT give an error in case of breaking that contract.
The adaptive end part means that if base
isn’t the same as fed to
SignatureBuilder::write
, we’ll try to write any additional written data to the end.
This makes it feasible to apply diffs after modifying base
, without all
modifications being overridden.
Security
The diff
should be sanitized if input is suspected to be malicious.
Errors
If this returns an error, consider base
to be bogus data.
Returns ApplyError::RefOutOfBounds
if a reference is out of bounds of the base
.
Ok to unwrap if Self::in_bounds
.
Examples
See Self::apply_overlaps
.
sourcepub fn revert(
&self,
current: &[u8],
target: &mut Vec<u8>,
fill_byte: u8
) -> Result<(), ApplyError>
pub fn revert(
&self,
current: &[u8],
target: &mut Vec<u8>,
fill_byte: u8
) -> Result<(), ApplyError>
Reverts current
to what it would have been before applying this diff.
This completely overrides target
.
Say I have the data: hello there - from vim
and the diff is [Segment::Ref(0..8)]
, the new data (current
) will be
hello th
. The length of the original data is stored, but the lost bytes are
unrecoverable. They are filled with fill_byte
. That should probably be b' '
for text
applications.
Security
The diff
should be sanitized if input is suspected to be malicious.
Errors
Returns ApplyError::RefOutOfBounds
if a reference is out of bounds of the base
.
Trait Implementations
sourceimpl<S: Clone + ExtendVec + 'static> Clone for Difference<S>
impl<S: Clone + ExtendVec + 'static> Clone for Difference<S>
sourcefn clone(&self) -> Difference<S>
fn clone(&self) -> Difference<S>
Returns a copy of the value. Read more
1.0.0 · sourcefn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
Performs copy-assignment from source
. Read more
sourceimpl<S: Debug + ExtendVec + 'static> Debug for Difference<S>
impl<S: Debug + ExtendVec + 'static> Debug for Difference<S>
sourceimpl<'de, S: ExtendVec + 'static> Deserialize<'de> for Difference<S> where
S: Deserialize<'de>,
impl<'de, S: ExtendVec + 'static> Deserialize<'de> for Difference<S> where
S: Deserialize<'de>,
sourcefn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error> where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error> where
__D: Deserializer<'de>,
Deserialize this value from the given Serde deserializer. Read more
sourceimpl<S: PartialEq + ExtendVec + 'static> PartialEq<Difference<S>> for Difference<S>
impl<S: PartialEq + ExtendVec + 'static> PartialEq<Difference<S>> for Difference<S>
sourcefn eq(&self, other: &Difference<S>) -> bool
fn eq(&self, other: &Difference<S>) -> bool
This method tests for self
and other
values to be equal, and is used
by ==
. Read more
sourcefn ne(&self, other: &Difference<S>) -> bool
fn ne(&self, other: &Difference<S>) -> bool
This method tests for !=
.
sourceimpl<S: ExtendVec + 'static> Serialize for Difference<S> where
S: Serialize,
impl<S: ExtendVec + 'static> Serialize for Difference<S> where
S: Serialize,
impl<S: Eq + ExtendVec + 'static> Eq for Difference<S>
impl<S: ExtendVec + 'static> StructuralEq for Difference<S>
impl<S: ExtendVec + 'static> StructuralPartialEq for Difference<S>
Auto Trait Implementations
impl<S> RefUnwindSafe for Difference<S> where
S: RefUnwindSafe,
impl<S> Send for Difference<S> where
S: Send,
impl<S> Sync for Difference<S> where
S: Sync,
impl<S> Unpin for Difference<S> where
S: Unpin,
impl<S> UnwindSafe for Difference<S> where
S: UnwindSafe,
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more