Skip to main content

nwnrs_resmemfile/
read.rs

1use std::{io::Cursor, sync::Arc, time::SystemTime};
2
3use nwnrs_checksums::prelude::*;
4use nwnrs_exo::prelude::*;
5use nwnrs_resman::prelude::*;
6use nwnrs_resref::prelude::*;
7use tracing::{debug, instrument};
8
9use crate::{ResMemFile, ResMemFileResult};
10
11/// Wraps owned bytes as a one-entry in-memory resource container.
12///
13/// # Errors
14///
15/// Returns [`crate::ResMemFileError`] if the resource reference is invalid.
16#[allow(clippy :: redundant_closure_call)]
match (move ||
                {

                    #[allow(unknown_lints, unreachable_code, clippy ::
                    diverging_sub_expression, clippy :: empty_loop, clippy ::
                    let_unit_value, clippy :: let_with_type_underscore, clippy
                    :: needless_return, clippy :: unreachable)]
                    if false {
                        let __tracing_attr_fake_return:
                                ResMemFileResult<ResMemFile> = loop {};
                        return __tracing_attr_fake_return;
                    }
                    {
                        let label = label.into();
                        let bytes = bytes.into();
                        let len = bytes.len();
                        let stream = shared_stream(Cursor::new(bytes));
                        let result =
                            ResMemFile {
                                label: label.clone(),
                                len,
                                entry: Res::new_with_stream(new_res_origin(::alloc::__export::must_use({
                                                ::alloc::fmt::format(format_args!("ResMemFile:{0}", label))
                                            }), label.clone()), resref, SystemTime::UNIX_EPOCH, stream,
                                    i64::try_from(len).map_err(|e|
                                                {
                                                    ResManError::Message(::alloc::__export::must_use({
                                                                ::alloc::fmt::format(format_args!("resource size exceeds i64 range: {0}",
                                                                        e))
                                                            }))
                                                })?, 0, ExoResFileCompressionType::None, None, len,
                                    EMPTY_SECURE_HASH),
                            };
                        {
                            use ::tracing::__macro_support::Callsite as _;
                            static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                                {
                                    static META: ::tracing::Metadata<'static> =
                                        {
                                            ::tracing_core::metadata::Metadata::new("event src/read.rs:45",
                                                "nwnrs_resmemfile::read", ::tracing::Level::DEBUG,
                                                ::tracing_core::__macro_support::Option::Some("src/read.rs"),
                                                ::tracing_core::__macro_support::Option::Some(45u32),
                                                ::tracing_core::__macro_support::Option::Some("nwnrs_resmemfile::read"),
                                                ::tracing_core::field::FieldSet::new(&["message",
                                                                {
                                                                    const NAME:
                                                                        ::tracing::__macro_support::FieldName<{
                                                                            ::tracing::__macro_support::FieldName::len("len")
                                                                        }> =
                                                                        ::tracing::__macro_support::FieldName::new("len");
                                                                    NAME.as_str()
                                                                }], ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                                ::tracing::metadata::Kind::EVENT)
                                        };
                                    ::tracing::callsite::DefaultCallsite::new(&META)
                                };
                            let enabled =
                                ::tracing::Level::DEBUG <=
                                            ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                        ::tracing::Level::DEBUG <=
                                            ::tracing::level_filters::LevelFilter::current() &&
                                    {
                                        let interest = __CALLSITE.interest();
                                        !interest.is_never() &&
                                            ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                                                interest)
                                    };
                            if enabled {
                                (|value_set: ::tracing::field::ValueSet|
                                            {
                                                let meta = __CALLSITE.metadata();
                                                ::tracing::Event::dispatch(meta, &value_set);
                                                ;
                                            })({
                                        #[allow(unused_imports)]
                                        use ::tracing::field::{debug, display, Value};
                                        __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("wrapped in-memory resource")
                                                                    as &dyn ::tracing::field::Value)),
                                                        (::tracing::__macro_support::Option::Some(&len as
                                                                    &dyn ::tracing::field::Value))])
                                    });
                            } else { ; }
                        };
                        Ok(result)
                    }
                })()
    {
        #[allow(clippy :: unit_arg)]
        Ok(x) => Ok(x),
    Err(e) => {
        {
            use ::tracing::__macro_support::Callsite as _;
            static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                {
                    static META: ::tracing::Metadata<'static> =
                        {
                            ::tracing_core::metadata::Metadata::new("event src/read.rs:16",
                                "nwnrs_resmemfile::read", ::tracing::Level::ERROR,
                                ::tracing_core::__macro_support::Option::Some("src/read.rs"),
                                ::tracing_core::__macro_support::Option::Some(16u32),
                                ::tracing_core::__macro_support::Option::Some("nwnrs_resmemfile::read"),
                                ::tracing_core::field::FieldSet::new(&[{
                                                    const NAME:
                                                        ::tracing::__macro_support::FieldName<{
                                                            ::tracing::__macro_support::FieldName::len("error")
                                                        }> =
                                                        ::tracing::__macro_support::FieldName::new("error");
                                                    NAME.as_str()
                                                }], ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                ::tracing::metadata::Kind::EVENT)
                        };
                    ::tracing::callsite::DefaultCallsite::new(&META)
                };
            let enabled =
                ::tracing::Level::ERROR <=
                            ::tracing::level_filters::STATIC_MAX_LEVEL &&
                        ::tracing::Level::ERROR <=
                            ::tracing::level_filters::LevelFilter::current() &&
                    {
                        let interest = __CALLSITE.interest();
                        !interest.is_never() &&
                            ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                                interest)
                    };
            if enabled {
                (|value_set: ::tracing::field::ValueSet|
                            {
                                let meta = __CALLSITE.metadata();
                                ::tracing::Event::dispatch(meta, &value_set);
                                ;
                            })({
                        #[allow(unused_imports)]
                        use ::tracing::field::{debug, display, Value};
                        __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::display(&e)
                                                    as &dyn ::tracing::field::Value))])
                    });
            } else { ; }
        };
        Err(e)
    }
}#[instrument(level = "debug", skip_all, err)]
17pub fn read_resmemfile(
18    label: impl Into<String>,
19    resref: ResRef,
20    bytes: impl Into<Vec<u8>>,
21) -> ResMemFileResult<ResMemFile> {
22    let label = label.into();
23    let bytes = bytes.into();
24    let len = bytes.len();
25    let stream = shared_stream(Cursor::new(bytes));
26
27    let result = ResMemFile {
28        label: label.clone(),
29        len,
30        entry: Res::new_with_stream(
31            new_res_origin(format!("ResMemFile:{label}"), label.clone()),
32            resref,
33            SystemTime::UNIX_EPOCH,
34            stream,
35            i64::try_from(len).map_err(|e| {
36                ResManError::Message(format!("resource size exceeds i64 range: {e}"))
37            })?,
38            0,
39            ExoResFileCompressionType::None,
40            None,
41            len,
42            EMPTY_SECURE_HASH,
43        ),
44    };
45    debug!(len, "wrapped in-memory resource");
46    Ok(result)
47}
48
49/// Wraps shared bytes as a one-entry in-memory resource container.
50///
51/// # Errors
52///
53/// Returns [`crate::ResMemFileError`] if the resource reference is invalid.
54#[allow(clippy :: redundant_closure_call)]
match (move ||
                {

                    #[allow(unknown_lints, unreachable_code, clippy ::
                    diverging_sub_expression, clippy :: empty_loop, clippy ::
                    let_unit_value, clippy :: let_with_type_underscore, clippy
                    :: needless_return, clippy :: unreachable)]
                    if false {
                        let __tracing_attr_fake_return:
                                ResMemFileResult<ResMemFile> = loop {};
                        return __tracing_attr_fake_return;
                    }
                    { read_resmemfile(label, resref, bytes.as_ref().to_vec()) }
                })()
    {
        #[allow(clippy :: unit_arg)]
        Ok(x) => Ok(x),
    Err(e) => {
        {
            use ::tracing::__macro_support::Callsite as _;
            static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                {
                    static META: ::tracing::Metadata<'static> =
                        {
                            ::tracing_core::metadata::Metadata::new("event src/read.rs:54",
                                "nwnrs_resmemfile::read", ::tracing::Level::ERROR,
                                ::tracing_core::__macro_support::Option::Some("src/read.rs"),
                                ::tracing_core::__macro_support::Option::Some(54u32),
                                ::tracing_core::__macro_support::Option::Some("nwnrs_resmemfile::read"),
                                ::tracing_core::field::FieldSet::new(&[{
                                                    const NAME:
                                                        ::tracing::__macro_support::FieldName<{
                                                            ::tracing::__macro_support::FieldName::len("error")
                                                        }> =
                                                        ::tracing::__macro_support::FieldName::new("error");
                                                    NAME.as_str()
                                                }], ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                ::tracing::metadata::Kind::EVENT)
                        };
                    ::tracing::callsite::DefaultCallsite::new(&META)
                };
            let enabled =
                ::tracing::Level::ERROR <=
                            ::tracing::level_filters::STATIC_MAX_LEVEL &&
                        ::tracing::Level::ERROR <=
                            ::tracing::level_filters::LevelFilter::current() &&
                    {
                        let interest = __CALLSITE.interest();
                        !interest.is_never() &&
                            ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                                interest)
                    };
            if enabled {
                (|value_set: ::tracing::field::ValueSet|
                            {
                                let meta = __CALLSITE.metadata();
                                ::tracing::Event::dispatch(meta, &value_set);
                                ;
                            })({
                        #[allow(unused_imports)]
                        use ::tracing::field::{debug, display, Value};
                        __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::display(&e)
                                                    as &dyn ::tracing::field::Value))])
                    });
            } else { ; }
        };
        Err(e)
    }
}#[instrument(level = "debug", skip_all, err)]
55pub fn read_resmemfile_arc(
56    label: impl Into<String>,
57    resref: ResRef,
58    bytes: Arc<[u8]>,
59) -> ResMemFileResult<ResMemFile> {
60    read_resmemfile(label, resref, bytes.as_ref().to_vec())
61}
62
63#[allow(clippy::panic)]
64#[cfg(test)]
65mod tests {
66    use std::sync::Arc;
67
68    use nwnrs_resman::{CachePolicy, ResContainer};
69    use nwnrs_resref::ResRef;
70    use nwnrs_restype::ResType;
71
72    use crate::{read_resmemfile, read_resmemfile_arc};
73
74    #[test]
75    fn wraps_owned_bytes_as_resource_container() {
76        let rr = match ResRef::new("alpha", ResType(2027)) {
77            Ok(value) => value,
78            Err(error) => panic!("alpha rr: {error}"),
79        };
80        let resmem = match read_resmemfile("mem", rr.clone(), b"payload".to_vec()) {
81            Ok(value) => value,
82            Err(error) => panic!("read resmemfile: {error}"),
83        };
84        assert_eq!(resmem.len(), 7);
85        assert!(!resmem.is_empty());
86        assert!(resmem.contains(&rr));
87        let bytes = match resmem.res().read_all(CachePolicy::Bypass) {
88            Ok(value) => value,
89            Err(error) => panic!("read payload: {error}"),
90        };
91        assert_eq!(bytes, b"payload".to_vec());
92    }
93
94    #[test]
95    fn wraps_shared_bytes_without_changing_contents() {
96        let rr = match ResRef::new("beta", ResType(2027)) {
97            Ok(value) => value,
98            Err(error) => panic!("beta rr: {error}"),
99        };
100        let resmem = match read_resmemfile_arc("mem-arc", rr, Arc::from(&b"arc"[..])) {
101            Ok(value) => value,
102            Err(error) => panic!("read resmemfile arc: {error}"),
103        };
104        let bytes = match resmem.res().read_all(CachePolicy::Bypass) {
105            Ok(value) => value,
106            Err(error) => panic!("read shared payload: {error}"),
107        };
108        assert_eq!(bytes, b"arc".to_vec());
109    }
110}