aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMax Audron <audron@cocaine.farm>2021-07-21 18:25:16 +0200
committerMax Audron <audron@cocaine.farm>2021-07-21 18:28:09 +0200
commit96369928a757633df543837ffd1e9f537486869b (patch)
tree6be680de0a09afb4219cbdaa6340d86079acf08d
parentfix network object (diff)
change IRC MessageType to be a bitflag instead of enum
the BufferSyncer object uses this type in a bitflag manner to indicate all the kinds of change that happened. bitflag still allows very enum esque usage so the change is okay for the Message object.
Diffstat (limited to '')
-rw-r--r--Cargo.toml2
-rw-r--r--src/primitive/message.rs146
2 files changed, 94 insertions, 54 deletions
diff --git a/Cargo.toml b/Cargo.toml
index 41a88e6..620f4e0 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -21,6 +21,8 @@ time = "0.2"
num-traits = "0.2"
num-derive = "0.3"
+bitflags = "1"
+
itertools = "0.10"
libquassel-derive = { path = "./derive" }
diff --git a/src/primitive/message.rs b/src/primitive/message.rs
index 36a55c5..e73f3dd 100644
--- a/src/primitive/message.rs
+++ b/src/primitive/message.rs
@@ -1,6 +1,4 @@
-use std::vec::Vec;
-
-use num_derive::{FromPrimitive, ToPrimitive};
+use std::{collections::HashMap, convert::TryInto, vec::Vec};
use failure::Error;
@@ -8,6 +6,8 @@ use crate::{deserialize::*, serialize::*};
use crate::primitive::BufferInfo;
+use super::Variant;
+
/// The Message struct represents a Message as received in IRC
///
/// Messages are, like all other struct based types, serialized sequentially.
@@ -68,7 +68,7 @@ impl Serialize for Message {
#[cfg(not(feature = "long-time"))]
values.append(&mut i32::serialize(&(self.timestamp as i32))?);
- values.append(&mut i32::serialize(&(self.msg_type as i32))?);
+ values.append(&mut i32::serialize(&(self.msg_type.bits()))?);
values.append(&mut i8::serialize(&(self.flags as i8))?);
values.append(&mut BufferInfo::serialize(&self.buffer)?);
values.append(&mut String::serialize_utf8(&self.sender)?);
@@ -155,7 +155,7 @@ impl Deserialize for Message {
Self {
msg_id,
timestamp,
- msg_type: MessageType::from(msg_type),
+ msg_type: MessageType::from_bits(msg_type).unwrap(),
flags,
buffer,
sender,
@@ -171,55 +171,93 @@ impl Deserialize for Message {
}
}
-#[repr(i32)]
-#[derive(Copy, Clone, Debug, std::cmp::PartialEq, FromPrimitive, ToPrimitive)]
-pub enum MessageType {
- None = 0x00000000,
- Plain = 0x00000001,
- Notice = 0x00000002,
- Action = 0x00000004,
- Nick = 0x00000008,
- Mode = 0x00000010,
- Join = 0x00000020,
- Part = 0x00000040,
- Quit = 0x00000080,
- Kick = 0x00000100,
- Kill = 0x00000200,
- Server = 0x00000400,
- Info = 0x00000800,
- Error = 0x00001000,
- DayChange = 0x00002000,
- Topic = 0x00004000,
- NetsplitJoin = 0x00008000,
- NetsplitQuit = 0x00010000,
- Invite = 0x00020000,
- Markerline = 0x00040000,
+// #[repr(i32)]
+// #[derive(Copy, Clone, Debug, std::cmp::PartialEq, FromPrimitive, ToPrimitive)]
+// pub enum MessageType {
+// None = 0x00000000,
+// Plain = 0x00000001,
+// Notice = 0x00000002,
+// Action = 0x00000004,
+// Nick = 0x00000008,
+// Mode = 0x00000010,
+// Join = 0x00000020,
+// Part = 0x00000040,
+// Quit = 0x00000080,
+// Kick = 0x00000100,
+// Kill = 0x00000200,
+// Server = 0x00000400,
+// Info = 0x00000800,
+// Error = 0x00001000,
+// DayChange = 0x00002000,
+// Topic = 0x00004000,
+// NetsplitJoin = 0x00008000,
+// NetsplitQuit = 0x00010000,
+// Invite = 0x00020000,
+// Markerline = 0x00040000,
+// }
+use bitflags::bitflags;
+
+bitflags! {
+ pub struct MessageType: i32 {
+ const NONE = 0x00000000;
+ const PLAIN = 0x00000001;
+ const NOTICE = 0x00000002;
+ const ACTION = 0x00000004;
+ const NICK = 0x00000008;
+ const MODE = 0x00000010;
+ const JOIN = 0x00000020;
+ const PART = 0x00000040;
+ const QUIT = 0x00000080;
+ const KICK = 0x00000100;
+ const KILL = 0x00000200;
+ const SERVER = 0x00000400;
+ const INFO = 0x00000800;
+ const ERROR = 0x00001000;
+ const DAY_CHANGE = 0x00002000;
+ const TOPIC = 0x00004000;
+ const NETSPLIT_JOIN = 0x00008000;
+ const NETSPLIT_QUIT = 0x00010000;
+ const INVITE = 0x00020000;
+ const MARKERLINE = 0x00040000;
+ }
}
-impl From<i32> for MessageType {
- fn from(val: i32) -> Self {
- match val {
- 0x00000001 => MessageType::Plain,
- 0x00000002 => MessageType::Notice,
- 0x00000004 => MessageType::Action,
- 0x00000008 => MessageType::Nick,
- 0x00000010 => MessageType::Mode,
- 0x00000020 => MessageType::Join,
- 0x00000040 => MessageType::Part,
- 0x00000080 => MessageType::Quit,
- 0x00000100 => MessageType::Kick,
- 0x00000200 => MessageType::Kill,
- 0x00000400 => MessageType::Server,
- 0x00000800 => MessageType::Info,
- 0x00001000 => MessageType::Error,
- 0x00002000 => MessageType::DayChange,
- 0x00004000 => MessageType::Topic,
- 0x00008000 => MessageType::NetsplitJoin,
- 0x00010000 => MessageType::NetsplitQuit,
- 0x00020000 => MessageType::Invite,
- 0x00040000 => MessageType::Markerline,
- _ => unimplemented!(),
- }
+impl<T> crate::message::Network for HashMap<T, MessageType>
+where
+ T: std::convert::TryFrom<Variant> + Into<Variant> + Clone + std::hash::Hash + std::cmp::Eq,
+{
+ type Item = super::VariantList;
+
+ fn to_network(&self) -> Self::Item {
+ let mut res = Vec::with_capacity(self.len() * 2);
+
+ self.iter().for_each(|(k, v)| {
+ res.push((*k).clone().into());
+ res.push((*v).clone().bits().into());
+ });
+
+ return res;
+ }
+
+ fn from_network(input: &mut Self::Item) -> Self {
+ use itertools::Itertools;
+
+ let mut res = HashMap::with_capacity(input.len() / 2);
+
+ input.iter().tuples().for_each(|(k, v)| {
+ res.insert(
+ match T::try_from(k.clone()) {
+ Ok(it) => it,
+ _ => unreachable!(),
+ },
+ {
+ let typ = v.try_into().expect("failed to get from variant");
+ MessageType::from_bits(typ).expect("failed to get messagetype from i32")
+ },
+ );
+ });
+
+ return res;
}
}
@@ -234,7 +272,7 @@ mod tests {
let message = Message {
msg_id: 1,
timestamp: 1609846597,
- msg_type: MessageType::Plain,
+ msg_type: MessageType::PLAIN,
flags: 0,
buffer: BufferInfo {
id: 1,
@@ -268,7 +306,7 @@ mod tests {
let message = Message {
msg_id: 1,
timestamp: 1609846597,
- msg_type: MessageType::Plain,
+ msg_type: MessageType::PLAIN,
flags: 0,
buffer: BufferInfo {
id: 1,