keramics_formats/
os_file_resolver.rs

1/* Copyright 2024-2025 Joachim Metz <joachim.metz@gmail.com>
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License. You may
5 * obtain a copy of the License at https://www.apache.org/licenses/LICENSE-2.0
6 *
7 * Unless required by applicable law or agreed to in writing, software
8 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10 * License for the specific language governing permissions and limitations
11 * under the License.
12 */
13
14use std::path::PathBuf;
15
16use keramics_core::{DataStreamReference, ErrorTrace, open_os_data_stream};
17
18use super::file_resolver::{FileResolver, FileResolverReference};
19use super::path_component::PathComponent;
20
21pub struct OsFileResolver {
22    /// Base path.
23    base_path: PathBuf,
24}
25
26impl OsFileResolver {
27    /// Creates a new file resolver.
28    pub fn new(base_path: PathBuf) -> Self {
29        Self {
30            base_path: base_path,
31        }
32    }
33}
34
35impl FileResolver for OsFileResolver {
36    /// Retrieves a data stream with the specified path.
37    fn get_data_stream(
38        &self,
39        path_components: &[PathComponent],
40    ) -> Result<Option<DataStreamReference>, ErrorTrace> {
41        let mut path_buf: PathBuf = self.base_path.clone();
42
43        for path_component in path_components.iter() {
44            match path_component {
45                PathComponent::String(string) => {
46                    path_buf.push(string);
47                }
48                _ => {
49                    return Err(keramics_core::error_trace_new!(
50                        "Unsupported path component"
51                    ));
52                }
53            }
54        }
55        let data_stream: DataStreamReference = match open_os_data_stream(&path_buf) {
56            Ok(data_stream) => data_stream,
57            Err(error) => {
58                return Err(keramics_core::error_trace_new_with_error!(
59                    "Unable to open data stream with error",
60                    error
61                ));
62            }
63        };
64        Ok(Some(data_stream))
65    }
66}
67
68/// Opens a new operating system file resolver.
69pub fn open_os_file_resolver(base_path: &PathBuf) -> Result<FileResolverReference, ErrorTrace> {
70    let file_resolver: OsFileResolver = OsFileResolver::new(base_path.clone());
71
72    Ok(FileResolverReference::new(Box::new(file_resolver)))
73}
74
75#[cfg(test)]
76mod tests {
77    use super::*;
78
79    use std::path::PathBuf;
80
81    #[test]
82    fn test_get_data_stream() -> Result<(), ErrorTrace> {
83        let path_buf: PathBuf = PathBuf::from("../test_data/");
84        let file_resolver: OsFileResolver = OsFileResolver::new(path_buf);
85
86        let path_components: [PathComponent; 1] = [PathComponent::from("file.txt")];
87
88        let data_stream: Option<DataStreamReference> =
89            file_resolver.get_data_stream(&path_components)?;
90        assert!(data_stream.is_some());
91
92        Ok(())
93    }
94
95    #[test]
96    fn test_open_os_file_resolver() -> Result<(), ErrorTrace> {
97        let path_buf: PathBuf = PathBuf::from("../test_data/");
98        let _ = open_os_file_resolver(&path_buf)?;
99
100        Ok(())
101    }
102}