flatty_io/blocking/
send.rs1#[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 fn alloc(&mut self) -> Result<(), Self::Error>;
17
18 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 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}