TCTags -> TCStrings to be more general

This commit is contained in:
Dustin J. Mitchell
2022-02-06 16:40:17 +00:00
parent 3d248b55fd
commit 831eb0bb15
5 changed files with 42 additions and 42 deletions

View File

@@ -312,7 +312,7 @@ static void test_task_get_tags(void) {
TEST_ASSERT_EQUAL(TC_RESULT_OK, tc_task_add_tag(task, tc_string_borrow("next"))); TEST_ASSERT_EQUAL(TC_RESULT_OK, tc_task_add_tag(task, tc_string_borrow("next")));
TCTags tags = tc_task_get_tags(task); TCStrings tags = tc_task_get_tags(task);
int found_pending = false, found_next = false; int found_pending = false, found_next = false;
for (size_t i = 0; i < tags.len; i++) { for (size_t i = 0; i < tags.len; i++) {
@@ -326,7 +326,7 @@ static void test_task_get_tags(void) {
TEST_ASSERT_TRUE(found_pending); TEST_ASSERT_TRUE(found_pending);
TEST_ASSERT_TRUE(found_next); TEST_ASSERT_TRUE(found_next);
tc_tags_free(&tags); tc_strings_free(&tags);
TEST_ASSERT_NULL(tags.items); TEST_ASSERT_NULL(tags.items);
tc_task_free(task); tc_task_free(task);

View File

@@ -3,11 +3,11 @@
mod traits; mod traits;
mod util; mod util;
pub mod arrays;
pub mod atomic; pub mod atomic;
pub mod replica; pub mod replica;
pub mod result; pub mod result;
pub mod status; pub mod status;
pub mod string; pub mod string;
pub mod strings;
pub mod task; pub mod task;
pub mod uuid; pub mod uuid;

View File

@@ -3,41 +3,41 @@ use crate::traits::*;
use crate::util::{drop_pointer_array, vec_into_raw_parts}; use crate::util::{drop_pointer_array, vec_into_raw_parts};
use std::ptr::NonNull; use std::ptr::NonNull;
/// TCTags represents a list of tags associated with a task. /// TCStrings represents a list of tags associated with a task.
/// ///
/// The content of this struct must be treated as read-only. /// The content of this struct must be treated as read-only.
/// ///
/// The lifetime of a TCTags instance is independent of the task, and it /// The lifetime of a TCStrings instance is independent of the task, and it
/// will remain valid even if the task is freed. /// will remain valid even if the task is freed.
#[repr(C)] #[repr(C)]
pub struct TCTags { pub struct TCStrings {
/// number of tags in items /// number of tags in items
len: libc::size_t, len: libc::size_t,
/// total size of items (internal use only) /// total size of items (internal use only)
_capacity: libc::size_t, _capacity: libc::size_t,
/// strings representing each tag. these remain owned by the TCTags instance and will be freed /// strings representing each tag. these remain owned by the TCStrings instance and will be freed
/// by tc_tags_free. /// by tc_strings_free.
items: *const NonNull<TCString<'static>>, items: *const NonNull<TCString<'static>>,
} }
impl PassByValue for Vec<NonNull<TCString<'static>>> { impl PassByValue for Vec<NonNull<TCString<'static>>> {
type CType = TCTags; type CType = TCStrings;
unsafe fn from_ctype(arg: TCTags) -> Self { unsafe fn from_ctype(arg: TCStrings) -> Self {
// SAFETY: // SAFETY:
// - C treats TCTags as read-only, so items, len, and _capacity all came // - C treats TCStrings as read-only, so items, len, and _capacity all came
// from a Vec originally. // from a Vec originally.
unsafe { Vec::from_raw_parts(arg.items as *mut _, arg.len, arg._capacity) } unsafe { Vec::from_raw_parts(arg.items as *mut _, arg.len, arg._capacity) }
} }
fn as_ctype(self) -> TCTags { fn as_ctype(self) -> TCStrings {
// emulate Vec::into_raw_parts(): // emulate Vec::into_raw_parts():
// - disable dropping the Vec with ManuallyDrop // - disable dropping the Vec with ManuallyDrop
// - extract ptr, len, and capacity using those methods // - extract ptr, len, and capacity using those methods
let (items, len, _capacity) = vec_into_raw_parts(self); let (items, len, _capacity) = vec_into_raw_parts(self);
TCTags { TCStrings {
len, len,
_capacity, _capacity,
items, items,
@@ -45,7 +45,7 @@ impl PassByValue for Vec<NonNull<TCString<'static>>> {
} }
} }
impl Default for TCTags { impl Default for TCStrings {
fn default() -> Self { fn default() -> Self {
Self { Self {
len: 0, len: 0,
@@ -55,13 +55,13 @@ impl Default for TCTags {
} }
} }
/// Free a TCTags instance. The instance, and all TCStrings it contains, must not be used after /// Free a TCStrings instance. The instance, and all TCStrings it contains, must not be used after
/// this call. /// this call.
#[no_mangle] #[no_mangle]
pub extern "C" fn tc_tags_free<'a>(tctags: *mut TCTags) { pub extern "C" fn tc_strings_free<'a>(tctags: *mut TCStrings) {
debug_assert!(!tctags.is_null()); debug_assert!(!tctags.is_null());
// SAFETY: // SAFETY:
// - *tctags is a valid TCTags (caller promises to treat it as read-only) // - *tctags is a valid TCStrings (caller promises to treat it as read-only)
let tags = unsafe { Vec::take_from_arg(tctags, TCTags::default()) }; let tags = unsafe { Vec::take_from_arg(tctags, TCStrings::default()) };
drop_pointer_array(tags); drop_pointer_array(tags);
} }

View File

@@ -1,7 +1,7 @@
use crate::traits::*; use crate::traits::*;
use crate::util::err_to_tcstring; use crate::util::err_to_tcstring;
use crate::{ use crate::{
arrays::TCTags, replica::TCReplica, result::TCResult, status::TCStatus, string::TCString, replica::TCReplica, result::TCResult, status::TCStatus, string::TCString, strings::TCStrings,
uuid::TCUuid, uuid::TCUuid,
}; };
use chrono::{DateTime, TimeZone, Utc}; use chrono::{DateTime, TimeZone, Utc};
@@ -319,7 +319,7 @@ pub extern "C" fn tc_task_has_tag<'a>(task: *mut TCTask, tag: *mut TCString) ->
/// Get the tags for the task. The task must not be NULL. /// Get the tags for the task. The task must not be NULL.
#[no_mangle] #[no_mangle]
pub extern "C" fn tc_task_get_tags<'a>(task: *mut TCTask) -> TCTags { pub extern "C" fn tc_task_get_tags<'a>(task: *mut TCTask) -> TCStrings {
wrap(task, |task| { wrap(task, |task| {
let tcstrings: Vec<NonNull<TCString<'static>>> = task let tcstrings: Vec<NonNull<TCString<'static>>> = task
.get_tags() .get_tags()

View File

@@ -118,14 +118,23 @@ typedef struct TCString TCString;
typedef struct TCTask TCTask; typedef struct TCTask TCTask;
/** /**
* TCTags represents a list of tags associated with a task. * TCUuid is used as a task identifier. Uuids do not contain any pointers and need not be freed.
* Uuids are typically treated as opaque, but the bytes are available in big-endian format.
*
*/
typedef struct TCUuid {
uint8_t bytes[16];
} TCUuid;
/**
* TCStrings represents a list of tags associated with a task.
* *
* The content of this struct must be treated as read-only. * The content of this struct must be treated as read-only.
* *
* The lifetime of a TCTags instance is independent of the task, and it * The lifetime of a TCStrings instance is independent of the task, and it
* will remain valid even if the task is freed. * will remain valid even if the task is freed.
*/ */
typedef struct TCTags { typedef struct TCStrings {
/** /**
* number of tags in items * number of tags in items
*/ */
@@ -135,31 +144,16 @@ typedef struct TCTags {
*/ */
size_t _capacity; size_t _capacity;
/** /**
* strings representing each tag. these remain owned by the TCTags instance and will be freed * strings representing each tag. these remain owned by the TCStrings instance and will be freed
* by tc_tags_free. * by tc_strings_free.
*/ */
struct TCString *const *items; struct TCString *const *items;
} TCTags; } TCStrings;
/**
* TCUuid is used as a task identifier. Uuids do not contain any pointers and need not be freed.
* Uuids are typically treated as opaque, but the bytes are available in big-endian format.
*
*/
typedef struct TCUuid {
uint8_t bytes[16];
} TCUuid;
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif // __cplusplus #endif // __cplusplus
/**
* Free a TCTags instance. The instance, and all TCStrings it contains, must not be used after
* this call.
*/
void tc_tags_free(struct TCTags *tctags);
/** /**
* Create a new TCReplica with an in-memory database. The contents of the database will be * Create a new TCReplica with an in-memory database. The contents of the database will be
* lost when it is freed. * lost when it is freed.
@@ -278,6 +272,12 @@ const char *tc_string_content_with_len(struct TCString *tcstring, size_t *len_ou
*/ */
void tc_string_free(struct TCString *tcstring); void tc_string_free(struct TCString *tcstring);
/**
* Free a TCStrings instance. The instance, and all TCStrings it contains, must not be used after
* this call.
*/
void tc_strings_free(struct TCStrings *tctags);
/** /**
* Convert an immutable task into a mutable task. * Convert an immutable task into a mutable task.
* *
@@ -357,7 +357,7 @@ bool tc_task_has_tag(struct TCTask *task, struct TCString *tag);
/** /**
* Get the tags for the task. The task must not be NULL. * Get the tags for the task. The task must not be NULL.
*/ */
struct TCTags tc_task_get_tags(struct TCTask *task); struct TCStrings tc_task_get_tags(struct TCTask *task);
/** /**
* Set a mutable task's status. * Set a mutable task's status.