feat(package): implement first version of espanso-hub provider
This commit is contained in:
		
							parent
							
								
									393f431bc3
								
							
						
					
					
						commit
						23a73f7ea2
					
				
							
								
								
									
										74
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										74
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							| 
						 | 
				
			
			@ -105,6 +105,15 @@ version = "0.1.6"
 | 
			
		|||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "block-buffer"
 | 
			
		||||
version = "0.9.0"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "generic-array",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "bstr"
 | 
			
		||||
version = "0.2.15"
 | 
			
		||||
| 
						 | 
				
			
			@ -302,6 +311,15 @@ version = "0.8.2"
 | 
			
		|||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "ea221b5284a47e40033bf9b66f35f984ec0ea2931eb03505246cd27a963f981b"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "cpufeatures"
 | 
			
		||||
version = "0.2.1"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "95059428f66df56b63431fdb4e1947ed2190586af5c5a8a8b71122bdf5a7f469"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "libc",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "crc32fast"
 | 
			
		||||
version = "1.2.1"
 | 
			
		||||
| 
						 | 
				
			
			@ -425,6 +443,15 @@ version = "2.0.0"
 | 
			
		|||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "digest"
 | 
			
		||||
version = "0.9.0"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "generic-array",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "dirs"
 | 
			
		||||
version = "1.0.5"
 | 
			
		||||
| 
						 | 
				
			
			@ -786,6 +813,7 @@ dependencies = [
 | 
			
		|||
 "anyhow",
 | 
			
		||||
 "fs_extra",
 | 
			
		||||
 "glob",
 | 
			
		||||
 "hex",
 | 
			
		||||
 "lazy_static",
 | 
			
		||||
 "log",
 | 
			
		||||
 "natord",
 | 
			
		||||
| 
						 | 
				
			
			@ -795,6 +823,7 @@ dependencies = [
 | 
			
		|||
 "serde",
 | 
			
		||||
 "serde_json",
 | 
			
		||||
 "serde_yaml",
 | 
			
		||||
 "sha2",
 | 
			
		||||
 "tempdir",
 | 
			
		||||
 "thiserror",
 | 
			
		||||
 "zip",
 | 
			
		||||
| 
						 | 
				
			
			@ -1034,6 +1063,16 @@ version = "0.3.55"
 | 
			
		|||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "generic-array"
 | 
			
		||||
version = "0.14.4"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "typenum",
 | 
			
		||||
 "version_check",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "getrandom"
 | 
			
		||||
version = "0.1.16"
 | 
			
		||||
| 
						 | 
				
			
			@ -1105,6 +1144,12 @@ dependencies = [
 | 
			
		|||
 "libc",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "hex"
 | 
			
		||||
version = "0.4.3"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "html2text"
 | 
			
		||||
version = "0.2.1"
 | 
			
		||||
| 
						 | 
				
			
			@ -1338,9 +1383,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
 | 
			
		|||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "libc"
 | 
			
		||||
version = "0.2.98"
 | 
			
		||||
version = "0.2.101"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "320cfe77175da3a483efed4bc0adc1968ca050b098ce4f2f1c13a56626128790"
 | 
			
		||||
checksum = "3cb00336871be5ed2c8ed44b60ae9959dc5b9f08539422ed43f09e34ecaeba21"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "libdbus-sys"
 | 
			
		||||
| 
						 | 
				
			
			@ -1785,6 +1830,12 @@ version = "1.8.0"
 | 
			
		|||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "opaque-debug"
 | 
			
		||||
version = "0.3.0"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "opener"
 | 
			
		||||
version = "0.5.0"
 | 
			
		||||
| 
						 | 
				
			
			@ -2350,6 +2401,19 @@ dependencies = [
 | 
			
		|||
 "yaml-rust 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "sha2"
 | 
			
		||||
version = "0.9.6"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "9204c41a1597a8c5af23c82d1c921cb01ec0a4c59e07a9c7306062829a3903f3"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "block-buffer",
 | 
			
		||||
 "cfg-if 1.0.0",
 | 
			
		||||
 "cpufeatures",
 | 
			
		||||
 "digest",
 | 
			
		||||
 "opaque-debug",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "simplelog"
 | 
			
		||||
version = "0.9.0"
 | 
			
		||||
| 
						 | 
				
			
			@ -2721,6 +2785,12 @@ version = "0.2.3"
 | 
			
		|||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "typenum"
 | 
			
		||||
version = "1.14.0"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "b63708a265f51345575b27fe43f9500ad611579e764c79edbc2037b1121959ec"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "unicase"
 | 
			
		||||
version = "2.6.0"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -19,4 +19,6 @@ lazy_static = "1.4.0"
 | 
			
		|||
regex = "1.4.3"
 | 
			
		||||
zip = "0.5.13"
 | 
			
		||||
scopeguard = "1.1.0"
 | 
			
		||||
fs_extra = "1.2.0"
 | 
			
		||||
fs_extra = "1.2.0"
 | 
			
		||||
sha2 = "0.9.6"
 | 
			
		||||
hex = "0.4.3"
 | 
			
		||||
| 
						 | 
				
			
			@ -22,6 +22,8 @@ use std::path::Path;
 | 
			
		|||
use anyhow::{bail, Result};
 | 
			
		||||
 | 
			
		||||
mod archive;
 | 
			
		||||
#[macro_use]
 | 
			
		||||
mod logging;
 | 
			
		||||
mod manifest;
 | 
			
		||||
mod package;
 | 
			
		||||
mod provider;
 | 
			
		||||
| 
						 | 
				
			
			@ -29,12 +31,12 @@ mod resolver;
 | 
			
		|||
mod util;
 | 
			
		||||
 | 
			
		||||
pub use archive::{ArchivedPackage, Archiver, SaveOptions, StoredPackage};
 | 
			
		||||
pub use provider::{PackageSpecifier, PackageProvider};
 | 
			
		||||
pub use package::Package;
 | 
			
		||||
pub use provider::{PackageProvider, PackageSpecifier};
 | 
			
		||||
 | 
			
		||||
// TODO: once the download is completed, avoid copying files beginning with "."
 | 
			
		||||
 | 
			
		||||
pub fn get_provider(package: &PackageSpecifier) -> Result<Box<dyn PackageProvider>> {
 | 
			
		||||
pub fn get_provider(package: &PackageSpecifier,) -> Result<Box<dyn PackageProvider>> {
 | 
			
		||||
  if let Some(git_repo_url) = package.git_repo_url.as_deref() {
 | 
			
		||||
    if !package.use_native_git {
 | 
			
		||||
      let matches_known_hosts =
 | 
			
		||||
| 
						 | 
				
			
			@ -73,14 +75,15 @@ pub fn get_provider(package: &PackageSpecifier) -> Result<Box<dyn PackageProvide
 | 
			
		|||
    // (because it's not authenticated)
 | 
			
		||||
    Ok(Box::new(provider::git::GitPackageProvider::new()))
 | 
			
		||||
  } else {
 | 
			
		||||
    // TODO: use espanso-hub method
 | 
			
		||||
    bail!("espanso hub method not yet implemented")
 | 
			
		||||
    // Download from the official espanso hub
 | 
			
		||||
    Ok(Box::new(provider::hub::EspansoHubPackageProvider::new()))
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
pub fn get_archiver(package_dir: &Path) -> Result<Box<dyn Archiver>> {
 | 
			
		||||
  Ok(Box::new(archive::default::DefaultArchiver::new(package_dir)))
 | 
			
		||||
  Ok(Box::new(archive::default::DefaultArchiver::new(
 | 
			
		||||
    package_dir,
 | 
			
		||||
  )))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[cfg(test)]
 | 
			
		||||
| 
						 | 
				
			
			@ -94,4 +97,4 @@ pub(crate) mod tests {
 | 
			
		|||
 | 
			
		||||
    action(&tmp_path);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										23
									
								
								espanso-package/src/logging.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								espanso-package/src/logging.rs
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,23 @@
 | 
			
		|||
#[macro_export]
 | 
			
		||||
macro_rules! info_println {
 | 
			
		||||
  ($($tts:tt)*) => {
 | 
			
		||||
    println!($($tts)*);
 | 
			
		||||
    log::info!($($tts)*);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[macro_export]
 | 
			
		||||
macro_rules! warn_eprintln {
 | 
			
		||||
  ($($tts:tt)*) => {
 | 
			
		||||
    eprintln!($($tts)*);
 | 
			
		||||
    log::warn!($($tts)*);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[macro_export]
 | 
			
		||||
macro_rules! error_eprintln {
 | 
			
		||||
  ($($tts:tt)*) => {
 | 
			
		||||
    eprintln!($($tts)*);
 | 
			
		||||
    log::error!($($tts)*);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										137
									
								
								espanso-package/src/provider/hub.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										137
									
								
								espanso-package/src/provider/hub.rs
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,137 @@
 | 
			
		|||
/*
 | 
			
		||||
 * This file is part of espanso.
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2019-2021 Federico Terzi
 | 
			
		||||
 *
 | 
			
		||||
 * espanso is free software: you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * espanso is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with espanso.  If not, see <https://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
use super::PackageProvider;
 | 
			
		||||
use crate::{
 | 
			
		||||
  package::DefaultPackage, resolver::resolve_package, util::download::read_string_from_url,
 | 
			
		||||
  Package, PackageSpecifier,
 | 
			
		||||
};
 | 
			
		||||
use anyhow::{anyhow, Context, Result};
 | 
			
		||||
use serde::{Deserialize, Serialize};
 | 
			
		||||
 | 
			
		||||
pub const ESPANSO_HUB_PACKAGE_INDEX_URL: &str =
 | 
			
		||||
  "https://github.com/espanso/hub/releases/latest/download/package_index.json";
 | 
			
		||||
 | 
			
		||||
pub struct EspansoHubPackageProvider {}
 | 
			
		||||
 | 
			
		||||
impl EspansoHubPackageProvider {
 | 
			
		||||
  pub fn new() -> Self {
 | 
			
		||||
    Self {}
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl PackageProvider for EspansoHubPackageProvider {
 | 
			
		||||
  fn name(&self) -> String {
 | 
			
		||||
    "espanso-hub".to_string()
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  fn download(&self, package: &PackageSpecifier) -> Result<Box<dyn Package>> {
 | 
			
		||||
    // TODO: pass index update flag
 | 
			
		||||
    let index = self
 | 
			
		||||
      .get_index(true)
 | 
			
		||||
      .context("unable to get package index from espanso hub")?;
 | 
			
		||||
 | 
			
		||||
    let package_info = index
 | 
			
		||||
      .get_package(&package.name, package.version.as_deref())
 | 
			
		||||
      .ok_or_else(|| {
 | 
			
		||||
        anyhow!(
 | 
			
		||||
          "unable to find package '{}@{}' in the espanso hub",
 | 
			
		||||
          package.name,
 | 
			
		||||
          package.version.as_deref().unwrap_or("latest")
 | 
			
		||||
        )
 | 
			
		||||
      })?;
 | 
			
		||||
 | 
			
		||||
    let archive_sha256 = read_string_from_url(&package_info.archive_sha256_url)
 | 
			
		||||
      .context("unable to read archive sha256 signature")?;
 | 
			
		||||
 | 
			
		||||
    let temp_dir = tempdir::TempDir::new("espanso-package-download")?;
 | 
			
		||||
 | 
			
		||||
    crate::util::download::download_and_extract_zip_verify_sha256(
 | 
			
		||||
      &package_info.archive_url,
 | 
			
		||||
      temp_dir.path(),
 | 
			
		||||
      Some(&archive_sha256),
 | 
			
		||||
    )?;
 | 
			
		||||
 | 
			
		||||
    let resolved_package =
 | 
			
		||||
      resolve_package(temp_dir.path(), &package.name, package.version.as_deref())?;
 | 
			
		||||
 | 
			
		||||
    let package = DefaultPackage::new(
 | 
			
		||||
      resolved_package.manifest,
 | 
			
		||||
      temp_dir,
 | 
			
		||||
      resolved_package.base_dir,
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    Ok(Box::new(package))
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl EspansoHubPackageProvider {
 | 
			
		||||
  fn get_index(&self, _force_update: bool) -> Result<PackageIndex> {
 | 
			
		||||
    // TODO: if force_update is false, we should try to use a locally-cached version of the package index
 | 
			
		||||
    self.download_index()
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  fn download_index(&self) -> Result<PackageIndex> {
 | 
			
		||||
    info_println!("fetching package index...");
 | 
			
		||||
    let json_body = read_string_from_url(ESPANSO_HUB_PACKAGE_INDEX_URL)?;
 | 
			
		||||
 | 
			
		||||
    let index: PackageIndex = serde_json::from_str(&json_body)?;
 | 
			
		||||
 | 
			
		||||
    Ok(index)
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Debug, Serialize, Deserialize)]
 | 
			
		||||
struct PackageIndex {
 | 
			
		||||
  last_update: u64,
 | 
			
		||||
  packages: Vec<PackageInfo>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Debug, Clone, Serialize, Deserialize)]
 | 
			
		||||
struct PackageInfo {
 | 
			
		||||
  name: String,
 | 
			
		||||
  title: String,
 | 
			
		||||
  author: String,
 | 
			
		||||
  description: String,
 | 
			
		||||
  version: String,
 | 
			
		||||
 | 
			
		||||
  archive_url: String,
 | 
			
		||||
  archive_sha256_url: String,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl PackageIndex {
 | 
			
		||||
  fn get_package(&self, name: &str, version: Option<&str>) -> Option<PackageInfo> {
 | 
			
		||||
    let mut matching_packages: Vec<PackageInfo> = self
 | 
			
		||||
      .packages
 | 
			
		||||
      .iter()
 | 
			
		||||
      .filter(|package| package.name == name)
 | 
			
		||||
      .cloned()
 | 
			
		||||
      .collect();
 | 
			
		||||
 | 
			
		||||
    matching_packages.sort_by(|a, b| natord::compare(&a.version, &b.version));
 | 
			
		||||
 | 
			
		||||
    if let Some(explicit_version) = version {
 | 
			
		||||
      matching_packages
 | 
			
		||||
        .into_iter()
 | 
			
		||||
        .find(|package| package.version == explicit_version)
 | 
			
		||||
    } else {
 | 
			
		||||
      matching_packages.into_iter().last()
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -21,6 +21,7 @@ use anyhow::Result;
 | 
			
		|||
 | 
			
		||||
use crate::Package;
 | 
			
		||||
 | 
			
		||||
pub(crate) mod hub;
 | 
			
		||||
pub(crate) mod git;
 | 
			
		||||
pub(crate) mod github;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -17,15 +17,35 @@
 | 
			
		|||
 * along with espanso.  If not, see <https://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
use anyhow::{Context, Result};
 | 
			
		||||
use anyhow::{Context, Result, bail};
 | 
			
		||||
use std::io::{copy, Cursor};
 | 
			
		||||
use std::path::Path;
 | 
			
		||||
use sha2::{Sha256, Digest};
 | 
			
		||||
 | 
			
		||||
pub fn download_and_extract_zip(url: &str, dest_dir: &Path) -> Result<()> {
 | 
			
		||||
  download_and_extract_zip_verify_sha256(url, dest_dir, None)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn download_and_extract_zip_verify_sha256(url: &str, dest_dir: &Path, sha256: Option<&str>) -> Result<()> {
 | 
			
		||||
  let data = download(url).context("error downloading archive")?;
 | 
			
		||||
  if let Some(sha256) = sha256 {
 | 
			
		||||
    info_println!("validating sha256 signature...");
 | 
			
		||||
    if !verify_sha256(&data, sha256) {
 | 
			
		||||
      bail!("signature mismatch");
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  extract_zip(data, dest_dir).context("error extracting archive")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn read_string_from_url(url: &str) -> Result<String> {
 | 
			
		||||
  let client = reqwest::blocking::Client::builder();
 | 
			
		||||
  let client = client.build()?;
 | 
			
		||||
 | 
			
		||||
  let response = client.get(url).send()?;
 | 
			
		||||
 | 
			
		||||
  Ok(response.text()?)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn download(url: &str) -> Result<Vec<u8>> {
 | 
			
		||||
  let client = reqwest::blocking::Client::builder();
 | 
			
		||||
  let client = client.build()?;
 | 
			
		||||
| 
						 | 
				
			
			@ -37,6 +57,14 @@ fn download(url: &str) -> Result<Vec<u8>> {
 | 
			
		|||
  Ok(buffer)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn verify_sha256(data: &[u8], sha256: &str) -> bool {
 | 
			
		||||
  let mut hasher = Sha256::new();
 | 
			
		||||
  hasher.update(data);
 | 
			
		||||
  let result = hasher.finalize();
 | 
			
		||||
  let hash = hex::encode(result);
 | 
			
		||||
  hash == sha256
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Adapted from zip-rs extract.rs example
 | 
			
		||||
fn extract_zip(data: Vec<u8>, dest_dir: &Path) -> Result<()> {
 | 
			
		||||
  let reader = Cursor::new(data);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue
	
	Block a user