use core::{
any::TypeId,
ptr::{self, NonNull},
};
use crate::{FrameKind, HeaderSeq, Key, ProtocolError, nash::NameHash, wire_frames};
use cordyceps::{Linked, list::Links};
use postcard::ser_flavors;
use serde::Serialize;
pub mod borrow;
pub mod endpoint;
pub mod owned;
pub mod raw_owned;
pub mod topic;
#[derive(Debug)]
pub struct Attributes {
pub kind: FrameKind,
pub discoverable: bool,
}
#[derive(Debug)]
pub struct SocketHeader {
pub(crate) links: Links<SocketHeader>, pub(crate) vtable: &'static SocketVTable, pub key: Key, pub nash: Option<NameHash>, pub attrs: Attributes, pub port: u8, }
#[cfg_attr(feature = "defmt-v1", derive(defmt::Format))]
#[derive(Debug, PartialEq, Eq)]
#[non_exhaustive]
pub enum SocketSendError {
NoSpace,
DeserFailed,
TypeMismatch,
WhatTheHell,
}
#[derive(Debug, Clone)]
pub struct SocketVTable {
pub(crate) recv_owned: Option<RecvOwned>,
pub(crate) recv_bor: Option<RecvBorrowed>,
pub(crate) recv_raw: RecvRaw,
pub(crate) recv_err: Option<RecvError>,
}
#[derive(Debug)]
#[cfg_attr(feature = "defmt-v1", derive(defmt::Format))]
pub struct HeaderMessage<T> {
pub hdr: HeaderSeq,
pub t: T,
}
pub type Response<T> = Result<HeaderMessage<T>, HeaderMessage<ProtocolError>>;
pub type BorSerFn = fn(NonNull<()>, HeaderSeq, &mut [u8]) -> Result<usize, SocketSendError>;
pub type RecvOwned = fn(
NonNull<()>,
NonNull<()>,
HeaderSeq,
&TypeId,
) -> Result<(), SocketSendError>;
pub type RecvBorrowed = fn(
NonNull<()>,
NonNull<()>,
HeaderSeq,
BorSerFn,
) -> Result<(), SocketSendError>;
pub type RecvRaw = fn(
NonNull<()>,
&[u8],
HeaderSeq,
) -> Result<(), SocketSendError>;
pub type RecvError = fn(
NonNull<()>,
HeaderSeq,
ProtocolError,
);
pub(crate) fn borser<T: Serialize>(
that: NonNull<()>,
hdr: HeaderSeq,
out: &mut [u8],
) -> Result<usize, SocketSendError> {
let that = that.cast::<T>();
let that: &T = unsafe { that.as_ref() };
let ser = ser_flavors::Slice::new(out);
let Ok(used) = wire_frames::encode_frame_ty(ser, &hdr, that) else {
log::trace!("BOOP");
return Err(SocketSendError::NoSpace);
};
Ok(used.len())
}
unsafe impl Linked<Links<SocketHeader>> for SocketHeader {
type Handle = NonNull<SocketHeader>;
fn into_ptr(r: Self::Handle) -> core::ptr::NonNull<Self> {
r
}
unsafe fn from_ptr(ptr: core::ptr::NonNull<Self>) -> Self::Handle {
ptr
}
unsafe fn links(target: NonNull<Self>) -> NonNull<Links<SocketHeader>> {
let node = unsafe { ptr::addr_of_mut!((*target.as_ptr()).links) };
unsafe { NonNull::new_unchecked(node) }
}
}
impl SocketSendError {
pub fn to_error(&self) -> ProtocolError {
match self {
SocketSendError::NoSpace => ProtocolError::SSE_NO_SPACE,
SocketSendError::DeserFailed => ProtocolError::SSE_DESER_FAILED,
SocketSendError::TypeMismatch => ProtocolError::SSE_TYPE_MISMATCH,
SocketSendError::WhatTheHell => ProtocolError::SSE_WHAT_THE_HELL,
}
}
}