comtrya_lib/atoms/http/
download.rs

1use crate::atoms::Outcome;
2
3use super::super::Atom;
4use std::io::Write;
5use std::{fs::File, path::PathBuf};
6
7pub struct Download {
8    pub url: String,
9    pub to: PathBuf,
10}
11
12impl std::fmt::Display for Download {
13    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
14        write!(f, "HttpDownload from {} to {}", self.url, self.to.display())
15    }
16}
17
18impl Atom for Download {
19    fn plan(&self) -> anyhow::Result<Outcome> {
20        // Initial implementation will return false if the local file
21        // doesn't exist. I'd like to include a SHA to verify the
22        // correct version exists; or perhaps a TTL when omitted?
23
24        Ok(Outcome {
25            side_effects: vec![],
26            should_run: !PathBuf::from(&self.to).exists(),
27        })
28    }
29
30    fn execute(&mut self) -> anyhow::Result<()> {
31        let response = reqwest::blocking::get(&self.url)?;
32
33        let mut file = File::create(&self.to)?;
34
35        let content = response.bytes()?;
36        file.write_all(&content)?;
37
38        Ok(())
39    }
40}
41
42#[cfg(test)]
43mod tests {
44    use super::*;
45    use pretty_assertions::assert_eq;
46    use tempfile::tempdir;
47
48    #[test]
49    fn it_can() {
50        let tmpdir = tempdir().unwrap();
51        let to_file = tmpdir.path().join("download");
52
53        let mut atom = Download {
54            url: String::from("https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png"),
55            to: to_file,
56        };
57
58        assert_eq!(true, atom.plan().unwrap().should_run);
59
60        let result = atom.execute();
61        assert_eq!(true, result.is_ok());
62        assert_eq!(false, atom.plan().unwrap().should_run);
63    }
64}