use std::collections::BTreeSet;
use read_fonts::{
ArrayOfNullableOffsets, ArrayOfOffsets, FontData, FontReadWithArgs, Offset, ReadArgs, ReadError,
};
use types::{BigEndian, Scalar};
use crate::{NullableOffsetMarker, OffsetMarker};
pub trait FromTableRef<T>: FromObjRef<T> {
fn from_table_ref(from: &T) -> Self {
let data = FontData::new(&[]);
Self::from_obj_ref(from, data)
}
}
pub trait FromObjRef<T: ?Sized>: Sized {
fn from_obj_ref(from: &T, data: FontData) -> Self;
}
pub trait ToOwnedObj<T> {
fn to_owned_obj(&self, data: FontData) -> T;
}
pub trait ToOwnedTable<T>: ToOwnedObj<T> {
fn to_owned_table(&self) -> T;
}
impl<U, T> ToOwnedObj<U> for T
where
U: FromObjRef<T>,
{
fn to_owned_obj(&self, data: FontData) -> U {
U::from_obj_ref(self, data)
}
}
impl<U, T> ToOwnedTable<U> for T
where
U: FromTableRef<T>,
{
fn to_owned_table(&self) -> U {
U::from_table_ref(self)
}
}
impl<T> FromObjRef<BigEndian<T>> for T
where
T: Scalar,
BigEndian<T>: Copy,
{
fn from_obj_ref(from: &BigEndian<T>, _: FontData) -> Self {
from.get()
}
}
impl FromObjRef<u8> for u8 {
fn from_obj_ref(from: &u8, _data: FontData) -> Self {
*from
}
}
impl<T, U> FromObjRef<&[U]> for Vec<T>
where
T: FromObjRef<U>,
{
fn from_obj_ref(from: &&[U], data: FontData) -> Self {
from.iter().map(|item| item.to_owned_obj(data)).collect()
}
}
impl<T, U> FromObjRef<&[U]> for BTreeSet<T>
where
T: FromObjRef<U> + std::cmp::Ord,
{
fn from_obj_ref(from: &&[U], data: FontData) -> Self {
from.iter().map(|item| item.to_owned_obj(data)).collect()
}
}
impl<T: FromObjRef<U>, U> FromObjRef<Option<U>> for Option<T> {
fn from_obj_ref(from: &Option<U>, data: FontData) -> Self {
from.as_ref().map(|inner| T::from_obj_ref(inner, data))
}
}
impl<T: FromTableRef<U>, U> FromTableRef<Option<U>> for Option<T> {
fn from_table_ref(from: &Option<U>) -> Self {
from.as_ref().map(ToOwnedTable::to_owned_table)
}
}
impl<T: FromObjRef<U> + Default, U, const N: usize> FromObjRef<Result<U, ReadError>>
for OffsetMarker<T, N>
{
fn from_obj_ref(from: &Result<U, ReadError>, data: FontData) -> Self {
match from {
Err(_) => OffsetMarker::default(),
Ok(table) => OffsetMarker::new(table.to_owned_obj(data)),
}
}
}
impl<T: FromObjRef<U>, U, const N: usize> FromObjRef<Option<Result<U, ReadError>>>
for NullableOffsetMarker<T, N>
{
fn from_obj_ref(from: &Option<Result<U, ReadError>>, data: FontData) -> Self {
match from {
Some(Ok(table)) => NullableOffsetMarker::new(Some(table.to_owned_obj(data))),
_ => NullableOffsetMarker::new(None),
}
}
}
impl<T: FromTableRef<U> + Default, U, const N: usize> FromTableRef<Result<U, ReadError>>
for OffsetMarker<T, N>
{
fn from_table_ref(from: &Result<U, ReadError>) -> Self {
match from {
Err(_) => OffsetMarker::default(),
Ok(table) => OffsetMarker::new(table.to_owned_table()),
}
}
}
impl<T: FromTableRef<U>, U, const N: usize> FromTableRef<Option<Result<U, ReadError>>>
for NullableOffsetMarker<T, N>
{
fn from_table_ref(from: &Option<Result<U, ReadError>>) -> Self {
match from {
Some(Ok(table)) => NullableOffsetMarker::new(Some(table.to_owned_table())),
_ => NullableOffsetMarker::new(None),
}
}
}
impl<'a, T, U, O, const N: usize> FromObjRef<ArrayOfOffsets<'a, U, O>> for Vec<OffsetMarker<T, N>>
where
T: FromObjRef<U> + Default,
U: ReadArgs + FontReadWithArgs<'a>,
U::Args: 'static,
O: Scalar + Offset,
{
fn from_obj_ref(from: &ArrayOfOffsets<'a, U, O>, data: FontData) -> Self {
from.iter()
.map(|x| OffsetMarker::from_obj_ref(&x, data))
.collect()
}
}
impl<'a, T, U, O, const N: usize> FromObjRef<ArrayOfNullableOffsets<'a, U, O>>
for Vec<NullableOffsetMarker<T, N>>
where
T: FromObjRef<U> + Default,
U: ReadArgs + FontReadWithArgs<'a>,
U::Args: 'static,
O: Scalar + Offset,
{
fn from_obj_ref(from: &ArrayOfNullableOffsets<'a, U, O>, data: FontData) -> Self {
from.iter()
.map(|x| NullableOffsetMarker::from_obj_ref(&x, data))
.collect()
}
}
impl<'a, T, U, O, const N: usize> FromTableRef<ArrayOfOffsets<'a, U, O>> for Vec<OffsetMarker<T, N>>
where
T: FromTableRef<U> + Default,
U: ReadArgs + FontReadWithArgs<'a>,
U::Args: 'static,
O: Scalar + Offset,
{
}
impl<'a, T, U, O, const N: usize> FromTableRef<ArrayOfNullableOffsets<'a, U, O>>
for Vec<NullableOffsetMarker<T, N>>
where
T: FromObjRef<U> + Default,
U: ReadArgs + FontReadWithArgs<'a>,
U::Args: 'static,
O: Scalar + Offset,
{
}