Skip to main content

AdapterKeyName

Enum AdapterKeyName 

Source
#[non_exhaustive]
pub enum AdapterKeyName { NoneAdapter, LabView, LabViewStdPrototype, LabViewNxg, Cvi, CviStdPrototype, DllFlex, Sequence, Automation, DotNet, Python, HtBasic, }
Expand description

A code-module adapter, by the key the engine knows it under (AdapterKeyNames).

The key is what Engine::new_step and Step::adapter_key_name exchange, and it is a string rather than a number, so this exists to keep those strings in one checked place instead of spread across call sites.

use rs_teststand::AdapterKeyName;

assert_eq!(AdapterKeyName::LabView.as_str(), "G Flexible VI Adapter");
assert_eq!(
    AdapterKeyName::from_key("Sequence Adapter"),
    Some(AdapterKeyName::Sequence)
);

A key names an adapter the engine recognizes, not one the station can necessarily run: calling a LabVIEW step needs LabVIEW present. Building a step with the key succeeds either way; only running it does not.

Two keys are obsolete, and the documentation says so outright: the standard-prototype Self::LabViewStdPrototype and Self::CviStdPrototype are to be replaced by Self::LabView and Self::Cvi. They are kept here because engines back to 2016 accept them and old sequence files contain them, but a step built with one reports back its replacement, so a comparison of “asked for” against “got” differs for exactly those two, by design rather than by accident. Self::is_obsolete and Self::replacement make that checkable instead of folklore.

Variants (Non-exhaustive)§

This enum is marked as non-exhaustive
Non-exhaustive enums could have additional variants added in future. Therefore, when matching against variants of non-exhaustive enums, an extra wildcard arm must be added to account for any future variants.
§

NoneAdapter

No code module, the step type does its own work (NoneAdapterKeyName).

§

LabView

The LabVIEW adapter (FlexLVAdapterKeyName, value “G Flexible VI Adapter”). This is what the editor calls the LabVIEW Adapter today, and the one to reach for.

§

LabViewStdPrototype

The superseded standard-prototype LabVIEW adapter. Obsolete, the documentation directs callers to Self::LabView, and the engine substitutes it. The type library carries this one key under two names, LVAdapterKeyName and GAdapterKeyName, so the crate names it once.

§

LabViewNxg

LabVIEW NXG (LabVIEWNXGAdapterKeyName), its own key for the discontinued second-generation product, not a spelling of the above.

§

Cvi

A C/CVI function with any prototype (FlexCVIAdapterKeyName).

§

CviStdPrototype

A C/CVI function with the standard prototype. Obsolete, the documentation directs callers to Self::Cvi (StdCVIAdapterKeyName).

§

DllFlex

A DLL function with any prototype (FlexCAdapterKeyName).

§

Sequence

Another sequence (SequenceAdapterKeyName).

§

Automation

An ActiveX automation server (AutomationAdapterKeyName).

§

DotNet

A .NET assembly member (DotNetAdapterKeyname).

§

Python

A Python module (PythonAdapterKeyName).

§

HtBasic

HTBasic (HTBasicAdapterKeyName).

Implementations§

Source§

impl AdapterKeyName

Source

pub const fn as_str(self) -> &'static str

The key the engine expects.

Examples found in repository?
examples/result_list_parse.rs (line 42)
36fn add_pass_fail(
37    engine: &Engine,
38    sequence: &Sequence,
39    name: &str,
40    source: &str,
41) -> Result<(), Error> {
42    let step = engine.new_step(AdapterKeyName::NoneAdapter.as_str(), "PassFailTest")?;
43    step.set_name(name)?;
44    step.as_property_object()?
45        .set_val_string("DataSource", insert_if_missing(), source)?;
46    sequence.insert_step(
47        &step,
48        sequence.get_num_steps(StepGroup::Main)?,
49        StepGroup::Main,
50    )
51}
52
53/// Adds a numeric limit test with a fixed measurement.
54fn add_numeric(
55    engine: &Engine,
56    sequence: &Sequence,
57    name: &str,
58    source: &str,
59    low: f64,
60    high: f64,
61) -> Result<(), Error> {
62    let step = engine.new_step(AdapterKeyName::NoneAdapter.as_str(), "NumericLimitTest")?;
63    step.set_name(name)?;
64    let properties = step.as_property_object()?;
65    properties.set_val_string("DataSource", insert_if_missing(), source)?;
66    properties.set_val_number("Limits.Low", insert_if_missing(), low)?;
67    properties.set_val_number("Limits.High", insert_if_missing(), high)?;
68    sequence.insert_step(
69        &step,
70        sequence.get_num_steps(StepGroup::Main)?,
71        StepGroup::Main,
72    )
73}
74
75/// Adds a statement step that records nothing, to show the gap it leaves.
76fn add_unrecorded_filler(engine: &Engine, sequence: &Sequence, name: &str) -> Result<(), Error> {
77    let step = engine.new_step(AdapterKeyName::NoneAdapter.as_str(), "Statement")?;
78    step.set_name(name)?;
79    step.set_result_recording_option(ResultRecordingOption::Disabled)?;
80    sequence.insert_step(
81        &step,
82        sequence.get_num_steps(StepGroup::Main)?,
83        StepGroup::Main,
84    )
85}
More examples
Hide additional examples
examples/step_insert_from_template.rs (line 54)
51fn build_prototype(engine: &Engine) -> Result<Step, Error> {
52    // The maintained LabVIEW adapter. The standard-prototype key still exists
53    // but the documentation marks it obsolete in favour of this one.
54    let step = engine.new_step(AdapterKeyName::LabView.as_str(), "Action")?;
55    step.set_name("Measure (VI)")?;
56    step.set_run_mode(RunMode::Normal)?;
57    step.as_property_object()?.set_val_string(
58        VI_PATH,
59        PropertyOptions::INSERT_IF_MISSING.bits(),
60        r"example.lvlibp\measure.vi",
61    )?;
62    Ok(step)
63}
examples/execution_run_subsequence.rs (line 48)
44fn add_action(engine: &Engine, sequence: &Sequence, name: &str) -> Result<(), Error> {
45    // The None adapter is what actually means "no code module"; an empty key
46    // would let the step type pick, and a step on a real adapter fails at run
47    // time with "module has not yet been specified".
48    let step = engine.new_step(AdapterKeyName::NoneAdapter.as_str(), "Action")?;
49    step.set_name(name)?;
50    step.set_record_result(true)?;
51    sequence.insert_step(
52        &step,
53        sequence.get_num_steps(StepGroup::Main)?,
54        StepGroup::Main,
55    )
56}
examples/execution_run_test_headless.rs (line 70)
62fn add_numeric_limit_test(
63    engine: &Engine,
64    sequence: &Sequence,
65    name: &str,
66    data_source: &str,
67    low: f64,
68    high: f64,
69) -> Result<(), Error> {
70    let step = engine.new_step(AdapterKeyName::NoneAdapter.as_str(), "NumericLimitTest")?;
71    step.set_name(name)?;
72    step.set_record_result(true)?;
73
74    let properties = step.as_property_object()?;
75    properties.set_val_string("DataSource", insert_if_missing(), data_source)?;
76    properties.set_val_number("Limits.Low", insert_if_missing(), low)?;
77    properties.set_val_number("Limits.High", insert_if_missing(), high)?;
78
79    sequence.insert_step(
80        &step,
81        sequence.get_num_steps(StepGroup::Main)?,
82        StepGroup::Main,
83    )
84}
examples/step_insert.rs (line 44)
37fn vi_call_step(
38    engine: &Engine,
39    name: &str,
40    vi_path: &str,
41    project_path: &str,
42    run_mode: RunMode,
43) -> Result<Step, Error> {
44    let step = engine.new_step(AdapterKeyName::LabView.as_str(), "Action")?;
45    step.set_name(name)?;
46    step.set_run_mode(run_mode)?;
47    // Recorded explicitly rather than left to the default, so the step shows up
48    // in the result list a report is built from.
49    step.set_result_recording_option(ResultRecordingOption::Enabled)?;
50
51    let properties = step.as_property_object()?;
52    properties.set_val_string(VI_PATH, insert_if_missing(), vi_path)?;
53    if !project_path.is_empty() {
54        properties.set_val_string(PROJECT_PATH, insert_if_missing(), project_path)?;
55    }
56    Ok(step)
57}
58
59/// The index of a step within a group, by name.
60///
61/// `None` when no step of that name is in the group, which a caller should
62/// treat as "append at the end" rather than as a failure: a sequence is free
63/// not to contain the step someone expected.
64fn index_of(sequence: &Sequence, name: &str, group: StepGroup) -> Result<Option<i32>, Error> {
65    for index in 0..sequence.get_num_steps(group)? {
66        if sequence.get_step(index, group)?.name()? == name {
67            return Ok(Some(index));
68        }
69    }
70    Ok(None)
71}
72
73fn main() -> Result<(), Box<dyn std::error::Error>> {
74    let engine = Engine::new()?;
75
76    // A file to insert into. Built here so the example depends on nothing that
77    // has to exist on the station first.
78    let sequence_file = engine.new_sequence_file()?;
79    let subsequence = engine.new_sequence()?;
80    subsequence.set_name("CustomSubsequence")?;
81    let existing = engine.new_step(AdapterKeyName::NoneAdapter.as_str(), "Action")?;
82    existing.set_name(TARGET_STEP)?;
83    subsequence.insert_step(&existing, 0, StepGroup::Main)?;
84    sequence_file.insert_sequence(&subsequence)?;
85
86    // Where to insert: in front of the target, or at the end if it is absent.
87    let insert_at = if let Some(index) = index_of(&subsequence, TARGET_STEP, StepGroup::Main)? {
88        println!("Found {TARGET_STEP} at index {index}; inserting in front of it.");
89        index
90    } else {
91        let end = subsequence.get_num_steps(StepGroup::Main)?;
92        println!("{TARGET_STEP} not found; appending at index {end}.");
93        end
94    };
95
96    for (offset, (name, vi, project, mode)) in [
97        (
98            "Measure Voltage (VI)",
99            r"instruments.lvlibp\measure_voltage.vi",
100            "",
101            RunMode::Normal,
102        ),
103        (
104            "Measure Current (VI)",
105            r"instruments.lvlibp\measure_current.vi",
106            r"instruments.lvproj",
107            RunMode::Skip,
108        ),
109    ]
110    .into_iter()
111    .enumerate()
112    {
113        let step = vi_call_step(&engine, name, vi, project, mode)?;
114        let at = insert_at + i32::try_from(offset).unwrap_or(0);
115        subsequence.insert_step(&step, at, StepGroup::Main)?;
116    }
117
118    println!(
119        "\n{} now holds {} step(s):",
120        subsequence.name()?,
121        subsequence.get_num_steps(StepGroup::Main)?
122    );
123    for index in 0..subsequence.get_num_steps(StepGroup::Main)? {
124        let step = subsequence.get_step(index, StepGroup::Main)?;
125        let properties = step.as_property_object()?;
126        let vi = properties
127            .get_val_string(VI_PATH, none())
128            .unwrap_or_else(|_| "<no VI>".to_owned());
129        println!(
130            "  [{index}] {} - {:?}, run mode {:?}, records {:?}",
131            step.name()?,
132            step.adapter_key_name()?,
133            step.run_mode()?,
134            step.result_recording_option()?
135        );
136        if vi != "<no VI>" {
137            println!("        calls {vi}");
138        }
139    }
140
141    let path = std::env::temp_dir().join("rs_teststand_step_insert.seq");
142    let path = path.to_string_lossy().into_owned();
143    sequence_file.save(&path)?;
144    println!("\nSaved to {path}");
145    Ok(())
146}
Source

pub fn from_key(key: &str) -> Option<Self>

Recognizes a key read back from a step.

None means the key is not one this build names, a newer engine’s adapter, or a step that has none, which is information, not an error.

Source

pub const fn is_obsolete(self) -> bool

Whether the documentation marks this key obsolete.

An obsolete key still works, engines back to 2016 accept it, and old sequence files are full of them, but a step built with one reports replacement back instead.

Source

pub const fn replacement(self) -> Option<Self>

The key the documentation directs callers to instead, if any.

Trait Implementations§

Source§

impl Clone for AdapterKeyName

Source§

fn clone(&self) -> AdapterKeyName

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Copy for AdapterKeyName

Source§

impl Debug for AdapterKeyName

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Display for AdapterKeyName

Source§

fn fmt(&self, formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Eq for AdapterKeyName

Source§

impl Hash for AdapterKeyName

Source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
1.3.0 · Source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
Source§

impl PartialEq for AdapterKeyName

Source§

fn eq(&self, other: &AdapterKeyName) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl StructuralPartialEq for AdapterKeyName

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.