add TC prefix to types, too
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
10
lib/build.rs
10
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()
|
||||
|
||||
@@ -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) });
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user