inc-complete 0.10.3

A library for writing incremental computations that re-execute the minimum number of steps when an input is changed
Documentation
use crate::Db;
use crate::db::START_VERSION;
use crate::define_input;
use crate::define_intermediate;
use crate::impl_storage;
use crate::storage::SingletonStorage;

// Emulate this spreadsheet:
//      A
// 1 [ =20 ]
// 2 [ =A1 + 1 ]
// 3 [ =A2 + 2 ]
#[derive(Clone, Debug, Default)]
struct A1;

#[derive(Clone, Debug, PartialEq, Eq, Hash, Default)]
struct A2;

#[derive(Clone, Debug, PartialEq, Eq, Hash, Default)]
struct A3;

#[derive(Default)]
struct Spreadsheet {
    a1: SingletonStorage<A1>,
    a2: SingletonStorage<A2>,
    a3: SingletonStorage<A3>,
}

impl_storage!(Spreadsheet,
    a1: A1,
    a2: A2,
    a3: A3,
);

define_input!(0, A1 -> i32, Spreadsheet);
define_intermediate!(1, A2 -> i32, Spreadsheet, |_, handle| {
    handle.get(A1) + 1
});
define_intermediate!(2, A3 -> i32, Spreadsheet, |_, handle| {
    handle.get(A2) + 2
});

// Test that we can compute a basic chain of computation
//      A
// 1 [ =20 ]
// 2 [ =A1 + 1 ]
// 3 [ =A2 + 2 ]
#[test]
fn basic() {
    let mut db = Db::<Spreadsheet>::new();
    db.update_input(A1, 20);
    let result = db.get(A3);
    assert_eq!(result, 23);
}

// Test that we can re-use values from past runs
//      A
// 1 [ =20 ]
// 2 [ =A1 + 1 ]
// 3 [ =A2 + 2 ]
#[test]
fn no_recompute_basic() {
    let mut db = Db::<Spreadsheet>::new();
    db.update_input(A1, 20);
    let result1 = db.get(A3);
    let result2 = db.get(A3);
    assert_eq!(result1, 23);
    assert_eq!(result2, 23);

    // Only 1 input has been updated
    let expected_version = START_VERSION + 1;
    assert_eq!(db.version(), expected_version);

    db.with_cell_data(&A1, |a1| {
        assert_eq!(a1.last_updated_version, expected_version);
        assert_eq!(a1.last_verified_version, expected_version);
    });

    db.with_cell_data(&A2, |a2| {
        assert_eq!(a2.last_updated_version, expected_version);
        assert_eq!(a2.last_verified_version, expected_version);
    });

    db.with_cell_data(&A3, |a3| {
        assert_eq!(a3.last_updated_version, expected_version);
        assert_eq!(a3.last_verified_version, expected_version);
    });
}