horntail/entry/
accessor.rs1use 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}