Skip to main content

qubit_fs/temp/
temp_resource_factory.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//! Temporary resource factory trait.
11
12use std::fmt::Debug;
13use std::process;
14use std::sync::Arc;
15use std::sync::atomic::{
16    AtomicU64,
17    Ordering,
18};
19use std::time::{
20    SystemTime,
21    UNIX_EPOCH,
22};
23
24use crate::{
25    FileSystem,
26    FsPath,
27    FsResult,
28    TempDir,
29    TempDirOptions,
30    TempFile,
31    TempFileOptions,
32};
33
34/// Global counter used to reduce temporary name collision risk.
35static TEMP_COUNTER: AtomicU64 = AtomicU64::new(0);
36
37/// Factory for filesystem-owned temporary resources.
38pub trait TempResourceFactory: Debug + Send + Sync {
39    /// Creates a temporary file.
40    ///
41    /// # Parameters
42    /// - `owner`: Filesystem that will own the temporary file.
43    /// - `options`: Temporary file creation options.
44    ///
45    /// # Returns
46    /// Temporary file handle with cleanup responsibility.
47    ///
48    /// # Errors
49    /// Returns [`crate::FsError`] when the temporary file cannot be created.
50    fn create_file(&self, owner: Arc<dyn FileSystem>, options: &TempFileOptions) -> FsResult<Box<dyn TempFile>>;
51
52    /// Creates a temporary directory.
53    ///
54    /// # Parameters
55    /// - `owner`: Filesystem that will own the temporary directory.
56    /// - `options`: Temporary directory creation options.
57    ///
58    /// # Returns
59    /// Temporary directory handle with cleanup responsibility.
60    ///
61    /// # Errors
62    /// Returns [`crate::FsError`] when the temporary directory cannot be
63    /// created.
64    fn create_dir(&self, owner: Arc<dyn FileSystem>, options: &TempDirOptions) -> FsResult<Box<dyn TempDir>>;
65
66    /// Builds a temporary resource path using the common rs-fs naming format.
67    ///
68    /// The default format is `{prefix}{process_id}-{unix_epoch_nanos}-{counter}{suffix}`.
69    /// Implementations may use this helper to share the common format, or ignore
70    /// it and apply provider-specific naming rules.
71    ///
72    /// # Parameters
73    /// - `parent`: Optional parent path. Root is used when absent.
74    /// - `prefix`: Temporary name prefix.
75    /// - `suffix`: Temporary name suffix.
76    ///
77    /// # Returns
78    /// Generated temporary path.
79    ///
80    /// # Errors
81    /// Returns [`crate::FsError`] when the generated path is invalid.
82    fn make_temp_path(&self, parent: Option<&FsPath>, prefix: &str, suffix: &str) -> FsResult<FsPath> {
83        let parent = parent.cloned().unwrap_or_else(FsPath::root);
84        let counter = TEMP_COUNTER.fetch_add(1, Ordering::Relaxed);
85        let nanos = SystemTime::now()
86            .duration_since(UNIX_EPOCH)
87            .unwrap_or_default()
88            .as_nanos();
89        let name = format!("{prefix}{}-{nanos}-{counter}{suffix}", process::id());
90        parent.join(&name)
91    }
92}