qubit_fs/provider/file_resource.rs
1/*******************************************************************************
2 *
3 * Copyright (c) 2026 Haixing Hu.
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0.
8 *
9 ******************************************************************************/
10//! Bound filesystem resource.
11
12use std::sync::Arc;
13
14use crate::{
15 CopyOptions,
16 CopyOutcome,
17 CreateDirOptions,
18 DeleteOptions,
19 DirectoryStream,
20 FileMetadata,
21 FileReader,
22 FileSystem,
23 FileSystemExt,
24 FileWriter,
25 FsPath,
26 FsResult,
27 ListOptions,
28 ReadOptions,
29 RenameOptions,
30 WriteOptions,
31 WriteOutcome,
32};
33
34/// A filesystem path bound to the filesystem that owns it.
35///
36/// `FileResource` is the high-level resource object returned by
37/// [`FileSystems::resource`](crate::FileSystems::resource) and
38/// [`FileSystemRegistry::resource`](crate::FileSystemRegistry::resource). It
39/// keeps path operations close to the resolved filesystem without making
40/// [`FsPath`](crate::FsPath) itself carry any backend state.
41#[derive(Debug, Clone)]
42pub struct FileResource {
43 fs: Arc<dyn FileSystem>,
44 path: FsPath,
45}
46
47impl FileResource {
48 /// Creates a new filesystem resource.
49 ///
50 /// # Parameters
51 /// - `fs`: Filesystem instance that owns the path.
52 /// - `path`: Filesystem-local path.
53 ///
54 /// # Returns
55 /// A resource bound to the supplied filesystem and path.
56 #[must_use]
57 pub fn new(fs: Arc<dyn FileSystem>, path: FsPath) -> Self {
58 Self { fs, path }
59 }
60
61 /// Returns the filesystem that owns this resource.
62 ///
63 /// # Returns
64 /// A shared reference to the owning filesystem.
65 #[must_use]
66 pub fn fs(&self) -> &dyn FileSystem {
67 self.fs.as_ref()
68 }
69
70 /// Returns the filesystem-local path of this resource.
71 ///
72 /// # Returns
73 /// A shared reference to the filesystem-local path.
74 #[must_use]
75 pub fn path(&self) -> &FsPath {
76 &self.path
77 }
78
79 /// Reads metadata for this resource.
80 ///
81 /// # Returns
82 /// File metadata for this resource.
83 ///
84 /// # Errors
85 /// Returns an error when the owning filesystem cannot read metadata for the
86 /// resource path.
87 pub fn metadata(&self) -> FsResult<FileMetadata> {
88 self.fs.path_metadata(&self.path)
89 }
90
91 /// Checks whether this resource exists.
92 ///
93 /// # Returns
94 /// `true` when the resource exists.
95 ///
96 /// # Errors
97 /// Returns an error when the owning filesystem cannot determine existence
98 /// for the resource path.
99 pub fn exists(&self) -> FsResult<bool> {
100 self.fs.exists(&self.path)
101 }
102
103 /// Lists child entries under this resource.
104 ///
105 /// # Parameters
106 /// - `options`: Listing options.
107 ///
108 /// # Returns
109 /// A directory stream for the resource path.
110 ///
111 /// # Errors
112 /// Returns an error when the owning filesystem cannot open a directory
113 /// stream for the resource path.
114 pub fn list(&self, options: &ListOptions) -> FsResult<Box<dyn DirectoryStream>> {
115 self.fs.list(&self.path, options)
116 }
117
118 /// Opens this resource for reading.
119 ///
120 /// # Parameters
121 /// - `options`: Read options.
122 ///
123 /// # Returns
124 /// A file reader for the resource path.
125 ///
126 /// # Errors
127 /// Returns an error when the owning filesystem cannot open the resource for
128 /// reading.
129 pub fn open_reader(&self, options: &ReadOptions) -> FsResult<Box<dyn FileReader>> {
130 self.fs.open_reader(&self.path, options)
131 }
132
133 /// Opens this resource for writing.
134 ///
135 /// # Parameters
136 /// - `options`: Write options.
137 ///
138 /// # Returns
139 /// A file writer for the resource path.
140 ///
141 /// # Errors
142 /// Returns an error when the owning filesystem cannot open the resource for
143 /// writing.
144 pub fn open_writer(&self, options: &WriteOptions) -> FsResult<Box<dyn FileWriter>> {
145 self.fs.open_writer(&self.path, options)
146 }
147
148 /// Reads this resource into memory.
149 ///
150 /// # Returns
151 /// The complete byte content of this resource.
152 ///
153 /// # Errors
154 /// Returns an error when the owning filesystem cannot open or read the
155 /// resource.
156 pub fn read_all(&self) -> FsResult<Vec<u8>> {
157 self.fs.read_all(&self.path)
158 }
159
160 /// Writes all bytes to this resource.
161 ///
162 /// # Parameters
163 /// - `bytes`: Complete byte content to write.
164 ///
165 /// # Returns
166 /// Write outcome reported by the owning filesystem.
167 ///
168 /// # Errors
169 /// Returns an error when the owning filesystem cannot open, write, flush, or
170 /// commit the resource.
171 pub fn write_all(&self, bytes: &[u8]) -> FsResult<WriteOutcome> {
172 self.fs.write_all(&self.path, bytes)
173 }
174
175 /// Creates this resource as a directory.
176 ///
177 /// # Parameters
178 /// - `options`: Directory creation options.
179 ///
180 /// # Errors
181 /// Returns an error when the owning filesystem cannot create the directory.
182 pub fn create_dir(&self, options: &CreateDirOptions) -> FsResult<()> {
183 self.fs.create_dir(&self.path, options)
184 }
185
186 /// Deletes this resource.
187 ///
188 /// # Parameters
189 /// - `options`: Delete options.
190 ///
191 /// # Errors
192 /// Returns an error when the owning filesystem cannot delete the resource.
193 pub fn delete(&self, options: &DeleteOptions) -> FsResult<()> {
194 self.fs.delete(&self.path, options)
195 }
196
197 /// Renames this resource to another filesystem-local path.
198 ///
199 /// # Parameters
200 /// - `target`: Target filesystem-local path.
201 /// - `options`: Rename options.
202 ///
203 /// # Errors
204 /// Returns an error when the owning filesystem cannot rename the resource.
205 pub fn rename_to(&self, target: &FsPath, options: &RenameOptions) -> FsResult<()> {
206 self.fs.rename(&self.path, target, options)
207 }
208
209 /// Copies this resource to another filesystem-local path.
210 ///
211 /// # Parameters
212 /// - `target`: Target filesystem-local path.
213 /// - `options`: Copy options.
214 ///
215 /// # Returns
216 /// Copy outcome reported by the owning filesystem.
217 ///
218 /// # Errors
219 /// Returns an error when the owning filesystem cannot copy the resource.
220 pub fn copy_to(&self, target: &FsPath, options: &CopyOptions) -> FsResult<CopyOutcome> {
221 self.fs.copy(&self.path, target, options)
222 }
223}