rsynko_memory/
download.rs1use crate::DownloadSyntax;
2use crate::{DownloadEvent, DownloadProgress};
3use rsynko_download::*;
4use std::cell::{Cell, RefCell};
5use std::collections::BTreeMap;
6use std::io::{Cursor, Read};
7use std::path::{Path, PathBuf};
8use thiserror::Error;
9
10#[derive(Debug, Error, PartialEq, Eq)]
12pub enum ReferenceFetchError {
13 #[error("unknown resource {0}")]
15 UnknownResource(String),
16}
17
18#[derive(Debug, Error, PartialEq, Eq)]
20#[error("publication refused")]
21pub struct ReferencePublishError;
22
23#[derive(Debug, Default)]
25pub struct ReferenceDownloadEnv {
26 resources: BTreeMap<String, Vec<u8>>,
27 refuse_publication: bool,
28 files: RefCell<BTreeMap<PathBuf, Vec<u8>>>,
29 abandoned: Cell<usize>,
30 events: RefCell<Vec<DownloadEvent>>,
31 progress: RefCell<Vec<DownloadProgress>>,
32}
33
34impl ReferenceDownloadEnv {
35 pub fn register_resource(
37 &mut self,
38 url: impl Into<String>,
39 bytes: impl Into<Vec<u8>>,
40 ) -> Option<Vec<u8>> {
41 self.resources.insert(url.into(), bytes.into())
42 }
43
44 pub fn refuse_publication(&mut self) {
46 self.refuse_publication = true;
47 }
48
49 #[must_use]
51 pub fn abandoned(&self) -> usize {
52 self.abandoned.get()
53 }
54
55 #[must_use]
57 pub fn file(&self, path: &Path) -> Option<Vec<u8>> {
58 self.files.borrow().get(path).cloned()
59 }
60
61 #[must_use]
63 pub fn events(&self) -> Vec<DownloadEvent> {
64 self.events.borrow().clone()
65 }
66
67 #[must_use]
69 pub fn progress(&self) -> Vec<DownloadProgress> {
70 self.progress.borrow().clone()
71 }
72}
73
74impl FetchStreamAlg for ReferenceDownloadEnv {
75 type Error = ReferenceFetchError;
76 type Stream = Cursor<Vec<u8>>;
77
78 fn open_fetch(&self, url: &str) -> Result<FetchStream<Self::Stream>, Self::Error> {
79 let bytes = self
80 .resources
81 .get(url)
82 .cloned()
83 .ok_or_else(|| ReferenceFetchError::UnknownResource(url.to_owned()))?;
84 let total = u64::try_from(bytes.len()).ok();
85 Ok(FetchStream::new(Cursor::new(bytes), total))
86 }
87
88 fn read_fetch(
89 &self,
90 stream: &mut Self::Stream,
91 buffer: &mut [u8],
92 ) -> Result<usize, Self::Error> {
93 Ok(stream.read(buffer).unwrap_or(0))
94 }
95}
96
97impl AtomicPublishAlg for ReferenceDownloadEnv {
98 type Error = ReferencePublishError;
99 type Publication = (PathBuf, Vec<u8>);
100
101 fn begin_publication(&self, destination: &Path) -> Result<Self::Publication, Self::Error> {
102 Ok((destination.to_owned(), Vec::default()))
103 }
104
105 fn write_publication(
106 &self,
107 publication: &mut Self::Publication,
108 bytes: &[u8],
109 ) -> Result<(), Self::Error> {
110 if self.refuse_publication {
111 return Err(ReferencePublishError);
112 }
113 publication.1.extend_from_slice(bytes);
114 Ok(())
115 }
116
117 fn commit_publication(&self, publication: Self::Publication) -> Result<(), Self::Error> {
118 self.files.borrow_mut().insert(publication.0, publication.1);
119 Ok(())
120 }
121
122 fn abort_publication(&self, _: Self::Publication) {
123 self.abandoned.set(self.abandoned.get() + 1);
124 }
125}
126
127impl DownloadReportAlg for ReferenceDownloadEnv {
128 type Event = DownloadEvent;
129
130 fn report_download(&self, event: DownloadEvent) {
131 self.events.borrow_mut().push(event);
132 }
133}
134
135impl DownloadProgressAlg for ReferenceDownloadEnv {
136 type Progress = DownloadProgress;
137
138 fn report_progress(&self, progress: DownloadProgress) {
139 self.progress.borrow_mut().push(progress);
140 }
141}
142
143impl DownloadObservationAlg for ReferenceDownloadEnv {
144 type Event = DownloadEvent;
145 type Progress = DownloadProgress;
146
147 fn download_progress(
148 &self,
149 destination: &Path,
150 downloaded: u64,
151 total: Option<u64>,
152 ) -> Self::Progress {
153 DownloadSyntax.download_progress(destination, downloaded, total)
154 }
155
156 fn download_succeeded(&self, destination: &Path, bytes: u64) -> Self::Event {
157 DownloadSyntax.download_succeeded(destination, bytes)
158 }
159
160 fn download_failed(&self, destination: &Path, message: String) -> Self::Event {
161 DownloadSyntax.download_failed(destination, message)
162 }
163}