1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
use std::ptr::NonNull;
use twizzler_abi::{meta::MetaInfo, object::NULLPAGE_SIZE};
use crate::{
marker::{BaseType, BaseVersion, ObjSafe},
object::Object,
};
/// Possible errors from getting a reference to an object's base.
#[derive(Debug)]
pub enum BaseError {
InvalidTag,
InvalidVersion(BaseVersion),
}
fn match_tags(_meta: NonNull<MetaInfo>) -> Result<(), BaseError> {
// TODO
Ok(())
}
impl<T: BaseType + ObjSafe> Object<T> {
/// Get a reference to the base of an object. Checks to see if the tags and version information
/// for the BaseType match.
pub fn base(&self) -> Result<&T, BaseError> {
let meta = unsafe { self.meta() };
match_tags(meta)?;
Ok(unsafe { self.base_unchecked() })
}
}
impl<BaseType> Object<BaseType> {
/// Get a reference to the base of an object, bypassing version and tag checks.
///
/// # Safety
/// The caller must ensure that the base of the object really is of type BaseType.
pub unsafe fn base_unchecked(&self) -> &BaseType {
self.slot
.raw_lea::<BaseType>(NULLPAGE_SIZE)
.as_ref()
.unwrap()
}
/// Get a mutable reference to the base of an object, bypassing version and tag checks.
///
/// # Safety
/// The caller must ensure that the base of the object really is of type BaseType.
#[allow(clippy::mut_from_ref)]
pub unsafe fn base_mut_unchecked(&self) -> &mut BaseType {
self.slot
.raw_lea_mut::<BaseType>(NULLPAGE_SIZE)
.as_mut()
.unwrap()
}
}