Skip to main content

ambient_ci/action_impl/
http_get.rs

1#![allow(clippy::result_large_err)]
2
3use reqwest::StatusCode;
4use serde::{Deserialize, Serialize};
5
6use crate::{
7    action::{ActionError, Context, Pair},
8    action_impl::ActionImpl,
9    util::http_get_to_file,
10};
11
12/// Download a file into dependencies.
13///
14/// Only download if the file is missing from dependencies, or has changed
15/// on the server.
16#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
17pub struct HttpGet {
18    items: Vec<Pair>,
19}
20
21impl HttpGet {
22    pub(crate) fn new(items: Vec<Pair>) -> Self {
23        Self { items }
24    }
25
26    pub(crate) fn items(&self) -> &[Pair] {
27        &self.items
28    }
29}
30
31impl ActionImpl for HttpGet {
32    fn execute(&self, context: &mut Context) -> Result<(), ActionError> {
33        let deps = context.deps_dir();
34        for pair in self.items.iter() {
35            let filename = deps.join(pair.filename());
36            http_get_to_file(pair.url(), &filename).map_err(HttpGetError::Util)?;
37        }
38        Ok(())
39    }
40}
41
42/// Errors from `http_get` action.
43#[derive(Debug, thiserror::Error)]
44pub enum HttpGetError {
45    /// Forwarded from `util` module.
46    #[error(transparent)]
47    Util(#[from] crate::util::UtilError),
48
49    /// Can't format time as string.
50    #[error("failed to format time stamp")]
51    TimeFormat(#[source] time::error::Format),
52
53    /// Can't build an HTTP client.
54    #[error("failed to create HTTP client")]
55    ClientBuild(#[source] reqwest::Error),
56
57    /// Can't create an HTTP client.
58    #[error("failed to build a reqwest client")]
59    Client(#[source] reqwest::Error),
60
61    /// Can't build an HTTP request.
62    #[error("failed to build a reqwest request")]
63    BuildRequest(#[source] reqwest::Error),
64
65    /// Can't get file with GET.
66    #[error("failed to GET URL {0:?}")]
67    Get(String, reqwest::Error),
68
69    /// Can't get GET response body.
70    #[error("failed to get body of response from {0:?}")]
71    GetBody(String, reqwest::Error),
72
73    /// HTTP GET returned weird status code.
74    #[error("failure getting file with HTTP GET: status code {0}")]
75    UnwantedStatus(StatusCode),
76}
77
78impl From<HttpGetError> for ActionError {
79    fn from(value: HttpGetError) -> Self {
80        Self::HttpGet(value)
81    }
82}