flatty_io/blocking/
send.rs

1#[cfg(feature = "io")]
2use crate::IoBuffer;
3use crate::SendError;
4use core::{
5    marker::PhantomData,
6    ops::{Deref, DerefMut},
7};
8use flatty::{self, prelude::*, Emplacer};
9#[cfg(feature = "io")]
10use std::io::Write;
11
12pub trait WriteBuffer: DerefMut<Target = [u8]> {
13    type Error;
14
15    /// Allocate some fixed amount of bytes in the buffer.
16    fn alloc(&mut self) -> Result<(), Self::Error>;
17
18    /// Send exactly `count` bytes from buffer.
19    /// Remaining bytes are discarded.
20    fn write_all(&mut self, count: usize) -> Result<(), Self::Error>;
21}
22
23pub struct Sender<M: Flat + ?Sized, B: WriteBuffer> {
24    pub(crate) buffer: B,
25    _ghost: PhantomData<M>,
26}
27
28impl<M: Flat + ?Sized, B: WriteBuffer> Sender<M, B> {
29    pub fn new(buf_send: B) -> Self {
30        Self {
31            buffer: buf_send,
32            _ghost: PhantomData,
33        }
34    }
35}
36
37#[cfg(feature = "io")]
38pub type IoSender<M, P> = Sender<M, IoBuffer<P>>;
39
40#[cfg(feature = "io")]
41impl<M: Flat + ?Sized, P: Write> IoSender<M, P> {
42    pub fn io(pipe: P, max_msg_len: usize) -> Self {
43        Self::new(IoBuffer::new(pipe, 2 * max_msg_len.max(M::MIN_SIZE), M::ALIGN))
44    }
45}
46
47impl<M: Flat + ?Sized, B: WriteBuffer> Sender<M, B> {
48    pub fn alloc(&mut self) -> Result<UninitSendGuard<'_, M, B>, SendError<B::Error>> {
49        self.buffer.alloc()?;
50        Ok(UninitSendGuard::new(&mut self.buffer))
51    }
52}
53
54impl<'a, M: Flat + ?Sized, B: WriteBuffer> SendGuard<'a, M, B> {
55    pub fn send(self) -> Result<(), SendError<B::Error>> {
56        let size = self.size();
57        self.buffer.write_all(size)
58    }
59}
60
61pub struct SendGuard<'a, M: Flat + ?Sized, B: WriteBuffer + 'a, const INIT: bool = true> {
62    pub(crate) buffer: &'a mut B,
63    _ghost: PhantomData<M>,
64}
65
66pub type UninitSendGuard<'a, M, B> = SendGuard<'a, M, B, false>;
67
68impl<'a, M: Flat + ?Sized, B: WriteBuffer + 'a> UninitSendGuard<'a, M, B> {
69    pub(crate) fn new(buffer: &'a mut B) -> Self {
70        Self {
71            buffer,
72            _ghost: PhantomData,
73        }
74    }
75
76    pub fn as_bytes(&self) -> &[u8] {
77        self.buffer
78    }
79    pub fn as_mut_bytes(&mut self) -> &mut [u8] {
80        self.buffer
81    }
82
83    /// # Safety
84    ///
85    /// Underlying message data must be initialized.
86    pub unsafe fn assume_init(self) -> SendGuard<'a, M, B> {
87        SendGuard {
88            buffer: self.buffer,
89            _ghost: PhantomData,
90        }
91    }
92
93    pub fn new_in_place(self, emplacer: impl Emplacer<M>) -> Result<SendGuard<'a, M, B>, flatty::Error> {
94        M::new_in_place(self.buffer, emplacer)?;
95        Ok(unsafe { self.assume_init() })
96    }
97}
98
99impl<'a, M: Flat + FlatDefault + ?Sized, B: WriteBuffer + 'a> UninitSendGuard<'a, M, B> {
100    pub fn default_in_place(self) -> Result<SendGuard<'a, M, B>, flatty::Error> {
101        M::default_in_place(self.buffer)?;
102        Ok(unsafe { self.assume_init() })
103    }
104}
105
106impl<'a, M: Flat + ?Sized, B: WriteBuffer + 'a> Deref for SendGuard<'a, M, B> {
107    type Target = M;
108    fn deref(&self) -> &M {
109        unsafe { M::from_bytes_unchecked(self.buffer) }
110    }
111}
112
113impl<'a, M: Flat + ?Sized, B: WriteBuffer + 'a> DerefMut for SendGuard<'a, M, B> {
114    fn deref_mut(&mut self) -> &mut M {
115        unsafe { M::from_mut_bytes_unchecked(self.buffer) }
116    }
117}