Added `UntypedSerializedMessage`: A `SerializedMessage` whos original value type has been erased. A `SerializedMessage<V>` can be converted into this with `.into_untyped()`, and can be converted back with the `unsafe` function `into_typed<V>()`.

Untyped serialized mmessages cannot be deserialized, they must first be given a type with `into_typed<V>()`. This operation is unsafe as it may cause a potential type confusion if the message"s original `V` is different from the newly specified `V`.

Fortune for rsh's current commit: Half curse − 半凶
message-write-to-buf
Avril 3 years ago
parent c286708bff
commit 6afb148068

@ -27,6 +27,9 @@ pub use builder::*;
pub mod value;
pub use value::MessageValue;
/// A `SerializedMessage` whos type has been erased.
pub type UntypedSerializedMessage = SerializedMessage<value::UntypedMessageValue>;
/// Size of encrypted AES key
pub const RSA_BLOCK_SIZE: usize = 512;
@ -86,6 +89,8 @@ struct SerHeader
timestamp: u64,
/// `id` of message this one is responding to, if needed.
responds_to: Option<Uuid>,
//TODO: Add `flags` bitflags
//TODO: Add `kind` enum
}
/// A reference to a message's header.
@ -104,7 +109,7 @@ impl<V: ?Sized + MessageValue> AsRef<V> for Message<V>
///
/// Messages of this type are not yet validated, and may be invalid/corrupt. The validation happens when converting back to a `Message<V>` (of the same `V`.)
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct SerializedMessage<V: ?Sized + MessageValue>
pub struct SerializedMessage<V: ?Sized>
{
header: SerHeader,
/// cbor serialised `V`.
@ -231,7 +236,7 @@ impl<V: ?Sized + MessageValue> Message<V>
}
}
impl<V: ?Sized + MessageValue> SerializedMessage<V>
impl<V: ?Sized> SerializedMessage<V>
{
/// Get the message header
#[inline(always)] pub fn header(&self) -> MessageHeader<'_, V>
@ -315,6 +320,16 @@ impl<V: ?Sized + MessageValue> SerializedMessage<V>
Ok(w)
}
/// Consume into `Vec<u8>`.
pub fn into_bytes(self) -> Vec<u8>
{
let mut v = Vec::with_capacity(self.data.len()<<1);
self.into_writer(&mut v).expect("Failed to write to in-memory buffer");
v
}
}
impl<V: ?Sized + MessageValue> SerializedMessage<V>
{
/// Create from a reader.
///
/// The message may be in an invalid state. It is only possible to extract the value after validating it into a `Message<V>`.
@ -397,13 +412,7 @@ impl<V: ?Sized + MessageValue> SerializedMessage<V>
_phantom: PhantomData,
})
}
/// Consume into `Vec<u8>`.
pub fn into_bytes(self) -> Vec<u8>
{
let mut v = Vec::with_capacity(self.data.len()<<1);
self.into_writer(&mut v).expect("Failed to write to in-memory buffer");
v
}
/// Create from bytes
#[inline] pub fn from_bytes(bytes: impl AsRef<[u8]>) -> eyre::Result<Self>
{

@ -1,5 +1,6 @@
//! Message values
use super::*;
use std::mem;
use serde::{Serialize, Deserialize};
/// A value that can be used for messages.
@ -26,8 +27,40 @@ pub struct MessageValueAny(Box<dyn Any +'static>);
//where T: Serialize + for<'de> Deserialize<'de> + Any{}
*/
/// A type-unsafe `MessageValue` that can be used to transmute `SerializedMessage` instances.
/// A type-unsafe value that can be used to transmute `SerializedMessage` instances.
///
/// This operation is unsafe and can result in deserializing the `SerializedMessage` failing, or even worse, a type confusion.
#[derive(Debug, Serialize, Deserialize)]
///
/// This type does not implement `MessageValue`, as serialized messages of this value cannot be created (from `Message::serialize()`), nor deserialized. They must first be converted into a typed `SerializedMessage<V>` with `UntypedSerializedMessage::into_typed<V>()`.
///
/// This is an empty (!) type.
#[derive(Debug)]
pub enum UntypedMessageValue{}
impl SerializedMessage<UntypedMessageValue>
{
/// Transmute into a specifically typed `SerializedMessage`
///
/// # Safety
/// If `V` is not the original type of this message (before being untyped), then deserialisation will likely fail, or, much worse, cause a *type consufion* bug, where the object of type `V` is successfully deserialized with an invalid value from an unknown type.
/// Take special care when using this.
pub const unsafe fn into_typed<V: MessageValue + ?Sized>(self) -> SerializedMessage<V>
{
mem::transmute(self)
}
}
impl<V: MessageValue + ?Sized> SerializedMessage<V>
{
/// Consume this value into an untyped `SerializedMessage`.
///
/// # Safety
/// This operation is safe, however, doing anything at all with the resulting `SerializedMessage` is not.
/// It must be unsafly converted into a types message before it can be deserialized.
pub const fn into_untyped(self) -> SerializedMessage<UntypedMessageValue>
{
unsafe {
mem::transmute(self)
}
}
}

Loading…
Cancel
Save