Skip to main content

nwnrs_resfile/
types.rs

1use std::{
2    fmt, io,
3    path::{Path, PathBuf},
4};
5
6use nwnrs_resman::prelude::*;
7use nwnrs_resref::prelude::*;
8
9/// Errors returned while reading a single-file resource container.
10#[derive(#[automatically_derived]
impl ::core::fmt::Debug for ResFileError {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            ResFileError::Io(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Io",
                    &__self_0),
            ResFileError::ResMan(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "ResMan",
                    &__self_0),
            ResFileError::ResRef(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "ResRef",
                    &__self_0),
            ResFileError::Message(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "Message", &__self_0),
        }
    }
}Debug)]
11pub enum ResFileError {
12    /// Filesystem access failed.
13    Io(io::Error),
14    /// Resource manager setup failed.
15    ResMan(ResManError),
16    /// Resource reference parsing failed.
17    ResRef(nwnrs_resref::ResRefError),
18    /// The input path was invalid.
19    Message(String),
20}
21
22impl ResFileError {
23    pub(crate) fn msg(message: impl Into<String>) -> Self {
24        Self::Message(message.into())
25    }
26}
27
28impl fmt::Display for ResFileError {
29    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
30        match self {
31            Self::Io(error) => error.fmt(f),
32            Self::ResMan(error) => error.fmt(f),
33            Self::ResRef(error) => error.fmt(f),
34            Self::Message(message) => f.write_str(message),
35        }
36    }
37}
38
39impl std::error::Error for ResFileError {}
40
41impl From<io::Error> for ResFileError {
42    fn from(value: io::Error) -> Self {
43        Self::Io(value)
44    }
45}
46
47impl From<ResManError> for ResFileError {
48    fn from(value: ResManError) -> Self {
49        Self::ResMan(value)
50    }
51}
52
53impl From<nwnrs_resref::ResRefError> for ResFileError {
54    fn from(value: nwnrs_resref::ResRefError) -> Self {
55        Self::ResRef(value)
56    }
57}
58
59/// A single file exposed as a one-entry resource container.
60#[derive(#[automatically_derived]
impl ::core::fmt::Debug for ResFile {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field3_finish(f, "ResFile",
            "path", &self.path, "label", &self.label, "entry", &&self.entry)
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for ResFile {
    #[inline]
    fn clone(&self) -> ResFile {
        ResFile {
            path: ::core::clone::Clone::clone(&self.path),
            label: ::core::clone::Clone::clone(&self.label),
            entry: ::core::clone::Clone::clone(&self.entry),
        }
    }
}Clone)]
61pub struct ResFile {
62    pub(crate) path:  PathBuf,
63    pub(crate) label: String,
64    pub(crate) entry: Res,
65}
66
67impl ResFile {
68    /// Returns the underlying file path.
69    #[must_use]
70    pub fn path(&self) -> &Path {
71        &self.path
72    }
73
74    /// Returns the display label used for this container.
75    #[must_use]
76    pub fn label(&self) -> &str {
77        &self.label
78    }
79
80    /// Returns the contained resource entry.
81    #[must_use]
82    pub fn res(&self) -> Res {
83        self.entry.clone()
84    }
85}
86
87impl fmt::Display for ResFile {
88    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
89        f.write_fmt(format_args!("ResFile:{0}", self.label))write!(f, "ResFile:{}", self.label)
90    }
91}
92
93impl ResContainer for ResFile {
94    fn contains(&self, rr: &ResRef) -> bool {
95        self.entry.resref() == *rr
96    }
97
98    fn demand(&self, rr: &ResRef) -> ResManResult<Res> {
99        if self.contains(rr) {
100            Ok(self.entry.clone())
101        } else {
102            Err(ResManError::Message(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("not found: {0}", rr))
    })format!("not found: {rr}")))
103        }
104    }
105
106    fn count(&self) -> usize {
107        1
108    }
109
110    fn contents(&self) -> Vec<ResRef> {
111        ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [self.entry.resref()]))vec![self.entry.resref()]
112    }
113}
114
115/// Result type for single-file resource operations.
116pub type ResFileResult<T> = Result<T, ResFileError>;