common_meta/key/
node_address.rs1use std::fmt::Display;
16
17use api::v1::meta::Role;
18use serde::{Deserialize, Serialize};
19use snafu::OptionExt;
20
21use crate::error::{InvalidMetadataSnafu, Result};
22use crate::key::{MetadataKey, NODE_ADDRESS_PATTERN, NODE_ADDRESS_PREFIX};
23use crate::peer::Peer;
24
25#[derive(Debug, PartialEq)]
29pub struct NodeAddressKey {
30 pub role: Role,
31 pub node_id: u64,
32}
33
34impl NodeAddressKey {
35 pub fn new(role: Role, node_id: u64) -> Self {
36 Self { role, node_id }
37 }
38
39 pub fn with_datanode(node_id: u64) -> Self {
40 Self::new(Role::Datanode, node_id)
41 }
42
43 pub fn with_flownode(node_id: u64) -> Self {
44 Self::new(Role::Flownode, node_id)
45 }
46}
47
48#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
49pub struct NodeAddressValue {
50 pub peer: Peer,
51}
52
53impl NodeAddressValue {
54 pub fn new(peer: Peer) -> Self {
55 Self { peer }
56 }
57}
58
59impl MetadataKey<'_, NodeAddressKey> for NodeAddressKey {
60 fn to_bytes(&self) -> Vec<u8> {
61 self.to_string().into_bytes()
62 }
63
64 fn from_bytes(bytes: &[u8]) -> Result<NodeAddressKey> {
65 let key = std::str::from_utf8(bytes).map_err(|e| {
66 InvalidMetadataSnafu {
67 err_msg: format!(
68 "NodeAddressKey '{}' is not a valid UTF8 string: {e}",
69 String::from_utf8_lossy(bytes)
70 ),
71 }
72 .build()
73 })?;
74 let captures = NODE_ADDRESS_PATTERN
75 .captures(key)
76 .context(InvalidMetadataSnafu {
77 err_msg: format!("Invalid NodeAddressKey '{key}'"),
78 })?;
79 let role = captures[1].parse::<i32>().unwrap();
81 let role = Role::try_from(role).map_err(|_| {
82 InvalidMetadataSnafu {
83 err_msg: format!("Invalid Role value: {role}"),
84 }
85 .build()
86 })?;
87 let node_id = captures[2].parse::<u64>().unwrap();
88 Ok(NodeAddressKey::new(role, node_id))
89 }
90}
91
92impl Display for NodeAddressKey {
93 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
94 write!(
95 f,
96 "{}/{}/{}",
97 NODE_ADDRESS_PREFIX, self.role as i32, self.node_id
98 )
99 }
100}
101
102#[cfg(test)]
103mod tests {
104 use super::*;
105
106 #[test]
107 fn test_node_address_key() {
108 let key = NodeAddressKey::new(Role::Datanode, 1);
109 let bytes = key.to_bytes();
110 let key2 = NodeAddressKey::from_bytes(&bytes).unwrap();
111 assert_eq!(key, key2);
112
113 let key = NodeAddressKey::new(Role::Flownode, 3);
114 let bytes = key.to_bytes();
115 let key2 = NodeAddressKey::from_bytes(&bytes).unwrap();
116 assert_eq!(key, key2);
117 }
118}