tycho/partial/async_/
element.rs

1use tokio::io::{AsyncRead, AsyncSeek};
2
3use crate::error::TychoResult;
4use crate::ident::ElementIdent;
5use crate::partial::{PartialElement, PartialReader};
6use crate::read::async_::element::read_element_ident_async;
7use crate::read::async_::length::read_length_async;
8use crate::read::async_::string::read_tstring_async;
9use crate::read::async_::value::{read_value_async, read_value_ident_async};
10use crate::types::ident::ValueIdent;
11use futures::future::BoxFuture;
12use futures::FutureExt;
13use crate::partial::types::{PartialStruct, PartialList, PartialArray, PartialMap, PartialCompression};
14
15pub fn read_partial_element_async<R: AsyncRead + AsyncSeek + Unpin + Send>(reader: &mut PartialReader<R>) -> BoxFuture<TychoResult<PartialElement>> {
16    async move {
17        let ident = read_element_ident_async(reader).await?;
18
19        match ident {
20            ElementIdent::Unit => Ok(PartialElement::Unit),
21            ElementIdent::Value => {
22                let prefix = read_value_ident_async(reader).await?;
23                let value = read_value_async(reader, &prefix).await?;
24                Ok(PartialElement::Value(value))
25            },
26
27            ElementIdent::None => Ok(PartialElement::Option(None)),
28            ElementIdent::Some => read_partial_element_async(reader).await,
29
30            ElementIdent::Variant => {
31                let name = read_tstring_async(reader).await?;
32                let value = read_partial_element_async(reader).await?;
33
34                Ok(PartialElement::Variant(name, Box::new(value)))
35            }
36
37            ElementIdent::Struct => {
38                let size = read_length_async(reader).await? as u64;
39                let pos = reader.pointer.clone();
40                reader.jump_async(&size).await?;
41                Ok(PartialElement::Struct(PartialStruct::new(reader.pointer(pos, size), 0, ())))
42            },
43
44            ElementIdent::List => {
45                let size = read_length_async(reader).await? as u64;
46                let pos = reader.pointer.clone();
47                reader.jump_async(&size).await?;
48                Ok(PartialElement::List(PartialList::new(reader.pointer(pos, size), 0, ())))
49            },
50
51            ElementIdent::Array => {
52                let array_type = read_value_ident_async(reader).await?;
53
54                if array_type == ValueIdent::Null {
55                    return Ok(PartialElement::Array(PartialArray::empty(reader.empty_pointer(), array_type)))
56                }
57
58                let size = read_length_async(reader).await? as u64;
59                let pos = reader.pointer.clone();
60                reader.jump_async(&size).await?;
61                Ok(PartialElement::Array(PartialArray::new(reader.pointer(pos, size), 0, array_type)))
62            },
63
64            ElementIdent::Map => {
65                let key_type = read_value_ident_async(reader).await?;
66
67                if key_type == ValueIdent::Null {
68                    return Ok(PartialElement::Map(PartialMap::empty(reader.empty_pointer(), key_type)))
69                }
70
71                let size = read_length_async(reader).await? as u64;
72                let pos = reader.pointer.clone();
73                reader.jump_async(&size).await?;
74                Ok(PartialElement::Map(PartialMap::new(reader.pointer(pos, size), 0, key_type)))
75            },
76
77            ElementIdent::Compression => {
78                let size = read_length_async(reader).await? as u64;
79                let pos = reader.pointer.clone();
80                reader.jump_async(&size).await?;
81                Ok(PartialElement::Compression(PartialCompression::new(reader.pointer(pos, size))))
82            }
83        }
84    }.boxed()
85}