1pub mod blocking_impl {
5 use crate::{
6 base::Header,
7 element::Element,
8 functional::Encode,
9 master::{Cluster, Segment},
10 };
11 use std::io::{Read, Write};
12
13 pub trait ReadFrom: Sized {
15 fn read_from<R: Read + ?Sized>(r: &mut R) -> crate::Result<Self>;
17 }
18
19 pub trait ReadElement: Sized + Element {
21 fn read_element<R: Read + ?Sized>(header: &Header, r: &mut R) -> crate::Result<Self> {
23 let body = header.read_body(r)?;
24 Self::decode_body(&mut &body[..])
25 }
26 }
27 impl<T: Element> ReadElement for T {}
28
29 impl Header {
30 pub(crate) fn read_body<R: Read + ?Sized>(&self, r: &mut R) -> crate::Result<Vec<u8>> {
32 let size = if self.size.is_unknown && [Segment::ID, Cluster::ID].contains(&self.id) {
34 return Err(crate::Error::ElementBodySizeUnknown(self.id));
35 } else {
36 *self.size
37 };
38 let cap = size.min(4096) as usize;
40 let mut buf = Vec::with_capacity(cap);
41 let n = std::io::copy(&mut r.take(size), &mut buf)?;
42 if size != n {
43 return Err(crate::Error::OutOfBounds);
44 }
45 Ok(buf)
46 }
47 }
48
49 pub trait WriteTo {
51 fn write_to<W: Write + ?Sized>(&self, w: &mut W) -> crate::Result<()>;
53 }
54
55 impl<T: Encode> WriteTo for T {
56 fn write_to<W: Write + ?Sized>(&self, w: &mut W) -> crate::Result<()> {
57 let mut buf = vec![];
59 self.encode(&mut buf)?;
60 w.write_all(&buf)?;
61 Ok(())
62 }
63 }
64
65 pub trait WriteElement: Sized + Element {
67 fn write_element<W: Write + ?Sized>(
69 &self,
70 header: &Header,
71 w: &mut W,
72 ) -> crate::Result<()> {
73 header.write_to(w)?;
74 let mut buf = vec![];
75 self.encode_body(&mut buf)?;
76 w.write_all(&buf)?;
77 Ok(())
78 }
79 }
80 impl<T: Element> WriteElement for T {}
81}
82#[cfg(feature = "tokio")]
84#[cfg_attr(docsrs, doc(cfg(feature = "tokio")))]
85pub mod tokio_impl {
86 use crate::{
87 base::Header,
88 element::Element,
89 master::{Cluster, Segment},
90 };
91
92 use std::future::Future;
93 use tokio::io::{AsyncRead, AsyncReadExt, AsyncWriteExt};
94
95 pub trait AsyncReadFrom: Sized {
97 fn async_read_from<R: tokio::io::AsyncRead + Unpin + ?Sized>(
99 r: &mut R,
100 ) -> impl Future<Output = crate::Result<Self>>;
101 }
102
103 pub trait AsyncReadElement: Sized + Element {
105 fn async_read_element<R: tokio::io::AsyncRead + Unpin + ?Sized>(
107 header: &Header,
108 r: &mut R,
109 ) -> impl std::future::Future<Output = crate::Result<Self>> {
110 async {
111 let body = header.read_body_tokio(r).await?;
112 Self::decode_body(&mut &body[..])
113 }
114 }
115 }
116 impl<T: Element> AsyncReadElement for T {}
117
118 pub trait AsyncWriteTo {
120 fn async_write_to<W: tokio::io::AsyncWrite + Unpin + ?Sized>(
122 &self,
123 w: &mut W,
124 ) -> impl std::future::Future<Output = crate::Result<()>>;
125 }
126
127 impl<T: crate::functional::Encode> AsyncWriteTo for T {
128 async fn async_write_to<W: tokio::io::AsyncWrite + Unpin + ?Sized>(
129 &self,
130 w: &mut W,
131 ) -> crate::Result<()> {
132 let mut buf = vec![];
134 self.encode(&mut buf)?;
135 Ok(w.write_all(&buf).await?)
136 }
137 }
138
139 pub trait AsyncWriteElement: Sized + Element {
141 fn async_write_element<W: tokio::io::AsyncWrite + Unpin + ?Sized>(
143 &self,
144 header: &Header,
145 w: &mut W,
146 ) -> impl std::future::Future<Output = crate::Result<()>> {
147 async {
148 header.async_write_to(w).await?;
149 let mut buf = vec![];
150 self.encode_body(&mut buf)?;
151 Ok(w.write_all(&buf).await?)
152 }
153 }
154 }
155 impl<T: Element> AsyncWriteElement for T {}
156
157 impl Header {
158 pub(crate) async fn read_body_tokio<R: AsyncRead + Unpin + ?Sized>(
160 &self,
161 r: &mut R,
162 ) -> crate::Result<Vec<u8>> {
163 let size = if self.size.is_unknown && [Segment::ID, Cluster::ID].contains(&self.id) {
165 return Err(crate::Error::ElementBodySizeUnknown(self.id));
166 } else {
167 *self.size
168 };
169 let cap = size.min(4096) as usize;
171 let mut buf = Vec::with_capacity(cap);
172 let n = tokio::io::copy(&mut r.take(size), &mut buf).await?;
173 if size != n {
174 return Err(crate::Error::OutOfBounds);
175 }
176 Ok(buf)
177 }
178 }
179}