hebo_codec/
string_pair_data.rs

1// Copyright (c) 2021 Xu Shaohua <shaohua@biofan.org>. All rights reserved.
2// Use of this source is governed by Apache-2.0 License that can be found
3// in the LICENSE file.
4
5use std::fmt;
6
7use crate::{ByteArray, DecodeError, DecodePacket, EncodeError, EncodePacket, StringData};
8
9/// A UTF-8 String Pair consists of two UTF-8 Encoded Strings.
10///
11/// This data type is used to hold name-value pairs.
12/// The first string serves as the name, and the second string contains the value.
13///
14/// Both strings MUST comply with the requirements for UTF-8 Encoded Strings [MQTT-1.5.7-1].
15/// If a receiver (Client or Server) receives a string pair which does not meet
16/// these requirements it is a Malformed Packet.
17///
18/// ```text
19/// +----------------------+
20/// | Key Length           |
21/// |                      |
22/// +----------------------+
23/// | Key characters       |
24/// |                      |
25/// +----------------------+
26/// | Value Length         |
27/// |                      |
28/// +----------------------+
29/// | Value characters     |
30/// |                      |
31/// +----------------------+
32/// ```
33#[derive(Clone, Debug, Default, PartialEq, Eq)]
34pub struct StringPairData(StringData, StringData);
35
36impl StringPairData {
37    /// Create a new string pair.
38    ///
39    /// # Errors
40    ///
41    /// Returns errors if key or value is too large.
42    pub fn new(key: &str, value: &str) -> Result<Self, EncodeError> {
43        let key = StringData::from(key)?;
44        let value = StringData::from(value)?;
45        Ok(Self(key, value))
46    }
47
48    /// Get key in pair.
49    #[must_use]
50    pub const fn key(&self) -> &StringData {
51        &self.0
52    }
53
54    /// Get string value in pari.
55    #[must_use]
56    pub const fn value(&self) -> &StringData {
57        &self.1
58    }
59
60    /// Get byte length in packet.
61    #[must_use]
62    pub fn bytes(&self) -> usize {
63        self.0.bytes() + self.1.bytes()
64    }
65}
66
67impl fmt::Display for StringPairData {
68    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
69        write!(f, "({}, {})", self.0, self.1)
70    }
71}
72
73impl DecodePacket for StringPairData {
74    fn decode(ba: &mut ByteArray) -> Result<Self, DecodeError> {
75        let key = StringData::decode(ba)?;
76        let value = StringData::decode(ba)?;
77        Ok(Self(key, value))
78    }
79}
80
81impl EncodePacket for StringPairData {
82    fn encode(&self, buf: &mut Vec<u8>) -> Result<usize, EncodeError> {
83        let key_len = self.0.encode(buf)?;
84        let value_len = self.1.encode(buf)?;
85        Ok(key_len + value_len)
86    }
87}