1use super::PolicyValidationContext;
6use super::parser::{PolicyCursor, PolicyData, PolicyOffset};
7use crate::policy::{Counted, Parse, Validate};
8use std::marker::PhantomData;
9use zerocopy::FromBytes;
10
11pub trait HasMetadata {
17 type Metadata: FromBytes + Sized;
19}
20
21pub trait Walk {
25 fn walk(policy_data: &PolicyData, offset: PolicyOffset) -> PolicyOffset;
29}
30
31#[derive(Debug, Clone, Copy)]
36pub struct View<T> {
37 phantom: PhantomData<T>,
38
39 start: PolicyOffset,
41
42 end: PolicyOffset,
44}
45
46impl<T> View<T> {
47 pub fn new(start: PolicyOffset, end: PolicyOffset) -> Self {
49 Self { phantom: PhantomData, start, end }
50 }
51}
52
53impl<T: Sized> View<T> {
54 pub fn at(start: PolicyOffset) -> Self {
58 let end = start + std::mem::size_of::<T>() as u32;
59 Self::new(start, end)
60 }
61}
62
63impl<T: FromBytes + Sized> View<T> {
64 pub fn read(&self, policy_data: &PolicyData) -> T {
71 debug_assert_eq!(self.end - self.start, std::mem::size_of::<T>() as u32);
72 let start = self.start as usize;
73 let end = self.end as usize;
74 T::read_from_bytes(&policy_data[start..end]).unwrap()
75 }
76}
77
78impl<T: HasMetadata> View<T> {
79 pub fn metadata(&self) -> View<T::Metadata> {
83 View::<T::Metadata>::at(self.start)
84 }
85
86 pub fn read_metadata(&self, policy_data: &PolicyData) -> T::Metadata {
88 self.metadata().read(policy_data)
89 }
90}
91
92impl<T: Parse> View<T> {
93 pub fn parse(&self, policy_data: &PolicyData) -> T {
99 let cursor = PolicyCursor::new_at(policy_data.clone(), self.start);
100 let (object, _) =
101 T::parse(cursor).map_err(Into::<anyhow::Error>::into).expect("policy should be valid");
102 object
103 }
104}
105
106impl<T: Validate + Parse> Validate for View<T> {
107 type Error = anyhow::Error;
108
109 fn validate(&self, context: &mut PolicyValidationContext) -> Result<(), Self::Error> {
110 let object = self.parse(&context.data);
111 object.validate(context).map_err(Into::<anyhow::Error>::into)
112 }
113}
114
115#[derive(Debug, Clone, Copy)]
120pub struct ArrayDataView<D> {
121 phantom: PhantomData<D>,
122 start: PolicyOffset,
123 count: u32,
124}
125
126impl<D> ArrayDataView<D> {
127 pub fn new(start: PolicyOffset, count: u32) -> Self {
129 Self { phantom: PhantomData, start, count }
130 }
131
132 pub fn iter(self, policy_data: &PolicyData) -> ArrayDataViewIter<D> {
139 ArrayDataViewIter::new(policy_data.clone(), self.start, self.count)
140 }
141}
142
143pub struct ArrayDataViewIter<D> {
148 phantom: PhantomData<D>,
149 policy_data: PolicyData,
150 offset: PolicyOffset,
151 remaining: u32,
152}
153
154impl<T> ArrayDataViewIter<T> {
155 pub(crate) fn new(policy_data: PolicyData, offset: PolicyOffset, remaining: u32) -> Self {
157 Self { phantom: PhantomData, policy_data, offset, remaining }
158 }
159}
160
161impl<D: Walk> std::iter::Iterator for ArrayDataViewIter<D> {
162 type Item = View<D>;
163
164 fn next(&mut self) -> Option<Self::Item> {
165 if self.remaining > 0 {
166 let start = self.offset;
167 self.offset = D::walk(&self.policy_data, start);
168 self.remaining -= 1;
169 Some(View::new(start, self.offset))
170 } else {
171 None
172 }
173 }
174}
175
176#[derive(Debug, Clone, Copy)]
181pub(crate) struct ArrayView<M, D> {
182 phantom: PhantomData<(M, D)>,
183 start: PolicyOffset,
184 count: u32,
185}
186
187impl<M, D> ArrayView<M, D> {
188 pub fn new(start: PolicyOffset, count: u32) -> Self {
190 Self { phantom: PhantomData, start, count }
191 }
192}
193
194impl<M: Sized, D> ArrayView<M, D> {
195 pub fn metadata(&self) -> View<M> {
197 View::<M>::at(self.start)
198 }
199
200 pub fn data(&self) -> ArrayDataView<D> {
202 ArrayDataView::new(self.metadata().end, self.count)
203 }
204}
205
206fn parse_array_data<D: Parse>(
207 cursor: PolicyCursor,
208 count: u32,
209) -> Result<PolicyCursor, anyhow::Error> {
210 let mut tail = cursor;
211 for _ in 0..count {
212 let (_, next) = D::parse(tail).map_err(Into::<anyhow::Error>::into)?;
213 tail = next;
214 }
215 Ok(tail)
216}
217
218impl<M: Counted + Parse + Sized, D: Parse> Parse for ArrayView<M, D> {
219 type Error = anyhow::Error;
222
223 fn parse(cursor: PolicyCursor) -> Result<(Self, PolicyCursor), Self::Error> {
224 let start = cursor.offset();
225 let (metadata, cursor) = M::parse(cursor).map_err(Into::<anyhow::Error>::into)?;
226 let count = metadata.count();
227 let cursor = parse_array_data::<D>(cursor, count)?;
228 Ok((Self::new(start, count), cursor))
229 }
230}