#![doc = include_str!("../README.md")]
#[cfg(test)]
#[macro_use]
extern crate assert_matches;
use anyhow::{bail, Error, Result};
use clap::ValueEnum;
use std::cmp::Ordering;
use std::fmt;
use std::ops::{Add, AddAssign, Sub, SubAssign};
pub mod backends;
pub mod commands;
pub mod creator;
pub mod ebml;
pub mod reader;
pub mod updater;
pub mod writer;
#[derive(Clone, Copy, Debug, Eq, PartialEq, PartialOrd)]
pub struct Size(pub u64);
impl From<u64> for Size {
fn from(val: u64) -> Self {
Size(val)
}
}
impl TryInto<Size> for usize {
type Error = Error;
fn try_into(self) -> Result<Size, Error> {
Ok(Size(self.try_into()?))
}
}
impl fmt::Display for Size {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.0.fmt(f)
}
}
impl Add for Size {
type Output = Size;
fn add(self, other: Self) -> Self {
let res = self
.0
.checked_add(other.0)
.unwrap_or_else(|| panic!("Failed to add {self} and {other}"));
Size(res)
}
}
impl AddAssign for Size {
fn add_assign(&mut self, other: Self) {
self.0 = self
.0
.checked_add(other.0)
.unwrap_or_else(|| panic!("Failed to add {self} and {other}"));
}
}
impl Sub for Size {
type Output = Size;
fn sub(self, other: Self) -> Self {
let res = self
.0
.checked_sub(other.0)
.unwrap_or_else(|| panic!("Failed to subtract {self} and {other}"));
Size(res)
}
}
impl SubAssign for Size {
fn sub_assign(&mut self, other: Self) {
self.0 = self
.0
.checked_sub(other.0)
.unwrap_or_else(|| panic!("Failed to subtract {self} and {other}"));
}
}
impl PartialEq<u64> for Size {
fn eq(&self, other: &u64) -> bool {
self.0 == *other
}
}
impl PartialEq<Size> for u64 {
fn eq(&self, other: &Size) -> bool {
*self == other.0
}
}
impl PartialOrd<u64> for Size {
fn partial_cmp(&self, other: &u64) -> Option<Ordering> {
self.0.partial_cmp(other)
}
}
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, PartialOrd)]
pub struct Position(pub usize);
impl From<usize> for Position {
fn from(val: usize) -> Self {
Position(val)
}
}
impl fmt::Display for Position {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.0.fmt(f)
}
}
impl Add<Size> for Position {
type Output = Position;
fn add(self, other: Size) -> Self {
Position(
self.0
.checked_add(other.0 as usize)
.unwrap_or_else(|| panic!("Failed to add {self} and {other}")),
)
}
}
impl AddAssign<Size> for Position {
fn add_assign(&mut self, other: Size) {
self.0 = self
.0
.checked_add(other.0 as usize)
.unwrap_or_else(|| panic!("Failed to add {self} and {other}"))
}
}
impl Sub<Size> for Position {
type Output = Position;
fn sub(self, other: Size) -> Self {
Position(
self.0
.checked_sub(other.0 as usize)
.unwrap_or_else(|| panic!("Failed to subtract {self} to {other}")),
)
}
}
impl SubAssign<Size> for Position {
fn sub_assign(&mut self, other: Size) {
self.0 = self
.0
.checked_sub(other.0 as usize)
.unwrap_or_else(|| panic!("Failed to subtract {self} and {other}"));
}
}
impl Sub for Position {
type Output = Size;
fn sub(self, other: Position) -> Size {
let res = u64::try_from(
self.0
.checked_sub(other.0)
.unwrap_or_else(|| panic!("Failed to subtract {self} and {other}")),
)
.unwrap_or_else(|_| panic!("Failed to convert ({self} - {other}) to u64"));
Size(res)
}
}
impl SubAssign for Position {
fn sub_assign(&mut self, other: Position) {
self.0 = self
.0
.checked_sub(other.0)
.unwrap_or_else(|| panic!("Failed to subtract {self} and {other}"))
}
}
impl PartialEq<usize> for Position {
fn eq(&self, other: &usize) -> bool {
self.0 == *other
}
}
impl PartialEq<Position> for usize {
fn eq(&self, other: &Position) -> bool {
*self == other.0
}
}
impl PartialOrd<usize> for Position {
fn partial_cmp(&self, other: &usize) -> Option<Ordering> {
self.0.partial_cmp(other)
}
}
#[derive(Clone, Copy, Hash, ValueEnum, Debug, PartialEq)]
pub enum IdxDescription {
Sha1Fmphgo,
Sha1gitFmphgo,
Sha256Fmphgo,
Blake2Fmphgo,
}
impl IdxDescription {
pub const fn key_len(self) -> Size {
Size(match self {
IdxDescription::Sha1Fmphgo | IdxDescription::Sha1gitFmphgo => 20,
IdxDescription::Sha256Fmphgo | IdxDescription::Blake2Fmphgo => 32,
})
}
pub const fn description(self) -> &'static str {
match self {
IdxDescription::Sha1Fmphgo => "key:sha1 pkg:cargo/ph@0.10.0 swh:1:dir:795095368f036f42adebcb75782a61494940e9b8 ph::fmph::GOFunction",
IdxDescription::Sha1gitFmphgo => "key:sha1_git pkg:cargo/ph@0.10.0 swh:1:dir:795095368f036f42adebcb75782a61494940e9b8 ph::fmph::GOFunction",
IdxDescription::Sha256Fmphgo => "key:sha256 pkg:cargo/ph@0.10.0 swh:1:dir:795095368f036f42adebcb75782a61494940e9b8 ph::fmph::GOFunction",
IdxDescription::Blake2Fmphgo => "key:blake2s256 pkg:cargo/ph@0.10.0 swh:1:dir:795095368f036f42adebcb75782a61494940e9b8 ph::fmph::GOFunction",
}
}
pub fn from_description(description: &str) -> Result<IdxDescription> {
match description {
"key:sha1 pkg:cargo/ph@0.10.0 swh:1:dir:795095368f036f42adebcb75782a61494940e9b8 ph::fmph::GOFunction" => Ok(IdxDescription::Sha1Fmphgo),
"key:sha1_git pkg:cargo/ph@0.10.0 swh:1:dir:795095368f036f42adebcb75782a61494940e9b8 ph::fmph::GOFunction" => Ok(IdxDescription::Sha1gitFmphgo),
"key:sha256 pkg:cargo/ph@0.10.0 swh:1:dir:795095368f036f42adebcb75782a61494940e9b8 ph::fmph::GOFunction" => Ok(IdxDescription::Sha256Fmphgo),
"key:blake2s256 pkg:cargo/ph@0.10.0 swh:1:dir:795095368f036f42adebcb75782a61494940e9b8 ph::fmph::GOFunction" => Ok(IdxDescription::Blake2Fmphgo),
_ => Err(reader::MosaicReaderError::UnknownIdxDescription{ description: description.to_string() }.into())
}
}
}
impl fmt::Display for IdxDescription {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
IdxDescription::Sha1Fmphgo => write!(f, "SHA1"),
IdxDescription::Sha1gitFmphgo => write!(f, "SHA1Git"),
IdxDescription::Sha256Fmphgo => write!(f, "SHA256"),
IdxDescription::Blake2Fmphgo => write!(f, "BLAKE2"),
}
}
}
#[derive(PartialEq, Debug, Clone, Copy)]
pub enum CompressionMethod {
None,
Zstd,
ZstdDict,
}
impl fmt::Display for CompressionMethod {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str(String::from(*self).as_str())
}
}
impl From<CompressionMethod> for String {
fn from(val: CompressionMethod) -> Self {
match val {
CompressionMethod::None => String::from("none"),
CompressionMethod::Zstd => String::from("zstd"),
CompressionMethod::ZstdDict => String::from("zstd.dict"),
}
}
}
impl TryFrom<String> for CompressionMethod {
type Error = Error;
fn try_from(value: String) -> Result<Self, Self::Error> {
match value.as_str() {
"none" => Ok(CompressionMethod::None),
"zstd" => Ok(CompressionMethod::Zstd),
"zstd.dict" => Ok(CompressionMethod::ZstdDict),
_ => bail!("Unknown compression method: {}", value),
}
}
}