add TC prefix to types, too

This commit is contained in:
Dustin J. Mitchell 2022-01-23 19:57:42 +00:00
parent 46e08bc040
commit 821118106a
6 changed files with 69 additions and 77 deletions

View file

@ -10,16 +10,6 @@ fn main() {
.with_language(Language::C)
.with_config(Config {
cpp_compat: true,
export: ExportConfig {
item_types: vec![
ItemType::Structs,
ItemType::Globals,
ItemType::Functions,
ItemType::Constants,
ItemType::OpaqueItems,
],
..Default::default()
},
..Default::default()
})
.generate()

View file

@ -1,30 +1,29 @@
use libc::c_char;
use std::ffi::{CStr, CString, OsStr};
use std::path::PathBuf;
use taskchampion::Replica as TCReplica;
use taskchampion::StorageConfig;
use taskchampion::{Replica, StorageConfig};
// TODO: unix-only
use std::os::unix::ffi::OsStrExt;
/// A replica represents an instance of a user's task data, providing an easy interface
/// for querying and modifying that data.
pub struct Replica {
pub struct TCReplica {
// TODO: make this an option so that it can be take()n when holding a mut ref
inner: TCReplica,
inner: Replica,
error: Option<CString>,
}
/// Create a new Replica.
/// Create a new TCReplica.
///
/// If path is NULL, then an in-memory replica is created. Otherwise, path is the path to the
/// on-disk storage for this replica. The path argument is no longer referenced after return.
///
/// Returns NULL on error; see tc_replica_error.
///
/// Replicas are not threadsafe.
/// TCReplicas are not threadsafe.
#[no_mangle]
pub extern "C" fn tc_replica_new<'a>(path: *const c_char) -> *mut Replica {
pub extern "C" fn tc_replica_new<'a>(path: *const c_char) -> *mut TCReplica {
let storage_res = if path.is_null() {
StorageConfig::InMemory.into_storage()
} else {
@ -40,23 +39,23 @@ pub extern "C" fn tc_replica_new<'a>(path: *const c_char) -> *mut Replica {
Err(_) => return std::ptr::null_mut(),
};
Box::into_raw(Box::new(Replica {
inner: TCReplica::new(storage),
Box::into_raw(Box::new(TCReplica {
inner: Replica::new(storage),
error: None,
}))
}
/// Utility function to safely convert *mut Replica into &mut Replica
fn rep_ref(rep: *mut Replica) -> &'static mut Replica {
/// Utility function to safely convert *mut TCReplica into &mut TCReplica
fn rep_ref(rep: *mut TCReplica) -> &'static mut TCReplica {
debug_assert!(!rep.is_null());
unsafe { &mut *rep }
}
fn wrap<'a, T, F>(rep: *mut Replica, f: F, err_value: T) -> T
fn wrap<'a, T, F>(rep: *mut TCReplica, f: F, err_value: T) -> T
where
F: FnOnce(&mut TCReplica) -> anyhow::Result<T>,
F: FnOnce(&mut Replica) -> anyhow::Result<T>,
{
let rep: &'a mut Replica = rep_ref(rep);
let rep: &'a mut TCReplica = rep_ref(rep);
match f(&mut rep.inner) {
Ok(v) => v,
Err(e) => {
@ -76,7 +75,7 @@ where
/// Returns -1 on error, 0 if there are no local operations to undo, and 1 if operations were
/// undone.
#[no_mangle]
pub extern "C" fn tc_replica_undo<'a>(rep: *mut Replica) -> i32 {
pub extern "C" fn tc_replica_undo<'a>(rep: *mut TCReplica) -> i32 {
wrap(rep, |rep| Ok(if rep.undo()? { 1 } else { 0 }), -1)
}
@ -84,8 +83,8 @@ pub extern "C" fn tc_replica_undo<'a>(rep: *mut Replica) -> i32 {
///
/// The returned string is valid until the next replica operation.
#[no_mangle]
pub extern "C" fn tc_replica_error<'a>(rep: *mut Replica) -> *const c_char {
let rep: &'a Replica = rep_ref(rep);
pub extern "C" fn tc_replica_error<'a>(rep: *mut TCReplica) -> *const c_char {
let rep: &'a TCReplica = rep_ref(rep);
if let Some(ref e) = rep.error {
e.as_ptr()
} else {
@ -93,8 +92,8 @@ pub extern "C" fn tc_replica_error<'a>(rep: *mut Replica) -> *const c_char {
}
}
/// Free a Replica.
/// Free a TCReplica.
#[no_mangle]
pub extern "C" fn tc_replica_free(rep: *mut Replica) {
pub extern "C" fn tc_replica_free(rep: *mut TCReplica) {
drop(unsafe { Box::from_raw(rep) });
}

View file

@ -1,60 +1,63 @@
use libc;
use taskchampion::Uuid as TcUuid;
use taskchampion::Uuid;
/// Uuid is used as a task identifier. Uuids do not contain any pointers and need not be freed.
/// 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]
#[repr(C)]
pub struct Uuid([u8; 16]);
pub struct TCUuid([u8; 16]);
impl From<TcUuid> for Uuid {
fn from(uuid: TcUuid) -> Uuid {
impl From<Uuid> for TCUuid {
fn from(uuid: Uuid) -> TCUuid {
// TODO: can we avoid clone here?
Uuid(uuid.as_bytes().clone())
TCUuid(uuid.as_bytes().clone())
}
}
impl From<Uuid> for TcUuid {
fn from(uuid: Uuid) -> TcUuid {
TcUuid::from_bytes(uuid.0)
impl From<TCUuid> for Uuid {
fn from(uuid: TCUuid) -> Uuid {
Uuid::from_bytes(uuid.0)
}
}
/// Create a new, randomly-generated UUID.
#[no_mangle]
pub extern "C" fn tc_uuid_new_v4() -> Uuid {
TcUuid::new_v4().into()
pub extern "C" fn tc_uuid_new_v4() -> TCUuid {
Uuid::new_v4().into()
}
/// Create a new UUID with the nil value.
#[no_mangle]
pub extern "C" fn tc_uuid_nil() -> Uuid {
TcUuid::nil().into()
pub extern "C" fn tc_uuid_nil() -> TCUuid {
Uuid::nil().into()
}
/// Length, in bytes, of a C string containing a Uuid.
/// Length, in bytes, of a C string containing a TCUuid.
#[no_mangle]
pub static TC_UUID_STRING_BYTES: usize = ::uuid::adapter::Hyphenated::LENGTH;
/// Write the string representation of a Uuid into the given buffer, which must be
/// 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.
#[no_mangle]
pub extern "C" fn tc_uuid_to_str<'a>(uuid: Uuid, out: *mut libc::c_char) {
pub extern "C" fn tc_uuid_to_str<'a>(uuid: TCUuid, out: *mut libc::c_char) {
debug_assert!(!out.is_null());
let buf: &'a mut [u8] = unsafe {
std::slice::from_raw_parts_mut(out as *mut u8, ::uuid::adapter::Hyphenated::LENGTH)
};
let uuid: TcUuid = uuid.into();
let uuid: Uuid = uuid.into();
uuid.to_hyphenated().encode_lower(buf);
}
/// Parse the given value as a UUID. The value must be exactly TC_UUID_STRING_BYTES long. Returns
/// false on failure.
#[no_mangle]
pub extern "C" fn tc_uuid_from_str<'a>(val: *const libc::c_char, out: *mut Uuid) -> bool {
pub extern "C" fn tc_uuid_from_str<'a>(val: *const libc::c_char, out: *mut TCUuid) -> bool {
debug_assert!(!val.is_null());
debug_assert!(!out.is_null());
let slice = unsafe { std::slice::from_raw_parts(val as *const u8, TC_UUID_STRING_BYTES) };
if let Ok(s) = std::str::from_utf8(slice) {
if let Ok(u) = TcUuid::parse_str(s) {
if let Ok(u) = Uuid::parse_str(s) {
unsafe { *out = u.into() };
return true;
}

View file

@ -6,53 +6,53 @@
/// A replica represents an instance of a user's task data, providing an easy interface
/// for querying and modifying that data.
struct Replica;
struct TCReplica;
/// Uuid is used as a task identifier. Uuids do not contain any pointers and need not be freed.
struct Uuid {
uint8_t _0[16];
/// TCUuid is used as a task identifier. Uuids do not contain any pointers and need not be freed.
struct TCUuid {
uint8_t bytes[16];
};
extern "C" {
extern const uintptr_t TC_UUID_STRING_BYTES;
/// Create a new Replica.
/// Create a new TCReplica.
///
/// If path is NULL, then an in-memory replica is created. Otherwise, path is the path to the
/// on-disk storage for this replica. The path argument is no longer referenced after return.
///
/// Returns NULL on error; see tc_replica_error.
///
/// Replicas are not threadsafe.
Replica *tc_replica_new(const char *path);
/// TCReplicas are not threadsafe.
TCReplica *tc_replica_new(const char *path);
/// Undo local operations until the most recent UndoPoint.
///
/// Returns -1 on error, 0 if there are no local operations to undo, and 1 if operations were
/// undone.
int32_t tc_replica_undo(Replica *rep);
int32_t tc_replica_undo(TCReplica *rep);
/// Get the latest error for a replica, or NULL if the last operation succeeded.
///
/// The returned string is valid until the next replica operation.
const char *tc_replica_error(Replica *rep);
const char *tc_replica_error(TCReplica *rep);
/// Free a Replica.
void tc_replica_free(Replica *rep);
/// Free a TCReplica.
void tc_replica_free(TCReplica *rep);
/// Create a new, randomly-generated UUID.
Uuid tc_uuid_new_v4();
TCUuid tc_uuid_new_v4();
/// Create a new UUID with the nil value.
Uuid tc_uuid_nil();
TCUuid tc_uuid_nil();
/// Write the string representation of a Uuid into the given buffer, which must be
/// 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.
void tc_uuid_to_str(Uuid uuid, char *out);
void tc_uuid_to_str(TCUuid uuid, char *out);
/// Parse the given value as a UUID. The value must be exactly TC_UUID_STRING_BYTES long. Returns
/// false on failure.
bool tc_uuid_from_str(const char *val, Uuid *out);
bool tc_uuid_from_str(const char *val, TCUuid *out);
} // extern "C"