188 lines
4.7 KiB
Rust
188 lines
4.7 KiB
Rust
use automerge as am;
|
|
use std::cell::RefCell;
|
|
use std::ops::Deref;
|
|
|
|
use crate::actor_id::AMactorId;
|
|
|
|
pub mod item;
|
|
pub mod items;
|
|
|
|
macro_rules! to_obj_id {
|
|
($handle:expr) => {{
|
|
match $handle.as_ref() {
|
|
Some(obj_id) => obj_id,
|
|
None => &automerge::ROOT,
|
|
}
|
|
}};
|
|
}
|
|
|
|
pub(crate) use to_obj_id;
|
|
|
|
macro_rules! to_obj_type {
|
|
($am_obj_type:expr) => {{
|
|
match $am_obj_type {
|
|
AMobjType::Map => am::ObjType::Map,
|
|
AMobjType::List => am::ObjType::List,
|
|
AMobjType::Text => am::ObjType::Text,
|
|
AMobjType::Void => return AMresult::err("Invalid AMobjType value").into(),
|
|
}
|
|
}};
|
|
}
|
|
|
|
pub(crate) use to_obj_type;
|
|
|
|
/// \struct AMobjId
|
|
/// \installed_headerfile
|
|
/// \brief An object's unique identifier.
|
|
#[derive(Eq, PartialEq)]
|
|
pub struct AMobjId {
|
|
body: am::ObjId,
|
|
c_actor_id: RefCell<Option<AMactorId>>,
|
|
}
|
|
|
|
impl AMobjId {
|
|
pub fn new(obj_id: am::ObjId) -> Self {
|
|
Self {
|
|
body: obj_id,
|
|
c_actor_id: Default::default(),
|
|
}
|
|
}
|
|
|
|
pub fn actor_id(&self) -> *const AMactorId {
|
|
let mut c_actor_id = self.c_actor_id.borrow_mut();
|
|
match c_actor_id.as_mut() {
|
|
None => {
|
|
if let am::ObjId::Id(_, actor_id, _) = &self.body {
|
|
return c_actor_id.insert(AMactorId::new(actor_id));
|
|
}
|
|
}
|
|
Some(value) => {
|
|
return value;
|
|
}
|
|
}
|
|
std::ptr::null()
|
|
}
|
|
}
|
|
|
|
impl AsRef<am::ObjId> for AMobjId {
|
|
fn as_ref(&self) -> &am::ObjId {
|
|
&self.body
|
|
}
|
|
}
|
|
|
|
impl Deref for AMobjId {
|
|
type Target = am::ObjId;
|
|
|
|
fn deref(&self) -> &Self::Target {
|
|
&self.body
|
|
}
|
|
}
|
|
|
|
/// \memberof AMobjId
|
|
/// \brief Gets the actor identifier of an object identifier.
|
|
///
|
|
/// \param[in] obj_id A pointer to an `AMobjId` struct.
|
|
/// \return A pointer to an `AMactorId` struct or `NULL`.
|
|
/// \pre \p obj_id `!= NULL`.
|
|
/// \internal
|
|
///
|
|
/// # Safety
|
|
/// obj_id must be a valid pointer to an AMobjId
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn AMobjIdActorId(obj_id: *const AMobjId) -> *const AMactorId {
|
|
if let Some(obj_id) = obj_id.as_ref() {
|
|
return obj_id.actor_id();
|
|
};
|
|
std::ptr::null()
|
|
}
|
|
|
|
/// \memberof AMobjId
|
|
/// \brief Gets the counter of an object identifier.
|
|
///
|
|
/// \param[in] obj_id A pointer to an `AMobjId` struct.
|
|
/// \return A 64-bit unsigned integer.
|
|
/// \pre \p obj_id `!= NULL`.
|
|
/// \internal
|
|
///
|
|
/// # Safety
|
|
/// obj_id must be a valid pointer to an AMobjId
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn AMobjIdCounter(obj_id: *const AMobjId) -> u64 {
|
|
if let Some(obj_id) = obj_id.as_ref() {
|
|
match obj_id.as_ref() {
|
|
am::ObjId::Id(counter, _, _) => *counter,
|
|
am::ObjId::Root => 0,
|
|
}
|
|
} else {
|
|
u64::MAX
|
|
}
|
|
}
|
|
|
|
/// \memberof AMobjId
|
|
/// \brief Tests the equality of two object identifiers.
|
|
///
|
|
/// \param[in] obj_id1 A pointer to an `AMobjId` struct.
|
|
/// \param[in] obj_id2 A pointer to an `AMobjId` struct.
|
|
/// \return `true` if \p obj_id1 `==` \p obj_id2 and `false` otherwise.
|
|
/// \pre \p obj_id1 `!= NULL`.
|
|
/// \pre \p obj_id2 `!= NULL`.
|
|
/// \internal
|
|
///
|
|
/// #Safety
|
|
/// obj_id1 must be a valid AMobjId pointer
|
|
/// obj_id2 must be a valid AMobjId pointer
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn AMobjIdEqual(obj_id1: *const AMobjId, obj_id2: *const AMobjId) -> bool {
|
|
match (obj_id1.as_ref(), obj_id2.as_ref()) {
|
|
(Some(obj_id1), Some(obj_id2)) => obj_id1 == obj_id2,
|
|
(None, Some(_)) | (Some(_), None) | (None, None) => false,
|
|
}
|
|
}
|
|
|
|
/// \memberof AMobjId
|
|
/// \brief Gets the index of an object identifier.
|
|
///
|
|
/// \param[in] obj_id A pointer to an `AMobjId` struct.
|
|
/// \return A 64-bit unsigned integer.
|
|
/// \pre \p obj_id `!= NULL`.
|
|
/// \internal
|
|
///
|
|
/// # Safety
|
|
/// obj_id must be a valid pointer to an AMobjId
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn AMobjIdIndex(obj_id: *const AMobjId) -> usize {
|
|
if let Some(obj_id) = obj_id.as_ref() {
|
|
match obj_id.as_ref() {
|
|
am::ObjId::Id(_, _, index) => *index,
|
|
am::ObjId::Root => 0,
|
|
}
|
|
} else {
|
|
usize::MAX
|
|
}
|
|
}
|
|
|
|
/// \ingroup enumerations
|
|
/// \enum AMobjType
|
|
/// \brief The type of an object value.
|
|
#[repr(u8)]
|
|
pub enum AMobjType {
|
|
/// A void.
|
|
/// \note This tag is unalphabetized to evaluate as false.
|
|
Void = 0,
|
|
/// A list.
|
|
List,
|
|
/// A key-value map.
|
|
Map,
|
|
/// A list of Unicode graphemes.
|
|
Text,
|
|
}
|
|
|
|
impl From<am::ObjType> for AMobjType {
|
|
fn from(o: am::ObjType) -> Self {
|
|
match o {
|
|
am::ObjType::Map | am::ObjType::Table => AMobjType::Map,
|
|
am::ObjType::List => AMobjType::List,
|
|
am::ObjType::Text => AMobjType::Text,
|
|
}
|
|
}
|
|
}
|