1use std::collections::BTreeSet;
4
5use read_fonts::{ArrayOfNullableOffsets, ArrayOfOffsets, FontData, FontRead, Offset, ReadError};
6use types::{BigEndian, Scalar};
7
8use crate::{NullableOffsetMarker, OffsetMarker};
9
10pub trait FromTableRef<T>: FromObjRef<T> {
15 fn from_table_ref(from: &T) -> Self {
16 let data = FontData::new(&[]);
17 Self::from_obj_ref(from, data)
18 }
19}
20
21pub trait FromObjRef<T: ?Sized>: Sized {
32 fn from_obj_ref(from: &T, data: FontData) -> Self;
34}
35
36pub trait ToOwnedObj<T> {
42 fn to_owned_obj(&self, data: FontData) -> T;
44}
45
46pub trait ToOwnedTable<T>: ToOwnedObj<T> {
50 fn to_owned_table(&self) -> T;
51}
52
53impl<U, T> ToOwnedObj<U> for T
54where
55 U: FromObjRef<T>,
56{
57 fn to_owned_obj(&self, data: FontData) -> U {
58 U::from_obj_ref(self, data)
59 }
60}
61
62impl<U, T> ToOwnedTable<U> for T
63where
64 U: FromTableRef<T>,
65{
66 fn to_owned_table(&self) -> U {
67 U::from_table_ref(self)
68 }
69}
70
71impl<T> FromObjRef<BigEndian<T>> for T
72where
73 T: Scalar,
74 BigEndian<T>: Copy,
75{
76 fn from_obj_ref(from: &BigEndian<T>, _: FontData) -> Self {
77 from.get()
78 }
79}
80
81impl FromObjRef<u8> for u8 {
83 fn from_obj_ref(from: &u8, _data: FontData) -> Self {
84 *from
85 }
86}
87
88impl<T, U> FromObjRef<&[U]> for Vec<T>
89where
90 T: FromObjRef<U>,
91{
92 fn from_obj_ref(from: &&[U], data: FontData) -> Self {
93 from.iter().map(|item| item.to_owned_obj(data)).collect()
94 }
95}
96
97impl<T, U> FromObjRef<&[U]> for BTreeSet<T>
98where
99 T: FromObjRef<U> + std::cmp::Ord,
100{
101 fn from_obj_ref(from: &&[U], data: FontData) -> Self {
102 from.iter().map(|item| item.to_owned_obj(data)).collect()
103 }
104}
105
106impl<T: FromObjRef<U>, U> FromObjRef<Option<U>> for Option<T> {
108 fn from_obj_ref(from: &Option<U>, data: FontData) -> Self {
109 from.as_ref().map(|inner| T::from_obj_ref(inner, data))
110 }
111}
112
113impl<T: FromTableRef<U>, U> FromTableRef<Option<U>> for Option<T> {
115 fn from_table_ref(from: &Option<U>) -> Self {
116 from.as_ref().map(ToOwnedTable::to_owned_table)
117 }
118}
119
120impl<T: FromObjRef<U> + Default, U, const N: usize> FromObjRef<Result<U, ReadError>>
123 for OffsetMarker<T, N>
124{
125 fn from_obj_ref(from: &Result<U, ReadError>, data: FontData) -> Self {
126 match from {
127 Err(_) => OffsetMarker::default(),
128 Ok(table) => OffsetMarker::new(table.to_owned_obj(data)),
129 }
130 }
131}
132
133impl<T: FromObjRef<U> + Default, U, const N: usize> FromObjRef<Option<U>> for OffsetMarker<T, N> {
135 fn from_obj_ref(from: &Option<U>, data: FontData) -> Self {
136 match from {
137 None => OffsetMarker::default(),
138 Some(table) => OffsetMarker::new(table.to_owned_obj(data)),
139 }
140 }
141}
142
143impl<T: FromObjRef<U>, U, const N: usize> FromObjRef<Option<Result<U, ReadError>>>
144 for NullableOffsetMarker<T, N>
145{
146 fn from_obj_ref(from: &Option<Result<U, ReadError>>, data: FontData) -> Self {
147 match from {
148 Some(Ok(table)) => NullableOffsetMarker::new(Some(table.to_owned_obj(data))),
149 _ => NullableOffsetMarker::new(None),
150 }
151 }
152}
153
154impl<T: FromTableRef<U> + Default, U, const N: usize> FromTableRef<Result<U, ReadError>>
156 for OffsetMarker<T, N>
157{
158 fn from_table_ref(from: &Result<U, ReadError>) -> Self {
159 match from {
160 Err(_) => OffsetMarker::default(),
161 Ok(table) => OffsetMarker::new(table.to_owned_table()),
162 }
163 }
164}
165
166impl<T: FromTableRef<U> + Default, U, const N: usize> FromTableRef<Option<U>>
168 for OffsetMarker<T, N>
169{
170 fn from_table_ref(from: &Option<U>) -> Self {
171 match from {
172 None => OffsetMarker::default(),
173 Some(table) => OffsetMarker::new(table.to_owned_table()),
174 }
175 }
176}
177
178impl<T: FromTableRef<U>, U, const N: usize> FromTableRef<Option<Result<U, ReadError>>>
180 for NullableOffsetMarker<T, N>
181{
182 fn from_table_ref(from: &Option<Result<U, ReadError>>) -> Self {
183 match from {
184 Some(Ok(table)) => NullableOffsetMarker::new(Some(table.to_owned_table())),
185 _ => NullableOffsetMarker::new(None),
186 }
187 }
188}
189
190impl<'a, T, U, O, const N: usize> FromObjRef<ArrayOfOffsets<'a, U, O>> for Vec<OffsetMarker<T, N>>
192where
193 T: FromObjRef<U> + Default,
194 U: FontRead<'a>,
195 U::Args: 'static,
196 O: Scalar + Offset,
197{
198 fn from_obj_ref(from: &ArrayOfOffsets<'a, U, O>, data: FontData) -> Self {
199 from.iter()
200 .map(|x| OffsetMarker::from_obj_ref(&x, data))
201 .collect()
202 }
203}
204
205impl<'a, T, U, O, const N: usize> FromObjRef<ArrayOfNullableOffsets<'a, U, O>>
206 for Vec<NullableOffsetMarker<T, N>>
207where
208 T: FromObjRef<U> + Default,
209 U: FontRead<'a>,
210 U::Args: 'static,
211 O: Scalar + Offset,
212{
213 fn from_obj_ref(from: &ArrayOfNullableOffsets<'a, U, O>, data: FontData) -> Self {
214 from.iter()
215 .map(|x| NullableOffsetMarker::from_obj_ref(&x, data))
216 .collect()
217 }
218}
219
220impl<'a, T, U, O, const N: usize> FromTableRef<ArrayOfOffsets<'a, U, O>> for Vec<OffsetMarker<T, N>>
221where
222 T: FromTableRef<U> + Default,
223 U: FontRead<'a>,
224 U::Args: 'static,
225 O: Scalar + Offset,
226{
227}
228
229impl<'a, T, U, O, const N: usize> FromTableRef<ArrayOfNullableOffsets<'a, U, O>>
230 for Vec<NullableOffsetMarker<T, N>>
231where
232 T: FromObjRef<U> + Default,
233 U: FontRead<'a>,
234 U::Args: 'static,
235 O: Scalar + Offset,
236{
237}