use crate::{
Def, Facet, FieldBuilder, OxPtrConst, OxPtrMut, Shape, ShapeBuilder, StructType, Type,
TypeOpsIndirect, TypeParam, UserType, VTableIndirect,
};
unsafe fn range_debug<Idx>(
ox: OxPtrConst,
f: &mut core::fmt::Formatter<'_>,
) -> Option<core::fmt::Result> {
let this = unsafe { ox.get::<core::ops::Range<Idx>>() };
Some((|| {
let fields = match &ox.shape().ty {
Type::User(UserType::Struct(s)) => &s.fields,
_ => return Err(core::fmt::Error),
};
let start_shape = fields[0].shape.get();
let end_shape = fields[1].shape.get();
let start_ptr = crate::PtrConst::new(&this.start);
if let Some(result) = unsafe { start_shape.call_debug(start_ptr, f) } {
result?;
} else {
return Err(core::fmt::Error);
}
write!(f, "..")?;
let end_ptr = crate::PtrConst::new(&this.end);
if let Some(result) = unsafe { end_shape.call_debug(end_ptr, f) } {
result?;
} else {
return Err(core::fmt::Error);
}
Ok(())
})())
}
unsafe fn range_drop<Idx>(ox: OxPtrMut) {
unsafe {
core::ptr::drop_in_place(ox.ptr().as_byte_ptr() as *mut core::ops::Range<Idx>);
}
}
unsafe impl<'a, Idx: Facet<'a>> Facet<'a> for core::ops::Range<Idx> {
const SHAPE: &'static Shape = &const {
const fn build_vtable<Idx>() -> VTableIndirect {
VTableIndirect {
display: None,
debug: Some(range_debug::<Idx>),
hash: None,
invariants: None,
parse: None,
parse_bytes: None,
try_from: None,
try_into_inner: None,
try_borrow_inner: None,
partial_eq: None,
partial_cmp: None,
cmp: None,
}
}
const fn build_type_ops<Idx>() -> TypeOpsIndirect {
TypeOpsIndirect {
drop_in_place: range_drop::<Idx>,
default_in_place: None,
clone_into: None,
is_truthy: None,
}
}
ShapeBuilder::for_sized::<core::ops::Range<Idx>>("Range")
.module_path("core::ops")
.ty(Type::User(UserType::Struct(StructType {
kind: crate::StructKind::Struct,
repr: crate::Repr::default(),
fields: &const {
[
FieldBuilder::new(
"start",
crate::shape_of::<Idx>,
core::mem::offset_of!(core::ops::Range<Idx>, start),
)
.build(),
FieldBuilder::new(
"end",
crate::shape_of::<Idx>,
core::mem::offset_of!(core::ops::Range<Idx>, end),
)
.build(),
]
},
})))
.def(Def::Scalar)
.type_params(&[TypeParam {
name: "Idx",
shape: Idx::SHAPE,
}])
.vtable_indirect(&const { build_vtable::<Idx>() })
.type_ops_indirect(&const { build_type_ops::<Idx>() })
.build()
};
}