Skip to main content

horntail/entry/
accessor.rs

1use crate::reader::Accessor;
2use std::io::SeekFrom;
3
4pub trait AccessorBuilder {
5    fn into_boxed(self) -> Box<dyn AccessorBuilder>
6    where
7        Self: Sized + 'static,
8    {
9        Box::new(self)
10    }
11
12    fn clone_boxed(&self) -> Box<dyn AccessorBuilder>;
13
14    fn accessor(&self) -> Box<dyn Accessor>;
15}
16
17#[derive(Default, Debug, Copy, Clone)]
18pub struct AccessorOpt {
19    pub offset: usize,
20    pub ver_hash: u16,
21    pub parent_offset: usize,
22}
23
24impl AccessorOpt {
25    pub fn clone_with(&self, offset: usize) -> AccessorOpt {
26        AccessorOpt {
27            ver_hash: self.ver_hash,
28            parent_offset: self.parent_offset,
29            offset,
30        }
31    }
32
33    #[inline]
34    pub fn clone_with_parent(&self, offset: usize, parent_offset: usize) -> AccessorOpt {
35        AccessorOpt {
36            ver_hash: self.ver_hash,
37            parent_offset,
38            offset,
39        }
40    }
41
42    pub fn accessor(&self, builder: &dyn AccessorBuilder) -> Box<dyn Accessor> {
43        let mut accessor = builder.accessor();
44        accessor.seek(SeekFrom::Start(self.offset as u64));
45        accessor
46    }
47}
48
49pub trait FromBuilder {
50    fn from_builder(opt: AccessorOpt, builder: &dyn AccessorBuilder) -> Self;
51}
52
53impl<T> FromBuilder for T
54where
55    T: TryFromBuilder,
56    T::Error: std::fmt::Display,
57{
58    fn from_builder(opt: AccessorOpt, builder: &dyn AccessorBuilder) -> Self {
59        T::try_from_builder(opt, builder).unwrap_or_else(|e| panic!("from builder: {e}"))
60    }
61}
62
63pub trait FromAccessor {
64    fn from_accessor(opt: AccessorOpt, builder: &mut dyn Accessor) -> Self;
65}
66
67impl<T> FromAccessor for T
68where
69    T: TryFromAccessor,
70    T::Error: std::fmt::Display,
71{
72    fn from_accessor(opt: AccessorOpt, accessor: &mut dyn Accessor) -> Self {
73        T::try_from_accessor(opt, accessor).unwrap_or_else(|e| panic!("from accessor: {e}"))
74    }
75}
76
77pub trait TryFromBuilder: Sized {
78    type Error;
79
80    fn try_from_builder(
81        opt: AccessorOpt,
82        builder: &dyn AccessorBuilder,
83    ) -> Result<Self, Self::Error>;
84}
85
86impl<T> TryFromBuilder for T
87where
88    T: TryFromAccessor,
89    T::Error: std::fmt::Display,
90{
91    type Error = T::Error;
92
93    fn try_from_builder(
94        opt: AccessorOpt,
95        builder: &dyn AccessorBuilder,
96    ) -> Result<Self, Self::Error> {
97        let mut accessor = opt.accessor(builder);
98        Self::try_from_accessor(opt, accessor.as_mut())
99    }
100}
101
102pub trait TryFromAccessor: Sized {
103    type Error;
104
105    fn try_from_accessor(
106        opt: AccessorOpt,
107        accessor: &mut dyn Accessor,
108    ) -> Result<Self, Self::Error>;
109}