From b01285d7807e966967b380c543a8f51ca0649c36 Mon Sep 17 00:00:00 2001 From: "Dustin J. Mitchell" Date: Thu, 10 Feb 2022 01:18:50 +0000 Subject: [PATCH] add some simple replica functions --- .../src/bindings_tests/replica.c | 20 ++++++++++ lib/src/replica.rs | 37 +++++++++++++++++-- lib/taskchampion.h | 15 ++++++++ taskchampion/src/replica.rs | 2 +- 4 files changed, 70 insertions(+), 4 deletions(-) diff --git a/integration-tests/src/bindings_tests/replica.c b/integration-tests/src/bindings_tests/replica.c index 14084ab00..7e598695b 100644 --- a/integration-tests/src/bindings_tests/replica.c +++ b/integration-tests/src/bindings_tests/replica.c @@ -31,6 +31,24 @@ static void test_replica_undo_empty(void) { tc_replica_free(rep); } +// adding an undo point succeeds +static void test_replica_add_undo_point(void) { + TCReplica *rep = tc_replica_new_in_memory(); + TEST_ASSERT_NULL(tc_replica_error(rep)); + TEST_ASSERT_EQUAL(TC_RESULT_OK, tc_replica_add_undo_point(rep, true)); + TEST_ASSERT_NULL(tc_replica_error(rep)); + tc_replica_free(rep); +} + +// rebuilding working set succeeds +static void test_replica_rebuild_working_set(void) { + TCReplica *rep = tc_replica_new_in_memory(); + TEST_ASSERT_NULL(tc_replica_error(rep)); + TEST_ASSERT_EQUAL(TC_RESULT_OK, tc_replica_rebuild_working_set(rep, true)); + TEST_ASSERT_NULL(tc_replica_error(rep)); + tc_replica_free(rep); +} + // When tc_replica_undo is passed NULL for undone_out, it still succeeds static void test_replica_undo_empty_null_undone_out(void) { TCReplica *rep = tc_replica_new_in_memory(); @@ -190,6 +208,8 @@ int replica_tests(void) { RUN_TEST(test_replica_creation); RUN_TEST(test_replica_creation_disk); RUN_TEST(test_replica_undo_empty); + RUN_TEST(test_replica_add_undo_point); + RUN_TEST(test_replica_rebuild_working_set); RUN_TEST(test_replica_undo_empty_null_undone_out); RUN_TEST(test_replica_task_creation); RUN_TEST(test_replica_all_tasks); diff --git a/lib/src/replica.rs b/lib/src/replica.rs index 619dc2c46..b946efb34 100644 --- a/lib/src/replica.rs +++ b/lib/src/replica.rs @@ -271,6 +271,40 @@ pub unsafe extern "C" fn tc_replica_undo<'a>( ) } +/// Add an UndoPoint, if one has not already been added by this Replica. This occurs automatically +/// when a change is made. The `force` flag allows forcing a new UndoPoint even if one has already +/// been created by this Replica, and may be useful when a Replica instance is held for a long time +/// and used to apply more than one user-visible change. +#[no_mangle] +pub unsafe extern "C" fn tc_replica_add_undo_point(rep: *mut TCReplica, force: bool) -> TCResult { + wrap( + rep, + |rep| { + rep.add_undo_point(force)?; + Ok(TCResult::Ok) + }, + TCResult::Error, + ) +} + +/// Rebuild this replica's working set, based on whether tasks are pending or not. If `renumber` +/// is true, then existing tasks may be moved to new working-set indices; in any case, on +/// completion all pending tasks are in the working set and all non- pending tasks are not. +#[no_mangle] +pub unsafe extern "C" fn tc_replica_rebuild_working_set( + rep: *mut TCReplica, + renumber: bool, +) -> TCResult { + wrap( + rep, + |rep| { + rep.rebuild_working_set(renumber)?; + Ok(TCResult::Ok) + }, + TCResult::Error, + ) +} + /// Get the latest error for a replica, or NULL if the last operation succeeded. Subsequent calls /// to this function will return NULL. The rep pointer must not be NULL. The caller must free the /// returned string. @@ -297,6 +331,3 @@ pub unsafe extern "C" fn tc_replica_free(rep: *mut TCReplica) { } drop(replica); } - -// TODO: tc_replica_rebuild_working_set -// TODO: tc_replica_add_undo_point diff --git a/lib/taskchampion.h b/lib/taskchampion.h index ed8321fd7..0e5753f67 100644 --- a/lib/taskchampion.h +++ b/lib/taskchampion.h @@ -253,6 +253,21 @@ struct TCTask *tc_replica_import_task_with_uuid(struct TCReplica *rep, struct TC */ TCResult tc_replica_undo(struct TCReplica *rep, int32_t *undone_out); +/** + * Add an UndoPoint, if one has not already been added by this Replica. This occurs automatically + * when a change is made. The `force` flag allows forcing a new UndoPoint even if one has already + * been created by this Replica, and may be useful when a Replica instance is held for a long time + * and used to apply more than one user-visible change. + */ +TCResult tc_replica_add_undo_point(struct TCReplica *rep, bool force); + +/** + * Rebuild this replica's working set, based on whether tasks are pending or not. If `renumber` + * is true, then existing tasks may be moved to new working-set indices; in any case, on + * completion all pending tasks are in the working set and all non- pending tasks are not. + */ +TCResult tc_replica_rebuild_working_set(struct TCReplica *rep, bool renumber); + /** * Get the latest error for a replica, or NULL if the last operation succeeded. Subsequent calls * to this function will return NULL. The rep pointer must not be NULL. The caller must free the diff --git a/taskchampion/src/replica.rs b/taskchampion/src/replica.rs index 2dd1e4887..79938423f 100644 --- a/taskchampion/src/replica.rs +++ b/taskchampion/src/replica.rs @@ -177,7 +177,7 @@ impl Replica { /// Add an UndoPoint, if one has not already been added by this Replica. This occurs /// automatically when a change is made. The `force` flag allows forcing a new UndoPoint - /// even if one has laready been created by this Replica, and may be useful when a Replica + /// even if one has already been created by this Replica, and may be useful when a Replica /// instance is held for a long time and used to apply more than one user-visible change. pub fn add_undo_point(&mut self, force: bool) -> anyhow::Result<()> { if force || !self.added_undo_point {