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}