1use alloc::{string::String, vec::Vec};
4
5use thiserror::Error;
6
7use crate::{flag::types::M2dirFlags, path::M2dirPath};
8
9#[derive(Clone, Debug, Error)]
12pub enum ParseFilenameError {
13 #[error("path {0} is not a regular file")]
15 NotFile(M2dirPath),
16 #[error("path {0} is missing a filename")]
18 MissingFilename(M2dirPath),
19 #[error("entry {path} does not match filename spec: {reason}")]
21 InvalidFilename {
22 path: M2dirPath,
23 reason: &'static str,
24 },
25 #[error("invalid checksum for {path}: expected {expected:?}, got {got:?}")]
28 InvalidChecksum {
29 path: M2dirPath,
30 expected: String,
31 got: String,
32 },
33}
34
35#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
37pub struct M2dirEntry {
38 id: String,
39 path: M2dirPath,
40}
41
42impl M2dirEntry {
43 pub fn from_parts(id: impl Into<String>, path: impl Into<M2dirPath>) -> Self {
47 Self {
48 id: id.into(),
49 path: path.into(),
50 }
51 }
52
53 pub fn path(&self) -> &M2dirPath {
55 &self.path
56 }
57
58 pub fn id(&self) -> &str {
61 &self.id
62 }
63
64 pub fn checksum(&self) -> &str {
67 self.id.rsplit_once('.').map(|(c, _)| c).unwrap_or(&self.id)
68 }
69}
70
71#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
75pub struct M2dirFullEntry {
76 entry: M2dirEntry,
77 contents: Vec<u8>,
78 flags: M2dirFlags,
79}
80
81impl M2dirFullEntry {
82 pub fn from_parts(entry: M2dirEntry, contents: Vec<u8>, flags: M2dirFlags) -> Self {
83 Self {
84 entry,
85 contents,
86 flags,
87 }
88 }
89
90 pub fn entry(&self) -> &M2dirEntry {
91 &self.entry
92 }
93
94 pub fn contents(&self) -> &[u8] {
95 &self.contents
96 }
97
98 pub fn flags(&self) -> &M2dirFlags {
99 &self.flags
100 }
101}