abi_stable/type_layout/
tl_fields.rs
1use super::*;
2
3use std::{iter, slice};
4
5#[repr(C)]
8#[derive(Copy, Clone, StableAbi)]
9#[sabi(unsafe_sabi_opaque_fields)]
10pub struct CompTLFields {
11 comp_fields: *const CompTLField,
13
14 functions: Option<&'static TLFunctions>,
16
17 comp_fields_len: u16,
18}
19
20unsafe impl Sync for CompTLFields {}
21unsafe impl Send for CompTLFields {}
22
23impl CompTLFields {
24 pub const EMPTY: Self = Self::from_fields(rslice![]);
26
27 pub const fn new(
29 comp_fields: RSlice<'static, CompTLFieldRepr>,
30 functions: Option<&'static TLFunctions>,
31 ) -> Self {
32 Self {
33 comp_fields: comp_fields.as_ptr() as *const CompTLFieldRepr as *const CompTLField,
34 comp_fields_len: comp_fields.len() as u16,
35
36 functions,
37 }
38 }
39
40 pub const fn from_fields(comp_fields: RSlice<'static, CompTLField>) -> Self {
42 Self {
43 comp_fields: comp_fields.as_ptr(),
44 comp_fields_len: comp_fields.len() as u16,
45
46 functions: None,
47 }
48 }
49
50 pub fn comp_fields(&self) -> &'static [CompTLField] {
52 unsafe { slice::from_raw_parts(self.comp_fields, self.comp_fields_len as usize) }
53 }
54
55 pub const fn comp_fields_rslice(&self) -> RSlice<'static, CompTLField> {
57 unsafe { RSlice::from_raw_parts(self.comp_fields, self.comp_fields_len as usize) }
58 }
59
60 pub fn field_names(
62 &self,
63 shared_vars: &MonoSharedVars,
64 ) -> impl ExactSizeIterator<Item = &'static str> + Clone + 'static {
65 let fields = self.comp_fields();
66 let strings = shared_vars.strings();
67
68 fields.iter().map(move |field| field.name(strings))
69 }
70
71 pub fn get_field_name(
73 &self,
74 index: usize,
75 shared_vars: &MonoSharedVars,
76 ) -> Option<&'static str> {
77 let strings = shared_vars.strings();
78
79 self.comp_fields().get(index).map(|f| f.name(strings))
80 }
81
82 pub const fn len(&self) -> usize {
84 self.comp_fields_len as usize
85 }
86
87 pub const fn is_empty(&self) -> bool {
89 self.comp_fields_len == 0
90 }
91
92 pub const fn expand(self, shared_vars: &'static SharedVars) -> TLFields {
94 TLFields {
95 shared_vars,
96 comp_fields: self.comp_fields_rslice(),
97 functions: self.functions,
98 }
99 }
100}
101
102#[repr(C)]
106#[derive(Copy, Clone, StableAbi)]
107pub struct TLFields {
108 shared_vars: &'static SharedVars,
109
110 comp_fields: RSlice<'static, CompTLField>,
111
112 functions: Option<&'static TLFunctions>,
114}
115
116impl TLFields {
117 pub const fn from_fields(
119 comp_fields: &'static [CompTLField],
120 shared_vars: &'static SharedVars,
121 ) -> Self {
122 Self {
123 comp_fields: RSlice::from_slice(comp_fields),
124 shared_vars,
125 functions: None,
126 }
127 }
128
129 pub const fn len(&self) -> usize {
131 self.comp_fields.len()
132 }
133
134 pub const fn is_empty(&self) -> bool {
136 self.comp_fields.is_empty()
137 }
138
139 pub fn get(&self, i: usize) -> Option<TLField> {
141 self.comp_fields
142 .get(i)
143 .map(|field| field.expand(i, self.functions, self.shared_vars))
144 }
145
146 pub fn iter(&self) -> TLFieldsIterator {
148 TLFieldsIterator {
149 shared_vars: self.shared_vars,
150 comp_fields: self.comp_fields.as_slice().iter().enumerate(),
151 functions: self.functions,
152 }
153 }
154
155 pub fn to_vec(&self) -> Vec<TLField> {
157 self.iter().collect()
158 }
159}
160
161impl IntoIterator for TLFields {
162 type IntoIter = TLFieldsIterator;
163 type Item = TLField;
164
165 #[inline]
166 fn into_iter(self) -> Self::IntoIter {
167 self.iter()
168 }
169}
170
171impl Debug for TLFields {
172 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
173 f.debug_list().entries(self.iter()).finish()
174 }
175}
176
177impl Display for TLFields {
178 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
179 for field in self.iter() {
180 Display::fmt(&field, f)?;
181 writeln!(f)?;
182 }
183 Ok(())
184 }
185}
186
187impl Eq for TLFields {}
188impl PartialEq for TLFields {
189 fn eq(&self, other: &Self) -> bool {
190 self.iter().eq(other.iter())
191 }
192}
193
194#[derive(Clone, Debug)]
198pub struct TLFieldsIterator {
199 shared_vars: &'static SharedVars,
200
201 comp_fields: iter::Enumerate<slice::Iter<'static, CompTLField>>,
202
203 functions: Option<&'static TLFunctions>,
205}
206
207impl Iterator for TLFieldsIterator {
208 type Item = TLField;
209
210 fn next(&mut self) -> Option<TLField> {
211 self.comp_fields
212 .next()
213 .map(|(i, field)| field.expand(i, self.functions, self.shared_vars))
214 }
215
216 fn size_hint(&self) -> (usize, Option<usize>) {
217 let len = self.comp_fields.len();
218 (len, Some(len))
219 }
220 fn count(self) -> usize {
221 self.comp_fields.len()
222 }
223}
224
225impl std::iter::ExactSizeIterator for TLFieldsIterator {}