1#![cfg_attr(docsrs, feature(doc_auto_cfg))]
35#![warn(missing_docs)]
36
37#[cfg(target_arch = "wasm32")]
38extern crate wasm_bindgen;
39
40#[cfg(feature = "compress")]
41mod encoder;
42#[cfg(feature = "compress")]
44pub mod encoder_options;
45mod encryption;
46mod error;
47mod reader;
48
49#[cfg(feature = "compress")]
50mod writer;
51
52pub(crate) mod archive;
53pub(crate) mod bitset;
54pub(crate) mod block;
55mod codec;
56pub(crate) mod decoder;
57
58mod time;
59#[cfg(feature = "util")]
60mod util;
61
62use std::{
63 io::{Read, Write},
64 ops::{Deref, DerefMut},
65};
66
67pub use archive::*;
68pub use block::*;
69pub use encryption::Password;
70pub use error::Error;
71pub use reader::{ArchiveReader, BlockDecoder};
72pub use time::NtTime;
73#[cfg(all(feature = "compress", feature = "util", not(target_arch = "wasm32")))]
74pub use util::compress::*;
75#[cfg(all(feature = "util", not(target_arch = "wasm32")))]
76pub use util::decompress::*;
77#[cfg(all(feature = "util", target_arch = "wasm32"))]
78pub use util::wasm::*;
79#[cfg(feature = "compress")]
80pub use writer::*;
81
82trait ByteReader {
83 fn read_u8(&mut self) -> std::io::Result<u8>;
84
85 #[cfg(feature = "brotli")]
86 fn read_u16(&mut self) -> std::io::Result<u16>;
87
88 fn read_u32(&mut self) -> std::io::Result<u32>;
89
90 fn read_u64(&mut self) -> std::io::Result<u64>;
91}
92
93trait ByteWriter {
94 #[cfg(feature = "compress")]
95 fn write_u8(&mut self, value: u8) -> std::io::Result<()>;
96
97 fn write_u16(&mut self, value: u16) -> std::io::Result<()>;
98
99 #[cfg(feature = "compress")]
100 fn write_u32(&mut self, value: u32) -> std::io::Result<()>;
101
102 #[cfg(feature = "compress")]
103 fn write_u64(&mut self, value: u64) -> std::io::Result<()>;
104}
105
106impl<T: Read> ByteReader for T {
107 #[inline(always)]
108 fn read_u8(&mut self) -> std::io::Result<u8> {
109 let mut buf = [0; 1];
110 self.read_exact(&mut buf)?;
111 Ok(buf[0])
112 }
113
114 #[cfg(feature = "brotli")]
115 #[inline(always)]
116 fn read_u16(&mut self) -> std::io::Result<u16> {
117 let mut buf = [0; 2];
118 self.read_exact(buf.as_mut())?;
119 Ok(u16::from_le_bytes(buf))
120 }
121
122 #[inline(always)]
123 fn read_u32(&mut self) -> std::io::Result<u32> {
124 let mut buf = [0; 4];
125 self.read_exact(buf.as_mut())?;
126 Ok(u32::from_le_bytes(buf))
127 }
128
129 #[inline(always)]
130 fn read_u64(&mut self) -> std::io::Result<u64> {
131 let mut buf = [0; 8];
132 self.read_exact(buf.as_mut())?;
133 Ok(u64::from_le_bytes(buf))
134 }
135}
136
137impl<T: Write> ByteWriter for T {
138 #[cfg(feature = "compress")]
139 #[inline(always)]
140 fn write_u8(&mut self, value: u8) -> std::io::Result<()> {
141 self.write_all(&[value])
142 }
143
144 #[inline(always)]
145 fn write_u16(&mut self, value: u16) -> std::io::Result<()> {
146 self.write_all(&value.to_le_bytes())
147 }
148
149 #[cfg(feature = "compress")]
150 #[inline(always)]
151 fn write_u32(&mut self, value: u32) -> std::io::Result<()> {
152 self.write_all(&value.to_le_bytes())
153 }
154
155 #[cfg(feature = "compress")]
156 #[inline(always)]
157 fn write_u64(&mut self, value: u64) -> std::io::Result<()> {
158 self.write_all(&value.to_le_bytes())
159 }
160}
161
162trait AutoFinish {
164 fn finish_ignore_error(self);
166}
167
168#[allow(private_bounds)]
170pub struct AutoFinisher<T: AutoFinish>(Option<T>);
171
172impl<T: AutoFinish> Drop for AutoFinisher<T> {
173 fn drop(&mut self) {
174 if let Some(writer) = self.0.take() {
175 writer.finish_ignore_error();
176 }
177 }
178}
179
180impl<T: AutoFinish> Deref for AutoFinisher<T> {
181 type Target = T;
182
183 fn deref(&self) -> &Self::Target {
184 self.0.as_ref().unwrap()
185 }
186}
187
188impl<T: AutoFinish> DerefMut for AutoFinisher<T> {
189 fn deref_mut(&mut self) -> &mut Self::Target {
190 self.0.as_mut().unwrap()
191 }
192}