iroh_blobs/util/
mem_or_file.rs1use std::{fs::File, io};
2
3use bao_tree::io::sync::{ReadAt, Size};
4use bytes::Bytes;
5
6#[derive(Debug)]
10pub enum MemOrFile<M, F> {
11 Mem(M),
13 File(F),
15}
16
17impl<M, F> MemOrFile<M, (F, u64)>
20where
21 M: AsRef<[u8]>,
22{
23 pub fn size(&self) -> u64 {
25 match self {
26 MemOrFile::Mem(mem) => mem.as_ref().len() as u64,
27 MemOrFile::File((_, size)) => *size,
28 }
29 }
30}
31
32impl ReadAt for MemOrFile<Bytes, File> {
33 fn read_at(&self, offset: u64, buf: &mut [u8]) -> io::Result<usize> {
34 match self {
35 MemOrFile::Mem(mem) => mem.as_ref().read_at(offset, buf),
36 MemOrFile::File(file) => file.read_at(offset, buf),
37 }
38 }
39}
40
41impl Size for MemOrFile<Bytes, File> {
42 fn size(&self) -> io::Result<Option<u64>> {
43 match self {
44 MemOrFile::Mem(mem) => Ok(Some(mem.len() as u64)),
45 MemOrFile::File(file) => file.size(),
46 }
47 }
48}
49
50impl<M: Default, F> Default for MemOrFile<M, F> {
51 fn default() -> Self {
52 MemOrFile::Mem(Default::default())
53 }
54}
55
56impl<M, F> MemOrFile<M, F> {
57 pub fn as_ref(&self) -> MemOrFile<&M, &F> {
59 match self {
60 MemOrFile::Mem(mem) => MemOrFile::Mem(mem),
61 MemOrFile::File(file) => MemOrFile::File(file),
62 }
63 }
64
65 pub fn is_mem(&self) -> bool {
67 matches!(self, MemOrFile::Mem(_))
68 }
69
70 pub fn mem(&self) -> Option<&M> {
72 match self {
73 MemOrFile::Mem(mem) => Some(mem),
74 MemOrFile::File(_) => None,
75 }
76 }
77
78 pub fn map_file<F2>(self, f: impl FnOnce(F) -> F2) -> MemOrFile<M, F2> {
80 match self {
81 MemOrFile::Mem(mem) => MemOrFile::Mem(mem),
82 MemOrFile::File(file) => MemOrFile::File(f(file)),
83 }
84 }
85
86 pub fn try_map_file<F2, E>(
88 self,
89 f: impl FnOnce(F) -> Result<F2, E>,
90 ) -> Result<MemOrFile<M, F2>, E> {
91 match self {
92 MemOrFile::Mem(mem) => Ok(MemOrFile::Mem(mem)),
93 MemOrFile::File(file) => f(file).map(MemOrFile::File),
94 }
95 }
96
97 pub fn map_mem<M2>(self, f: impl FnOnce(M) -> M2) -> MemOrFile<M2, F> {
99 match self {
100 MemOrFile::Mem(mem) => MemOrFile::Mem(f(mem)),
101 MemOrFile::File(file) => MemOrFile::File(file),
102 }
103 }
104}