mirror of
https://github.com/GothenburgBitFactory/taskwarrior.git
synced 2025-08-23 14:36:44 +02:00
ffi for tc_task_get/set_value
This commit is contained in:
parent
7cecac3328
commit
4fdb46fd47
3 changed files with 117 additions and 4 deletions
|
@ -111,6 +111,54 @@ static void test_task_get_set_description(void) {
|
||||||
tc_replica_free(rep);
|
tc_replica_free(rep);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// updating arbitrary attributes on a task works
|
||||||
|
static void test_task_get_set_attribute(void) {
|
||||||
|
TCReplica *rep = tc_replica_new_in_memory();
|
||||||
|
TEST_ASSERT_NULL(tc_replica_error(rep).ptr);
|
||||||
|
|
||||||
|
TCTask *task = tc_replica_new_task(
|
||||||
|
rep,
|
||||||
|
TC_STATUS_PENDING,
|
||||||
|
tc_string_borrow("my task"));
|
||||||
|
TEST_ASSERT_NOT_NULL(task);
|
||||||
|
|
||||||
|
TCString foo;
|
||||||
|
|
||||||
|
foo = tc_task_get_value(task, tc_string_borrow("foo"));
|
||||||
|
TEST_ASSERT_NULL(foo.ptr);
|
||||||
|
|
||||||
|
tc_task_to_mut(task, rep);
|
||||||
|
TEST_ASSERT_EQUAL(TC_RESULT_OK, tc_task_set_value(task,
|
||||||
|
tc_string_borrow("foo"),
|
||||||
|
tc_string_borrow("updated")));
|
||||||
|
|
||||||
|
foo = tc_task_get_value(task, tc_string_borrow("foo"));
|
||||||
|
TEST_ASSERT_NOT_NULL(foo.ptr);
|
||||||
|
TEST_ASSERT_EQUAL_STRING("updated", tc_string_content(&foo));
|
||||||
|
tc_string_free(&foo);
|
||||||
|
|
||||||
|
tc_task_to_immut(task);
|
||||||
|
|
||||||
|
foo = tc_task_get_value(task, tc_string_borrow("foo"));
|
||||||
|
TEST_ASSERT_NOT_NULL(foo.ptr);
|
||||||
|
TEST_ASSERT_EQUAL_STRING("updated", tc_string_content(&foo));
|
||||||
|
tc_string_free(&foo);
|
||||||
|
|
||||||
|
TCString null = { .ptr = NULL };
|
||||||
|
|
||||||
|
tc_task_to_mut(task, rep);
|
||||||
|
TEST_ASSERT_EQUAL(TC_RESULT_OK, tc_task_set_value(task,
|
||||||
|
tc_string_borrow("foo"),
|
||||||
|
null));
|
||||||
|
|
||||||
|
foo = tc_task_get_value(task, tc_string_borrow("foo"));
|
||||||
|
TEST_ASSERT_NULL(foo.ptr);
|
||||||
|
|
||||||
|
tc_task_free(task);
|
||||||
|
|
||||||
|
tc_replica_free(rep);
|
||||||
|
}
|
||||||
|
|
||||||
// updating entry on a task works
|
// updating entry on a task works
|
||||||
static void test_task_get_set_entry(void) {
|
static void test_task_get_set_entry(void) {
|
||||||
TCReplica *rep = tc_replica_new_in_memory();
|
TCReplica *rep = tc_replica_new_in_memory();
|
||||||
|
@ -652,6 +700,7 @@ int task_tests(void) {
|
||||||
RUN_TEST(test_task_free_mutable_task);
|
RUN_TEST(test_task_free_mutable_task);
|
||||||
RUN_TEST(test_task_get_set_status);
|
RUN_TEST(test_task_get_set_status);
|
||||||
RUN_TEST(test_task_get_set_description);
|
RUN_TEST(test_task_get_set_description);
|
||||||
|
RUN_TEST(test_task_get_set_attribute);
|
||||||
RUN_TEST(test_task_get_set_entry);
|
RUN_TEST(test_task_get_set_entry);
|
||||||
RUN_TEST(test_task_get_set_modified);
|
RUN_TEST(test_task_get_set_modified);
|
||||||
RUN_TEST(test_task_get_set_wait_and_is_waiting);
|
RUN_TEST(test_task_get_set_wait_and_is_waiting);
|
||||||
|
|
|
@ -294,8 +294,7 @@ pub unsafe extern "C" fn tc_task_get_taskmap(task: *mut TCTask) -> TCKVList {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get a task's description, or NULL if the task cannot be represented as a C string (e.g., if it
|
/// Get a task's description.
|
||||||
/// contains embedded NUL characters).
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_task_get_description(task: *mut TCTask) -> TCString {
|
pub unsafe extern "C" fn tc_task_get_description(task: *mut TCTask) -> TCString {
|
||||||
wrap(task, |task| {
|
wrap(task, |task| {
|
||||||
|
@ -306,6 +305,27 @@ pub unsafe extern "C" fn tc_task_get_description(task: *mut TCTask) -> TCString
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get a task property's value, or NULL if the task has no such property, (including if the
|
||||||
|
/// property name is not valid utf-8).
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn tc_task_get_value(task: *mut TCTask, property: TCString) -> TCString {
|
||||||
|
// SAFETY:
|
||||||
|
// - property is valid (promised by caller)
|
||||||
|
// - caller will not use property after this call (convention)
|
||||||
|
let mut property = unsafe { TCString::val_from_arg(property) };
|
||||||
|
wrap(task, |task| {
|
||||||
|
if let Ok(property) = property.as_str() {
|
||||||
|
let value = task.get_value(property);
|
||||||
|
if let Some(value) = value {
|
||||||
|
// SAFETY:
|
||||||
|
// - caller promises to free this string
|
||||||
|
return unsafe { TCString::return_val(value.into()) };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TCString::default() // null value
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/// Get the entry timestamp for a task (when it was created), or 0 if not set.
|
/// Get the entry timestamp for a task (when it was created), or 0 if not set.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_task_get_entry(task: *mut TCTask) -> libc::time_t {
|
pub unsafe extern "C" fn tc_task_get_entry(task: *mut TCTask) -> libc::time_t {
|
||||||
|
@ -507,6 +527,40 @@ pub unsafe extern "C" fn tc_task_set_status(task: *mut TCTask, status: TCStatus)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set a mutable task's property value by name. If value.ptr is NULL, the property is removed.
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn tc_task_set_value(
|
||||||
|
task: *mut TCTask,
|
||||||
|
property: TCString,
|
||||||
|
value: TCString,
|
||||||
|
) -> TCResult {
|
||||||
|
// SAFETY:
|
||||||
|
// - property is valid (promised by caller)
|
||||||
|
// - caller will not use property after this call (convention)
|
||||||
|
let mut property = unsafe { TCString::val_from_arg(property) };
|
||||||
|
let value = if value.is_null() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
// SAFETY:
|
||||||
|
// - value is valid (promised by caller, after NULL check)
|
||||||
|
// - caller will not use value after this call (convention)
|
||||||
|
Some(unsafe { TCString::val_from_arg(value) })
|
||||||
|
};
|
||||||
|
wrap_mut(
|
||||||
|
task,
|
||||||
|
|task| {
|
||||||
|
let value_str = if let Some(mut v) = value {
|
||||||
|
Some(v.as_str()?.to_string())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
task.set_value(property.as_str()?.to_string(), value_str)?;
|
||||||
|
Ok(TCResult::Ok)
|
||||||
|
},
|
||||||
|
TCResult::Error,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/// Set a mutable task's description.
|
/// Set a mutable task's description.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tc_task_set_description(
|
pub unsafe extern "C" fn tc_task_set_description(
|
||||||
|
|
|
@ -751,11 +751,16 @@ enum TCStatus tc_task_get_status(struct TCTask *task);
|
||||||
struct TCKVList tc_task_get_taskmap(struct TCTask *task);
|
struct TCKVList tc_task_get_taskmap(struct TCTask *task);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a task's description, or NULL if the task cannot be represented as a C string (e.g., if it
|
* Get a task's description.
|
||||||
* contains embedded NUL characters).
|
|
||||||
*/
|
*/
|
||||||
struct TCString tc_task_get_description(struct TCTask *task);
|
struct TCString tc_task_get_description(struct TCTask *task);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a task property's value, or NULL if the task has no such property, (including if the
|
||||||
|
* property name is not valid utf-8).
|
||||||
|
*/
|
||||||
|
struct TCString tc_task_get_value(struct TCTask *task, struct TCString property);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the entry timestamp for a task (when it was created), or 0 if not set.
|
* Get the entry timestamp for a task (when it was created), or 0 if not set.
|
||||||
*/
|
*/
|
||||||
|
@ -837,6 +842,11 @@ struct TCUdaList tc_task_get_legacy_udas(struct TCTask *task);
|
||||||
*/
|
*/
|
||||||
TCResult tc_task_set_status(struct TCTask *task, enum TCStatus status);
|
TCResult tc_task_set_status(struct TCTask *task, enum TCStatus status);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a mutable task's property value by name. If value.ptr is NULL, the property is removed.
|
||||||
|
*/
|
||||||
|
TCResult tc_task_set_value(struct TCTask *task, struct TCString property, struct TCString value);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set a mutable task's description.
|
* Set a mutable task's description.
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue