1use std::fmt::Debug;
2use std::net::SocketAddr;
3use std::num::NonZeroU64;
4
5use serde::Deserialize;
6use serde::Serialize;
7
8use crate::INVALID_NODE_ID;
9use crate::LOCAL_NODE_ID;
10use crate::Node;
11use crate::node_lookup_local;
12use crate::node_lookup_remote;
13use crate::node_register;
14
15#[derive(Serialize, Deserialize)]
17enum PidWire {
18 WithNode(NonZeroU64, String, SocketAddr),
19 NodeUnavailable(NonZeroU64),
20}
21
22#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
24pub enum Pid {
25 Local(NonZeroU64),
26 Remote(NonZeroU64, u64),
27}
28
29impl Pid {
30 pub(crate) fn local(id: u64) -> Self {
32 Self::Local(NonZeroU64::new(id).unwrap())
33 }
34
35 pub(crate) fn remote(id: u64, node: u64) -> Self {
37 Self::Remote(NonZeroU64::new(id).unwrap(), node)
38 }
39
40 pub const fn is_local(&self) -> bool {
42 matches!(self, Self::Local(_))
43 }
44
45 pub const fn is_remote(&self) -> bool {
47 matches!(self, Self::Remote(_, _))
48 }
49
50 pub(crate) const fn id(&self) -> u64 {
52 match self {
53 Self::Local(id) => id.get(),
54 Self::Remote(id, _) => id.get(),
55 }
56 }
57
58 pub(crate) const fn node(&self) -> u64 {
60 match self {
61 Self::Local(_) => LOCAL_NODE_ID,
62 Self::Remote(_, node) => *node,
63 }
64 }
65}
66
67impl Debug for Pid {
68 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
69 match self {
70 Self::Local(id) => write!(f, "Pid<0, {}>", id),
71 Self::Remote(id, node) => write!(f, "Pid<{}, {}>", node, id),
72 }
73 }
74}
75
76impl Serialize for Pid {
77 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
78 where
79 S: serde::Serializer,
80 {
81 let pid: PidWire = match self {
82 Self::Local(id) => match node_lookup_local() {
83 Some((name, address)) => PidWire::WithNode(*id, name, address),
84 None => PidWire::NodeUnavailable(*id),
85 },
86 Self::Remote(id, node) => match node_lookup_remote(*node) {
87 Some((name, address)) => PidWire::WithNode(*id, name, address),
88 None => PidWire::NodeUnavailable(*id),
89 },
90 };
91
92 pid.serialize(serializer)
93 }
94}
95
96impl<'de> Deserialize<'de> for Pid {
97 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
98 where
99 D: serde::Deserializer<'de>,
100 {
101 let node: PidWire = PidWire::deserialize(deserializer)?;
102
103 match node {
104 PidWire::WithNode(id, node_name, node_address) => match node_lookup_local() {
105 Some((name, address)) => {
106 if name == node_name && address == node_address {
107 Ok(Pid::Local(id))
108 } else {
109 let node = node_register(Node::from((node_name, node_address)), false);
110
111 Ok(Pid::Remote(id, node))
112 }
113 }
114 None => Ok(Pid::Remote(id, INVALID_NODE_ID)),
115 },
116 PidWire::NodeUnavailable(id) => Ok(Self::Remote(id, INVALID_NODE_ID)),
117 }
118 }
119}