///|
/// OPC UA DateTime stored as 100-nanosecond intervals since 1601-01-01 UTC.
pub(all) struct UaDateTime {
ticks : Int64
}
///|
/// Ticks between 1601-01-01 and 1970-01-01.
pub const UA_UNIX_EPOCH_TICKS : Int64 = 116_444_736_000_000_000L
///|
/// Construct a DateTime from raw OPC UA ticks.
pub fn UaDateTime::from_ticks(ticks : Int64) -> UaDateTime {
{ ticks, }
}
///|
/// Convert Unix milliseconds to OPC UA ticks.
pub fn UaDateTime::from_unix_ms(unix_ms : Int64) -> UaDateTime raise UaError {
if unix_ms > 910_692_730_085_477L || unix_ms < -11_644_473_600_000L {
raise InvalidValue(
"Unix milliseconds are outside the OPC UA DateTime range",
)
}
{ ticks: unix_ms * 10_000L + UA_UNIX_EPOCH_TICKS, }
}
///|
/// Convert OPC UA ticks to Unix milliseconds, truncating sub-millisecond values.
pub fn UaDateTime::to_unix_ms(self : UaDateTime) -> Int64 {
(self.ticks - UA_UNIX_EPOCH_TICKS) / 10_000L
}
///|
/// Decode a DateTime.
pub fn UaReader::read_datetime(self : UaReader) -> UaDateTime raise UaError {
{ ticks: self.read_int64(), }
}
///|
/// Encode a DateTime.
pub fn UaWriter::write_datetime(self : UaWriter, value : UaDateTime) -> Unit {
self.write_int64(value.ticks)
}
///|
/// OPC UA StatusCode severity is encoded in the two most significant bits.
pub(all) enum StatusSeverity {
Good
Uncertain
Bad
}
///|
/// OPC UA StatusCode.
pub(all) struct StatusCode {
value : UInt32
}
///|
/// Construct a StatusCode from its raw wire value.
pub fn StatusCode::new(value : UInt32) -> StatusCode {
{ value, }
}
///|
/// Raw wire value.
pub fn StatusCode::raw(self : StatusCode) -> UInt32 {
self.value
}
///|
/// Decode the severity from the top two bits.
pub fn StatusCode::severity(self : StatusCode) -> StatusSeverity {
match self.value >> 30 {
0 => Good
1 => Uncertain
_ => Bad
}
}
///|
/// Whether the status severity is Good.
pub fn StatusCode::is_good(self : StatusCode) -> Bool {
match self.severity() {
Good => true
Uncertain | Bad => false
}
}
///|
/// Human-readable status severity.
pub fn StatusCode::severity_name(self : StatusCode) -> String {
match self.severity() {
Good => "Good"
Uncertain => "Uncertain"
Bad => "Bad"
}
}
///|
/// Decode a StatusCode.
pub fn UaReader::read_status_code(self : UaReader) -> StatusCode raise UaError {
{ value: self.read_uint32(), }
}
///|
/// Encode a StatusCode.
pub fn UaWriter::write_status_code(self : UaWriter, value : StatusCode) -> Unit {
self.write_uint32(value.value)
}