From 0ed62fa6dddf7cc758aa32042c70cc2a5e2d8ef8 Mon Sep 17 00:00:00 2001 From: 魏曹先生 <1992414357@qq.com> Date: Wed, 18 Mar 2026 10:20:05 +0800 Subject: Add AbsolutePath pattern to SpaceRootFindPattern --- systems/_framework/space_macro/src/lib.rs | 24 +++++------- systems/_framework/src/space.rs | 65 ++++++++++++++++++++++++------- 2 files changed, 61 insertions(+), 28 deletions(-) (limited to 'systems/_framework') diff --git a/systems/_framework/space_macro/src/lib.rs b/systems/_framework/space_macro/src/lib.rs index 7877181..a43e833 100644 --- a/systems/_framework/space_macro/src/lib.rs +++ b/systems/_framework/space_macro/src/lib.rs @@ -23,6 +23,7 @@ pub fn space_root_test_derive(input: TokenStream) -> TokenStream { use framework::space::Space; use std::env::{current_dir, set_current_dir}; use tokio::fs::{create_dir_all, remove_dir_all}; + use framework::space::SpaceRootFindPattern; #[tokio::test] async fn test_create_space() { @@ -31,27 +32,20 @@ pub fn space_root_test_derive(input: TokenStream) -> TokenStream { create_dir_all(&temp_dir).await.unwrap(); set_current_dir(&temp_dir).unwrap(); - let space = Space::new(#name::default()); + let mut space = Space::new(#name::default()); + + match #name::get_pattern() { + SpaceRootFindPattern::AbsolutePath(path_buf) => space.set_override_pattern(Some( + SpaceRootFindPattern::AbsolutePath(temp_dir.join(path_buf)), + )), + _ => {} + } assert!(space.space_dir_current().is_err()); space.init_here().await.unwrap(); assert!(space.space_dir_current().is_ok()); - - let space_dir = space.space_dir_current().unwrap(); - let pattern = <#name as framework::space::SpaceRoot>::get_pattern(); - - match pattern { - framework::space::SpaceRootFindPattern::IncludeDotDir(dir_name) => { - let expected_dir = space_dir.join(dir_name); - assert!(expected_dir.exists(), "Space directory {:?} should exist", expected_dir); - } - framework::space::SpaceRootFindPattern::IncludeFile(file_name) => { - let expected_file = space_dir.join(file_name); - assert!(expected_file.exists(), "Space file {:?} should exist", expected_file); - } - } } } }; diff --git a/systems/_framework/src/space.rs b/systems/_framework/src/space.rs index accb5df..8a9b2ec 100644 --- a/systems/_framework/src/space.rs +++ b/systems/_framework/src/space.rs @@ -16,6 +16,8 @@ pub struct Space { content: T, space_dir: RwLock>, current_dir: Option, + + pub(crate) override_pattern: Option, } impl Space { @@ -29,6 +31,7 @@ impl Space { content, space_dir: RwLock::new(None), current_dir: None, + override_pattern: None, } } @@ -38,10 +41,19 @@ impl Space { /// by calling `T::create_space()` at that path. pub async fn init(&self, path: impl AsRef) -> Result<(), SpaceError> { let path = path.as_ref(); - let pattern = T::get_pattern(); - - if !find_space_root_with(path.to_path_buf(), pattern).is_ok() { - T::create_space(path).await?; + let pattern = match &self.override_pattern { + Some(pattern) => pattern, + None => &T::get_pattern(), + }; + + // If using Absolute, directly read the internal path + let path = match &pattern { + SpaceRootFindPattern::AbsolutePath(path_buf) => path_buf.clone(), + _ => path.to_path_buf(), + }; + + if !find_space_root_with(&path, &pattern).is_ok() { + T::create_space(&path).await?; } Ok(()) } @@ -93,7 +105,10 @@ impl Space { } // Cache miss, find the space directory - let pattern = T::get_pattern(); + let pattern = match &self.override_pattern { + Some(pattern) => pattern, + None => &T::get_pattern(), + }; let result = find_space_root_with(current_dir.into(), pattern); match result { @@ -146,6 +161,13 @@ impl Space { *lock = space_dir; } } + + /// Set a custom pattern to override the default space root detection. + pub fn set_override_pattern(&mut self, pattern: Option) { + self.override_pattern = pattern; + // Clear cached space directory since pattern may have changed + self.update_space_dir(None); + } } impl Space { @@ -384,16 +406,22 @@ pub trait SpaceRoot: Sized { } pub enum SpaceRootFindPattern { + /// Search upward from the given current directory to find a directory containing the specified `.dir` IncludeDotDir(OsString), + + /// Search upward from the given current directory to find a directory containing the specified file name IncludeFile(OsString), + + /// Given a specific directory + AbsolutePath(PathBuf), } /// Find the space directory containing the current directory, /// Use Pattern to specify the search method /// /// For the full implementation, see `find_space_root_with` -pub fn find_space_root(pattern: SpaceRootFindPattern) -> Result { - find_space_root_with(current_dir()?, pattern) +pub fn find_space_root(pattern: &SpaceRootFindPattern) -> Result { + find_space_root_with(¤t_dir()?, &pattern) } /// Find the space directory containing the specified directory, @@ -413,7 +441,7 @@ pub fn find_space_root(pattern: SpaceRootFindPattern) -> Result Result Result Result, + pattern: &SpaceRootFindPattern, ) -> Result { // Get the pattern used for matching let match_pattern: Box bool> = match pattern { @@ -468,9 +496,20 @@ pub fn find_space_root_with( SpaceRootFindPattern::IncludeFile(file_name) => { Box::new(move |path| path.join(&file_name).is_file()) } + + // For absolute paths, return directly + // No search is performed + SpaceRootFindPattern::AbsolutePath(path) => { + if path.exists() && path.is_dir() { + return Ok(path.clone()); + } else { + return Err(SpaceError::SpaceNotFound); + } + } }; + // Match parent directories - let mut current = current_dir; + let mut current = current_dir.into(); loop { if match_pattern(current.as_path()) { return Ok(current); -- cgit