aboutsummaryrefslogtreecommitdiff
path: root/src/message/signalproxy/rpccall/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/message/signalproxy/rpccall/mod.rs136
1 files changed, 136 insertions, 0 deletions
diff --git a/src/message/signalproxy/rpccall/mod.rs b/src/message/signalproxy/rpccall/mod.rs
new file mode 100644
index 0000000..378d626
--- /dev/null
+++ b/src/message/signalproxy/rpccall/mod.rs
@@ -0,0 +1,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 = match_variant!(res.remove(0), Variant::ByteArray);
+
+ 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)),
+ }
+ }
+}