instrument_visa/
enumerator.rs1use crate::error::map_visa_error;
2use crate::rm::SharedRm;
3use crate::transport::read_identity_from_instrument;
4use instrument_core::address::{InterfaceKind, ResourceAddress};
5use instrument_core::enumerator::{RawResource, ResourceEnumerator};
6use instrument_core::Result;
7use std::ffi::CString;
8use visa_rs::enums::attribute::AttrIntfType;
9use visa_rs::prelude::{AccessMode, AsResourceManager, TIMEOUT_IMMEDIATE};
10
11pub struct VisaEnumerator {
13 rm: SharedRm,
14}
15
16impl VisaEnumerator {
17 pub fn new(rm: SharedRm) -> Self {
18 Self { rm }
19 }
20
21 fn intf_type_to_kind(intf: AttrIntfType) -> InterfaceKind {
22 if intf == AttrIntfType::VI_INTF_GPIB {
23 InterfaceKind::Gpib
24 } else if intf == AttrIntfType::VI_INTF_VXI || intf == AttrIntfType::VI_INTF_GPIB_VXI {
25 InterfaceKind::Vxi
26 } else if intf == AttrIntfType::VI_INTF_ASRL {
27 InterfaceKind::Serial
28 } else if intf == AttrIntfType::VI_INTF_TCPIP {
29 InterfaceKind::Tcpip
30 } else if intf == AttrIntfType::VI_INTF_USB {
31 InterfaceKind::Usb
32 } else if intf == AttrIntfType::VI_INTF_PXI {
33 InterfaceKind::Pxi
34 } else {
35 InterfaceKind::Unknown
36 }
37 }
38}
39
40impl ResourceEnumerator for VisaEnumerator {
41 fn list(&self, pattern: &str) -> Result<Vec<RawResource>> {
42 let expr = CString::new(pattern)
43 .map_err(|e| instrument_core::Error::Parse(e.to_string()))?
44 .into();
45 let list = self
46 .rm
47 .strong()
48 .find_res_list(&expr)
49 .map_err(map_visa_error)?;
50
51 let mut resources = Vec::new();
52 for res_id in list {
53 let res_id = res_id.map_err(map_visa_error)?;
54 let raw = res_id.to_string();
55 let mut address = ResourceAddress::parse(&raw)?;
56 if let Ok((intf, _)) = self.rm.strong().parse_res(&res_id) {
57 address.interface = VisaEnumerator::intf_type_to_kind(intf);
58 }
59
60 let mut identity_hint = instrument_core::transport::TransportIdentity {
61 interface: address.interface,
62 ..Default::default()
63 };
64
65 if let Ok(instr) =
66 self.rm
67 .strong()
68 .open(&res_id, AccessMode::NO_LOCK, TIMEOUT_IMMEDIATE)
69 {
70 identity_hint = read_identity_from_instrument(&instr);
71 identity_hint.interface = address.interface;
72 }
73
74 resources.push(RawResource {
75 address,
76 identity_hint,
77 });
78 }
79 Ok(resources)
80 }
81}