27 releases (9 breaking)

0.11.3 Jun 1, 2021
0.11.1 May 6, 2021
0.10.0 Mar 27, 2021
0.8.2 Dec 25, 2020
0.3.0 Mar 12, 2020

#495 in Rust patterns

Download history 60/week @ 2022-12-01 92/week @ 2022-12-08 54/week @ 2022-12-15 55/week @ 2022-12-22 23/week @ 2022-12-29 73/week @ 2023-01-05 47/week @ 2023-01-12 69/week @ 2023-01-19 343/week @ 2023-01-26 252/week @ 2023-02-02 192/week @ 2023-02-09 118/week @ 2023-02-16 70/week @ 2023-02-23 47/week @ 2023-03-02 53/week @ 2023-03-09 67/week @ 2023-03-16

239 downloads per month
Used in 5 crates (3 directly)






Deltoid is a type-driven rust library that can be used to calculate deltas. A delta Δ can be calculated between 2 values a and b of the same type. Once calculated, Δ can then be applied to the first value a to obtain a new value c that is equivalent to the second value b.

A primary use case for calculating delta's is to keep track of a sequence of related and potentially deeply-nested data trees while making sure to keep resource consumption (e.g. RAM, network bandwidth) reasonable. Since such a sequence may be exported for further processing, delta's are by definition de/serializable. This allows you to collect the data in once place as a sequence of delta's, export it (perhaps over a network connection), and then reconstruct the original sequence on the receiving side by successively applying the delta's in the sequence.


Add this to your Cargo.toml:

deltoid = "0.11.1"
deltoid-derive = "0.11.1"

Computing a delta, then applying it:

use deltoid::Deltoid;
use serde_derive::{Deserialize, Serialize};

#[derive(Deserialize, Serialize, Deltoid)]
struct Point {
    x: usize,
    y: usize,

fn main() {
    // Define 2 instances of the same type
    let point0 = Point { x:  0, y: 0 };
    let point1 = Point { x: 42, y: 8 };

    // Calculate the delta between them
    let delta = point0.delta(&point1).unwrap();

    // Apply  the delta to `point0`
    let point2 = point0.apply(delta).unwrap();
    assert_eq!(point1, point2);


There are some limitations to this library:

  1. Unions are not supported. Only structs and enums are currently supported.

  2. The derive macro tries to accommodate generic types, but for types making use of advanced generics a manual implementation is generally recommended over using deltoid-derive because it allows for finer control.

  3. Types that have fields that have a borrow type (i.e. &T and &mut T for some type T) are not currently supported. This limitation may be lifted in the future for mutable borrows, but is pretty fundamental for immutable borrows.

  4. It's possible that while developing you notice that a set of impls is missing for a type in Rust's stdlib. If so, this is because support for types that are a part of stdlib must be added manually and simply hasn't been done yet. You can file an issue for that, or even better, send a PR :)

Special Thanks

A special thanks to Accept B.V. for sponsoring this project.


~72K SLoC