opcua_types/
localized_text.rs

1// OPCUA for Rust
2// SPDX-License-Identifier: MPL-2.0
3// Copyright (C) 2017-2022 Adam Lock
4
5//! Contains the definition of `LocalizedText`.
6use std::{
7    fmt,
8    io::{Read, Write},
9};
10
11use crate::{encoding::*, string::*};
12
13/// A human readable text with an optional locale identifier.
14#[derive(PartialEq, Default, Debug, Clone, Serialize, Deserialize)]
15pub struct LocalizedText {
16    /// The locale. Omitted from stream if null or empty
17    pub locale: UAString,
18    /// The text in the specified locale. Omitted frmo stream if null or empty.
19    pub text: UAString,
20}
21
22impl<'a> From<&'a str> for LocalizedText {
23    fn from(value: &'a str) -> Self {
24        Self {
25            locale: UAString::from(""),
26            text: UAString::from(value),
27        }
28    }
29}
30
31impl From<&String> for LocalizedText {
32    fn from(value: &String) -> Self {
33        Self {
34            locale: UAString::from(""),
35            text: UAString::from(value),
36        }
37    }
38}
39
40impl From<String> for LocalizedText {
41    fn from(value: String) -> Self {
42        Self {
43            locale: UAString::from(""),
44            text: UAString::from(value),
45        }
46    }
47}
48
49impl fmt::Display for LocalizedText {
50    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
51        write!(f, "{}", self.text)
52    }
53}
54
55impl BinaryEncoder<LocalizedText> for LocalizedText {
56    fn byte_len(&self) -> usize {
57        let mut size = 1;
58        if !self.locale.is_empty() {
59            size += self.locale.byte_len();
60        }
61        if !self.text.is_empty() {
62            size += self.text.byte_len();
63        }
64        size
65    }
66
67    fn encode<S: Write>(&self, stream: &mut S) -> EncodingResult<usize> {
68        let mut size = 0;
69        // A bit mask that indicates which fields are present in the stream.
70        // The mask has the following bits:
71        // 0x01    Locale
72        // 0x02    Text
73        let mut encoding_mask: u8 = 0;
74        if !self.locale.is_empty() {
75            encoding_mask |= 0x1;
76        }
77        if !self.text.is_empty() {
78            encoding_mask |= 0x2;
79        }
80        size += encoding_mask.encode(stream)?;
81        if !self.locale.is_empty() {
82            size += self.locale.encode(stream)?;
83        }
84        if !self.text.is_empty() {
85            size += self.text.encode(stream)?;
86        }
87        Ok(size)
88    }
89
90    fn decode<S: Read>(stream: &mut S, decoding_options: &DecodingOptions) -> EncodingResult<Self> {
91        let encoding_mask = u8::decode(stream, decoding_options)?;
92        let locale = if encoding_mask & 0x1 != 0 {
93            UAString::decode(stream, decoding_options)?
94        } else {
95            UAString::null()
96        };
97        let text = if encoding_mask & 0x2 != 0 {
98            UAString::decode(stream, decoding_options)?
99        } else {
100            UAString::null()
101        };
102        Ok(LocalizedText { locale, text })
103    }
104}
105
106impl LocalizedText {
107    pub fn new(locale: &str, text: &str) -> LocalizedText {
108        LocalizedText {
109            locale: UAString::from(locale),
110            text: UAString::from(text),
111        }
112    }
113
114    pub fn null() -> LocalizedText {
115        LocalizedText {
116            locale: UAString::null(),
117            text: UAString::null(),
118        }
119    }
120}