async_proto/impls/
hematite_nbt.rs1use {
2 std::{
3 io::prelude::*,
4 pin::Pin,
5 },
6 fallible_collections::FallibleVec as _,
7 tokio::io::{
8 AsyncRead,
9 AsyncReadExt as _,
10 AsyncWrite,
11 AsyncWriteExt as _,
12 },
13 crate::{
14 ErrorContext,
15 LengthPrefixed,
16 Protocol,
17 ReadError,
18 ReadErrorKind,
19 WriteError,
20 WriteErrorKind,
21 },
22};
23
24#[cfg_attr(docsrs, doc(cfg(feature = "hematite-nbt")))]
26impl Protocol for nbt::Blob {
27 fn read<'a, R: AsyncRead + Unpin + Send + 'a>(stream: &'a mut R) -> Pin<Box<dyn Future<Output = Result<Self, ReadError>> + Send + 'a>> {
28 Self::read_length_prefixed(stream, u64::MAX)
29 }
30
31 fn write<'a, W: AsyncWrite + Unpin + Send + 'a>(&'a self, sink: &'a mut W) -> Pin<Box<dyn Future<Output = Result<(), WriteError>> + Send + 'a>> {
32 self.write_length_prefixed(sink, u64::MAX)
33 }
34
35 fn read_sync(stream: &mut impl Read) -> Result<Self, ReadError> {
36 Self::read_length_prefixed_sync(stream, u64::MAX)
37 }
38
39 fn write_sync(&self, sink: &mut impl Write) -> Result<(), WriteError> {
40 self.write_length_prefixed_sync(sink, u64::MAX)
41 }
42}
43
44#[cfg_attr(docsrs, doc(cfg(feature = "hematite-nbt")))]
45impl LengthPrefixed for nbt::Blob {
46 fn read_length_prefixed<'a, R: AsyncRead + Unpin + Send + 'a>(stream: &'a mut R, max_len: u64) -> Pin<Box<dyn Future<Output = Result<Self, ReadError>> + Send + 'a>> {
47 Box::pin(async move {
48 let len = super::read_len(stream, max_len, || ErrorContext::BuiltIn { for_type: "nbt::Blob" }).await?;
49 let mut buf = Vec::default();
50 buf.try_resize(len, 0).map_err(|e| ReadError {
51 context: ErrorContext::BuiltIn { for_type: "nbt::Blob" },
52 kind: e.into(),
53 })?;
54 stream.read_exact(&mut buf).await.map_err(|e| ReadError {
55 context: ErrorContext::BuiltIn { for_type: "nbt::Blob" },
56 kind: e.into(),
57 })?;
58 Self::from_gzip_reader(&mut &*buf).map_err(|e| ReadError {
59 context: ErrorContext::BuiltIn { for_type: "nbt::Blob" },
60 kind: ReadErrorKind::Custom(e.to_string()),
61 })
62 })
63 }
64
65 fn write_length_prefixed<'a, W: AsyncWrite + Unpin + Send + 'a>(&'a self, sink: &'a mut W, max_len: u64) -> Pin<Box<dyn Future<Output = Result<(), WriteError>> + Send + 'a>> {
66 Box::pin(async move {
67 let mut buf = Vec::default();
68 self.to_gzip_writer(&mut buf).map_err(|e| WriteError {
69 context: ErrorContext::BuiltIn { for_type: "nbt::Blob" },
70 kind: WriteErrorKind::Custom(e.to_string()),
71 })?;
72 super::write_len(sink, buf.len(), max_len, || ErrorContext::BuiltIn { for_type: "nbt::Blob" }).await?;
73 sink.write_all(&buf).await.map_err(|e| WriteError {
74 context: ErrorContext::BuiltIn { for_type: "nbt::Blob" },
75 kind: e.into(),
76 })?;
77 Ok(())
78 })
79 }
80
81 fn read_length_prefixed_sync(stream: &mut impl Read, max_len: u64) -> Result<Self, ReadError> {
82 let len = super::read_len_sync(stream, max_len, || ErrorContext::BuiltIn { for_type: "nbt::Blob" })?;
83 let mut buf = Vec::default();
84 buf.try_resize(len, 0).map_err(|e| ReadError {
85 context: ErrorContext::BuiltIn { for_type: "nbt::Blob" },
86 kind: e.into(),
87 })?;
88 stream.read_exact(&mut buf).map_err(|e| ReadError {
89 context: ErrorContext::BuiltIn { for_type: "nbt::Blob" },
90 kind: e.into(),
91 })?;
92 Self::from_gzip_reader(&mut &*buf).map_err(|e| ReadError {
93 context: ErrorContext::BuiltIn { for_type: "nbt::Blob" },
94 kind: ReadErrorKind::Custom(e.to_string()),
95 })
96 }
97
98 fn write_length_prefixed_sync(&self, sink: &mut impl Write, max_len: u64) -> Result<(), WriteError> {
99 let mut buf = Vec::default();
100 self.to_gzip_writer(&mut buf).map_err(|e| WriteError {
101 context: ErrorContext::BuiltIn { for_type: "nbt::Blob" },
102 kind: WriteErrorKind::Custom(e.to_string()),
103 })?;
104 super::write_len_sync(sink, buf.len(), max_len, || ErrorContext::BuiltIn { for_type: "nbt::Blob" })?;
105 sink.write_all(&buf).map_err(|e| WriteError {
106 context: ErrorContext::BuiltIn { for_type: "nbt::Blob" },
107 kind: e.into(),
108 })?;
109 Ok(())
110 }
111}