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::{BoxStream, StreamExt, once};
12use std::io;
13
14pub struct Resource {
17 pub content_range: ContentRange,
19
20 pub stream: BoxStream<'static, io::Result<Bytes>>,
22}
23
24impl Resource {
25 pub fn content_len(&self) -> u64 {
28 self.content_range.content_len()
29 }
30
31 pub fn total_len(&self) -> u64 {
33 self.content_range.total_len()
34 }
35
36 pub async fn read_to_end(&mut self, buf: &mut Vec<u8>) -> Result<(), Error> {
37 buf.reserve(self.content_len() as usize);
38 read_stream_to_end(&mut self.stream, buf).await.map_err(Error::Io)
39 }
40}
41
42impl std::fmt::Debug for Resource {
43 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
44 f.debug_struct("resource")
45 .field("content_range", &self.content_range)
46 .field("stream", &"..")
47 .finish()
48 }
49}
50
51impl TryFrom<RepositoryConfig> for Resource {
52 type Error = Error;
53
54 fn try_from(config: RepositoryConfig) -> Result<Resource, Error> {
55 let json = Bytes::from(serde_json::to_vec(&config).map_err(|e| anyhow::anyhow!(e))?);
56 let complete_len = json.len() as u64;
57 Ok(Resource {
58 content_range: ContentRange::Full { complete_len },
59 stream: once(ready(Ok(json))).boxed(),
60 })
61 }
62}