|
@@ -78,6 +78,8 @@ pub struct MessageHeader {
|
|
|
/// Group associated with the message.
|
|
|
/// In client-server mode receipts, this is the recipient instead.
|
|
|
pub group: String,
|
|
|
+ /// ID unique to a message and its receipt for a (sender, group) pair.
|
|
|
+ pub id: u32,
|
|
|
/// The type and size of the message payload.
|
|
|
pub body: MessageBody,
|
|
|
}
|
|
@@ -87,8 +89,9 @@ impl MessageHeader {
|
|
|
pub fn serialize(&self) -> SerializedMessage {
|
|
|
// serialized message header: {
|
|
|
// header_len: u32,
|
|
|
- // sender: {u32, utf-8}
|
|
|
- // group: {u32, utf-8}
|
|
|
+ // sender: {u32, utf-8},
|
|
|
+ // group: {u32, utf-8},
|
|
|
+ // id: u32,
|
|
|
// body_type: MessageBody (i.e., u32)
|
|
|
// }
|
|
|
|
|
@@ -97,7 +100,8 @@ impl MessageHeader {
|
|
|
MessageBody::Size(s) => s.get(),
|
|
|
};
|
|
|
|
|
|
- let header_len = (1 + 1 + 1 + 1) * size_of::<u32>() + self.sender.len() + self.group.len();
|
|
|
+ let header_len =
|
|
|
+ (1 + 1 + 1 + 1 + 1) * size_of::<u32>() + self.sender.len() + self.group.len();
|
|
|
|
|
|
let mut header: Vec<u8> = Vec::with_capacity(header_len);
|
|
|
|
|
@@ -107,6 +111,8 @@ impl MessageHeader {
|
|
|
serialize_str_to(&self.sender, &mut header);
|
|
|
serialize_str_to(&self.group, &mut header);
|
|
|
|
|
|
+ header.extend(self.id.to_be_bytes());
|
|
|
+
|
|
|
header.extend(body_type.to_be_bytes());
|
|
|
|
|
|
assert!(header.len() == header_len as usize);
|
|
@@ -125,6 +131,8 @@ impl MessageHeader {
|
|
|
let (group, buf) = deserialize_str(buf)?;
|
|
|
let group = group.to_string();
|
|
|
|
|
|
+ let (id, buf) = deserialize_u32(buf)?;
|
|
|
+
|
|
|
let (body, _) = deserialize_u32(buf)?;
|
|
|
let body = if let Some(size) = NonZeroU32::new(body) {
|
|
|
MessageBody::Size(size)
|
|
@@ -134,6 +142,7 @@ impl MessageHeader {
|
|
|
Ok(Self {
|
|
|
sender,
|
|
|
group,
|
|
|
+ id,
|
|
|
body,
|
|
|
})
|
|
|
}
|
|
@@ -146,6 +155,7 @@ impl MessageHeader {
|
|
|
pub struct MessageHeaderRef<'a> {
|
|
|
pub sender: &'a str,
|
|
|
pub group: &'a str,
|
|
|
+ pub id: u32,
|
|
|
pub body: MessageBody,
|
|
|
}
|
|
|
|
|
@@ -159,6 +169,8 @@ impl<'a> MessageHeaderRef<'a> {
|
|
|
let (group, buf) = deserialize_str(buf)?;
|
|
|
let group = group;
|
|
|
|
|
|
+ let (id, buf) = deserialize_u32(buf)?;
|
|
|
+
|
|
|
let (body, _) = deserialize_u32(buf)?;
|
|
|
let body = if let Some(size) = NonZeroU32::new(body) {
|
|
|
MessageBody::Size(size)
|
|
@@ -168,6 +180,7 @@ impl<'a> MessageHeaderRef<'a> {
|
|
|
Ok(Self {
|
|
|
sender,
|
|
|
group,
|
|
|
+ id,
|
|
|
body,
|
|
|
})
|
|
|
}
|
|
@@ -384,6 +397,7 @@ mod tests {
|
|
|
let m1 = MessageHeader {
|
|
|
sender: "Alice".to_string(),
|
|
|
group: "group".to_string(),
|
|
|
+ id: 1024,
|
|
|
body: MessageBody::Size(NonZeroU32::new(256).unwrap()),
|
|
|
};
|
|
|
|
|
@@ -398,6 +412,7 @@ mod tests {
|
|
|
let m1 = MessageHeader {
|
|
|
sender: "Alice".to_string(),
|
|
|
group: "group".to_string(),
|
|
|
+ id: 1024,
|
|
|
body: MessageBody::Receipt,
|
|
|
};
|
|
|
|
|
@@ -412,6 +427,7 @@ mod tests {
|
|
|
let m1 = MessageHeader {
|
|
|
sender: "Alice".to_string(),
|
|
|
group: "group".to_string(),
|
|
|
+ id: 1024,
|
|
|
body: MessageBody::Size(NonZeroU32::new(256).unwrap()),
|
|
|
};
|
|
|
|
|
@@ -429,6 +445,7 @@ mod tests {
|
|
|
let m1 = MessageHeader {
|
|
|
sender: "Alice".to_string(),
|
|
|
group: "group".to_string(),
|
|
|
+ id: 1024,
|
|
|
body: MessageBody::Receipt,
|
|
|
};
|
|
|
|
|
@@ -446,6 +463,7 @@ mod tests {
|
|
|
let m1 = MessageHeader {
|
|
|
sender: "Alice".to_string(),
|
|
|
group: "group".to_string(),
|
|
|
+ id: 1024,
|
|
|
body: MessageBody::Size(NonZeroU32::new(256).unwrap()),
|
|
|
};
|
|
|
|
|
@@ -466,6 +484,7 @@ mod tests {
|
|
|
let m1 = MessageHeader {
|
|
|
sender: "Alice".to_string(),
|
|
|
group: "group".to_string(),
|
|
|
+ id: 1024,
|
|
|
body: MessageBody::Receipt,
|
|
|
};
|
|
|
|