add working-set support
This commit is contained in:
@@ -14,6 +14,7 @@ pub mod string;
|
||||
pub mod task;
|
||||
pub mod uda;
|
||||
pub mod uuid;
|
||||
pub mod workingset;
|
||||
|
||||
pub(crate) mod types {
|
||||
pub(crate) use crate::annotation::{TCAnnotation, TCAnnotationList};
|
||||
@@ -24,4 +25,5 @@ pub(crate) mod types {
|
||||
pub(crate) use crate::task::{TCTask, TCTaskList};
|
||||
pub(crate) use crate::uda::{TCUDAList, TCUDA, UDA};
|
||||
pub(crate) use crate::uuid::{TCUuid, TCUuidList};
|
||||
pub(crate) use crate::workingset::TCWorkingSet;
|
||||
}
|
||||
|
||||
@@ -177,7 +177,21 @@ pub unsafe extern "C" fn tc_replica_all_task_uuids(rep: *mut TCReplica) -> TCUui
|
||||
)
|
||||
}
|
||||
|
||||
// TODO: tc_replica_working_set
|
||||
/// Get the current working set for this replica.
|
||||
///
|
||||
/// Returns NULL on error.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn tc_replica_working_set(rep: *mut TCReplica) -> *mut TCWorkingSet {
|
||||
wrap(
|
||||
rep,
|
||||
|rep| {
|
||||
let ws = rep.working_set()?;
|
||||
// SAFETY: caller promises to free this task
|
||||
Ok(unsafe { TCWorkingSet::return_val(ws.into()) })
|
||||
},
|
||||
std::ptr::null_mut(),
|
||||
)
|
||||
}
|
||||
|
||||
/// Get an existing task by its UUID.
|
||||
///
|
||||
|
||||
87
lib/src/workingset.rs
Normal file
87
lib/src/workingset.rs
Normal file
@@ -0,0 +1,87 @@
|
||||
use crate::traits::*;
|
||||
use crate::types::*;
|
||||
use taskchampion::{Uuid, WorkingSet};
|
||||
|
||||
/// A TCWorkingSet represents a snapshot of the working set for a replica. It is not automatically
|
||||
/// updated based on changes in the replica. Its lifetime is independent of the replica and it can
|
||||
/// be freed at any time.
|
||||
///
|
||||
/// To iterate over a working set, search indexes 1 through largest_index.
|
||||
pub struct TCWorkingSet(WorkingSet);
|
||||
|
||||
impl PassByPointer for TCWorkingSet {}
|
||||
|
||||
impl From<WorkingSet> for TCWorkingSet {
|
||||
fn from(ws: WorkingSet) -> TCWorkingSet {
|
||||
TCWorkingSet(ws)
|
||||
}
|
||||
}
|
||||
|
||||
/// Utility function to get a shared reference to the underlying WorkingSet.
|
||||
fn wrap<'a, T, F>(ws: *mut TCWorkingSet, f: F) -> T
|
||||
where
|
||||
F: FnOnce(&WorkingSet) -> T,
|
||||
{
|
||||
// SAFETY:
|
||||
// - ws is not null (promised by caller)
|
||||
// - ws outlives 'a (promised by caller)
|
||||
let tcws: &'a TCWorkingSet = unsafe { TCWorkingSet::from_arg_ref(ws) };
|
||||
f(&tcws.0)
|
||||
}
|
||||
|
||||
/// Get the working set's length, or the number of UUIDs it contains.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn tc_working_set_len(ws: *mut TCWorkingSet) -> usize {
|
||||
wrap(ws, |ws| ws.len())
|
||||
}
|
||||
|
||||
/// Get the working set's largest index.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn tc_working_set_largest_index(ws: *mut TCWorkingSet) -> usize {
|
||||
wrap(ws, |ws| ws.largest_index())
|
||||
}
|
||||
|
||||
/// Get the UUID for the task at the given index. Returns true if the UUID exists in the working
|
||||
/// set. If not, returns false and does not change uuid_out.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn tc_working_set_by_index(
|
||||
ws: *mut TCWorkingSet,
|
||||
index: usize,
|
||||
uuid_out: *mut TCUuid,
|
||||
) -> bool {
|
||||
debug_assert!(!uuid_out.is_null());
|
||||
wrap(ws, |ws| {
|
||||
if let Some(uuid) = ws.by_index(index) {
|
||||
// SAFETY:
|
||||
// - uuid_out is not NULL (promised by caller)
|
||||
// - alignment is not required
|
||||
unsafe { TCUuid::to_arg_out(uuid, uuid_out) };
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Get the working set index for the task with the given UUID. Returns 0 if the task is not in
|
||||
/// the working set.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn tc_working_set_by_uuid(ws: *mut TCWorkingSet, uuid: TCUuid) -> usize {
|
||||
wrap(ws, |ws| {
|
||||
// SAFETY:
|
||||
// - tcuuid is a valid TCUuid (all byte patterns are valid)
|
||||
let uuid: Uuid = unsafe { TCUuid::from_arg(uuid) };
|
||||
ws.by_uuid(uuid).unwrap_or(0)
|
||||
})
|
||||
}
|
||||
|
||||
/// Free a TCWorkingSet. The given value must not be NULL. The value must not be used after this
|
||||
/// function returns, and must not be freed more than once.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn tc_working_set_free(ws: *mut TCWorkingSet) {
|
||||
// SAFETY:
|
||||
// - rep is not NULL (promised by caller)
|
||||
// - caller will not use the TCWorkingSet after this (promised by caller)
|
||||
let ws = unsafe { TCWorkingSet::take_from_arg(ws) };
|
||||
drop(ws);
|
||||
}
|
||||
Reference in New Issue
Block a user