use std::fmt::{self, Debug};
use std::ops::Deref;
use super::super::MessageStructure;
use super::{DynamicSequenceElementMut, Proxy, ProxyMut, ProxySequence, Value, ValueMut};
#[derive(PartialEq, Eq)]
pub struct DynamicMessageView<'msg> {
pub(crate) structure: &'msg MessageStructure,
pub(crate) storage: &'msg [u8],
}
#[derive(PartialEq, Eq)]
pub struct DynamicMessageViewMut<'msg> {
pub(crate) structure: &'msg MessageStructure,
pub(crate) storage: &'msg mut [u8],
}
impl<'msg> Debug for DynamicMessageView<'msg> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
let mut struct_ = f.debug_struct(&self.structure().type_name);
for field in &self.structure().fields {
let value = self.get(&field.name).unwrap();
struct_.field(&field.name, &value as &dyn Debug);
}
struct_.finish()
}
}
impl<'msg> Deref for DynamicMessageView<'msg> {
type Target = MessageStructure;
fn deref(&self) -> &Self::Target {
self.structure
}
}
unsafe impl<'msg> Proxy<'msg> for DynamicMessageView<'msg> {
type Metadata = &'msg MessageStructure;
fn size_in_memory(structure: Self::Metadata) -> usize {
structure.size
}
unsafe fn new(bytes: &'msg [u8], structure: Self::Metadata) -> Self {
DynamicMessageView {
structure,
storage: bytes,
}
}
}
impl<'msg> DynamicMessageView<'msg> {
pub fn get(&self, field_name: &str) -> Option<Value<'msg>> {
let field_info = self.structure.get_field_info(field_name)?;
let size = field_info.size().unwrap_or(1);
let bytes = &self.storage[field_info.offset..field_info.offset + size];
unsafe { Value::new(bytes, field_info) }
}
pub fn structure(&self) -> &MessageStructure {
self.structure
}
pub fn iter(&self) -> impl Iterator<Item = (&str, Value<'_>)> + '_ {
self.structure.fields.iter().map(|field_info| {
let value = self.get(&field_info.name).unwrap();
(field_info.name.as_str(), value)
})
}
}
impl<'msg> Debug for DynamicMessageViewMut<'msg> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
DynamicMessageView {
structure: self.structure,
storage: &*self.storage,
}
.fmt(f)
}
}
impl<'msg> Deref for DynamicMessageViewMut<'msg> {
type Target = MessageStructure;
fn deref(&self) -> &Self::Target {
self.structure
}
}
impl<'msg> DynamicSequenceElementMut<'msg> for DynamicMessageViewMut<'msg> {
type InnerSequence = ProxySequence<'msg, Self>;
}
unsafe impl<'msg> ProxyMut<'msg> for DynamicMessageViewMut<'msg> {
type Metadata = &'msg MessageStructure;
fn size_in_memory(structure: Self::Metadata) -> usize {
structure.size
}
unsafe fn new(bytes: &'msg mut [u8], structure: Self::Metadata) -> Self {
DynamicMessageViewMut {
structure,
storage: bytes,
}
}
}
impl<'msg> DynamicMessageViewMut<'msg> {
pub fn get(&self, field_name: &str) -> Option<Value<'_>> {
let field_info = self.structure.get_field_info(field_name)?;
let size = field_info.size().unwrap_or(1);
let bytes = &self.storage[field_info.offset..field_info.offset + size];
unsafe { Value::new(bytes, field_info) }
}
pub fn get_mut(&mut self, field_name: &str) -> Option<ValueMut<'_>> {
let field_info = self.structure.get_field_info(field_name)?;
let size = field_info.size().unwrap_or(1);
let bytes = &mut self.storage[field_info.offset..field_info.offset + size];
Some(unsafe { ValueMut::new(bytes, field_info) })
}
pub fn structure(&self) -> &MessageStructure {
self.structure
}
pub fn iter(&self) -> impl Iterator<Item = (&str, Value<'_>)> + '_ {
self.structure.fields.iter().map(|field_info| {
let value = self.get(&field_info.name).unwrap();
(field_info.name.as_str(), value)
})
}
pub fn iter_mut(self) -> impl Iterator<Item = (&'msg str, ValueMut<'msg>)> + 'msg {
let offsets_next = self
.structure
.fields
.iter()
.map(|field_info| field_info.offset)
.chain([self.structure.size])
.skip(1);
self.structure.fields.iter().zip(offsets_next).scan(
self.storage,
|remainder: &mut &'msg mut [u8], (field_info, next_field_offset)| {
let rem = std::mem::take(remainder);
let (value_bytes, rem) = rem.split_at_mut(next_field_offset - field_info.offset);
*remainder = rem;
let value = unsafe { ValueMut::new(value_bytes, field_info) };
Some((field_info.name.as_str(), value))
},
)
}
}