pub trait Driver: Send + Sync {
// Required methods
fn read<'life0, 'life1, 'async_trait>(
&'life0 self,
tags: &'life1 [TagId],
) -> Pin<Box<dyn Future<Output = DriverResult<Vec<TagValue>>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
fn write<'life0, 'life1, 'async_trait>(
&'life0 self,
tag: &'life1 TagId,
value: TagWrite,
) -> Pin<Box<dyn Future<Output = DriverResult<WriteOutcome>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
fn browse<'life0, 'async_trait>(
&'life0 self,
request: BrowsePageRequest,
) -> Pin<Box<dyn Future<Output = DriverResult<BrowsePage>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait;
// Provided methods
fn capabilities<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = DriverResult<DriverCapabilities>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait { ... }
fn close_browse_session<'life0, 'life1, 'async_trait>(
&'life0 self,
_session_id: &'life1 str,
) -> Pin<Box<dyn Future<Output = DriverResult<()>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait { ... }
fn search<'life0, 'async_trait>(
&'life0 self,
_request: SearchRequest,
) -> Pin<Box<dyn Future<Output = DriverResult<Vec<SearchEvent>>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait { ... }
fn search_index_status<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = DriverResult<SearchIndexStatus>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait { ... }
fn refresh_search_index<'life0, 'async_trait>(
&'life0 self,
_force: bool,
) -> Pin<Box<dyn Future<Output = DriverResult<SearchIndexStatus>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait { ... }
fn control_search_index<'life0, 'async_trait>(
&'life0 self,
_action: SearchIndexControlAction,
) -> Pin<Box<dyn Future<Output = DriverResult<SearchIndexStatus>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait { ... }
fn set_search_index_auto_refresh<'life0, 'async_trait>(
&'life0 self,
_enabled: bool,
) -> Pin<Box<dyn Future<Output = DriverResult<SearchIndexStatus>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait { ... }
fn delete_search_index<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = DriverResult<SearchIndexStatus>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait { ... }
fn search_index<'life0, 'async_trait>(
&'life0 self,
_request: SearchIndexRequest,
) -> Pin<Box<dyn Future<Output = DriverResult<SearchIndexResponse>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait { ... }
}Expand description
Abstracts all tag I/O so bhtune-core’s tuning engine never knows what it’s talking to.
OpcDaDriver (via the opcda-bridge crate) is the primary driver for v1.
SimulatorDriver (an in-process FOPDT process model) and ReplayDriver (feeding back a
recorded golden-master trace) implement this same trait for CI/demo and validation
respectively. OpcUaDriver/ModbusDriver are roadmap items expected to slot in later
without requiring any change to this trait or to bhtune-core — that’s the entire point
of the seam.
Send + Sync so an implementation can be held behind Arc<dyn Driver> and shared across
async tasks (e.g. a CLI run and a concurrent history-retention sweep in the same process).
Connecting/constructing a specific driver (host/port, OPC DA server name, a trace file
path, simulator parameters) is deliberately not part of this trait — each
implementation’s own inherent constructor takes whatever it individually needs, since
forcing one uniform “connect” signature across such different drivers would either be
meaningless for some of them or leak implementation-specific parameters into the trait
every other implementation would have to ignore.
Required Methods§
Sourcefn read<'life0, 'life1, 'async_trait>(
&'life0 self,
tags: &'life1 [TagId],
) -> Pin<Box<dyn Future<Output = DriverResult<Vec<TagValue>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn read<'life0, 'life1, 'async_trait>(
&'life0 self,
tags: &'life1 [TagId],
) -> Pin<Box<dyn Future<Output = DriverResult<Vec<TagValue>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Reads the current value of every tag in tags, in one batched call where the driver
supports it (a single OPC DA Read RPC for all of them, rather than one round trip per
tag). Returns exactly one TagValue per requested tag, in the same order as tags.
A tag with genuinely bad or uncertain quality is still Ok — quality is data about
the reading, not a failure of the read itself — reserving Err for the read call not
reaching the driver at all, or the driver rejecting the request outright (e.g. an
unrecognized tag name).
Sourcefn write<'life0, 'life1, 'async_trait>(
&'life0 self,
tag: &'life1 TagId,
value: TagWrite,
) -> Pin<Box<dyn Future<Output = DriverResult<WriteOutcome>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn write<'life0, 'life1, 'async_trait>(
&'life0 self,
tag: &'life1 TagId,
value: TagWrite,
) -> Pin<Box<dyn Future<Output = DriverResult<WriteOutcome>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Writes value to tag.
Returns Ok(WriteOutcome) even when the driver rejects the write itself (read-only
tag, out-of-range value, permissions) — that is a normal, expected result of the
write reaching the driver, not an I/O failure. Err is reserved for the write call
not reaching the driver at all.
Sourcefn browse<'life0, 'async_trait>(
&'life0 self,
request: BrowsePageRequest,
) -> Pin<Box<dyn Future<Output = DriverResult<BrowsePage>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn browse<'life0, 'async_trait>(
&'life0 self,
request: BrowsePageRequest,
) -> Pin<Box<dyn Future<Output = DriverResult<BrowsePage>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Lists one bounded page of immediate children. Navigation uses opaque session, node, and continuation values returned by the driver; callers must not infer hierarchy by parsing punctuation in an ItemID.
Provided Methods§
Sourcefn capabilities<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = DriverResult<DriverCapabilities>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn capabilities<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = DriverResult<DriverCapabilities>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Reports the namespace capabilities of this driver/server pair.
Sourcefn close_browse_session<'life0, 'life1, 'async_trait>(
&'life0 self,
_session_id: &'life1 str,
) -> Pin<Box<dyn Future<Output = DriverResult<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn close_browse_session<'life0, 'life1, 'async_trait>(
&'life0 self,
_session_id: &'life1 str,
) -> Pin<Box<dyn Future<Output = DriverResult<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Releases a server-side browse session.
Sourcefn search<'life0, 'async_trait>(
&'life0 self,
_request: SearchRequest,
) -> Pin<Box<dyn Future<Output = DriverResult<Vec<SearchEvent>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn search<'life0, 'async_trait>(
&'life0 self,
_request: SearchRequest,
) -> Pin<Box<dyn Future<Output = DriverResult<Vec<SearchEvent>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Collects a bounded namespace search. Drivers that support progressive search may expose a richer stream through their concrete type; this method is the portable trait surface.
Sourcefn search_index_status<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = DriverResult<SearchIndexStatus>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn search_index_status<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = DriverResult<SearchIndexStatus>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Reports the gateway-owned persistent namespace-index status.
Sourcefn refresh_search_index<'life0, 'async_trait>(
&'life0 self,
_force: bool,
) -> Pin<Box<dyn Future<Output = DriverResult<SearchIndexStatus>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn refresh_search_index<'life0, 'async_trait>(
&'life0 self,
_force: bool,
) -> Pin<Box<dyn Future<Output = DriverResult<SearchIndexStatus>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Starts or coalesces a persistent namespace-index refresh.
Sourcefn control_search_index<'life0, 'async_trait>(
&'life0 self,
_action: SearchIndexControlAction,
) -> Pin<Box<dyn Future<Output = DriverResult<SearchIndexStatus>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn control_search_index<'life0, 'async_trait>(
&'life0 self,
_action: SearchIndexControlAction,
) -> Pin<Box<dyn Future<Output = DriverResult<SearchIndexStatus>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Pauses, resumes, or cancels a persistent namespace-index build.
Sourcefn set_search_index_auto_refresh<'life0, 'async_trait>(
&'life0 self,
_enabled: bool,
) -> Pin<Box<dyn Future<Output = DriverResult<SearchIndexStatus>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn set_search_index_auto_refresh<'life0, 'async_trait>(
&'life0 self,
_enabled: bool,
) -> Pin<Box<dyn Future<Output = DriverResult<SearchIndexStatus>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Enables or disables future automatic refreshes for this server’s index.
Sourcefn delete_search_index<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = DriverResult<SearchIndexStatus>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn delete_search_index<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = DriverResult<SearchIndexStatus>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Deletes this server’s persistent namespace index and enrollment.
Sourcefn search_index<'life0, 'async_trait>(
&'life0 self,
_request: SearchIndexRequest,
) -> Pin<Box<dyn Future<Output = DriverResult<SearchIndexResponse>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn search_index<'life0, 'async_trait>(
&'life0 self,
_request: SearchIndexRequest,
) -> Pin<Box<dyn Future<Output = DriverResult<SearchIndexResponse>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Queries the gateway-owned persistent namespace index.
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".