1use serde::{Deserialize, Serialize};
2
3use crate::GateValidationError;
4
5pub const RUNTIME_STAMPED_ACTOR_KINDS: &[&str] = &["actor", "anonymous", "agent"];
10
11pub fn split_stamped_label(label: &str) -> Option<(&str, &str)> {
16 label
17 .split_once(':')
18 .filter(|(kind, _)| RUNTIME_STAMPED_ACTOR_KINDS.contains(kind))
19}
20
21#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize)]
25pub struct ActorRef {
26 pub kind: String,
27 pub id: String,
28}
29
30#[derive(Deserialize)]
32struct RawActorRef {
33 kind: String,
34 id: String,
35}
36
37impl TryFrom<RawActorRef> for ActorRef {
38 type Error = GateValidationError;
39
40 fn try_from(raw: RawActorRef) -> Result<Self, Self::Error> {
41 Self::try_new(raw.kind, raw.id)
42 }
43}
44
45impl<'de> Deserialize<'de> for ActorRef {
46 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
47 where
48 D: serde::Deserializer<'de>,
49 {
50 let raw = RawActorRef::deserialize(deserializer)?;
51 ActorRef::try_from(raw).map_err(serde::de::Error::custom)
52 }
53}
54
55impl ActorRef {
56 pub fn try_new(
58 kind: impl Into<String>,
59 id: impl Into<String>,
60 ) -> Result<Self, GateValidationError> {
61 let kind = kind.into();
62 let id = id.into();
63 if kind.is_empty() {
64 return Err(GateValidationError::EmptyActorKind);
65 }
66 if id.is_empty() {
67 return Err(GateValidationError::EmptyActorId);
68 }
69 Ok(Self { kind, id })
70 }
71
72 pub fn new(kind: impl Into<String>, id: impl Into<String>) -> Self {
74 Self::try_new(kind, id).expect("ActorRef::new: kind and id must not be empty")
75 }
76
77 pub fn anonymous() -> Self {
79 Self {
80 kind: "anonymous".into(),
81 id: "local".into(),
82 }
83 }
84
85 pub fn is_anonymous(&self) -> bool {
87 self.kind == "anonymous"
88 }
89
90 pub fn binding_id(&self) -> Option<&str> {
95 if self.is_anonymous() {
96 None
97 } else {
98 Some(self.id.as_str())
99 }
100 }
101
102 pub fn label(&self) -> String {
105 if self.kind == "actor" {
106 self.id.clone()
107 } else {
108 format!("{}:{}", self.kind, self.id)
109 }
110 }
111}