1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
|
//! Remote Procedure Calls between client and server
//!
//! RpcCalls are serialized to a VariantList first containing the i32 representation of
//! [MessageType::RpcCall], then a ByteArray of the RPC Call Name and the arguments of the call as their own
//! types.
//!
//! In this module you can find structs for each RPC Call as well as the [RpcCall] enum that implements the
//! mapping and de-/serialization. Each struct has an impl of [RpcCallType] that has the meta information for
//! the name of the rpc call as well as it's direction
use crate::error::ProtocolError;
use crate::message::MessageType;
use crate::primitive::{Variant, VariantList};
use crate::serialize::{Deserialize, Serialize};
use libquassel_derive::From;
mod bufferinfo;
mod client;
mod identity;
mod message;
mod network;
mod objectrenamed;
mod passwordchange;
pub use bufferinfo::*;
pub use client::*;
pub use identity::*;
pub use message::*;
pub use network::*;
pub use objectrenamed::*;
pub use passwordchange::*;
#[derive(Clone, Debug, PartialEq, From)]
pub enum RpcCall {
DisplayMessage(DisplayMessage),
DisplayStatusMessage(DisplayStatusMessage),
SendInput(SendInput),
CreateIdentity(CreateIdentity),
RemoveIdentity(RemoveIdentity),
IdentityCreated(IdentityCreated),
IdentityRemoved(IdentityRemoved),
CreateNetwork(CreateNetwork),
RemoveNetwork(RemoveNetwork),
NetworkCreated(NetworkCreated),
NetworkRemoved(NetworkRemoved),
ChangePassword(ChangePassword),
PasswordChanged(PasswordChanged),
KickClient(KickClient),
DisconnectFromCore(DisconnectFromCore),
ObjectRename(ObjectRenamed),
BufferInfoUpdated(BufferInfoUpdated),
NotImplemented,
}
/// Direction of RPC Call
pub enum Direction {
ClientToServer,
ServerToClient,
}
pub trait RpcCallType {
/// String name of the call. Serialized as a [Variant::ByteArray]
const NAME: &str;
/// Whether the call is from the server to the client, or client to server
const DIRECTION: Direction;
/// Convert Self to network representation including it's [Self::NAME]
fn to_network(&self) -> Result<Vec<Variant>, ProtocolError>;
/// Create Self from network representation
fn from_network(size: usize, input: &mut VariantList) -> Result<(usize, RpcCall), crate::ProtocolError>
where
Self: Sized;
}
impl Serialize for RpcCall {
fn serialize(&self) -> Result<Vec<std::primitive::u8>, ProtocolError> {
let mut res = VariantList::new();
res.push(Variant::i32(MessageType::RpcCall as i32));
match self {
RpcCall::DisplayMessage(msg) => res.extend(msg.to_network()?),
RpcCall::DisplayStatusMessage(msg) => res.extend(msg.to_network()?),
RpcCall::SendInput(msg) => res.extend(msg.to_network()?),
RpcCall::CreateIdentity(msg) => res.extend(msg.to_network()?),
RpcCall::RemoveIdentity(msg) => res.extend(msg.to_network()?),
RpcCall::IdentityCreated(msg) => res.extend(msg.to_network()?),
RpcCall::IdentityRemoved(msg) => res.extend(msg.to_network()?),
RpcCall::CreateNetwork(msg) => res.extend(msg.to_network()?),
RpcCall::RemoveNetwork(msg) => res.extend(msg.to_network()?),
RpcCall::NetworkCreated(msg) => res.extend(msg.to_network()?),
RpcCall::NetworkRemoved(msg) => res.extend(msg.to_network()?),
RpcCall::ChangePassword(msg) => res.extend(msg.to_network()?),
RpcCall::PasswordChanged(msg) => res.extend(msg.to_network()?),
RpcCall::KickClient(msg) => res.extend(msg.to_network()?),
RpcCall::DisconnectFromCore(msg) => res.extend(msg.to_network()?),
RpcCall::ObjectRename(msg) => res.extend(msg.to_network()?),
RpcCall::BufferInfoUpdated(msg) => res.extend(msg.to_network()?),
RpcCall::NotImplemented => todo!(),
}
res.serialize()
}
}
impl Deserialize for RpcCall {
fn parse(b: &[std::primitive::u8]) -> Result<(std::primitive::usize, Self), ProtocolError> {
let (size, mut res) = VariantList::parse(&b)?;
res.remove(0);
let rpc: String = res.remove(0).try_into().unwrap();
match rpc.as_str() {
DisplayMessage::NAME => DisplayMessage::from_network(size, &mut res),
DisplayStatusMessage::NAME => DisplayStatusMessage::from_network(size, &mut res),
SendInput::NAME => SendInput::from_network(size, &mut res),
CreateIdentity::NAME => CreateIdentity::from_network(size, &mut res),
RemoveIdentity::NAME => RemoveIdentity::from_network(size, &mut res),
IdentityCreated::NAME => IdentityCreated::from_network(size, &mut res),
IdentityRemoved::NAME => IdentityRemoved::from_network(size, &mut res),
CreateNetwork::NAME => CreateNetwork::from_network(size, &mut res),
RemoveNetwork::NAME => RemoveNetwork::from_network(size, &mut res),
NetworkCreated::NAME => NetworkCreated::from_network(size, &mut res),
NetworkRemoved::NAME => NetworkRemoved::from_network(size, &mut res),
ChangePassword::NAME => ChangePassword::from_network(size, &mut res),
PasswordChanged::NAME => PasswordChanged::from_network(size, &mut res),
KickClient::NAME => KickClient::from_network(size, &mut res),
DisconnectFromCore::NAME => DisconnectFromCore::from_network(size, &mut res),
ObjectRenamed::NAME => ObjectRenamed::from_network(size, &mut res),
BufferInfoUpdated::NAME => BufferInfoUpdated::from_network(size, &mut res),
_ => return Ok((size, RpcCall::NotImplemented)),
}
}
}
|