#[ cfg( feature = "glob" ) ]
fn main() -> Result< (), workspace_tools ::WorkspaceError >
{
println!( "🔍 workspace resource discovery with glob patterns\n" );
if std ::env ::var( "WORKSPACE_PATH" ).is_err()
{
std ::env ::set_var( "WORKSPACE_PATH", std ::env ::current_dir().unwrap() );
}
let ws = workspace_tools ::workspace()?;
setup_demo_structure( &ws )?;
println!( "📁 created demo project structure" );
println!( "workspace: {}\n", ws.root().display() );
println!( "1️⃣ finding rust source files: " );
let rust_files = ws.find_resources( "src/**/*.rs" )?;
print_files( &rust_files, " " );
println!( "\n2️⃣ finding test files: " );
let test_files = ws.find_resources( "tests/**/*.rs" )?;
print_files( &test_files, " " );
println!( "\n3️⃣ finding configuration files: " );
let config_files = ws.find_resources( "config/*" )?;
print_files( &config_files, " " );
println!( "\n4️⃣ finding documentation: " );
let doc_files = ws.find_resources( "docs/**/*.md" )?;
print_files( &doc_files, " " );
println!( "\n5️⃣ finding image assets: " );
let image_files = ws.find_resources( "assets/**/*.{png,jpg,svg}" )?;
print_files( &image_files, " " );
println!( "\n6️⃣ smart config file discovery: " );
let configs = vec![ "app", "database", "logging", "nonexistent" ];
for config_name in configs
{
match ws.find_config( config_name )
{
Ok( config_path ) =>
println!( " {} config: {}", config_name, config_path.display() ),
Err( _ ) =>
println!( " {config_name} config: not found" ),
}
}
println!( "\n7️⃣ advanced glob patterns: " );
let patterns = vec!
[
( "**/*.toml", "all toml files recursively" ),
( "src/**/mod.rs", "module files in src" ),
( "**/test_*.rs", "test files anywhere" ),
( "assets/**", "all assets recursively" ),
( "config/*.{yml,yaml}", "yaml configs only" ),
];
for ( pattern, description ) in patterns
{
match ws.find_resources( pattern )
{
Ok( files ) => println!( " {} : {} files", description, files.len() ),
Err( e ) => println!( " {description} : error - {e}" ),
}
}
println!( "\n8️⃣ filtering and processing results: " );
let all_rust_files = ws.find_resources( "**/*.rs" )?;
let src_files: Vec< _ > = all_rust_files.iter()
.filter( | path | path.to_string_lossy().contains( "/src/" ) )
.collect();
let test_files: Vec< _ > = all_rust_files.iter()
.filter( | path | path.to_string_lossy().contains( "/tests/" ) )
.collect();
println!( " total rust files: {}", all_rust_files.len() );
println!( " source files: {}", src_files.len() );
println!( " test files: {}", test_files.len() );
cleanup_demo_structure( &ws );
println!( "\n💡 resource discovery best practices: " );
println!( " • use specific patterns to avoid finding too many files" );
println!( " • prefer find_config() for configuration discovery" );
println!( " • handle glob errors gracefully (invalid patterns)" );
println!( " • filter results in rust rather than complex glob patterns" );
println!( " • cache results if you'll reuse them frequently" );
println!( "\n🎯 next: run example 005 to learn about secret management" );
Ok( () )
}
#[ cfg( feature = "glob" ) ]
fn setup_demo_structure( ws: &workspace_tools ::Workspace ) -> Result< (), workspace_tools ::WorkspaceError >
{
use std ::fs;
let dirs = vec!
[
"src/modules",
"src/utils",
"tests/integration",
"tests/unit",
"config",
"docs/api",
"docs/guides",
"assets/images",
"assets/fonts",
];
for dir in dirs
{
let path = ws.join( dir );
fs ::create_dir_all( &path )
.map_err( | e | workspace_tools ::WorkspaceError ::IoError( e.to_string() ) )?;
}
let files = vec!
[
( "src/lib.rs", "//! main library\npub mod utils;" ),
( "src/main.rs", "fn main() { println!(\"hello\"); }" ),
( "src/modules/auth.rs", "// authentication module" ),
( "src/modules/mod.rs", "pub mod auth;" ),
( "src/utils/helpers.rs", "// helper functions" ),
( "src/utils/mod.rs", "pub mod helpers;" ),
( "tests/integration/test_auth.rs", "#[ test ] fn test_auth() {}" ),
( "tests/unit/test_helpers.rs", "#[ test ] fn test_helpers() {}" ),
( "config/app.toml", "[app]\nname = \"demo\"\nport = 8080" ),
( "config/database.yaml", "host: localhost\nport: 5432" ),
( "config/logging.yml", "level: info" ),
( "docs/readme.md", "# project documentation" ),
( "docs/api/auth.md", "# authentication api" ),
( "docs/guides/setup.md", "# setup guide" ),
( "assets/images/logo.png", "fake png data" ),
( "assets/images/icon.svg", "< svg >icon< /svg >" ),
( "assets/fonts/main.ttf", "fake font data" ),
];
for ( path, content ) in files
{
let file_path = ws.join( path );
fs ::write( &file_path, content )
.map_err( | e | workspace_tools ::WorkspaceError ::IoError( e.to_string() ) )?;
}
Ok( () )
}
#[ cfg( feature = "glob" ) ]
fn cleanup_demo_structure( ws: &workspace_tools ::Workspace )
{
use std ::fs;
let dirs = vec![ "src", "tests", "config", "docs", "assets" ];
for dir in dirs
{
let path = ws.join( dir );
let _ = fs ::remove_dir_all( path ); }
}
#[ cfg( feature = "glob" ) ]
fn print_files( files: &[ std ::path ::PathBuf ], indent: &str )
{
if files.is_empty()
{
println!( "{indent}(no files found)" );
}
else
{
for file in files
{
println!( "{}{}", indent, file.display() );
}
}
}
#[ cfg( not( feature = "glob" ) ) ]
fn main()
{
println!( "🚨 this example requires the 'glob' feature" );
println!( "run with: cargo run --example 004_resource_discovery --features glob" );
println!();
println!( "to enable glob feature permanently, add to cargo.toml: " );
println!( r#"[dependencies]"# );
println!( r#"workspace_tools = {{ version = "0.1", features = ["glob"] }}"# );
}