Message de/serial test written (currently failing due to serde_cbor being greedy when deserialising from reader)
Fortune for rsh's current commit: Middle blessing − 中吉specialisation
parent
c41d5c2c28
commit
3e59440609
@ -0,0 +1,105 @@
|
|||||||
|
//! Building `Message<V>`s
|
||||||
|
use super::*;
|
||||||
|
use std::time::SystemTime;
|
||||||
|
|
||||||
|
/// Builder for the `Message<V>` type
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
pub struct MessageBuilder<V: ?Sized>
|
||||||
|
{
|
||||||
|
sign: bool,
|
||||||
|
encrypt: bool,
|
||||||
|
respond: Option<Uuid>,
|
||||||
|
|
||||||
|
_phantom: PhantomData<V>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<V: ?Sized + MessageValue> Default for MessageBuilder<V>
|
||||||
|
{
|
||||||
|
#[inline]
|
||||||
|
fn default() -> Self
|
||||||
|
{
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl<V: ?Sized> MessageBuilder<V>
|
||||||
|
{
|
||||||
|
/// Create a new builder for a message with default settings
|
||||||
|
pub const fn new() -> Self
|
||||||
|
{
|
||||||
|
Self {
|
||||||
|
sign: false,
|
||||||
|
encrypt: false,
|
||||||
|
respond: None,
|
||||||
|
_phantom: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Specify if the message should be signed when serialized.
|
||||||
|
pub const fn sign(mut self, sign: bool) -> Self
|
||||||
|
{
|
||||||
|
self.sign = sign;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Specify if the message should be encrypted when serialized.
|
||||||
|
///
|
||||||
|
/// A key will be generated randomly for the message on creation.
|
||||||
|
pub const fn encrypt(mut self, encrypt: bool) -> Self
|
||||||
|
{
|
||||||
|
self.encrypt = encrypt;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Specify a message ID that this message should respond to.
|
||||||
|
pub const fn respond(mut self, to: Uuid) -> Self
|
||||||
|
{
|
||||||
|
self.respond = Some(to);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<V: ?Sized + MessageValue> MessageBuilder<V>
|
||||||
|
{
|
||||||
|
/// Create a message from this builder with this value.
|
||||||
|
pub fn create(self, value: V) -> eyre::Result<Message<V>>
|
||||||
|
{
|
||||||
|
let key = if self.encrypt {
|
||||||
|
Some(aes::AesKey::generate().wrap_err(eyre!("Failed to generate session key"))?)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
let header = SerHeader::new(self.respond);
|
||||||
|
|
||||||
|
Ok(Message {
|
||||||
|
header,
|
||||||
|
key,
|
||||||
|
sign: self.sign,
|
||||||
|
value,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the current unix timestamp.
|
||||||
|
pub(super) fn timestamp_now() -> u64
|
||||||
|
{
|
||||||
|
match SystemTime::now().duration_since(SystemTime::UNIX_EPOCH) {
|
||||||
|
Ok(n) => n.as_secs(),
|
||||||
|
Err(_) => panic!("Timestamp for now returned before unix epoch."),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SerHeader
|
||||||
|
{
|
||||||
|
/// Create a new header with optional response ID.
|
||||||
|
#[inline] pub fn new(responds: Option<Uuid>) -> Self
|
||||||
|
{
|
||||||
|
Self {
|
||||||
|
id: Uuid::new_v4(),
|
||||||
|
idemp: Uuid::new_v4(),
|
||||||
|
timestamp: timestamp_now(),
|
||||||
|
responds_to: responds,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in new issue