hff_core/write/
data_source.rs1use crate::{Error, Result};
2use std::{
3 fmt::Debug,
4 fs::File,
5 path::{Path, PathBuf},
6};
7
8#[derive(Debug)]
10pub enum DataSource<'a> {
11 Owned(Vec<u8>),
13 Ref(&'a [u8]),
15 File(File, u64),
17 #[cfg(feature = "compression")]
19 Compressed(u32, Option<Box<DataSource<'a>>>, Option<Vec<u8>>),
20}
21
22impl<'a> DataSource<'a> {
23 pub fn owned(data: impl Into<Vec<u8>>) -> Self {
25 Self::Owned(data.into())
26 }
27
28 pub fn reference(data: &'a [u8]) -> Self {
30 Self::Ref(data)
31 }
32
33 pub fn file(source: File, len: u64) -> Self {
35 Self::File(source, len)
36 }
37
38 #[cfg(feature = "compression")]
40 pub fn compressed(level: u32, source: DataSource<'a>) -> Self {
41 Self::Compressed(level, Some(Box::new(source)), None)
42 }
43
44 pub fn len(&self) -> Option<usize> {
46 match self {
47 Self::Owned(d) => Some(d.len()),
48 Self::Ref(d) => Some(d.len()),
49 Self::File(_, l) => Some(*l as usize),
50 #[cfg(feature = "compression")]
51 Self::Compressed(_, _, data) => {
52 if let Some(data) = data {
53 Some(data.len())
54 } else {
55 None
56 }
57 }
58 }
59 }
60
61 pub fn prepare(&mut self) -> Result<u64> {
65 match self {
66 #[cfg(feature = "compression")]
67 Self::Compressed(level, source, data) => {
68 if let Some(source) = source.take() {
72 let source = *source;
73 match source {
74 DataSource::Owned(d) => *data = Some(d),
75 DataSource::Ref(d) => *data = Some(d.into()),
76 DataSource::File(mut f, _) => {
77 let mut buffer = vec![];
78 std::io::copy(&mut f, &mut buffer)?;
79 *data = Some(buffer);
80 }
81 _ => panic!(
82 "Invalid data source. Compressing compressed data for instance."
83 ),
84 }
85 } else {
86 if let Some(data) = data {
88 return Ok(data.len() as u64);
89 } else {
90 return Err(Error::Invalid(
91 "Internal error dealing with compressed data.".into(),
92 ));
93 }
94 };
95
96 let mut encoder = xz2::write::XzEncoder::new(vec![], (*level).min(9));
98 let source = data.take().unwrap();
99 std::io::copy(&mut source.as_slice(), &mut encoder)?;
100 *data = Some(encoder.finish()?);
101
102 Ok(data.as_ref().unwrap().len() as u64)
103 }
104 _ => Ok(self.len().unwrap() as u64),
106 }
107 }
108}
109
110impl<'a> TryInto<DataSource<'a>> for &str {
111 type Error = Error;
112
113 fn try_into(self) -> std::prelude::v1::Result<DataSource<'a>, Self::Error> {
114 Ok(DataSource::Owned(self.as_bytes().into()))
115 }
116}
117
118impl<'a> TryInto<DataSource<'a>> for String {
119 type Error = Error;
120
121 fn try_into(self) -> std::prelude::v1::Result<DataSource<'a>, Self::Error> {
122 Ok(DataSource::Owned(self.as_bytes().into()))
123 }
124}
125
126impl<'a> TryInto<DataSource<'a>> for &[u8] {
127 type Error = Error;
128
129 fn try_into(self) -> std::prelude::v1::Result<DataSource<'a>, Self::Error> {
130 Ok(DataSource::Owned(self.into()))
131 }
132}
133
134impl<'a> TryInto<DataSource<'a>> for Vec<u8> {
135 type Error = Error;
136
137 fn try_into(self) -> std::prelude::v1::Result<DataSource<'a>, Self::Error> {
138 Ok(DataSource::Owned(self))
139 }
140}
141
142impl<'a> TryInto<DataSource<'a>> for &Path {
143 type Error = Error;
144
145 fn try_into(self) -> std::prelude::v1::Result<DataSource<'a>, Self::Error> {
146 let file = std::fs::File::open(self)?;
147 let length = file.metadata()?.len();
148 Ok(DataSource::File(file, length))
149 }
150}
151
152impl<'a> TryInto<DataSource<'a>> for PathBuf {
153 type Error = Error;
154
155 fn try_into(self) -> std::prelude::v1::Result<DataSource<'a>, Self::Error> {
156 let file = std::fs::File::open(&self)?;
157 let length = file.metadata()?.len();
158 Ok(DataSource::File(file, length))
159 }
160}
161
162#[cfg(feature = "compression")]
163impl<'a, T> TryInto<DataSource<'a>> for (u32, T)
164where
165 T: TryInto<DataSource<'a>>,
166 <T as TryInto<DataSource<'a>>>::Error: std::fmt::Debug,
167 Error: From<<T as TryInto<DataSource<'a>>>::Error>,
168{
169 type Error = Error;
170
171 fn try_into(self) -> std::prelude::v1::Result<DataSource<'a>, Self::Error> {
172 Ok(DataSource::Compressed(
173 self.0,
174 Some(Box::new(self.1.try_into()?)),
175 None,
176 ))
177 }
178}