diff --git a/binding-tests/replica.cpp b/binding-tests/replica.cpp index 6400b8002..4e1053d8c 100644 --- a/binding-tests/replica.cpp +++ b/binding-tests/replica.cpp @@ -2,14 +2,14 @@ #include "doctest.h" #include "taskchampion.h" -TEST_CASE("creating an in-memory Replica does not crash") { - Replica *rep = tc_replica_new(NULL); +TEST_CASE("creating an in-memory TCReplica does not crash") { + TCReplica *rep = tc_replica_new(NULL); CHECK(tc_replica_error(rep) == NULL); tc_replica_free(rep); } -TEST_CASE("undo on an empty in-memory Replica does nothing") { - Replica *rep = tc_replica_new(NULL); +TEST_CASE("undo on an empty in-memory TCReplica does nothing") { + TCReplica *rep = tc_replica_new(NULL); CHECK(tc_replica_error(rep) == NULL); int rv = tc_replica_undo(rep); CHECK(rv == 0); diff --git a/binding-tests/uuid.cpp b/binding-tests/uuid.cpp index 949d081f0..aba07d867 100644 --- a/binding-tests/uuid.cpp +++ b/binding-tests/uuid.cpp @@ -3,12 +3,12 @@ #include "taskchampion.h" TEST_CASE("creating UUIDs does not crash") { - Uuid u1 = tc_uuid_new_v4(); - Uuid u2 = tc_uuid_nil(); + TCUuid u1 = tc_uuid_new_v4(); + TCUuid u2 = tc_uuid_nil(); } TEST_CASE("converting UUIDs to string works") { - Uuid u2 = tc_uuid_nil(); + TCUuid u2 = tc_uuid_nil(); REQUIRE(TC_UUID_STRING_BYTES == 36); char u2str[TC_UUID_STRING_BYTES]; @@ -17,22 +17,22 @@ TEST_CASE("converting UUIDs to string works") { } TEST_CASE("converting UUIDs from string works") { - Uuid u; + TCUuid u; char ustr[TC_UUID_STRING_BYTES] = "fdc314b7-f938-4845-b8d1-95716e4eb762"; CHECK(tc_uuid_from_str(ustr, &u)); - CHECK(u._0[0] == 0xfd); - // .. if these two are correct, probably it worked :) - CHECK(u._0[15] == 0x62); + CHECK(u.bytes[0] == 0xfd); + // .. if these two bytes are correct, then it probably worked :) + CHECK(u.bytes[15] == 0x62); } TEST_CASE("converting invalid UUIDs from string fails as expected") { - Uuid u; + TCUuid u; char ustr[TC_UUID_STRING_BYTES] = "not-a-valid-uuid"; CHECK(!tc_uuid_from_str(ustr, &u)); } TEST_CASE("converting invalid UTF-8 UUIDs from string fails as expected") { - Uuid u; + TCUuid u; char ustr[TC_UUID_STRING_BYTES] = "\xf0\x28\x8c\xbc"; CHECK(!tc_uuid_from_str(ustr, &u)); } diff --git a/lib/build.rs b/lib/build.rs index 74dfe0fc8..8d9db2f1f 100644 --- a/lib/build.rs +++ b/lib/build.rs @@ -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() diff --git a/lib/src/replica.rs b/lib/src/replica.rs index 98b38e389..44066507e 100644 --- a/lib/src/replica.rs +++ b/lib/src/replica.rs @@ -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, } -/// 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, + F: FnOnce(&mut Replica) -> anyhow::Result, { - 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) }); } diff --git a/lib/src/uuid.rs b/lib/src/uuid.rs index 5fbbe8d7a..8ce407afc 100644 --- a/lib/src/uuid.rs +++ b/lib/src/uuid.rs @@ -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 for Uuid { - fn from(uuid: TcUuid) -> Uuid { +impl From 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 for TcUuid { - fn from(uuid: Uuid) -> TcUuid { - TcUuid::from_bytes(uuid.0) +impl From 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; } diff --git a/lib/taskchampion.h b/lib/taskchampion.h index e5ad1de99..c018143d5 100644 --- a/lib/taskchampion.h +++ b/lib/taskchampion.h @@ -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"