opcua_types/
status_code.rs1use std::{
9 error::Error,
10 fmt,
11 fmt::Formatter,
12 io::{self, Read, Write},
13};
14
15use serde::{
16 de::{self, Visitor},
17 Deserialize, Deserializer, Serialize, Serializer,
18};
19
20pub use crate::{encoding::*, status_codes::StatusCode};
21
22impl fmt::Display for StatusCode {
26 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
27 let bits = self.bitflags();
29 if bits.is_empty() {
30 write!(f, "{}", self.name())
31 } else {
32 write!(f, "{}+{:?}", self.name(), bits)
33 }
34 }
35}
36
37impl BinaryEncoder<StatusCode> for StatusCode {
38 fn byte_len(&self) -> usize {
39 4
40 }
41
42 fn encode<S: Write>(&self, stream: &mut S) -> EncodingResult<usize> {
43 write_u32(stream, self.bits())
44 }
45
46 fn decode<S: Read>(stream: &mut S, _: &DecodingOptions) -> EncodingResult<Self> {
47 Ok(StatusCode::from_bits_truncate(read_u32(stream)?))
48 }
49}
50
51impl Error for StatusCode {}
52
53impl StatusCode {
54 pub fn bitflags(&self) -> StatusCode {
56 *self & StatusCode::BIT_MASK
57 }
58
59 pub fn status(&self) -> StatusCode {
61 *self & StatusCode::STATUS_MASK
62 }
63
64 pub fn is_bad(&self) -> bool {
66 self.contains(StatusCode::IS_ERROR)
67 }
68
69 pub fn is_uncertain(&self) -> bool {
71 self.contains(StatusCode::IS_UNCERTAIN)
72 }
73
74 pub fn is_good(&self) -> bool {
76 !self.is_bad() && !self.is_uncertain()
77 }
78}
79
80impl From<StatusCode> for io::Error {
99 fn from(e: StatusCode) -> io::Error {
100 io::Error::new(io::ErrorKind::Other, format!("StatusCode {}", e))
101 }
102}
103
104impl Serialize for StatusCode {
105 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
106 where
107 S: Serializer,
108 {
109 serializer.serialize_u32(self.bits())
110 }
111}
112
113struct StatusCodeVisitor;
114
115impl<'de> Visitor<'de> for StatusCodeVisitor {
116 type Value = u32;
117
118 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
119 formatter.write_str("an unsigned 32-bit integer")
120 }
121
122 fn visit_u32<E>(self, value: u32) -> Result<Self::Value, E>
123 where
124 E: de::Error,
125 {
126 Ok(value)
127 }
128}
129
130impl<'de> Deserialize<'de> for StatusCode {
131 fn deserialize<D>(deserializer: D) -> Result<Self, <D as Deserializer<'de>>::Error>
132 where
133 D: Deserializer<'de>,
134 {
135 Ok(StatusCode::from_bits_truncate(
136 deserializer.deserialize_u32(StatusCodeVisitor)?,
137 ))
138 }
139}
140
141#[test]
142fn status_code() {
143 assert!(StatusCode::Good.is_good());
144 assert!(!StatusCode::Good.is_bad());
145 assert!(!StatusCode::Good.is_uncertain());
146
147 assert!(StatusCode::UncertainLastUsableValue.is_uncertain());
148 assert!(!StatusCode::UncertainLastUsableValue.is_bad());
149 assert!(!StatusCode::UncertainLastUsableValue.is_good());
150
151 assert!(StatusCode::BadDecodingError.is_bad());
152 assert!(!StatusCode::BadDecodingError.is_uncertain());
153 assert!(!StatusCode::BadDecodingError.is_good());
154
155 assert_eq!(
156 (StatusCode::BadDecodingError | StatusCode::HISTORICAL_CALCULATED).status(),
157 StatusCode::BadDecodingError
158 );
159 assert_eq!(
160 (StatusCode::BadDecodingError | StatusCode::HISTORICAL_CALCULATED).bitflags(),
161 StatusCode::HISTORICAL_CALCULATED
162 );
163}