1use crate::range::ContentRange;
6use crate::repository::Error;
7use crate::util::read_stream_to_end;
8use bytes::Bytes;
9use fidl_fuchsia_pkg_ext::RepositoryConfig;
10use futures::future::ready;
11use futures::stream::once;
12use std::io;
13use std::pin::Pin;
14
15pub struct Resource {
18 pub content_range: ContentRange,
20
21 pub stream:
23 Pin<Box<dyn futures::stream::Stream<Item = io::Result<Bytes>> + Send + Sync + 'static>>,
24}
25
26impl Resource {
27 pub fn content_len(&self) -> u64 {
30 self.content_range.content_len()
31 }
32
33 pub fn total_len(&self) -> u64 {
35 self.content_range.total_len()
36 }
37
38 pub async fn read_to_end(&mut self, buf: &mut Vec<u8>) -> Result<(), Error> {
39 buf.reserve(self.content_len() as usize);
40 read_stream_to_end(&mut self.stream, buf).await.map_err(Error::Io)
41 }
42}
43
44impl std::fmt::Debug for Resource {
45 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
46 f.debug_struct("resource")
47 .field("content_range", &self.content_range)
48 .field("stream", &"..")
49 .finish()
50 }
51}
52
53impl TryFrom<RepositoryConfig> for Resource {
54 type Error = Error;
55
56 fn try_from(config: RepositoryConfig) -> Result<Resource, Error> {
57 let json = Bytes::from(serde_json::to_vec(&config).map_err(|e| anyhow::anyhow!(e))?);
58 let complete_len = json.len() as u64;
59 Ok(Resource {
60 content_range: ContentRange::Full { complete_len },
61 stream: Box::pin(once(ready(Ok(json)))),
62 })
63 }
64}