facet_reflect/poke/
list.rs1use crate::PokeValueUninit;
2use facet_core::{ListDef, ListVTable, Opaque, OpaqueConst, OpaqueUninit, Shape};
3
4pub struct PokeListUninit<'mem> {
6 data: OpaqueUninit<'mem>,
7 shape: &'static Shape,
8 def: ListDef,
9}
10
11impl<'mem> PokeListUninit<'mem> {
12 #[inline(always)]
13 pub fn into_value(self) -> PokeValueUninit<'mem> {
15 unsafe { PokeValueUninit::new(self.data, self.shape) }
16 }
17
18 #[inline(always)]
19 pub fn shape(&self) -> &'static Shape {
21 self.shape
22 }
23 pub(crate) unsafe fn new(
29 data: OpaqueUninit<'mem>,
30 shape: &'static Shape,
31 def: ListDef,
32 ) -> Self {
33 Self { data, shape, def }
34 }
35
36 pub fn init(self, size_hint: Option<usize>) -> Result<PokeList<'mem>, OpaqueUninit<'mem>> {
38 let res = if let Some(capacity) = size_hint {
39 let init_in_place_with_capacity = self.def.vtable.init_in_place_with_capacity;
40 unsafe { init_in_place_with_capacity(self.data, capacity) }
41 } else {
42 let pv = unsafe { PokeValueUninit::new(self.data, self.shape) };
43 pv.default_in_place().map_err(|_| ())
44 };
45 let data = res.map_err(|_| self.data)?;
46 Ok(unsafe { PokeList::new(data, self.shape, self.def) })
47 }
48}
49
50pub struct PokeList<'mem> {
52 data: Opaque<'mem>,
53 #[allow(dead_code)]
54 shape: &'static Shape,
55 def: ListDef,
56}
57
58impl<'mem> PokeList<'mem> {
59 pub(crate) unsafe fn new(data: Opaque<'mem>, shape: &'static Shape, def: ListDef) -> Self {
65 Self { data, shape, def }
66 }
67
68 #[inline(always)]
69 pub fn shape(&self) -> &'static Shape {
71 self.shape
72 }
73
74 #[inline(always)]
76 fn list_vtable(&self) -> &'static ListVTable {
77 self.def.vtable
78 }
79
80 pub unsafe fn push(&mut self, item: Opaque<'_>) {
87 unsafe { (self.list_vtable().push)(self.data, item) }
88 }
89
90 pub fn len(&self) -> usize {
92 unsafe { (self.list_vtable().len)(self.data.as_const()) }
93 }
94
95 pub fn is_empty(&self) -> bool {
97 self.len() == 0
98 }
99
100 pub fn get_item_ptr(&self, index: usize) -> OpaqueConst {
106 unsafe { (self.list_vtable().get_item_ptr)(self.data.as_const(), index) }
107 }
108
109 pub fn build_in_place(self) -> Opaque<'mem> {
111 self.data
112 }
113
114 pub fn def(&self) -> &ListDef {
116 &self.def
117 }
118}