Skip to main content

search_directory_manage/
search_directory_manage.rs

1//! Example: manage the station's search directories.
2//!
3//! Search directories are how the engine locates code modules, sequences and
4//! configuration files. This walks the collection, reads every attribute of
5//! each entry, then inserts, mutates, reorders and removes one, and commits the
6//! result to disk.
7//!
8//! The example restores the station to its original state: the entry it adds is
9//! the one it removes.
10
11use rs_teststand::{Engine, SearchDirectory, SearchDirectoryType};
12
13/// Describes an entry's type, spelling out the cases worth distinguishing.
14///
15/// An unrecognized value is reported with its raw number rather than hidden, a
16/// newer engine may define types this build does not name.
17fn describe_type(directory: &SearchDirectory) -> Result<String, rs_teststand::Error> {
18    let raw = directory.dir_type()?;
19    Ok(match SearchDirectoryType::try_from(raw) {
20        Ok(SearchDirectoryType::ExplicitDir) => "Explicit user directory (ExplicitDir)".to_owned(),
21        Ok(kind @ (SearchDirectoryType::WindowsDir | SearchDirectoryType::WindowsSystemDir)) => {
22            format!("OS-defined path ({kind})")
23        }
24        Ok(kind) => kind.to_string(),
25        Err(raw) => format!("Unknown ({raw})"),
26    })
27}
28
29fn print_entry(index: usize, directory: &SearchDirectory) -> Result<(), rs_teststand::Error> {
30    println!(
31        "[{index}] Type: {}, Path: '{}'",
32        describe_type(directory)?,
33        directory.path()?
34    );
35    println!(
36        "    Subdirs: {}, Disabled: {}, HiddenExcl: {}",
37        directory.search_subdirectories()?,
38        directory.disabled()?,
39        directory.exclude_hidden_subdirectories()?
40    );
41    println!(
42        "    ExtRestrict: '{}', ExtExcl: {}",
43        directory.file_extension_restrictions()?,
44        directory.exclude_file_extension()?
45    );
46    Ok(())
47}
48
49fn main() -> Result<(), rs_teststand::Error> {
50    let engine = Engine::new()?;
51    let search_directories = engine.search_directories()?;
52
53    println!("Total search directories: {}", search_directories.count()?);
54    for (index, directory) in search_directories.iter()?.enumerate() {
55        print_entry(index, &directory?)?;
56    }
57
58    // Insert at the front, so the new entry is searched first.
59    println!("\nInserting a new explicit search directory...");
60    let new_path = engine.bin_directory()?;
61    search_directories.insert(&new_path, 0, true, "", false, false)?;
62    println!("Total after insert: {}", search_directories.count()?);
63
64    let inserted = search_directories.get(0)?;
65    println!(
66        "New [0] Path: '{}', Subdirs: {}",
67        inserted.path()?,
68        inserted.search_subdirectories()?
69    );
70
71    // A disabled entry stays in the list but is not searched.
72    println!("Disabling the new directory...");
73    inserted.set_disabled(true)?;
74    println!("New [0] Disabled: {}", inserted.disabled()?);
75
76    // Order matters: entries are searched in list order.
77    println!("Moving the new directory to index 1...");
78    search_directories.move_search_directory(0, 1)?;
79    println!(
80        "Directory at index 1 is now: '{}'",
81        search_directories.get(1)?.path()?
82    );
83
84    println!("Removing the added directory to clean up...");
85    search_directories.remove(1)?;
86    println!("Total after cleanup: {}", search_directories.count()?);
87
88    // The engine writes search directories out at shutdown anyway. Committing
89    // now makes the change visible to other processes immediately, and passing
90    // `false` keeps a save conflict from raising a dialog.
91    engine.commit_globals_to_disk(false)?;
92    println!("Committed search directories configuration to disk.");
93
94    Ok(())
95}