From 8b160c7ee82fe3e376fae15ff0c64db77fcb7372 Mon Sep 17 00:00:00 2001 From: "Dustin J. Mitchell" Date: Tue, 1 Feb 2022 03:01:09 +0000 Subject: [PATCH] more task functions --- integration-tests/src/bindings_tests/task.c | 52 +++++++++++++++++ lib/src/task.rs | 63 ++++++++++++++++----- lib/taskchampion.h | 23 +++++++- 3 files changed, 123 insertions(+), 15 deletions(-) diff --git a/integration-tests/src/bindings_tests/task.c b/integration-tests/src/bindings_tests/task.c index 8b264e41f..74dcfcda7 100644 --- a/integration-tests/src/bindings_tests/task.c +++ b/integration-tests/src/bindings_tests/task.c @@ -172,6 +172,33 @@ static void test_task_get_set_wait_and_is_waiting(void) { tc_replica_free(rep); } +// updating modified on a task works +static void test_task_get_set_modified(void) { + TCReplica *rep = tc_replica_new_in_memory(); + TEST_ASSERT_NULL(tc_replica_error(rep)); + + TCTask *task = tc_replica_new_task( + rep, + TC_STATUS_PENDING, + tc_string_borrow("my task")); + TEST_ASSERT_NOT_NULL(task); + + // creation of a task sets modified to current time + TEST_ASSERT_NOT_EQUAL(0, tc_task_get_modified(task)); + + tc_task_to_mut(task, rep); + + TEST_ASSERT_EQUAL(TC_RESULT_OK, tc_task_set_modified(task, 1643679997)); + TEST_ASSERT_EQUAL(1643679997, tc_task_get_modified(task)); + + // zero is not allowed + TEST_ASSERT_EQUAL(TC_RESULT_ERROR, tc_task_set_modified(task, 0)); + + tc_task_free(task); + + tc_replica_free(rep); +} + // starting and stopping a task works, as seen by tc_task_is_active static void test_task_start_stop_is_active(void) { TCReplica *rep = tc_replica_new_in_memory(); @@ -197,6 +224,29 @@ static void test_task_start_stop_is_active(void) { tc_replica_free(rep); } +// tc_task_done and delete work and set the status +static void test_task_done_and_delete(void) { + TCReplica *rep = tc_replica_new_in_memory(); + TEST_ASSERT_NULL(tc_replica_error(rep)); + + TCTask *task = tc_replica_new_task( + rep, + TC_STATUS_PENDING, + tc_string_borrow("my task")); + TEST_ASSERT_NOT_NULL(task); + + tc_task_to_mut(task, rep); + + TEST_ASSERT_EQUAL(TC_STATUS_PENDING, tc_task_get_status(task)); + TEST_ASSERT_EQUAL(TC_RESULT_OK, tc_task_done(task)); + TEST_ASSERT_EQUAL(TC_STATUS_COMPLETED, tc_task_get_status(task)); + TEST_ASSERT_EQUAL(TC_RESULT_OK, tc_task_delete(task)); + TEST_ASSERT_EQUAL(TC_STATUS_DELETED, tc_task_get_status(task)); + + tc_task_free(task); + tc_replica_free(rep); +} + // adding tags to a task works, and invalid tags are rejected static void task_task_add_tag(void) { TCReplica *rep = tc_replica_new_in_memory(); @@ -249,8 +299,10 @@ int task_tests(void) { RUN_TEST(test_task_get_set_status); RUN_TEST(test_task_get_set_description); RUN_TEST(test_task_get_set_entry); + RUN_TEST(test_task_get_set_modified); RUN_TEST(test_task_get_set_wait_and_is_waiting); RUN_TEST(test_task_start_stop_is_active); + RUN_TEST(test_task_done_and_delete); RUN_TEST(task_task_add_tag); return UNITY_END(); } diff --git a/lib/src/task.rs b/lib/src/task.rs index 03318d1f9..4caa9a0c7 100644 --- a/lib/src/task.rs +++ b/lib/src/task.rs @@ -275,7 +275,11 @@ pub extern "C" fn tc_task_get_wait<'a>(task: *mut TCTask) -> libc::time_t { wrap(task, |task| to_time_t(task.get_wait())) } -// TODO: tc_task_get_modified +/// Get the modified timestamp for a task, or 0 if not set. +#[no_mangle] +pub extern "C" fn tc_task_get_modified<'a>(task: *mut TCTask) -> libc::time_t { + wrap(task, |task| to_time_t(task.get_modified())) +} /// Check if a task is waiting. #[no_mangle] @@ -312,7 +316,6 @@ pub extern "C" fn tc_task_has_tag<'a>(task: *mut TCTask, tag: *mut TCString) -> // TODO: tc_task_get_udas // TODO: tc_task_get_legacy_uda // TODO: tc_task_get_legacy_udas -// TODO: tc_task_get_modified /// Set a mutable task's status. #[no_mangle] @@ -350,7 +353,7 @@ pub extern "C" fn tc_task_set_description<'a>( /// Set a mutable task's entry (creation time). Pass entry=0 to unset /// the entry field. #[no_mangle] -pub extern "C" fn tc_task_set_entry<'a>(task: *mut TCTask, entry: libc::time_t) -> TCResult { +pub extern "C" fn tc_task_set_entry(task: *mut TCTask, entry: libc::time_t) -> TCResult { wrap_mut( task, |task| { @@ -361,10 +364,9 @@ pub extern "C" fn tc_task_set_entry<'a>(task: *mut TCTask, entry: libc::time_t) ) } -/// Set a mutable task's wait (creation time). Pass wait=0 to unset the -/// wait field. +/// Set a mutable task's wait timestamp. Pass wait=0 to unset the wait field. #[no_mangle] -pub extern "C" fn tc_task_set_wait<'a>(task: *mut TCTask, wait: libc::time_t) -> TCResult { +pub extern "C" fn tc_task_set_wait(task: *mut TCTask, wait: libc::time_t) -> TCResult { wrap_mut( task, |task| { @@ -375,12 +377,24 @@ pub extern "C" fn tc_task_set_wait<'a>(task: *mut TCTask, wait: libc::time_t) -> ) } -// TODO: tc_task_set_wait -// TODO: tc_task_set_modified +/// Set a mutable task's modified timestamp. The value cannot be zero. +#[no_mangle] +pub extern "C" fn tc_task_set_modified(task: *mut TCTask, modified: libc::time_t) -> TCResult { + wrap_mut( + task, + |task| { + task.set_modified( + to_datetime(modified).ok_or_else(|| anyhow::anyhow!("modified cannot be zero"))?, + )?; + Ok(TCResult::Ok) + }, + TCResult::Error, + ) +} /// Start a task. #[no_mangle] -pub extern "C" fn tc_task_start<'a>(task: *mut TCTask) -> TCResult { +pub extern "C" fn tc_task_start(task: *mut TCTask) -> TCResult { wrap_mut( task, |task| { @@ -393,7 +407,7 @@ pub extern "C" fn tc_task_start<'a>(task: *mut TCTask) -> TCResult { /// Stop a task. #[no_mangle] -pub extern "C" fn tc_task_stop<'a>(task: *mut TCTask) -> TCResult { +pub extern "C" fn tc_task_stop(task: *mut TCTask) -> TCResult { wrap_mut( task, |task| { @@ -404,12 +418,35 @@ pub extern "C" fn tc_task_stop<'a>(task: *mut TCTask) -> TCResult { ) } -// TODO: tc_task_done -// TODO: tc_task_delete +/// Mark a task as done. +#[no_mangle] +pub extern "C" fn tc_task_done(task: *mut TCTask) -> TCResult { + wrap_mut( + task, + |task| { + task.done()?; + Ok(TCResult::Ok) + }, + TCResult::Error, + ) +} + +/// Mark a task as deleted. +#[no_mangle] +pub extern "C" fn tc_task_delete(task: *mut TCTask) -> TCResult { + wrap_mut( + task, + |task| { + task.delete()?; + Ok(TCResult::Ok) + }, + TCResult::Error, + ) +} /// Add a tag to a mutable task. #[no_mangle] -pub extern "C" fn tc_task_add_tag<'a>(task: *mut TCTask, tag: *mut TCString) -> TCResult { +pub extern "C" fn tc_task_add_tag(task: *mut TCTask, tag: *mut TCString) -> TCResult { // SAFETY: // - tcstring is not NULL (promised by caller) // - caller is exclusive owner of tcstring (implicitly promised by caller) diff --git a/lib/taskchampion.h b/lib/taskchampion.h index f102d03aa..4a3a33b96 100644 --- a/lib/taskchampion.h +++ b/lib/taskchampion.h @@ -276,6 +276,11 @@ time_t tc_task_get_entry(struct TCTask *task); */ time_t tc_task_get_wait(struct TCTask *task); +/** + * Get the modified timestamp for a task, or 0 if not set. + */ +time_t tc_task_get_modified(struct TCTask *task); + /** * Check if a task is waiting. */ @@ -309,11 +314,15 @@ TCResult tc_task_set_description(struct TCTask *task, struct TCString *descripti TCResult tc_task_set_entry(struct TCTask *task, time_t entry); /** - * Set a mutable task's wait (creation time). Pass wait=0 to unset the - * wait field. + * Set a mutable task's wait timestamp. Pass wait=0 to unset the wait field. */ TCResult tc_task_set_wait(struct TCTask *task, time_t wait); +/** + * Set a mutable task's modified timestamp. The value cannot be zero. + */ +TCResult tc_task_set_modified(struct TCTask *task, time_t modified); + /** * Start a task. */ @@ -324,6 +333,16 @@ TCResult tc_task_start(struct TCTask *task); */ TCResult tc_task_stop(struct TCTask *task); +/** + * Mark a task as done. + */ +TCResult tc_task_done(struct TCTask *task); + +/** + * Mark a task as deleted. + */ +TCResult tc_task_delete(struct TCTask *task); + /** * Add a tag to a mutable task. */