1use crate::{
2 error::{Error, Result},
3 segment::Segment,
4 Endidness,
5};
6#[cfg(not(feature = "std"))]
7use alloc::vec::Vec;
8#[cfg(feature = "std")]
9use std::path::Path;
10
11mod vec_source;
12pub use vec_source::VecSource;
13
14#[cfg(feature = "with_bytes")]
18use bytes::Bytes;
19#[cfg(feature = "with_bytes")]
20mod bytes_source;
21
22#[cfg(feature = "with_bytes")]
23pub use bytes_source::BytesSource;
24
25#[cfg(feature = "memmap")]
26mod mmap;
27#[cfg(feature = "memmap")]
28pub use mmap::MappedFileSource;
29
30#[cfg(feature = "async")]
31use async_trait::async_trait;
32
33pub trait Source: Sized + Sync + Send {
46 type Item;
48
49 fn from_vec(items: Vec<Self::Item>) -> Result<Self> {
51 Self::from_vec_with_offset(items, 0)
52 }
53
54 fn from_vec_with_offset(items: Vec<Self::Item>, initial_offset: usize) -> Result<Self>;
57
58 fn validate_offset(&self, offset: usize) -> Result<()> {
61 if offset < self.lower_offset_limit() {
62 Err(Error::OffsetTooSmall { offset })
63 } else if offset > self.upper_offset_limit() {
64 Err(Error::OffsetTooLarge { offset })
65 } else {
66 Ok(())
67 }
68 }
69
70 fn size(&self) -> usize;
74
75 fn initial_offset(&self) -> usize;
78
79 fn all(&self) -> Result<Segment<Self::Item>> {
81 self.segment(self.lower_offset_limit(), self.upper_offset_limit())
82 }
83
84 fn segment(&self, start: usize, end: usize) -> Result<Segment<Self::Item>>;
86
87 fn get_n(&self, offset: usize, num_items: usize) -> Result<Segment<Self::Item>> {
89 self.validate_offset(offset)?;
90 self.validate_offset(offset + num_items)?;
91 self.segment(offset, offset + num_items)
92 }
93
94 fn all_before(&self, offset: usize) -> Result<Segment<Self::Item>> {
96 self.validate_offset(offset)?;
97 self.get_n(self.lower_offset_limit(), offset)
98 }
99
100 fn all_after(&self, offset: usize) -> Result<Segment<Self::Item>> {
102 self.validate_offset(offset)?;
103 self.get_n(offset, self.upper_offset_limit())
104 }
105
106 #[inline]
108 fn lower_offset_limit(&self) -> usize {
109 self.initial_offset()
110 }
111
112 #[inline]
114 fn upper_offset_limit(&self) -> usize {
115 self.size() + self.initial_offset()
116 }
117}
118
119#[cfg_attr(feature = "async", async_trait)]
120pub trait U8Source: Source<Item = u8> {
123 fn endidness(&self) -> Endidness;
125
126 fn change_endidness(&mut self, endidness: Endidness);
129
130 #[inline]
134 fn from_u8_slice(slice: &[u8], endidness: Endidness) -> Result<Self> {
135 Self::from_u8_slice_with_offset(slice, 0, endidness)
136 }
137
138 fn from_u8_slice_with_offset(
142 slice: &[u8],
143 initial_offset: usize,
144 endidness: Endidness,
145 ) -> Result<Self>;
146
147 #[inline]
149 fn from_u8_vec(items: Vec<u8>, endidness: Endidness) -> Result<Self> {
150 Self::from_u8_vec_with_offset(items, 0, endidness)
151 }
152
153 #[inline]
155 fn from_u8_vec_with_offset(
156 items: Vec<u8>,
157 initial_offset: usize,
158 endidness: Endidness,
159 ) -> Result<Self> {
160 Self::from_u8_slice_with_offset(&items, initial_offset, endidness)
161 }
162
163 #[cfg(feature = "std")]
164 #[inline]
166 fn from_file<P: AsRef<Path>>(path: P, endidness: Endidness) -> Result<Self> {
167 Self::from_file_with_offset(path, 0, endidness)
168 }
169
170 #[cfg(feature = "std")]
171 fn from_file_with_offset<P: AsRef<Path>>(
173 path: P,
174 initial_offset: usize,
175 endidness: Endidness,
176 ) -> Result<Self>;
177
178 #[cfg(feature = "async")]
179 #[inline]
181 async fn from_file_async<P>(path: P, endidness: Endidness) -> Result<Self>
182 where
183 P: AsRef<Path> + Sync + Send,
184 {
185 Self::from_file_with_offset_async(path, 0, endidness).await
186 }
187
188 #[cfg(feature = "async")]
189 async fn from_file_with_offset_async<P>(
191 path: P,
192 initial_offset: usize,
193 endidness: Endidness,
194 ) -> Result<Self>
195 where
196 P: AsRef<Path> + Sync + Send;
197
198 #[cfg(feature = "with_bytes")]
199 #[inline]
201 fn from_bytes(bytes: Bytes, endidness: Endidness) -> Result<Self> {
202 Self::from_bytes_with_offset(bytes, 0, endidness)
203 }
204
205 #[cfg(feature = "with_bytes")]
206 fn from_bytes_with_offset(
208 bytes: Bytes,
209 initial_offset: usize,
210 endidness: Endidness,
211 ) -> Result<Self>;
212}