Struct den::Difference

source ·
pub struct Difference<S: ExtendVec + 'static = Vec<u8>> { /* private fields */ }
Expand description

A delta between the local data and the data the Signature represents.

Implementations§

source§

impl Difference

source

pub fn minify( &self, block_size: usize, base: &[u8] ) -> Result<Self, MinifyError>

Changes the block size to block_size, shrinking the Segment::Unknowns 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.

source

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::Unknowns 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.

source§

impl<S: ExtendVec> Difference<S>

source

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.

source

pub fn segments(&self) -> &[Segment<S>]

Returns a reference to all the internal Segments.

This can be used for implementing algorithms other than Self::apply to apply the data.

agde uses this to convert from this format to their Section style.

source

pub fn segments_mut(&mut self) -> &mut Vec<Segment<S>>

Returns a mutable reference to all the internal Segments.

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).

source

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.

source

pub fn map_ref<NS: ExtendVec + 'static>( &self, f: impl FnMut(&S, usize) -> NS ) -> Difference<NS>

Map the ExtendVecs of the Segment::Unknowns 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.

source

pub fn map<NS: ExtendVec + 'static>( self, f: impl FnMut(S, usize) -> NS ) -> Difference<NS>

Map the ExtendVecs of the Segment::Unknowns 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.

source

pub fn block_size(&self) -> usize

The block size used by this diff.

source

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.

source

pub fn original_data_len(&self) -> usize

Get the length of the original data - the data fed to SignatureBuilder::write.

source

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.

source

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.

source

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);
source

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.

source

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.

source

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.

source

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.

source

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.

source

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.

source

pub fn is_empty(&self) -> bool

Returns true if this diff is a no-op.

source

pub fn verify(&self, base: &[u8], target: &[u8]) -> bool

Checks self if it gets base to target, without any allocations.

Returns true if that’s the case.

source

pub fn applied_len(&self, base: &[u8]) -> usize

Calculates the length of the output of Self::apply without any allocations.

source

pub fn in_bounds(&self, base: &[u8]) -> bool

Checks self only contains valid references to base. There will not occur any error from apply functions if this returns true.

Returns true if that’s the case.

Trait Implementations§

source§

impl<S: Clone + ExtendVec + 'static> Clone for Difference<S>

source§

fn clone(&self) -> Difference<S>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<S: ExtendVec + AsRef<[u8]>> Debug for Difference<S>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<'de, S> Deserialize<'de> for Difference<S>where S: Deserialize<'de> + ExtendVec + 'static,

source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
source§

impl<S: PartialEq + ExtendVec + 'static> PartialEq<Difference<S>> for Difference<S>

source§

fn eq(&self, other: &Difference<S>) -> bool

This method tests for self and other values to be equal, and is used by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
source§

impl<S> Serialize for Difference<S>where S: Serialize + ExtendVec + 'static,

source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>where __S: Serializer,

Serialize this value into the given Serde serializer. Read more
source§

impl<S: Eq + ExtendVec + 'static> Eq for Difference<S>

source§

impl<S: ExtendVec + 'static> StructuralEq for Difference<S>

source§

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§

source§

impl<T> Any for Twhere T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere T: ?Sized,

const: unstable · source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere T: ?Sized,

const: unstable · source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

const: unstable · source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for Twhere U: From<T>,

const: unstable · source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T> ToOwned for Twhere T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
const: unstable · source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
const: unstable · source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<T> DeserializeOwned for Twhere T: for<'de> Deserialize<'de>,