use crate::prelude::*;
use std::{fmt::Debug, mem, pin::Pin, sync::Arc};
#[derive(Clone, Default)]
pub struct EventPayload {
raw: Vec<Arc<Pin<Vec<u8>>>>,
data: ValueAndMeta<'static>,
}
impl Debug for EventPayload {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.data.fmt(f)
}
}
impl EventPayload {
#[must_use]
pub fn suffix(&self) -> &ValueAndMeta {
&self.data
}
#[must_use]
pub fn new<F>(raw: Vec<u8>, f: F) -> Self
where
F: for<'head> FnOnce(&'head mut [u8]) -> ValueAndMeta<'head>,
{
let mut raw = Pin::new(raw);
let data = f(raw.as_mut().get_mut());
let structured = unsafe { mem::transmute::<ValueAndMeta<'_>, ValueAndMeta<'static>>(data) };
let raw = vec![Arc::new(raw)];
Self {
raw,
data: structured,
}
}
pub fn try_new<E, F>(raw: Vec<u8>, f: F) -> std::result::Result<Self, E>
where
F: for<'head> FnOnce(&'head mut [u8]) -> std::result::Result<ValueAndMeta<'head>, E>,
{
let mut raw = Pin::new(raw);
let data = f(raw.as_mut().get_mut())?;
let structured = unsafe { mem::transmute::<ValueAndMeta<'_>, ValueAndMeta<'static>>(data) };
let raw = vec![Arc::new(raw)];
Ok(Self {
raw,
data: structured,
})
}
pub fn rent<'iref, F, R>(&'iref self, f: F) -> R
where
F: for<'head> FnOnce(&'head ValueAndMeta<'head>) -> R,
{
f(unsafe {
mem::transmute::<&'iref ValueAndMeta<'static>, &'iref ValueAndMeta<'iref>>(&self.data)
})
}
pub fn rent_mut<'iref, F, R>(&'iref mut self, f: F) -> R
where
F: for<'head> FnOnce(&'head mut ValueAndMeta<'head>) -> R,
{
f(unsafe {
mem::transmute::<&'iref mut ValueAndMeta<'static>, &'iref mut ValueAndMeta<'iref>>(
&mut self.data,
)
})
}
#[must_use]
pub fn parts<'value, 'borrow>(&'borrow self) -> (&'borrow Value<'value>, &'borrow Value<'value>)
where
'borrow: 'value,
{
let ValueAndMeta { ref v, ref m } = self.data;
(v, m)
}
pub fn consume<'iref, E, F>(
&'iref mut self,
mut other: EventPayload,
join_f: F,
) -> std::result::Result<(), E>
where
E: std::error::Error,
F: for<'head> FnOnce(
&'head mut ValueAndMeta<'head>,
ValueAndMeta<'head>,
) -> std::result::Result<(), E>,
{
self.raw.append(&mut other.raw);
join_f(
unsafe {
mem::transmute::<&'iref mut ValueAndMeta<'static>, &'iref mut ValueAndMeta<'iref>>(
&mut self.data,
)
},
unsafe { mem::transmute::<ValueAndMeta<'static>, ValueAndMeta<'iref>>(other.data) },
)
}
}
impl<T> From<T> for EventPayload
where
ValueAndMeta<'static>: From<T>,
{
fn from(vm: T) -> Self {
Self {
raw: Vec::new(),
data: vm.into(),
}
}
}
impl PartialEq for EventPayload {
fn eq(&self, other: &Self) -> bool {
self.data.eq(&other.data)
}
}
impl simd_json_derive::Serialize for EventPayload {
fn json_write<W>(&self, writer: &mut W) -> std::io::Result<()>
where
W: std::io::Write,
{
self.rent(|d| d.json_write(writer))
}
}
impl<'input> simd_json_derive::Deserialize<'input> for EventPayload {
fn from_tape(tape: &mut simd_json_derive::Tape<'input>) -> simd_json::Result<Self>
where
Self: Sized + 'input,
{
let ValueAndMeta { v, m } = simd_json_derive::Deserialize::from_tape(tape)?;
Ok(Self::new(vec![], |_| {
ValueAndMeta::from_parts(v.into_static(), m.into_static())
}))
}
}
#[derive(
Clone, Debug, PartialEq, Serialize, simd_json_derive::Serialize, simd_json_derive::Deserialize,
)]
pub struct ValueAndMeta<'event> {
v: Value<'event>,
m: Value<'event>,
}
impl<'event> ValueAndMeta<'event> {
#[must_use]
pub fn from_parts(v: Value<'event>, m: Value<'event>) -> Self {
Self { v, m }
}
#[must_use]
pub fn value(&self) -> &Value<'event> {
&self.v
}
#[must_use]
pub fn value_mut(&mut self) -> &mut Value<'event> {
&mut self.v
}
#[must_use]
pub fn meta(&self) -> &Value<'event> {
&self.m
}
#[must_use]
pub fn into_parts(self) -> (Value<'event>, Value<'event>) {
(self.v, self.m)
}
#[must_use]
pub fn parts_mut(&mut self) -> (&mut Value<'event>, &mut Value<'event>) {
(&mut self.v, &mut self.m)
}
#[must_use]
pub fn parts(&self) -> (&Value<'event>, &Value<'event>) {
(&self.v, &self.m)
}
}
impl<'event> Default for ValueAndMeta<'event> {
fn default() -> Self {
ValueAndMeta {
v: Value::object(),
m: Value::object(),
}
}
}
impl<'v> From<Value<'v>> for ValueAndMeta<'v> {
fn from(v: Value<'v>) -> ValueAndMeta<'v> {
ValueAndMeta {
v,
m: Value::object(),
}
}
}
impl<'v, T1, T2> From<(T1, T2)> for ValueAndMeta<'v>
where
Value<'v>: From<T1> + From<T2>,
{
fn from((v, m): (T1, T2)) -> Self {
ValueAndMeta {
v: Value::from(v),
m: Value::from(m),
}
}
}