Skip to main content

io_m2dir/entry/
types.rs

1//! Single m2dir entry: id, path, checksum helpers.
2
3use alloc::{string::String, vec::Vec};
4
5use thiserror::Error;
6
7use crate::{flag::types::M2dirFlags, path::M2dirPath};
8
9/// Errors that can occur while parsing or validating an entry
10/// filename.
11#[derive(Clone, Debug, Error)]
12pub enum ParseFilenameError {
13    /// The given path is not a regular file.
14    #[error("path {0} is not a regular file")]
15    NotFile(M2dirPath),
16    /// The path has no final filename component.
17    #[error("path {0} is missing a filename")]
18    MissingFilename(M2dirPath),
19    /// The filename does not match the m2dir specification.
20    #[error("entry {path} does not match filename spec: {reason}")]
21    InvalidFilename {
22        path: M2dirPath,
23        reason: &'static str,
24    },
25    /// The checksum embedded in the filename does not match the file
26    /// contents.
27    #[error("invalid checksum for {path}: expected {expected:?}, got {got:?}")]
28    InvalidChecksum {
29        path: M2dirPath,
30        expected: String,
31        got: String,
32    },
33}
34
35/// A single entry inside an [`crate::m2dir::types::M2dir`].
36#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
37pub struct M2dirEntry {
38    id: String,
39    path: M2dirPath,
40}
41
42impl M2dirEntry {
43    /// Builds an [`M2dirEntry`] from a path and its unique id without
44    /// checking the on-disk checksum. Used by coroutines that have
45    /// just delivered the entry and trust their own checksum.
46    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    /// Returns the path to the entry file.
54    pub fn path(&self) -> &M2dirPath {
55        &self.path
56    }
57
58    /// Returns the unique identifier of the entry (the
59    /// `<checksum>.<nonce>` portion of the filename).
60    pub fn id(&self) -> &str {
61        &self.id
62    }
63
64    /// Returns the checksum portion of the id (the chunk before the
65    /// last `.`).
66    pub fn checksum(&self) -> &str {
67        self.id.rsplit_once('.').map(|(c, _)| c).unwrap_or(&self.id)
68    }
69}
70
71/// An [`M2dirEntry`] paired with its file contents and flags
72/// metadata, as produced by the bulk reads on
73/// [`M2dirClient`](crate::client::M2dirClient).
74#[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}