~dkellner/chronofold

e5e10e03f828d467d16ad3e91122effd74e415ca — Dominik Kellner 9 months ago 2ba00a7
Use new format strings
7 files changed, 31 insertions(+), 33 deletions(-)

M README.md
M benches/dmonad.rs
M src/debug.rs
M src/lib.rs
M tests/corner_cases.rs
M tests/errors.rs
M tests/random.rs
M README.md => README.md +4 -4
@@ 51,9 51,9 @@ let ops_b: Vec<Op<AuthorId, char>> = {
// Now their respective states have diverged.
assert_eq!(
    "Hello chronfold - a data structure for versioned text!",
    format!("{}", cfold_a),
    format!("{cfold_a}"),
);
assert_eq!("Hello chronofold!", format!("{}", cfold_b));
assert_eq!("Hello chronofold!", format!("{cfold_b}"));

// As soon as both have seen all ops, their states have converged.
for op in ops_a {


@@ 63,8 63,8 @@ for op in ops_b {
    cfold_a.apply(op).unwrap();
}
let final_text = "Hello chronofold - a data structure for versioned text!";
assert_eq!(final_text, format!("{}", cfold_a));
assert_eq!(final_text, format!("{}", cfold_b));
assert_eq!(final_text, format!("{cfold_a}"));
assert_eq!(final_text, format!("{cfold_b}"));
```

# Roadmap

M benches/dmonad.rs => benches/dmonad.rs +10 -10
@@ 38,7 38,7 @@ fn append_chars(c: &mut Criterion) {
    let input = random_string(&mut rng, N..=N);
    bench(
        c,
        &format!("[B1.1] Append {} characters", N),
        &format!("[B1.1] Append {N} characters"),
        input.chars().collect(),
        |sess, c| {
            sess.push_back(c);


@@ 52,7 52,7 @@ fn insert_string(c: &mut Criterion) {
    let input = random_string(&mut rng, N..=N);
    bench(
        c,
        &format!("[B1.2] Insert string of length {}", N),
        &format!("[B1.2] Insert string of length {N}"),
        vec![input.clone()],
        |sess, s| {
            sess.extend(s.chars());


@@ 66,7 66,7 @@ fn prepend_chars(c: &mut Criterion) {
    let input = random_string(&mut rng, N..=N);
    bench(
        c,
        &format!("[B1.3] Prepend {} characters", N),
        &format!("[B1.3] Prepend {N} characters"),
        input.chars().collect(),
        |sess, c| {
            sess.push_front(c);


@@ 89,7 89,7 @@ fn insert_chars_at_random_positions(c: &mut Criterion) {

    bench(
        c,
        &format!("[B1.4] Insert {} characters at random positions", N),
        &format!("[B1.4] Insert {N} characters at random positions"),
        positions_and_chars,
        |sess, (pos, c)| {
            let idx = if pos == 0 {


@@ 120,7 120,7 @@ fn insert_words_at_random_positions(c: &mut Criterion) {

    bench(
        c,
        &format!("[B1.5] Insert {} words at random positions", N),
        &format!("[B1.5] Insert {N} words at random positions"),
        positions_and_words,
        |sess, (pos, s)| {
            // This is expected to be really slow, as accessing a specific


@@ 141,7 141,7 @@ fn insert_and_delete_string(c: &mut Criterion) {
    let s = random_string(&mut rng, N..=N);
    bench(
        c,
        &format!("[B1.6] Insert string of length {}, then delete it", N),
        &format!("[B1.6] Insert string of length {N}, then delete it"),
        vec![s],
        |sess, s| {
            let last_idx = sess.extend(s.chars()).unwrap();


@@ 175,7 175,7 @@ fn insert_and_delete_strings_at_random_positions(c: &mut Criterion) {

    bench(
        c,
        &format!("[B1.7] Insert/Delete {} strings at random positions", N),
        &format!("[B1.7] Insert/Delete {N} strings at random positions"),
        input,
        |sess, (start, end, s)| {
            let a = sess.as_ref().iter().nth(start).map(|(_, idx)| idx);


@@ 197,7 197,7 @@ fn bench<T: Clone, F: Fn(&mut Sess<'_>, T) + Copy, G: Fn(&CFold, &CFold) + Copy>
    apply_change: F,
    check: G,
) {
    c.bench_function(&format!("{} (time)", name), |b| {
    c.bench_function(&format!("{name} (time)"), |b| {
        b.iter_custom(|iters| {
            let mut elapsed = Duration::new(0, 0);
            for _i in 0..iters {


@@ 251,8 251,8 @@ fn measure_space<T, F: Fn(&mut Sess<'_>, T)>(name: &str, input: Vec<T>, apply_ch

fn assert_docs_equal(expected: &str) -> impl Fn(&CFold, &CFold) + Copy + '_ {
    move |doc1, doc2| {
        let text1 = format!("{}", doc1);
        let text2 = format!("{}", doc2);
        let text1 = format!("{doc1}");
        let text2 = format!("{doc2}");
        assert_eq!(text1, text2);
        assert_eq!(expected, text1);
    }

M src/debug.rs => src/debug.rs +6 -8
@@ 9,14 9,12 @@ impl<A: Author, T: fmt::Debug> Chronofold<A, T> {
            "idx", "ref", "next", "del"
        );
        for (idx, change) in self.log.iter().enumerate() {
            let log_idx = LogIndex(idx);
            let formatted_ref = format_option(self.references.get(&log_idx));
            let next = format_option(self.next_indices.get(&log_idx));
            let idx = LogIndex(idx);
            let ref_ = format_option(self.references.get(&idx));
            let next = format_option(self.next_indices.get(&idx));
            let del = format_option(change.1);
            result += &format!(
                "{:<4} | {:<4} | {:<4} | {:<4} | {:?}\n",
                idx, formatted_ref, next, del, change.0
            );
            let change = &change.0;
            result += &format!("{idx:<4} | {ref_:<4} | {next:<4} | {del:<4} | {change:?}\n");
        }
        result
    }


@@ 24,7 22,7 @@ impl<A: Author, T: fmt::Debug> Chronofold<A, T> {

fn format_option<T: fmt::Display>(option: Option<T>) -> String {
    match option {
        Some(t) => format!("{}", t),
        Some(t) => format!("{t}"),
        None => "".to_owned(),
    }
}

M src/lib.rs => src/lib.rs +4 -4
@@ 51,9 51,9 @@
//! // Now their respective states have diverged.
//! assert_eq!(
//!     "Hello chronfold - a data structure for versioned text!",
//!     format!("{}", cfold_a),
//!     format!("{cfold_a}"),
//! );
//! assert_eq!("Hello chronofold!", format!("{}", cfold_b));
//! assert_eq!("Hello chronofold!", format!("{cfold_b}"));
//!
//! // As soon as both have seen all ops, their states have converged.
//! for op in ops_a {


@@ 63,8 63,8 @@
//!     cfold_a.apply(op).unwrap();
//! }
//! let final_text = "Hello chronofold - a data structure for versioned text!";
//! assert_eq!(final_text, format!("{}", cfold_a));
//! assert_eq!(final_text, format!("{}", cfold_b));
//! assert_eq!(final_text, format!("{cfold_a}"));
//! assert_eq!(final_text, format!("{cfold_b}"));
//! ```

// As we only have a handful of public items, we've decided to re-export

M tests/corner_cases.rs => tests/corner_cases.rs +3 -3
@@ 105,7 105,7 @@ fn insert_referencing_deleted_element() {
    let idx = session.push_back('!');
    session.clear();
    session.insert_after(idx, '?');
    assert_eq!("?", format!("{}", cfold));
    assert_eq!("?", format!("{cfold}"));
}

fn assert_concurrent_eq<F, G>(expected: &str, initial: &str, mutate_left: F, mutate_right: G)


@@ 137,13 137,13 @@ where

    assert_eq!(
        expected,
        format!("{}", cfold_left),
        format!("{cfold_left}"),
        "\n{}",
        cfold_left.formatted_log(),
    );
    assert_eq!(
        expected,
        format!("{}", cfold_right),
        format!("{cfold_right}"),
        "\n{}",
        cfold_right.formatted_log(),
    );

M tests/errors.rs => tests/errors.rs +3 -3
@@ 7,7 7,7 @@ fn unknown_timestamp() {
    let op = Op::insert(Timestamp(LogIndex(1), 1), Some(unknown), '!');
    let err = cfold.apply(op.clone()).unwrap_err();
    assert_eq!(ChronofoldError::UnknownReference(op), err);
    assert_eq!("unknown reference <1, 42>", format!("{}", err));
    assert_eq!("unknown reference <1, 42>", format!("{err}"));
}

#[test]


@@ 20,7 20,7 @@ fn future_timestamp() {
    );
    let err = cfold.apply(op.clone()).unwrap_err();
    assert_eq!(ChronofoldError::FutureTimestamp(op), err);
    assert_eq!("future timestamp <9, 1>", format!("{}", err));
    assert_eq!("future timestamp <9, 1>", format!("{err}"));
}

#[test]


@@ 36,5 36,5 @@ fn existing_timestamp() {
    assert_eq!(Ok(()), cfold.apply(op.clone()));
    let err = cfold.apply(op.clone()).unwrap_err();
    assert_eq!(ChronofoldError::ExistingTimestamp(op), err);
    assert_eq!("existing timestamp <1, 1>", format!("{}", err));
    assert_eq!("existing timestamp <1, 1>", format!("{err}"));
}

M tests/random.rs => tests/random.rs +1 -1
@@ 30,7 30,7 @@ fn random_edits_by_two_authors() {
            cfold_alice.apply(op).unwrap();
        }
    }
    assert_eq!(format!("{}", cfold_alice), format!("{}", cfold_bob));
    assert_eq!(format!("{cfold_alice}"), format!("{cfold_bob}"));
}

fn random_edits(