read_fonts/
offset_array.rs1use crate::offset::ResolveNullableOffset;
7use font_types::{BigEndian, Nullable, Offset16, Scalar};
8
9use crate::{FontData, FontReadWithArgs, Offset, ReadArgs, ReadError, ResolveOffset};
10
11#[derive(Clone)]
18pub struct ArrayOfOffsets<'a, T: ReadArgs, O: Scalar = Offset16> {
19 offsets: &'a [BigEndian<O>],
20 data: FontData<'a>,
21 args: T::Args,
22}
23
24#[derive(Clone)]
29pub struct ArrayOfNullableOffsets<'a, T: ReadArgs, O: Scalar = Offset16> {
30 offsets: &'a [BigEndian<Nullable<O>>],
31 data: FontData<'a>,
32 args: T::Args,
33}
34
35impl<'a, T, O> ArrayOfOffsets<'a, T, O>
36where
37 O: Scalar,
38 T: ReadArgs,
39{
40 pub(crate) fn new(offsets: &'a [BigEndian<O>], data: FontData<'a>, args: T::Args) -> Self {
41 Self {
42 offsets,
43 data,
44 args,
45 }
46 }
47}
48
49impl<'a, T, O> ArrayOfOffsets<'a, T, O>
50where
51 O: Scalar + Offset,
52 T: ReadArgs + FontReadWithArgs<'a>,
53 T::Args: Copy + 'static,
54{
55 pub fn len(&self) -> usize {
57 self.offsets.len()
58 }
59
60 pub fn is_empty(&self) -> bool {
62 self.offsets.is_empty()
63 }
64
65 pub fn get(&self, idx: usize) -> Result<T, ReadError> {
70 self.offsets
71 .get(idx)
72 .ok_or(ReadError::InvalidCollectionIndex(idx as _))
73 .and_then(|o| o.get().resolve_with_args(self.data, &self.args))
74 }
75
76 pub fn iter(&self) -> impl Iterator<Item = Result<T, ReadError>> + 'a {
80 let mut iter = self.offsets.iter();
81 let args = self.args;
82 let data = self.data;
83 std::iter::from_fn(move || {
84 iter.next()
85 .map(|off| off.get().resolve_with_args(data, &args))
86 })
87 }
88}
89
90impl<'a, T, O> ArrayOfNullableOffsets<'a, T, O>
91where
92 O: Scalar + Offset,
93 T: ReadArgs,
94{
95 pub(crate) fn new(
96 offsets: &'a [BigEndian<Nullable<O>>],
97 data: FontData<'a>,
98 args: T::Args,
99 ) -> Self {
100 Self {
101 offsets,
102 data,
103 args,
104 }
105 }
106}
107
108impl<'a, T, O> ArrayOfNullableOffsets<'a, T, O>
109where
110 O: Scalar + Offset,
111 T: ReadArgs + FontReadWithArgs<'a>,
112 T::Args: Copy + 'static,
113{
114 pub fn len(&self) -> usize {
116 self.offsets.len()
117 }
118
119 pub fn is_empty(&self) -> bool {
121 self.offsets.is_empty()
122 }
123
124 pub fn get(&self, idx: usize) -> Option<Result<T, ReadError>> {
130 let Some(offset) = self.offsets.get(idx) else {
131 return Some(Err(ReadError::InvalidCollectionIndex(idx as _)));
132 };
133 offset.get().resolve_with_args(self.data, &self.args)
134 }
135
136 pub fn iter(&self) -> impl Iterator<Item = Option<Result<T, ReadError>>> + 'a {
140 let mut iter = self.offsets.iter();
141 let args = self.args;
142 let data = self.data;
143 std::iter::from_fn(move || {
144 iter.next()
145 .map(|off| off.get().resolve_with_args(data, &args))
146 })
147 }
148}