use rs_teststand::{
ConflictHandler, Engine, GetSeqFileOptions, PropValType, PropertyObject, SequenceFile,
};
const INSERT_IF_MISSING: i32 = 1;
fn set_string(
container: &PropertyObject,
name: &str,
value: &str,
) -> Result<(), rs_teststand::Error> {
if !container.exists(name, 0)? {
container.new_sub_property(name, PropValType::String, false, "", INSERT_IF_MISSING)?;
}
container.set_val_string(name, 0, value)
}
fn temporary_variable_lifecycle(container: &PropertyObject) -> Result<(), rs_teststand::Error> {
let name = "TempScratch";
let clone_name = "TempScratchCopy";
for stale in [name, clone_name] {
if container.exists(stale, 0)? {
container.delete_sub_property(stale, 0)?;
}
}
container.new_sub_property(name, PropValType::String, false, "", INSERT_IF_MISSING)?;
container.set_val_string(name, 0, "scratch")?;
println!(
" created {name} (String) = '{}'",
container.get_val_string(name, 0)?
);
container.delete_sub_property(name, 0)?;
container.new_sub_property(name, PropValType::Number, false, "", INSERT_IF_MISSING)?;
container.set_val_number(name, 0, 42.0)?;
println!(
" retyped {name} -> Number = {}",
container.get_val_number(name, 0)?
);
let copy = container.clone_property(name, 0)?;
container.set_property_object(clone_name, INSERT_IF_MISSING, ©)?;
println!(
" cloned {name} -> {clone_name} = {}",
container.get_val_number(clone_name, 0)?
);
container.delete_sub_property(clone_name, 0)?;
container.delete_sub_property(name, 0)?;
println!(
" removed both: {name} exists={}, {clone_name} exists={}",
container.exists(name, 0)?,
container.exists(clone_name, 0)?
);
Ok(())
}
fn open_sequence_file(engine: &Engine) -> Result<Option<SequenceFile>, rs_teststand::Error> {
let Some(path) = std::env::args().nth(1) else {
return Ok(None);
};
let file = engine.get_sequence_file_ex(
&path,
GetSeqFileOptions::DO_NOT_RUN_LOAD_CALLBACK,
ConflictHandler::Error,
)?;
Ok(Some(file))
}
fn main() -> Result<(), rs_teststand::Error> {
let engine = Engine::new()?;
let station_globals = engine.globals()?;
if !station_globals.exists("StationInfo", 0)? {
station_globals.new_sub_property(
"StationInfo",
PropValType::Container,
false,
"",
INSERT_IF_MISSING,
)?;
}
let station_info = station_globals.get_property_object("StationInfo", 0)?;
set_string(&station_info, "StationName", "STATION_01")?;
println!(
"StationGlobals.StationInfo.StationName = '{}'",
station_info.get_val_string("StationName", 0)?
);
if let Some(sequence_file) = open_sequence_file(&engine)? {
let file_globals = sequence_file.file_globals_default_values()?;
set_string(&file_globals, "BatchID", "BATCH-2026-Q2-001")?;
println!(
"FileGlobals.BatchID = '{}'",
file_globals.get_val_string("BatchID", 0)?
);
let main_sequence = sequence_file.get_sequence_by_name("MainSequence")?;
let locals = main_sequence.locals()?;
set_string(&locals, "OperatorName", "Alice")?;
println!(
"MainSequence.Locals.OperatorName = '{}'",
locals.get_val_string("OperatorName", 0)?
);
let parameters = main_sequence.parameters()?;
set_string(¶meters, "DUTSerial", "SN-000000")?;
println!(
"MainSequence.Parameters.DUTSerial = '{}'",
parameters.get_val_string("DUTSerial", 0)?
);
println!("\nTemporary variable lifecycle (Locals.TempScratch):");
temporary_variable_lifecycle(&locals)?;
engine.release_sequence_file_ex(sequence_file, 0)?;
} else {
println!("\n(pass a .seq path to also demonstrate locals, parameters and file globals)");
println!("\nTemporary variable lifecycle (StationGlobals.TempScratch):");
temporary_variable_lifecycle(&station_globals)?;
}
engine.commit_globals_to_disk(false)?;
println!("\nStation globals committed to disk.");
Ok(())
}