1#![doc = include_str!("../README.md")]
7
8#[cfg(test)]
9#[macro_use]
10extern crate assert_matches;
11
12use anyhow::{bail, Error, Result};
13use clap::ValueEnum;
14use std::cmp::Ordering;
15use std::fmt;
16use std::ops::{Add, AddAssign, Sub, SubAssign};
17pub mod backends;
18pub mod commands;
19pub mod creator;
20pub mod ebml;
21pub mod reader;
22pub mod updater;
23pub mod writer;
24
25#[derive(Clone, Copy, Debug, Eq, PartialEq, PartialOrd)]
26pub struct Size(pub u64);
35
36impl From<u64> for Size {
37 fn from(val: u64) -> Self {
38 Size(val)
39 }
40}
41
42impl TryInto<Size> for usize {
43 type Error = Error;
44
45 fn try_into(self) -> Result<Size, Error> {
46 Ok(Size(self.try_into()?))
47 }
48}
49
50impl fmt::Display for Size {
51 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
52 self.0.fmt(f)
53 }
54}
55
56impl Add for Size {
57 type Output = Size;
58
59 fn add(self, other: Self) -> Self {
60 let res = self
61 .0
62 .checked_add(other.0)
63 .unwrap_or_else(|| panic!("Failed to add {self} and {other}"));
64 Size(res)
65 }
66}
67
68impl AddAssign for Size {
69 fn add_assign(&mut self, other: Self) {
70 self.0 = self
71 .0
72 .checked_add(other.0)
73 .unwrap_or_else(|| panic!("Failed to add {self} and {other}"));
74 }
75}
76
77impl Sub for Size {
78 type Output = Size;
79
80 fn sub(self, other: Self) -> Self {
81 let res = self
82 .0
83 .checked_sub(other.0)
84 .unwrap_or_else(|| panic!("Failed to subtract {self} and {other}"));
85 Size(res)
86 }
87}
88
89impl SubAssign for Size {
90 fn sub_assign(&mut self, other: Self) {
91 self.0 = self
92 .0
93 .checked_sub(other.0)
94 .unwrap_or_else(|| panic!("Failed to subtract {self} and {other}"));
95 }
96}
97
98impl PartialEq<u64> for Size {
99 fn eq(&self, other: &u64) -> bool {
100 self.0 == *other
101 }
102}
103
104impl PartialEq<Size> for u64 {
105 fn eq(&self, other: &Size) -> bool {
106 *self == other.0
107 }
108}
109
110impl PartialOrd<u64> for Size {
111 fn partial_cmp(&self, other: &u64) -> Option<Ordering> {
112 self.0.partial_cmp(other)
113 }
114}
115
116#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, PartialOrd)]
117pub struct Position(pub usize);
127
128impl From<usize> for Position {
129 fn from(val: usize) -> Self {
130 Position(val)
131 }
132}
133
134impl fmt::Display for Position {
135 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
136 self.0.fmt(f)
137 }
138}
139
140impl Add<Size> for Position {
141 type Output = Position;
142
143 fn add(self, other: Size) -> Self {
144 Position(
145 self.0
146 .checked_add(other.0 as usize)
147 .unwrap_or_else(|| panic!("Failed to add {self} and {other}")),
148 )
149 }
150}
151
152impl AddAssign<Size> for Position {
153 fn add_assign(&mut self, other: Size) {
154 self.0 = self
155 .0
156 .checked_add(other.0 as usize)
157 .unwrap_or_else(|| panic!("Failed to add {self} and {other}"))
158 }
159}
160
161impl Sub<Size> for Position {
162 type Output = Position;
163
164 fn sub(self, other: Size) -> Self {
165 Position(
166 self.0
167 .checked_sub(other.0 as usize)
168 .unwrap_or_else(|| panic!("Failed to subtract {self} to {other}")),
169 )
170 }
171}
172
173impl SubAssign<Size> for Position {
174 fn sub_assign(&mut self, other: Size) {
175 self.0 = self
176 .0
177 .checked_sub(other.0 as usize)
178 .unwrap_or_else(|| panic!("Failed to subtract {self} and {other}"));
179 }
180}
181
182impl Sub for Position {
183 type Output = Size;
184
185 fn sub(self, other: Position) -> Size {
186 let res = u64::try_from(
187 self.0
188 .checked_sub(other.0)
189 .unwrap_or_else(|| panic!("Failed to subtract {self} and {other}")),
190 )
191 .unwrap_or_else(|_| panic!("Failed to convert ({self} - {other}) to u64"));
192 Size(res)
193 }
194}
195
196impl SubAssign for Position {
197 fn sub_assign(&mut self, other: Position) {
198 self.0 = self
199 .0
200 .checked_sub(other.0)
201 .unwrap_or_else(|| panic!("Failed to subtract {self} and {other}"))
202 }
203}
204
205impl PartialEq<usize> for Position {
206 fn eq(&self, other: &usize) -> bool {
207 self.0 == *other
208 }
209}
210
211impl PartialEq<Position> for usize {
212 fn eq(&self, other: &Position) -> bool {
213 *self == other.0
214 }
215}
216
217impl PartialOrd<usize> for Position {
218 fn partial_cmp(&self, other: &usize) -> Option<Ordering> {
219 self.0.partial_cmp(other)
220 }
221}
222
223#[derive(Clone, Copy, Hash, ValueEnum, Debug, PartialEq)]
226pub enum IdxDescription {
227 Sha1Fmphgo,
229
230 Sha1gitFmphgo,
232
233 Sha256Fmphgo,
235
236 Blake2Fmphgo,
238}
239
240impl IdxDescription {
241 pub const fn key_len(self) -> Size {
243 Size(match self {
244 IdxDescription::Sha1Fmphgo | IdxDescription::Sha1gitFmphgo => 20,
245 IdxDescription::Sha256Fmphgo | IdxDescription::Blake2Fmphgo => 32,
246 })
247 }
248
249 pub const fn description(self) -> &'static str {
251 match self {
252 IdxDescription::Sha1Fmphgo => "key:sha1 pkg:cargo/ph@0.10.0 swh:1:dir:795095368f036f42adebcb75782a61494940e9b8 ph::fmph::GOFunction",
253 IdxDescription::Sha1gitFmphgo => "key:sha1_git pkg:cargo/ph@0.10.0 swh:1:dir:795095368f036f42adebcb75782a61494940e9b8 ph::fmph::GOFunction",
254 IdxDescription::Sha256Fmphgo => "key:sha256 pkg:cargo/ph@0.10.0 swh:1:dir:795095368f036f42adebcb75782a61494940e9b8 ph::fmph::GOFunction",
255 IdxDescription::Blake2Fmphgo => "key:blake2s256 pkg:cargo/ph@0.10.0 swh:1:dir:795095368f036f42adebcb75782a61494940e9b8 ph::fmph::GOFunction",
256 }
257 }
258
259 pub fn from_description(description: &str) -> Result<IdxDescription> {
261 match description {
262 "key:sha1 pkg:cargo/ph@0.10.0 swh:1:dir:795095368f036f42adebcb75782a61494940e9b8 ph::fmph::GOFunction" => Ok(IdxDescription::Sha1Fmphgo),
263 "key:sha1_git pkg:cargo/ph@0.10.0 swh:1:dir:795095368f036f42adebcb75782a61494940e9b8 ph::fmph::GOFunction" => Ok(IdxDescription::Sha1gitFmphgo),
264 "key:sha256 pkg:cargo/ph@0.10.0 swh:1:dir:795095368f036f42adebcb75782a61494940e9b8 ph::fmph::GOFunction" => Ok(IdxDescription::Sha256Fmphgo),
265 "key:blake2s256 pkg:cargo/ph@0.10.0 swh:1:dir:795095368f036f42adebcb75782a61494940e9b8 ph::fmph::GOFunction" => Ok(IdxDescription::Blake2Fmphgo),
266 _ => Err(reader::MosaicReaderError::UnknownIdxDescription{ description: description.to_string() }.into())
267 }
268 }
269}
270
271impl fmt::Display for IdxDescription {
272 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
273 match self {
274 IdxDescription::Sha1Fmphgo => write!(f, "SHA1"),
275 IdxDescription::Sha1gitFmphgo => write!(f, "SHA1Git"),
276 IdxDescription::Sha256Fmphgo => write!(f, "SHA256"),
277 IdxDescription::Blake2Fmphgo => write!(f, "BLAKE2"),
278 }
279 }
280}
281
282#[derive(PartialEq, Debug, Clone, Copy)]
284pub enum CompressionMethod {
285 None,
286 Zstd,
287 ZstdDict,
288}
289
290impl fmt::Display for CompressionMethod {
291 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
292 f.write_str(String::from(*self).as_str())
293 }
294}
295
296impl From<CompressionMethod> for String {
297 fn from(val: CompressionMethod) -> Self {
298 match val {
299 CompressionMethod::None => String::from("none"),
300 CompressionMethod::Zstd => String::from("zstd"),
301 CompressionMethod::ZstdDict => String::from("zstd.dict"),
302 }
303 }
304}
305
306impl TryFrom<String> for CompressionMethod {
307 type Error = Error;
308 fn try_from(value: String) -> Result<Self, Self::Error> {
309 match value.as_str() {
310 "none" => Ok(CompressionMethod::None),
311 "zstd" => Ok(CompressionMethod::Zstd),
312 "zstd.dict" => Ok(CompressionMethod::ZstdDict),
313 _ => bail!("Unknown compression method: {}", value),
314 }
315 }
316}