add TC prefix to types, too
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user