tinymist_package/pack/
http.rs1use ecow::eco_format;
2use typst::diag::PackageError;
3
4use super::*;
5use crate::registry::threaded_http;
6
7#[derive(Clone)]
9pub struct HttpPack<S> {
10 pub specifier: PackageSpec,
12 pub url: S,
14}
15
16impl<S: AsRef<str>> HttpPack<S> {
17 pub fn new(specifier: PackageSpec, url: S) -> Self {
19 Self { specifier, url }
20 }
21}
22
23impl<S: AsRef<str>> fmt::Debug for HttpPack<S> {
24 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
25 write!(f, "HttpPack({})", self.url.as_ref())
26 }
27}
28
29impl<S: AsRef<str>> PackFs for HttpPack<S> {
30 fn read_all(
31 &mut self,
32 f: &mut (dyn FnMut(&str, PackFile) -> PackageResult<()> + Send + Sync),
33 ) -> PackageResult<()> {
34 let spec = &self.specifier;
35 let url = self.url.as_ref();
36 threaded_http(url, None, |resp| {
37 let reader = match resp.and_then(|r| r.error_for_status()) {
38 Ok(response) => response,
39 Err(err) if matches!(err.status().map(|s| s.as_u16()), Some(404)) => {
40 return Err(PackageError::NotFound(spec.clone()));
41 }
42 Err(err) => return Err(PackageError::NetworkFailed(Some(eco_format!("{err}")))),
43 };
44
45 let decompressed = flate2::read::GzDecoder::new(reader);
46 let mut tarbar = TarballPack::new(decompressed);
47
48 tarbar.read_all(f)
55 })
56 .ok_or_else(|| PackageError::Other(Some(eco_format!("cannot spawn http thread"))))?
57 }
58}
59
60impl<S: AsRef<str>> Pack for HttpPack<S> {}
61impl<P: AsRef<str>> PackExt for HttpPack<P> {}