Use ffizz_header to generate taskchampion.h

This commit is contained in:
Dustin J. Mitchell
2023-01-17 03:23:43 +00:00
committed by Dustin J. Mitchell
parent 989a330e46
commit 75e10676ce
20 changed files with 1881 additions and 1281 deletions

View File

@@ -3,14 +3,18 @@ use crate::types::*;
use libc;
use taskchampion::Uuid;
// NOTE: this must be a simple constant so that cbindgen can evaluate it
/// Length, in bytes, of the string representation of a UUID (without NUL terminator)
pub const TC_UUID_STRING_BYTES: usize = 36;
#[ffizz_header::item]
#[ffizz(order = 300)]
/// ***** TCUuid *****
///
/// 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.
///
/// cbindgen:field-names=[bytes]
/// ```c
/// typedef struct TCUuid {
/// uint8_t bytes[16];
/// } TCUuid;
/// ```
#[repr(C)]
pub struct TCUuid([u8; 16]);
@@ -28,35 +32,41 @@ impl PassByValue for TCUuid {
}
}
/// Create a new, randomly-generated UUID.
#[no_mangle]
pub unsafe extern "C" fn tc_uuid_new_v4() -> TCUuid {
// SAFETY:
// - value is not allocated
unsafe { TCUuid::return_val(Uuid::new_v4()) }
}
/// Create a new UUID with the nil value.
#[no_mangle]
pub unsafe extern "C" fn tc_uuid_nil() -> TCUuid {
// SAFETY:
// - value is not allocated
unsafe { TCUuid::return_val(Uuid::nil()) }
}
#[ffizz_header::item]
#[ffizz(order = 301)]
/// Length, in bytes, of the string representation of a UUID (without NUL terminator)
///
/// ```c
/// #define TC_UUID_STRING_BYTES 36
/// ```
// TODO: debug_assert or static_assert this somewhere?
pub const TC_UUID_STRING_BYTES: usize = 36;
#[ffizz_header::item]
#[ffizz(order = 310)]
/// TCUuidList represents a list of uuids.
///
/// The content of this struct must be treated as read-only.
///
/// ```c
/// typedef struct TCUuidList {
/// // number of uuids in items
/// size_t len;
/// // reserved
/// size_t _u1;
/// // Array of uuids. This pointer is never NULL for a valid TCUuidList.
/// struct TCUuid *items;
/// } TCUuidList;
/// ```
#[repr(C)]
pub struct TCUuidList {
/// number of uuids in items
len: libc::size_t,
/// total size of items (internal use only)
_capacity: libc::size_t,
capacity: libc::size_t,
/// array of uuids. these remain owned by the TCUuidList instance and will be freed by
/// tc_uuid_list_free. This pointer is never NULL for a valid TCUuidList.
/// Array of uuids. This pointer is never NULL for a valid TCUuidList.
items: *mut TCUuid,
}
@@ -66,7 +76,7 @@ impl CList for TCUuidList {
unsafe fn from_raw_parts(items: *mut Self::Element, len: usize, cap: usize) -> Self {
TCUuidList {
len,
_capacity: cap,
capacity: cap,
items,
}
}
@@ -81,12 +91,46 @@ impl CList for TCUuidList {
}
fn into_raw_parts(self) -> (*mut Self::Element, usize, usize) {
(self.items, self.len, self._capacity)
(self.items, self.len, self.capacity)
}
}
#[ffizz_header::item]
#[ffizz(order = 302)]
/// Create a new, randomly-generated UUID.
///
/// ```c
/// EXTERN_C struct TCUuid tc_uuid_new_v4(void);
/// ```
#[no_mangle]
pub unsafe extern "C" fn tc_uuid_new_v4() -> TCUuid {
// SAFETY:
// - value is not allocated
unsafe { TCUuid::return_val(Uuid::new_v4()) }
}
#[ffizz_header::item]
#[ffizz(order = 302)]
/// Create a new UUID with the nil value.
///
/// ```c
/// EXTERN_C struct TCUuid tc_uuid_nil(void);
/// ```
#[no_mangle]
pub unsafe extern "C" fn tc_uuid_nil() -> TCUuid {
// SAFETY:
// - value is not allocated
unsafe { TCUuid::return_val(Uuid::nil()) }
}
#[ffizz_header::item]
#[ffizz(order = 302)]
/// Write the string representation of a TCUuid into the given buffer, which must be
/// at least TC_UUID_STRING_BYTES long. No NUL terminator is added.
///
/// ```c
/// EXTERN_C void tc_uuid_to_buf(struct TCUuid tcuuid, char *buf);
/// ```
#[no_mangle]
pub unsafe extern "C" fn tc_uuid_to_buf(tcuuid: TCUuid, buf: *mut libc::c_char) {
debug_assert!(!buf.is_null());
@@ -104,8 +148,14 @@ pub unsafe extern "C" fn tc_uuid_to_buf(tcuuid: TCUuid, buf: *mut libc::c_char)
uuid.as_hyphenated().encode_lower(buf);
}
#[ffizz_header::item]
#[ffizz(order = 302)]
/// Return the hyphenated string representation of a TCUuid. The returned string
/// must be freed with tc_string_free.
///
/// ```c
/// EXTERN_C struct TCString tc_uuid_to_str(struct TCUuid tcuuid);
/// ```
#[no_mangle]
pub unsafe extern "C" fn tc_uuid_to_str(tcuuid: TCUuid) -> TCString {
// SAFETY:
@@ -117,8 +167,14 @@ pub unsafe extern "C" fn tc_uuid_to_str(tcuuid: TCUuid) -> TCString {
unsafe { TCString::return_val(s.into()) }
}
#[ffizz_header::item]
#[ffizz(order = 302)]
/// Parse the given string as a UUID. Returns TC_RESULT_ERROR on parse failure or if the given
/// string is not valid.
///
/// ```c
/// EXTERN_C TCResult tc_uuid_from_str(struct TCString s, struct TCUuid *uuid_out);
/// ```
#[no_mangle]
pub unsafe extern "C" fn tc_uuid_from_str(s: TCString, uuid_out: *mut TCUuid) -> TCResult {
debug_assert!(!s.is_null());
@@ -139,10 +195,16 @@ pub unsafe extern "C" fn tc_uuid_from_str(s: TCString, uuid_out: *mut TCUuid) ->
TCResult::Error
}
#[ffizz_header::item]
#[ffizz(order = 312)]
/// Free a TCUuidList instance. The instance, and all TCUuids it contains, must not be used after
/// this call.
///
/// When this call returns, the `items` pointer will be NULL, signalling an invalid TCUuidList.
///
/// ```c
/// EXTERN_C void tc_uuid_list_free(struct TCUuidList *tcuuids);
/// ```
#[no_mangle]
pub unsafe extern "C" fn tc_uuid_list_free(tcuuids: *mut TCUuidList) {
// SAFETY:
@@ -161,7 +223,7 @@ mod test {
let tcuuids = unsafe { TCUuidList::return_val(Vec::new()) };
assert!(!tcuuids.items.is_null());
assert_eq!(tcuuids.len, 0);
assert_eq!(tcuuids._capacity, 0);
assert_eq!(tcuuids.capacity, 0);
}
#[test]
@@ -171,6 +233,6 @@ mod test {
unsafe { tc_uuid_list_free(&mut tcuuids) };
assert!(tcuuids.items.is_null());
assert_eq!(tcuuids.len, 0);
assert_eq!(tcuuids._capacity, 0);
assert_eq!(tcuuids.capacity, 0);
}
}