pipeworks_core/
node_id.rs1use anyhow::{Context, Result};
2use bitcode::{Decode, Encode};
3use core::fmt;
4use once_cell::sync::Lazy;
5use rand::RngCore;
6use std::fs;
7use std::path::PathBuf;
8
9pub static NODE_ID: Lazy<NodeId> = Lazy::new(|| NodeId::new());
10
11#[derive(Encode, Decode, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
12pub struct Id([u8; 32]);
13
14#[derive(Encode, Decode, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
15pub struct NodeId {
16 pub node: Id,
17 pub machine: Id,
18}
19
20impl Id {
21 pub fn new() -> Self {
22 let mut rng = rand::rng();
23 let mut new_id = [0u8; 32];
24 rng.fill_bytes(&mut new_id);
25
26 Self(new_id)
27 }
28
29 pub fn new_fs(path: &PathBuf) -> Result<Self> {
30 let id = Self::new();
31
32 if let Some(parent) = path.parent() {
34 if !parent.exists() {
35 fs::create_dir_all(parent).with_context(|| parent.to_string_lossy().to_string())?;
36 }
37 }
38
39 fs::write(path, bitcode::encode(&id))?;
40
41 Ok(id)
42 }
43
44 pub fn load_from_path(path: &PathBuf) -> Result<Self> {
45 Ok(bitcode::decode(&fs::read(path)?)?)
46 }
47}
48
49impl NodeId {
50 pub fn new() -> Self {
51 let path = dirs::home_dir()
52 .expect("Could not find home directory")
53 .join(".local/share/wlabs/machine_id");
54
55 Self {
56 node: Id::new(),
57 machine: Id::load_from_path(&path)
58 .or_else(|_| Id::new_fs(&path))
59 .unwrap(),
60 }
61 }
62
63 pub fn is_me(&self) -> bool {
64 self.node == NODE_ID.node
65 }
66
67 pub fn is_my_machine(&self) -> bool {
68 self.machine == NODE_ID.machine
69 }
70}
71
72impl fmt::Display for NodeId {
73 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
74 match (self.is_me(), self.is_my_machine()) {
75 (true, true) => write!(f, "Self")?,
76 (true, false) => write!(f, "ERR(Self ID on different machine)")?,
77 (false, true) => write!(f, "[Id {}]", self.node)?,
78 (false, false) => write!(f, "[Id {} on LAN {}]", self.node, self.machine)?,
79 }
80
81 Ok(())
82 }
83}
84
85impl fmt::Debug for NodeId {
86 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
87 write!(f, "NodeId(")?;
88 <Self as fmt::Display>::fmt(self, f)?;
89 write!(f, ")")
90 }
91}
92
93impl fmt::Display for Id {
94 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
95 for byte in &self.0[0..2] {
96 write!(f, "{:02x}", byte)?;
97 }
98 Ok(())
99 }
100}
101
102impl fmt::Debug for Id {
103 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
104 write!(f, "MachineId(")?;
105 <Self as fmt::Display>::fmt(self, f)?;
106 write!(f, ")")
107 }
108}