use super::{AccessHelper, SetHelper};
use crate::{Error, Type, Value};
pub struct UnionField {
get_ptr: Option<AccessHelper>,
set_ptr: Option<SetHelper>,
name: &'static str,
assoc_ty: Type,
field_ty: Type,
}
impl UnionField {
pub unsafe fn new(
get_ptr: Option<AccessHelper>,
set_ptr: Option<SetHelper>,
name: &'static str,
assoc_ty: Type,
field_ty: Type,
) -> UnionField {
UnionField {
get_ptr,
set_ptr,
name,
assoc_ty,
field_ty,
}
}
pub fn name(&self) -> &'static str {
self.name
}
pub fn assoc_ty(&self) -> Type {
self.assoc_ty
}
pub fn ty(&self) -> Type {
self.field_ty
}
pub unsafe fn get_ref<'a>(&self, this: &'a Value<'a>) -> Result<Value<'a>, Error> {
self.get_ptr
.as_ref()
.map_or(Err(Error::UnsupportedOperation), |get_ptr| {
if this.ty() == self.assoc_ty() {
Ok((get_ptr)(this))
} else {
Err(Error::wrong_type(this.ty(), self.assoc_ty))
}
})
}
#[allow(clippy::suspicious_operation_groupings)]
pub unsafe fn set(&self, this: &mut Value<'_>, other: Value<'static>) -> Result<(), Error> {
self.set_ptr
.as_ref()
.map_or(Err(Error::UnsupportedOperation), |set_ptr| {
if this.ty() == self.assoc_ty() && other.ty() == self.ty() {
(set_ptr)(this, other);
Ok(())
} else {
Err(Error::wrong_type(this.ty(), self.assoc_ty))
}
})
}
}