tc_task_has_tag

This commit is contained in:
Dustin J. Mitchell 2022-02-01 01:02:49 +00:00
parent 03ffb6ce83
commit f2b3e5fd0a
3 changed files with 39 additions and 4 deletions

View file

@ -149,9 +149,13 @@ static void task_task_add_tag(void) {
tc_task_to_mut(task, rep);
TEST_ASSERT_FALSE(tc_task_has_tag(task, tc_string_borrow("next")));
TEST_ASSERT_EQUAL(TC_RESULT_OK, tc_task_add_tag(task, tc_string_borrow("next")));
TEST_ASSERT_NULL(tc_task_error(task));
TEST_ASSERT_TRUE(tc_task_has_tag(task, tc_string_borrow("next")));
// invalid - synthetic tag
TEST_ASSERT_EQUAL(TC_RESULT_ERROR, tc_task_add_tag(task, tc_string_borrow("PENDING")));
TCString *err = tc_task_error(task);
@ -170,7 +174,7 @@ static void task_task_add_tag(void) {
TEST_ASSERT_NOT_NULL(err);
tc_string_free(err);
// TODO: test getting the tag
TEST_ASSERT_TRUE(tc_task_has_tag(task, tc_string_borrow("next")));
tc_task_free(task);
tc_replica_free(rep);

View file

@ -2,6 +2,7 @@ use crate::util::err_to_tcstring;
use crate::{
replica::TCReplica, result::TCResult, status::TCStatus, string::TCString, uuid::TCUuid,
};
use std::convert::TryFrom;
use std::ops::Deref;
use std::str::FromStr;
use taskchampion::{Tag, Task, TaskMut};
@ -168,6 +169,15 @@ where
}
}
impl TryFrom<TCString<'_>> for Tag {
type Error = anyhow::Error;
fn try_from(tcstring: TCString) -> Result<Tag, anyhow::Error> {
let tagstr = tcstring.as_str()?;
Tag::from_str(tagstr)
}
}
/// Convert an immutable task into a mutable task.
///
/// The task must not be NULL. It is modified in-place, and becomes mutable.
@ -246,7 +256,23 @@ pub extern "C" fn tc_task_is_active<'a>(task: *mut TCTask) -> bool {
wrap(task, |task| task.is_active())
}
// TODO: tc_task_has_tag
/// Check if a task has the given tag. If the tag is invalid, this function will simply return
/// false with no error from `tc_task_error`. The given tag must not be NULL.
#[no_mangle]
pub extern "C" fn tc_task_has_tag<'a>(task: *mut TCTask, tag: *mut TCString) -> bool {
// SAFETY:
// - tcstring is not NULL (promised by caller)
// - caller is exclusive owner of tcstring (implicitly promised by caller)
let tcstring = unsafe { TCString::from_arg(tag) };
wrap(task, |task| {
if let Ok(tag) = Tag::try_from(tcstring) {
task.has_tag(&tag)
} else {
false
}
})
}
// TODO: tc_task_get_tags
// TODO: tc_task_get_annotations
// TODO: tc_task_get_uda
@ -331,8 +357,7 @@ pub extern "C" fn tc_task_add_tag<'a>(task: *mut TCTask, tag: *mut TCString) ->
wrap_mut(
task,
|task| {
let tagstr = tcstring.as_str()?;
let tag = Tag::from_str(tagstr)?;
let tag = Tag::try_from(tcstring)?;
task.add_tag(&tag)?;
Ok(TCResult::Ok)
},

View file

@ -269,6 +269,12 @@ struct TCString *tc_task_get_description(struct TCTask *task);
*/
bool tc_task_is_active(struct TCTask *task);
/**
* Check if a task has the given tag. If the tag is invalid, this function will simply return
* false with no error from `tc_task_error`. The given tag must not be NULL.
*/
bool tc_task_has_tag(struct TCTask *task, struct TCString *tag);
/**
* Set a mutable task's status.
*/