read_fonts/
offset_array.rs1use crate::offset::ResolveNullableOffset;
7use font_types::{BigEndian, Nullable, Offset16, Scalar};
8
9use crate::{FontData, FontRead, 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: FontRead<'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 pub(crate) fn iter_as_nullable(
93 &self,
94 ) -> impl Iterator<Item = Option<Result<T, ReadError>>> + 'a {
95 self.iter().map(|off| match off {
96 Err(ReadError::NullOffset) => None,
97 other => Some(other),
98 })
99 }
100}
101
102impl<'a, T, O> ArrayOfNullableOffsets<'a, T, O>
103where
104 O: Scalar + Offset,
105 T: ReadArgs,
106{
107 pub(crate) fn new(
108 offsets: &'a [BigEndian<Nullable<O>>],
109 data: FontData<'a>,
110 args: T::Args,
111 ) -> Self {
112 Self {
113 offsets,
114 data,
115 args,
116 }
117 }
118}
119
120impl<'a, T, O> ArrayOfNullableOffsets<'a, T, O>
121where
122 O: Scalar + Offset,
123 T: FontRead<'a>,
124 T::Args: Copy + 'static,
125{
126 pub fn len(&self) -> usize {
128 self.offsets.len()
129 }
130
131 pub fn is_empty(&self) -> bool {
133 self.offsets.is_empty()
134 }
135
136 pub fn get(&self, idx: usize) -> Option<Result<T, ReadError>> {
142 let Some(offset) = self.offsets.get(idx) else {
143 return Some(Err(ReadError::InvalidCollectionIndex(idx as _)));
144 };
145 offset.get().resolve_with_args(self.data, self.args)
146 }
147
148 pub fn iter(&self) -> impl Iterator<Item = Option<Result<T, ReadError>>> + 'a {
152 let mut iter = self.offsets.iter();
153 let args = self.args;
154 let data = self.data;
155 std::iter::from_fn(move || {
156 iter.next()
157 .map(|off| off.get().resolve_with_args(data, args))
158 })
159 }
160}