1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
use crate::opc_da::{
com_utils::{LocalPointer, RemoteArray, RemotePointer},
errors::{OpcError, OpcResult},
};
/// Common OPC server functionality trait.
///
/// Provides methods for locale management and error string retrieval.
/// This trait is implemented by all OPC DA servers to support basic
/// configuration and error handling capabilities.
pub trait CommonTrait {
fn interface(&self) -> OpcResult<&crate::bindings::comn::IOPCCommon>;
/// Sets the locale ID for server string localization.
///
/// # Arguments
/// * `locale_id` - Windows LCID (Locale ID) value for the desired language
///
/// # Returns
/// Result indicating if the locale was successfully set
fn set_locale_id(&self, locale_id: u32) -> OpcResult<()> {
// SAFETY: Calling COM interface method SetLocaleID.
unsafe { Ok(self.interface()?.SetLocaleID(locale_id)?) }
}
/// Gets the current locale ID used by the server.
///
/// # Returns
/// Windows LCID value representing the current locale
fn get_locale_id(&self) -> OpcResult<u32> {
// SAFETY: Calling COM interface method GetLocaleID.
unsafe { Ok(self.interface()?.GetLocaleID()?) }
}
/// Gets a list of locale IDs supported by the server.
///
/// # Returns
/// Array of Windows LCID values for supported locales
fn query_available_locale_ids(&self) -> OpcResult<RemoteArray<u32>> {
let mut locale_ids = RemoteArray::empty();
// SAFETY: Calling COM interface method QueryAvailableLocaleIDs.
unsafe {
self.interface()?
.QueryAvailableLocaleIDs(locale_ids.as_mut_len_ptr(), locale_ids.as_mut_ptr())?;
}
Ok(locale_ids)
}
/// Gets a localized error description string.
///
/// # Arguments
/// * `error` - HRESULT error code to get description for
///
/// # Returns
/// Localized error message string in current locale
fn get_error_string(&self, error: windows::core::HRESULT) -> OpcResult<String> {
// SAFETY: Calling COM interface method GetErrorString.
let output = unsafe { self.interface()?.GetErrorString(error)? };
RemotePointer::from(output)
.try_into()
.map_err(OpcError::from)
}
/// Sets a client name for server identification.
///
/// # Arguments
/// * `name` - Client application name or description
///
/// # Returns
/// Result indicating if the client name was successfully set
fn set_client_name(&self, name: &str) -> OpcResult<()> {
let name = LocalPointer::from(name);
// SAFETY: Calling COM interface method SetClientName with valid string pointer.
unsafe { Ok(self.interface()?.SetClientName(name.as_pcwstr())?) }
}
}