1use crate::ids::{CallId, CapId};
2use serde::{Deserialize, Serialize};
3use serde_json::Value;
4
5#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
6#[serde(untagged)]
7pub enum Target {
8 Cap { cap: CapIdWrapper },
9 Special { special: String },
10}
11
12#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
13pub struct CapIdWrapper {
14 pub id: CapId,
15}
16
17#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
18#[serde(untagged)]
19pub enum Outcome {
20 Success { value: Value },
21 Error { error: crate::error::RpcError },
22}
23
24#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
25#[serde(untagged)]
26pub enum Message {
27 Call {
28 call: CallMessage,
29 },
30 Result {
31 result: ResultMessage,
32 },
33 CapRef {
34 #[serde(rename = "capRef")]
35 cap_ref: CapRefMessage,
36 },
37 Dispose {
38 dispose: DisposeMessage,
39 },
40}
41
42#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
43pub struct CallMessage {
44 pub id: CallId,
45 pub target: Target,
46 pub member: String,
47 pub args: Vec<Value>,
48}
49
50#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
51pub struct ResultMessage {
52 pub id: CallId,
53 #[serde(flatten)]
54 pub outcome: Outcome,
55}
56
57#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
58pub struct CapRefMessage {
59 pub id: CapId,
60}
61
62#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
63pub struct DisposeMessage {
64 pub caps: Vec<CapId>,
65}
66
67impl Target {
68 pub fn cap(id: CapId) -> Self {
69 Target::Cap {
70 cap: CapIdWrapper { id },
71 }
72 }
73
74 pub fn special(name: String) -> Self {
75 Target::Special { special: name }
76 }
77}
78
79impl Message {
80 pub fn call(id: CallId, target: Target, member: String, args: Vec<Value>) -> Self {
81 Message::Call {
82 call: CallMessage {
83 id,
84 target,
85 member,
86 args,
87 },
88 }
89 }
90
91 pub fn result(id: CallId, outcome: Outcome) -> Self {
92 Message::Result {
93 result: ResultMessage { id, outcome },
94 }
95 }
96
97 pub fn cap_ref(id: CapId) -> Self {
98 Message::CapRef {
99 cap_ref: CapRefMessage { id },
100 }
101 }
102
103 pub fn dispose(caps: Vec<CapId>) -> Self {
104 Message::Dispose {
105 dispose: DisposeMessage { caps },
106 }
107 }
108}
109
110#[cfg(test)]
111mod tests {
112 use super::*;
113
114 #[test]
115 fn test_message_serialization() {
116 let msg = Message::call(
117 CallId::new(1),
118 Target::cap(CapId::new(42)),
119 "test".to_string(),
120 vec![Value::String("arg".to_string())],
121 );
122
123 let json = serde_json::to_string(&msg).unwrap();
124 let deserialized: Message = serde_json::from_str(&json).unwrap();
125 assert_eq!(msg, deserialized);
126 }
127}