changelog shortlog graph tags branches files raw help

Mercurial > core / changeset: lisp groveling and rust fmt

changeset 78: 966f92770ddf
parent 77: 65827de90d54
child 79: 24728cba3558
author: ellis <ellis@rwest.io>
date: Sun, 03 Dec 2023 23:25:08 -0500
files: lisp/ffi/alpm/alpm.asd lisp/ffi/alpm/constants.lisp lisp/ffi/bqn/bqn.asd lisp/ffi/bqn/constants.lisp lisp/ffi/k/constants.lisp lisp/ffi/k/k.asd lisp/ffi/tree-sitter/constants.lisp lisp/ffi/tree-sitter/tree-sitter.asd lisp/ffi/uring/constants.lisp lisp/ffi/uring/uring.asd lisp/ffi/zstd/constants.lisp lisp/ffi/zstd/zstd.asd rust/app/cli/cc-init/main.rs rust/app/cli/krypt/main.rs rust/app/cli/mailman/main.rs rust/lib/dl/src/errors.rs rust/lib/dl/src/lib.rs rust/lib/dl/tests/download-curl-resume.rs rust/lib/dl/tests/download-reqwest-resume.rs rust/lib/dl/tests/read-proxy-env.rs rust/lib/dl/tests/support/mod.rs rust/lib/util/src/bs/version.rs rust/lib/util/src/lib.rs
description: lisp groveling and rust fmt
     1.1--- a/lisp/ffi/alpm/alpm.asd	Sun Dec 03 22:18:30 2023 -0500
     1.2+++ b/lisp/ffi/alpm/alpm.asd	Sun Dec 03 23:25:08 2023 -0500
     1.3@@ -5,10 +5,23 @@
     1.4 ;;; Commentary:
     1.5 
     1.6 ;;; Code:
     1.7-(defsystem "alpm"
     1.8+(eval-when (:compile-toplevel :load-toplevel :execute)
     1.9+  (require :sb-grovel))
    1.10+
    1.11+(defpackage :alpm.sys
    1.12+  (:use :cl :asdf :sb-grovel :sb-alien))
    1.13+
    1.14+(in-package :alpm.sys)
    1.15+
    1.16+(defsystem :alpm
    1.17   :description "ALPM FFI"
    1.18-  :defsystem-depends-on (:asdf-package-system)
    1.19-  :class :package-inferred-system
    1.20-  :depends-on (:std :alpm/pkg)
    1.21-  :in-order-to ((test-op (test-op "alpm/tests")))
    1.22+  :depends-on (:sb-grovel :std)
    1.23+  :components ((:file "pkg")
    1.24+               (grovel-constants-file "constants"
    1.25+                                      :package :alpm))
    1.26+  :in-order-to ((test-op (test-op "alpm/tests"))))
    1.27+
    1.28+(defsystem :alpm/tests
    1.29+  :depends-on (:std/rt :alpm)
    1.30+  :components ((:file "tests"))
    1.31   :perform (test-op (op c) (uiop:symbol-call '#:rt '#:do-tests :alpm)))
     2.1--- a/lisp/ffi/alpm/constants.lisp	Sun Dec 03 22:18:30 2023 -0500
     2.2+++ b/lisp/ffi/alpm/constants.lisp	Sun Dec 03 23:25:08 2023 -0500
     2.3@@ -1,3 +1,3 @@
     2.4-()
     2.5+("stdlib.h" "alpm_list.h" "stdint.h" "sys/types.h" "stdarg.h" "archive.h" "archive_entry.h")
     2.6 
     2.7 ()
     3.1--- a/lisp/ffi/bqn/bqn.asd	Sun Dec 03 22:18:30 2023 -0500
     3.2+++ b/lisp/ffi/bqn/bqn.asd	Sun Dec 03 23:25:08 2023 -0500
     3.3@@ -10,10 +10,23 @@
     3.4 ;; see also: https://github.com/Detegr/cbqn-sys
     3.5 
     3.6 ;;; Code:
     3.7-(defsystem "bqn"
     3.8+(eval-when (:compile-toplevel :load-toplevel :execute)
     3.9+  (require :sb-grovel))
    3.10+
    3.11+(defpackage :bqn.sys
    3.12+  (:use :cl :asdf :sb-grovel :sb-alien))
    3.13+
    3.14+(in-package :bqn.sys)
    3.15+
    3.16+(defsystem :bqn
    3.17   :description "CBQN FFI"
    3.18-  :defsystem-depends-on (:asdf-package-system)
    3.19-  :class :package-inferred-system
    3.20-  :depends-on (:std :bqn/pkg)
    3.21-  :in-order-to ((test-op (test-op "bqn/tests")))
    3.22+  :depends-on (:sb-grovel :std)
    3.23+  :components ((:file "pkg")
    3.24+               (grovel-constants-file "constants"
    3.25+                                      :package :bqn))
    3.26+  :in-order-to ((test-op (test-op "bqn/tests"))))
    3.27+
    3.28+(defsystem :bqn/tests
    3.29+  :depends-on (:std/rt :bqn)
    3.30+  :components ((:file "tests"))
    3.31   :perform (test-op (op c) (uiop:symbol-call '#:rt '#:do-tests :bqn)))
     4.1--- a/lisp/ffi/bqn/constants.lisp	Sun Dec 03 22:18:30 2023 -0500
     4.2+++ b/lisp/ffi/bqn/constants.lisp	Sun Dec 03 23:25:08 2023 -0500
     4.3@@ -1,3 +1,11 @@
     4.4-()
     4.5+("stddef.h" "stdint.h" "stdbool.h" "bqnffi.h")
     4.6 
     4.7-()
     4.8+((:enum bqneltype 
     4.9+        ((elt-unk "elt_unk")
    4.10+         (elt-i8 "elt_i8")
    4.11+         (elt-i16 "elt_i16")
    4.12+         (elt-i32 "elt_i32")
    4.13+         (elt-f64 "elt_f64")
    4.14+         (elt-c8 "elt_c8")
    4.15+         (elt-c16 "elt_c16")
    4.16+         (elt-c32 "elt_c32"))))
     5.1--- a/lisp/ffi/k/constants.lisp	Sun Dec 03 22:18:30 2023 -0500
     5.2+++ b/lisp/ffi/k/constants.lisp	Sun Dec 03 23:25:08 2023 -0500
     5.3@@ -0,0 +1,3 @@
     5.4+("k.h")
     5.5+
     5.6+()
     6.1--- a/lisp/ffi/k/k.asd	Sun Dec 03 22:18:30 2023 -0500
     6.2+++ b/lisp/ffi/k/k.asd	Sun Dec 03 23:25:08 2023 -0500
     6.3@@ -7,10 +7,22 @@
     6.4 ;; 
     6.5 
     6.6 ;;; Code:
     6.7-(defsystem "k"
     6.8+(eval-when (:compile-toplevel :load-toplevel :execute)
     6.9+  (require :sb-grovel))
    6.10+
    6.11+(defpackage :k.sys
    6.12+  (:use :cl :asdf :sb-grovel :sb-alien))
    6.13+
    6.14+(in-package :k.sys)
    6.15+
    6.16+(defsystem :k
    6.17   :description "ngn/k FFI"
    6.18-  :defsystem-depends-on (:asdf-package-system)
    6.19-  :class :package-inferred-system
    6.20-  :depends-on (:std :k/pkg)
    6.21-  :in-order-to ((test-op (test-op "k/tests")))
    6.22+  :depends-on (:sb-grovel :std)
    6.23+  :components ((:file "pkg")
    6.24+               (grovel-constants-file "constants"
    6.25+                                      :package :k))
    6.26+  :in-order-to ((test-op (test-op "k/tests"))))
    6.27+
    6.28+(defsystem :k/tests
    6.29+  :depends-on (:std/rt :k)
    6.30   :perform (test-op (op c) (uiop:symbol-call '#:rt '#:do-tests :k)))
     7.1--- a/lisp/ffi/tree-sitter/constants.lisp	Sun Dec 03 22:18:30 2023 -0500
     7.2+++ b/lisp/ffi/tree-sitter/constants.lisp	Sun Dec 03 23:25:08 2023 -0500
     7.3@@ -0,0 +1,7 @@
     7.4+("stdio.h" "stdlib.h" "stdint.h" "stdbool.h" "tree_sitter/api.h" "tree_sitter/parser.h")
     7.5+
     7.6+((:integer +tree-sitter-language-version+ "TREE_SITTER_LANGUAGE_VERSION" t t)
     7.7+ (:integer +tree-sitter-min-compatible-language-version+ "TREE_SITTER_MIN_COMPATIBLE_LANGUAGE_VERSION" t t)
     7.8+ (:integer +ts-builtin-sym-error+ "ts_builtin_sym_error" t t)
     7.9+ (:integer +ts-builtin-sym-end+ "ts_builtin_sym_end" t t)
    7.10+ (:integer +tree-sitter-serialization-buffer-size+ "TREE_SITTER_SERIALIZATION_BUFFER_SIZE" t t))
     8.1--- a/lisp/ffi/tree-sitter/tree-sitter.asd	Sun Dec 03 22:18:30 2023 -0500
     8.2+++ b/lisp/ffi/tree-sitter/tree-sitter.asd	Sun Dec 03 23:25:08 2023 -0500
     8.3@@ -3,9 +3,22 @@
     8.4 ;; TREE-SITTER for lisp.
     8.5 
     8.6 ;;; Code:
     8.7+(eval-when (:compile-toplevel :load-toplevel :execute)
     8.8+  (require :sb-grovel))
     8.9+
    8.10+(defpackage :tree-sitter.sys
    8.11+  (:use :cl :asdf :sb-grovel :sb-alien))
    8.12+
    8.13+(in-package :tree-sitter.sys)
    8.14+
    8.15 (defsystem :tree-sitter
    8.16-  :class :package-inferred-system
    8.17-  :defsystem-depends-on (:asdf-package-system)
    8.18-  :depends-on (:std)
    8.19-  :in-order-to ((test-op (test-op :tree-sitter/tests)))
    8.20+  :depends-on (:sb-grovel :std)
    8.21+  :components ((:file "pkg")
    8.22+               (grovel-constants-file "constants"
    8.23+                                      :package :tree-sitter))
    8.24+  :in-order-to ((test-op (test-op :tree-sitter/tests))))
    8.25+
    8.26+(defsystem :tree-sitter/tests
    8.27+  :depends-on (:std/rt :tree-sitter)
    8.28+  :components ((:file "tests"))
    8.29   :perform (test-op (op c) (uiop:symbol-call '#:rt '#:do-tests :tree-sitter)))
     9.1--- a/lisp/ffi/uring/constants.lisp	Sun Dec 03 22:18:30 2023 -0500
     9.2+++ b/lisp/ffi/uring/constants.lisp	Sun Dec 03 23:25:08 2023 -0500
     9.3@@ -0,0 +1,5 @@
     9.4+("sys/socket.h" "sys/stat.h" "sys/uio.h" "errno.h" "signal.h" "stdbool.h"
     9.5+                "inttypes.h" "time.h" "fcntl.h" "sched.h" "linux/swab.h" "liburing/compat.h"
     9.6+                "liburing/io_uring.h" "liburing/io_uring_version.h" "liburing/barrier.h")
     9.7+
     9.8+()
    10.1--- a/lisp/ffi/uring/uring.asd	Sun Dec 03 22:18:30 2023 -0500
    10.2+++ b/lisp/ffi/uring/uring.asd	Sun Dec 03 23:25:08 2023 -0500
    10.3@@ -1,7 +1,20 @@
    10.4 ;;; uring.asd-*- mode: lisp; -*-
    10.5+(eval-when (:compile-toplevel :load-toplevel :execute)
    10.6+  (require :sb-grovel))
    10.7+
    10.8+(defpackage :uring.sys
    10.9+  (:use :cl :asdf :sb-grovel :sb-alien))
   10.10+
   10.11+(in-package :uring.sys)
   10.12+
   10.13 (defsystem :uring
   10.14-  :class :package-inferred-system
   10.15-  :defsystem-depends-on (:asdf-package-system)
   10.16-  :depends-on (:std :uring/pkg)
   10.17-  :in-order-to ((test-op (test-op :uring/tests)))
   10.18+  :depends-on (:sb-grovel :std)
   10.19+  :components ((:file "pkg")
   10.20+               (grovel-constants-file "constants"
   10.21+                                      :package :uring))
   10.22+  :in-order-to ((test-op (test-op :uring/tests))))
   10.23+
   10.24+(defsystem :uring/tests
   10.25+  :depends-on (:std/rt :uring)
   10.26+  :components ((:file "tests"))
   10.27   :perform (test-op (op c) (uiop:symbol-call '#:rt '#:do-tests :uring)))
    11.1--- a/lisp/ffi/zstd/constants.lisp	Sun Dec 03 22:18:30 2023 -0500
    11.2+++ b/lisp/ffi/zstd/constants.lisp	Sun Dec 03 23:25:08 2023 -0500
    11.3@@ -0,0 +1,39 @@
    11.4+("stddef.h" "zstd_errors.h" "zstd.h")
    11.5+
    11.6+((:enum zstd-errorcode
    11.7+        ((zstd-error-no-error "ZSTD_error_no_error")
    11.8+         (zstd-error-generic "ZSTD_error_GENERIC")
    11.9+         (zstd-error-prefix-unknown "ZSTD_error_prefix_unknown")
   11.10+         (zstd-error-version-unsupported "ZSTD_error_version_unsupported")
   11.11+         (zstd-error-frameparameter-unsupported "ZSTD_error_frameParameter_unsupported")
   11.12+         (zstd-error-frameparameter-windowtoolarge "ZSTD_error_frameParameter_windowTooLarge")
   11.13+         (zstd-error-corruption-detected "ZSTD_error_corruption_detected")
   11.14+         (zstd-error-checksum-wrong "ZSTD_error_checksum_wrong")
   11.15+         (zstd-error-literals-headerwrong "ZSTD_error_literals_headerWrong")
   11.16+         (zstd-error-dictionary-corrupted "ZSTD_error_dictionary_corrupted")
   11.17+         (zstd-error-dictionary-wrong "ZSTD_error_dictionary_wrong")
   11.18+         (zstd-error-dictionarycreation-failed "ZSTD_error_dictionaryCreation_failed")
   11.19+         (zstd-error-parameter-unsupported "ZSTD_error_parameter_unsupported")
   11.20+         (zstd-error-parameter-combination-unsupported "ZSTD_error_parameter_combination_unsupported")
   11.21+         (zstd-error-parameter-outofbound "ZSTD_error_parameter_outOfBound")
   11.22+         (zstd-error-tablelog-toolarge "ZSTD_error_tableLog_tooLarge")
   11.23+         (zstd-error-maxsymbolvalue-toolarge "ZSTD_error_maxSymbolValue_tooLarge")
   11.24+         (zstd-error-maxsymbolvalue-toosmall "ZSTD_error_maxSymbolValue_tooSmall")
   11.25+         (zstd-error-stabilitycondition-notrespected "ZSTD_error_stabilityCondition_notRespected")
   11.26+         (zstd-error-stage-wrong "ZSTD_error_stage_wrong")
   11.27+         (zstd-error-init-missing "ZSTD_error_init_missing")
   11.28+         (zstd-error-memory-allocation "ZSTD_error_memory_allocation")
   11.29+         (zstd-error-workspace-toosmall "ZSTD_error_workSpace_tooSmall")
   11.30+         (zstd-error-dstsize-toosmall "ZSTD_error_dstSize_tooSmall")
   11.31+         (zstd-error-srcsize-wrong "ZSTD_error_srcSize_wrong")
   11.32+         (zstd-error-dstbuffer-null "ZSTD_error_dstBuffer_null")
   11.33+         (zstd-error-noforwardprogress-destfull "ZSTD_error_noForwardProgress_destFull")
   11.34+         (zstd-error-noforwardprogress-inputempty "ZSTD_error_noForwardProgress_inputEmpty")
   11.35+         ;; UNSTABLE
   11.36+         (zstd-error-frameindex-toolarge "ZSTD_error_frameIndex_tooLarge")
   11.37+         (zstd-error-seekableio "ZSTD_error_seekableIO")
   11.38+         (zstd-error-dstbuffer-wrong "ZSTD_error_dstBuffer_wrong")
   11.39+         (zstd-error-srcbuffer-wrong "ZSTD_error_srcBuffer_wrong")
   11.40+         (zstd-error-sequenceproducer-failed "ZSTD_error_sequenceProducer_failed")
   11.41+         (zstd-error-externalsequences-invalid "ZSTD_error_externalSequences_invalid")
   11.42+         (zstd-error-maxcode "ZSTD_error_maxCode"))))
    12.1--- a/lisp/ffi/zstd/zstd.asd	Sun Dec 03 22:18:30 2023 -0500
    12.2+++ b/lisp/ffi/zstd/zstd.asd	Sun Dec 03 23:25:08 2023 -0500
    12.3@@ -1,7 +1,20 @@
    12.4 ;;; uring.asd-*- mode: lisp; -*-
    12.5+(eval-when (:compile-toplevel :load-toplevel :execute)
    12.6+  (require :sb-grovel))
    12.7+
    12.8+(defpackage :zstd.sys
    12.9+  (:use :cl :asdf :sb-grovel :sb-alien))
   12.10+
   12.11+(in-package :zstd.sys)
   12.12+
   12.13 (defsystem :zstd
   12.14-  :class :package-inferred-system
   12.15-  :defsystem-depends-on (:asdf-package-system)
   12.16-  :depends-on (:std :zstd/pkg)
   12.17-  :in-order-to ((test-op (test-op :zstd/tests)))
   12.18+  :depends-on (:sb-grovel :std)
   12.19+  :components ((:file "pkg")
   12.20+               (grovel-constants-file "constants"
   12.21+                                      :package :zstd))
   12.22+  :in-order-to ((test-op (test-op :zstd/tests))))
   12.23+
   12.24+(defsystem :zstd/tests
   12.25+  :depends-on (:std/rt :zstd)
   12.26+  :components ((:file "tests"))
   12.27   :perform (test-op (op c) (uiop:symbol-call '#:rt '#:do-tests :zstd)))
    13.1--- a/rust/app/cli/cc-init/main.rs	Sun Dec 03 22:18:30 2023 -0500
    13.2+++ b/rust/app/cli/cc-init/main.rs	Sun Dec 03 23:25:08 2023 -0500
    13.3@@ -1,12 +1,16 @@
    13.4 use clap::Parser;
    13.5-use std::path::Path;
    13.6-use logger::{Logger, info, trace};
    13.7-use util::{Result, Url};
    13.8-use util::{cli::log_level_str_from_cli};
    13.9 use dl::{download_to_path_with_backend, Backend, TlsBackend};
   13.10-use std::env;
   13.11+use logger::{info, trace, Logger};
   13.12+use std::{env, path::Path};
   13.13+use util::{cli::log_level_str_from_cli, Result, Url};
   13.14 
   13.15-pub const ABOUT: &str = concat!("cc-init ", env!("CORE_VERSION"), " (", env!("CORE_TARGET"), ")");
   13.16+pub const ABOUT: &str = concat!(
   13.17+  "cc-init ",
   13.18+  env!("CORE_VERSION"),
   13.19+  " (",
   13.20+  env!("CORE_TARGET"),
   13.21+  ")"
   13.22+);
   13.23 
   13.24 #[derive(Debug, Parser)]
   13.25 #[command(name="cc-init",author, version=env!("CORE_VERSION"), about=ABOUT)]
   13.26@@ -19,7 +23,7 @@
   13.27   level: u8,
   13.28 }
   13.29 
   13.30-fn dl<P:AsRef<Path> + std::fmt::Debug>(url:&str,dst:P) -> Result<()> {
   13.31+fn dl<P: AsRef<Path> + std::fmt::Debug>(url: &str, dst: P) -> Result<()> {
   13.32   info!("downloading {url} -> {dst:?}");
   13.33   let url = Url::parse(url)?;
   13.34   download_to_path_with_backend(
   13.35@@ -27,7 +31,8 @@
   13.36     &url,
   13.37     dst.as_ref(),
   13.38     true,
   13.39-    None)
   13.40+    None,
   13.41+  )
   13.42 }
   13.43 
   13.44 fn main() -> Result<()> {
    14.1--- a/rust/app/cli/krypt/main.rs	Sun Dec 03 22:18:30 2023 -0500
    14.2+++ b/rust/app/cli/krypt/main.rs	Sun Dec 03 23:25:08 2023 -0500
    14.3@@ -3,8 +3,7 @@
    14.4 use logger::{debug, info, trace, warn, Logger};
    14.5 use obj::Objective;
    14.6 use std::path::PathBuf;
    14.7-use util::Result;
    14.8-use util::cli::log_level_str_from_cli;
    14.9+use util::{cli::log_level_str_from_cli, Result};
   14.10 #[derive(Debug, Parser)]
   14.11 #[command(name="krypt",author, version, about, long_about = None)]
   14.12 struct Cli {
    15.1--- a/rust/app/cli/mailman/main.rs	Sun Dec 03 22:18:30 2023 -0500
    15.2+++ b/rust/app/cli/mailman/main.rs	Sun Dec 03 23:25:08 2023 -0500
    15.3@@ -1,9 +1,8 @@
    15.4 use clap::{Parser, Subcommand};
    15.5-use logger::{Logger,trace};
    15.6+use logger::{trace, Logger};
    15.7 // use obj::Objective;
    15.8 use std::path::PathBuf;
    15.9-use util::Result;
   15.10-use util::cli::log_level_str_from_cli;
   15.11+use util::{cli::log_level_str_from_cli, Result};
   15.12 // use jmap_client::{client::Client, core::query::Filter, email, mailbox};
   15.13 
   15.14 #[derive(Debug, Parser)]
    16.1--- a/rust/lib/dl/src/errors.rs	Sun Dec 03 22:18:30 2023 -0500
    16.2+++ b/rust/lib/dl/src/errors.rs	Sun Dec 03 23:25:08 2023 -0500
    16.3@@ -2,20 +2,20 @@
    16.4 
    16.5 #[derive(Debug, Error)]
    16.6 pub enum DownloadError {
    16.7-    #[error("http request returned an unsuccessful status code: {0}")]
    16.8-    HttpStatus(u32),
    16.9-    #[error("file not found")]
   16.10-    FileNotFound,
   16.11-    #[error("download backend '{0}' unavailable")]
   16.12-    BackendUnavailable(&'static str),
   16.13-    #[error("{0}")]
   16.14-    Message(String),
   16.15-    #[error(transparent)]
   16.16-    IoError(#[from] std::io::Error),
   16.17-    #[cfg(feature = "reqwest-backend")]
   16.18-    #[error(transparent)]
   16.19-    Reqwest(#[from] ::reqwest::Error),
   16.20-    #[cfg(feature = "curl-backend")]
   16.21-    #[error(transparent)]
   16.22-    CurlError(#[from] curl::Error),
   16.23+  #[error("http request returned an unsuccessful status code: {0}")]
   16.24+  HttpStatus(u32),
   16.25+  #[error("file not found")]
   16.26+  FileNotFound,
   16.27+  #[error("download backend '{0}' unavailable")]
   16.28+  BackendUnavailable(&'static str),
   16.29+  #[error("{0}")]
   16.30+  Message(String),
   16.31+  #[error(transparent)]
   16.32+  IoError(#[from] std::io::Error),
   16.33+  #[cfg(feature = "reqwest-backend")]
   16.34+  #[error(transparent)]
   16.35+  Reqwest(#[from] ::reqwest::Error),
   16.36+  #[cfg(feature = "curl-backend")]
   16.37+  #[error(transparent)]
   16.38+  CurlError(#[from] curl::Error),
   16.39 }
    17.1--- a/rust/lib/dl/src/lib.rs	Sun Dec 03 22:18:30 2023 -0500
    17.2+++ b/rust/lib/dl/src/lib.rs	Sun Dec 03 23:25:08 2023 -0500
    17.3@@ -1,8 +1,8 @@
    17.4 //! Easy file downloading
    17.5 #![deny(rust_2018_idioms)]
    17.6 
    17.7+use anyhow::{Context, Result};
    17.8 use std::path::Path;
    17.9-use anyhow::{Context, Result};
   17.10 use url::Url;
   17.11 mod errors;
   17.12 pub use crate::errors::*;
   17.13@@ -12,127 +12,135 @@
   17.14 
   17.15 #[derive(Debug, Copy, Clone)]
   17.16 pub enum Backend {
   17.17-    Curl,
   17.18-    Reqwest(TlsBackend),
   17.19+  Curl,
   17.20+  Reqwest(TlsBackend),
   17.21 }
   17.22 
   17.23 #[derive(Debug, Copy, Clone)]
   17.24 pub enum TlsBackend {
   17.25-    Rustls,
   17.26-    Default,
   17.27+  Rustls,
   17.28+  Default,
   17.29 }
   17.30 
   17.31 #[derive(Debug, Copy, Clone)]
   17.32 pub enum Event<'a> {
   17.33-    ResumingPartialDownload,
   17.34-    /// Received the Content-Length of the to-be downloaded data.
   17.35-    DownloadContentLengthReceived(u64),
   17.36-    /// Received some data.
   17.37-    DownloadDataReceived(&'a [u8]),
   17.38+  ResumingPartialDownload,
   17.39+  /// Received the Content-Length of the to-be downloaded data.
   17.40+  DownloadContentLengthReceived(u64),
   17.41+  /// Received some data.
   17.42+  DownloadDataReceived(&'a [u8]),
   17.43 }
   17.44 
   17.45 fn download_with_backend(
   17.46-    backend: Backend,
   17.47-    url: &Url,
   17.48-    resume_from: u64,
   17.49-    callback: &dyn Fn(Event<'_>) -> Result<()>,
   17.50+  backend: Backend,
   17.51+  url: &Url,
   17.52+  resume_from: u64,
   17.53+  callback: &dyn Fn(Event<'_>) -> Result<()>,
   17.54 ) -> Result<()> {
   17.55-    match backend {
   17.56-        Backend::Curl => curl::download(url, resume_from, callback),
   17.57-        Backend::Reqwest(tls) => reqwest_be::download(url, resume_from, callback, tls),
   17.58+  match backend {
   17.59+    Backend::Curl => curl::download(url, resume_from, callback),
   17.60+    Backend::Reqwest(tls) => {
   17.61+      reqwest_be::download(url, resume_from, callback, tls)
   17.62     }
   17.63+  }
   17.64 }
   17.65 
   17.66 type DownloadCallback<'a> = &'a dyn Fn(Event<'_>) -> Result<()>;
   17.67 
   17.68 pub fn download_to_path_with_backend(
   17.69-    backend: Backend,
   17.70-    url: &Url,
   17.71-    path: &Path,
   17.72-    resume_from_partial: bool,
   17.73-    callback: Option<DownloadCallback<'_>>,
   17.74+  backend: Backend,
   17.75+  url: &Url,
   17.76+  path: &Path,
   17.77+  resume_from_partial: bool,
   17.78+  callback: Option<DownloadCallback<'_>>,
   17.79 ) -> Result<()> {
   17.80-    use std::cell::RefCell;
   17.81-    use std::fs::remove_file;
   17.82-    use std::fs::OpenOptions;
   17.83-    use std::io::{Read, Seek, SeekFrom, Write};
   17.84+  use std::{
   17.85+    cell::RefCell,
   17.86+    fs::{remove_file, OpenOptions},
   17.87+    io::{Read, Seek, SeekFrom, Write},
   17.88+  };
   17.89 
   17.90-    || -> Result<()> {
   17.91-        let (file, resume_from) = if resume_from_partial {
   17.92-            let possible_partial = OpenOptions::new().read(true).open(path);
   17.93+  || -> Result<()> {
   17.94+    let (file, resume_from) = if resume_from_partial {
   17.95+      let possible_partial = OpenOptions::new().read(true).open(path);
   17.96 
   17.97-            let downloaded_so_far = if let Ok(mut partial) = possible_partial {
   17.98-                if let Some(cb) = callback {
   17.99-                    cb(Event::ResumingPartialDownload)?;
  17.100+      let downloaded_so_far = if let Ok(mut partial) = possible_partial {
  17.101+        if let Some(cb) = callback {
  17.102+          cb(Event::ResumingPartialDownload)?;
  17.103 
  17.104-                    let mut buf = vec![0; 32768];
  17.105-                    let mut downloaded_so_far = 0;
  17.106-                    loop {
  17.107-                        let n = partial.read(&mut buf)?;
  17.108-                        downloaded_so_far += n as u64;
  17.109-                        if n == 0 {
  17.110-                            break;
  17.111-                        }
  17.112-                        cb(Event::DownloadDataReceived(&buf[..n]))?;
  17.113-                    }
  17.114+          let mut buf = vec![0; 32768];
  17.115+          let mut downloaded_so_far = 0;
  17.116+          loop {
  17.117+            let n = partial.read(&mut buf)?;
  17.118+            downloaded_so_far += n as u64;
  17.119+            if n == 0 {
  17.120+              break;
  17.121+            }
  17.122+            cb(Event::DownloadDataReceived(&buf[..n]))?;
  17.123+          }
  17.124 
  17.125-                    downloaded_so_far
  17.126-                } else {
  17.127-                    let file_info = partial.metadata()?;
  17.128-                    file_info.len()
  17.129-                }
  17.130-            } else {
  17.131-                0
  17.132-            };
  17.133+          downloaded_so_far
  17.134+        } else {
  17.135+          let file_info = partial.metadata()?;
  17.136+          file_info.len()
  17.137+        }
  17.138+      } else {
  17.139+        0
  17.140+      };
  17.141+
  17.142+      let mut possible_partial = OpenOptions::new()
  17.143+        .write(true)
  17.144+        .create(true)
  17.145+        .open(path)
  17.146+        .context("error opening file for download")?;
  17.147 
  17.148-            let mut possible_partial = OpenOptions::new()
  17.149-                .write(true)
  17.150-                .create(true)
  17.151-                .open(path)
  17.152-                .context("error opening file for download")?;
  17.153-
  17.154-            possible_partial.seek(SeekFrom::End(0))?;
  17.155+      possible_partial.seek(SeekFrom::End(0))?;
  17.156 
  17.157-            (possible_partial, downloaded_so_far)
  17.158-        } else {
  17.159-            (
  17.160-                OpenOptions::new()
  17.161-                    .write(true)
  17.162-                    .create(true)
  17.163-                    .open(path)
  17.164-                    .context("error creating file for download")?,
  17.165-                0,
  17.166-            )
  17.167-        };
  17.168+      (possible_partial, downloaded_so_far)
  17.169+    } else {
  17.170+      (
  17.171+        OpenOptions::new()
  17.172+          .write(true)
  17.173+          .create(true)
  17.174+          .open(path)
  17.175+          .context("error creating file for download")?,
  17.176+        0,
  17.177+      )
  17.178+    };
  17.179 
  17.180-        let file = RefCell::new(file);
  17.181+    let file = RefCell::new(file);
  17.182 
  17.183-        download_with_backend(backend, url, resume_from, &|event| {
  17.184-            if let Event::DownloadDataReceived(data) = event {
  17.185-                file.borrow_mut()
  17.186-                    .write_all(data)
  17.187-                    .context("unable to write download to disk")?;
  17.188-            }
  17.189-            match callback {
  17.190-                Some(cb) => cb(event),
  17.191-                None => Ok(()),
  17.192-            }
  17.193-        })?;
  17.194+    download_with_backend(backend, url, resume_from, &|event| {
  17.195+      if let Event::DownloadDataReceived(data) = event {
  17.196+        file
  17.197+          .borrow_mut()
  17.198+          .write_all(data)
  17.199+          .context("unable to write download to disk")?;
  17.200+      }
  17.201+      match callback {
  17.202+        Some(cb) => cb(event),
  17.203+        None => Ok(()),
  17.204+      }
  17.205+    })?;
  17.206 
  17.207-        file.borrow_mut()
  17.208-            .sync_data()
  17.209-            .context("unable to sync download to disk")?;
  17.210+    file
  17.211+      .borrow_mut()
  17.212+      .sync_data()
  17.213+      .context("unable to sync download to disk")?;
  17.214 
  17.215-        Ok(())
  17.216-    }()
  17.217-    .map_err(|e| {
  17.218-        // TODO: We currently clear up the cached download on any error, should we restrict it to a subset?
  17.219-        if let Err(file_err) = remove_file(path).context("cleaning up cached downloads") {
  17.220-            file_err.context(e)
  17.221-        } else {
  17.222-            e
  17.223-        }
  17.224-    })
  17.225+    Ok(())
  17.226+  }()
  17.227+  .map_err(|e| {
  17.228+    // TODO: We currently clear up the cached download on any error, should we
  17.229+    // restrict it to a subset?
  17.230+    if let Err(file_err) =
  17.231+      remove_file(path).context("cleaning up cached downloads")
  17.232+    {
  17.233+      file_err.context(e)
  17.234+    } else {
  17.235+      e
  17.236+    }
  17.237+  })
  17.238 }
  17.239 
  17.240 #[cfg(all(not(feature = "reqwest-backend"), not(feature = "curl-backend")))]
  17.241@@ -142,316 +150,320 @@
  17.242 /// stack via libcurl
  17.243 #[cfg(feature = "curl-backend")]
  17.244 pub mod curl {
  17.245-    use std::cell::RefCell;
  17.246-    use std::str;
  17.247-    use std::time::Duration;
  17.248+  use std::{cell::RefCell, str, time::Duration};
  17.249 
  17.250-    use anyhow::{Context, Result};
  17.251-    use curl::easy::Easy;
  17.252-    use url::Url;
  17.253+  use anyhow::{Context, Result};
  17.254+  use curl::easy::Easy;
  17.255+  use url::Url;
  17.256 
  17.257-    use super::Event;
  17.258-    use crate::errors::*;
  17.259+  use super::Event;
  17.260+  use crate::errors::*;
  17.261 
  17.262-    pub fn download(
  17.263-        url: &Url,
  17.264-        resume_from: u64,
  17.265-        callback: &dyn Fn(Event<'_>) -> Result<()>,
  17.266-    ) -> Result<()> {
  17.267-        // Fetch either a cached libcurl handle (which will preserve open
  17.268-        // connections) or create a new one if it isn't listed.
  17.269-        //
  17.270-        // Once we've acquired it, reset the lifetime from 'static to our local
  17.271-        // scope.
  17.272-        thread_local!(static EASY: RefCell<Easy> = RefCell::new(Easy::new()));
  17.273-        EASY.with(|handle| {
  17.274-            let mut handle = handle.borrow_mut();
  17.275+  pub fn download(
  17.276+    url: &Url,
  17.277+    resume_from: u64,
  17.278+    callback: &dyn Fn(Event<'_>) -> Result<()>,
  17.279+  ) -> Result<()> {
  17.280+    // Fetch either a cached libcurl handle (which will preserve open
  17.281+    // connections) or create a new one if it isn't listed.
  17.282+    //
  17.283+    // Once we've acquired it, reset the lifetime from 'static to our local
  17.284+    // scope.
  17.285+    thread_local!(static EASY: RefCell<Easy> = RefCell::new(Easy::new()));
  17.286+    EASY.with(|handle| {
  17.287+      let mut handle = handle.borrow_mut();
  17.288 
  17.289-            handle.url(url.as_ref())?;
  17.290-            handle.follow_location(true)?;
  17.291-            handle.useragent(super::USER_AGENT)?;
  17.292+      handle.url(url.as_ref())?;
  17.293+      handle.follow_location(true)?;
  17.294+      handle.useragent(super::USER_AGENT)?;
  17.295 
  17.296-            if resume_from > 0 {
  17.297-                handle.resume_from(resume_from)?;
  17.298-            } else {
  17.299-                // an error here indicates that the range header isn't supported by underlying curl,
  17.300-                // so there's nothing to "clear" - safe to ignore this error.
  17.301-                let _ = handle.resume_from(0);
  17.302-            }
  17.303+      if resume_from > 0 {
  17.304+        handle.resume_from(resume_from)?;
  17.305+      } else {
  17.306+        // an error here indicates that the range header isn't supported by
  17.307+        // underlying curl, so there's nothing to "clear" - safe to
  17.308+        // ignore this error.
  17.309+        let _ = handle.resume_from(0);
  17.310+      }
  17.311 
  17.312-            // Take at most 30s to connect
  17.313-            handle.connect_timeout(Duration::new(30, 0))?;
  17.314+      // Take at most 30s to connect
  17.315+      handle.connect_timeout(Duration::new(30, 0))?;
  17.316 
  17.317-            {
  17.318-                let cberr = RefCell::new(None);
  17.319-                let mut transfer = handle.transfer();
  17.320+      {
  17.321+        let cberr = RefCell::new(None);
  17.322+        let mut transfer = handle.transfer();
  17.323 
  17.324-                // Data callback for libcurl which is called with data that's
  17.325-                // downloaded. We just feed it into our hasher and also write it out
  17.326-                // to disk.
  17.327-                transfer.write_function(|data| {
  17.328-                    match callback(Event::DownloadDataReceived(data)) {
  17.329-                        Ok(()) => Ok(data.len()),
  17.330-                        Err(e) => {
  17.331-                            *cberr.borrow_mut() = Some(e);
  17.332-                            Ok(0)
  17.333-                        }
  17.334-                    }
  17.335-                })?;
  17.336+        // Data callback for libcurl which is called with data that's
  17.337+        // downloaded. We just feed it into our hasher and also write it out
  17.338+        // to disk.
  17.339+        transfer.write_function(|data| {
  17.340+          match callback(Event::DownloadDataReceived(data)) {
  17.341+            Ok(()) => Ok(data.len()),
  17.342+            Err(e) => {
  17.343+              *cberr.borrow_mut() = Some(e);
  17.344+              Ok(0)
  17.345+            }
  17.346+          }
  17.347+        })?;
  17.348 
  17.349-                // Listen for headers and parse out a `Content-Length` (case-insensitive) if it
  17.350-                // comes so we know how much we're downloading.
  17.351-                transfer.header_function(|header| {
  17.352-                    if let Ok(data) = str::from_utf8(header) {
  17.353-                        let prefix = "content-length: ";
  17.354-                        if data.to_ascii_lowercase().starts_with(prefix) {
  17.355-                            if let Ok(s) = data[prefix.len()..].trim().parse::<u64>() {
  17.356-                                let msg = Event::DownloadContentLengthReceived(s + resume_from);
  17.357-                                match callback(msg) {
  17.358-                                    Ok(()) => (),
  17.359-                                    Err(e) => {
  17.360-                                        *cberr.borrow_mut() = Some(e);
  17.361-                                        return false;
  17.362-                                    }
  17.363-                                }
  17.364-                            }
  17.365-                        }
  17.366-                    }
  17.367-                    true
  17.368-                })?;
  17.369+        // Listen for headers and parse out a `Content-Length`
  17.370+        // (case-insensitive) if it comes so we know how much we're
  17.371+        // downloading.
  17.372+        transfer.header_function(|header| {
  17.373+          if let Ok(data) = str::from_utf8(header) {
  17.374+            let prefix = "content-length: ";
  17.375+            if data.to_ascii_lowercase().starts_with(prefix) {
  17.376+              if let Ok(s) = data[prefix.len()..].trim().parse::<u64>() {
  17.377+                let msg = Event::DownloadContentLengthReceived(s + resume_from);
  17.378+                match callback(msg) {
  17.379+                  Ok(()) => (),
  17.380+                  Err(e) => {
  17.381+                    *cberr.borrow_mut() = Some(e);
  17.382+                    return false;
  17.383+                  }
  17.384+                }
  17.385+              }
  17.386+            }
  17.387+          }
  17.388+          true
  17.389+        })?;
  17.390 
  17.391-                // If an error happens check to see if we had a filesystem error up
  17.392-                // in `cberr`, but we always want to punt it up.
  17.393-                transfer.perform().or_else(|e| {
  17.394-                    // If the original error was generated by one of our
  17.395-                    // callbacks, return it.
  17.396-                    match cberr.borrow_mut().take() {
  17.397-                        Some(cberr) => Err(cberr),
  17.398-                        None => {
  17.399-                            // Otherwise, return the error from curl
  17.400-                            if e.is_file_couldnt_read_file() {
  17.401-                                Err(e).context(DownloadError::FileNotFound)
  17.402-                            } else {
  17.403-                                Err(e).context("error during download")?
  17.404-                            }
  17.405-                        }
  17.406-                    }
  17.407-                })?;
  17.408+        // If an error happens check to see if we had a filesystem error up
  17.409+        // in `cberr`, but we always want to punt it up.
  17.410+        transfer.perform().or_else(|e| {
  17.411+          // If the original error was generated by one of our
  17.412+          // callbacks, return it.
  17.413+          match cberr.borrow_mut().take() {
  17.414+            Some(cberr) => Err(cberr),
  17.415+            None => {
  17.416+              // Otherwise, return the error from curl
  17.417+              if e.is_file_couldnt_read_file() {
  17.418+                Err(e).context(DownloadError::FileNotFound)
  17.419+              } else {
  17.420+                Err(e).context("error during download")?
  17.421+              }
  17.422             }
  17.423+          }
  17.424+        })?;
  17.425+      }
  17.426 
  17.427-            // If we didn't get a 20x or 0 ("OK" for files) then return an error
  17.428-            let code = handle.response_code()?;
  17.429-            match code {
  17.430-                0 | 200..=299 => {}
  17.431-                _ => {
  17.432-                    return Err(DownloadError::HttpStatus(code).into());
  17.433-                }
  17.434-            };
  17.435+      // If we didn't get a 20x or 0 ("OK" for files) then return an error
  17.436+      let code = handle.response_code()?;
  17.437+      match code {
  17.438+        0 | 200..=299 => {}
  17.439+        _ => {
  17.440+          return Err(DownloadError::HttpStatus(code).into());
  17.441+        }
  17.442+      };
  17.443 
  17.444-            Ok(())
  17.445-        })
  17.446-    }
  17.447+      Ok(())
  17.448+    })
  17.449+  }
  17.450 }
  17.451 
  17.452 #[cfg(feature = "reqwest-backend")]
  17.453 pub mod reqwest_be {
  17.454-    #[cfg(all(
  17.455-        not(feature = "reqwest-rustls-tls"),
  17.456-        not(feature = "reqwest-default-tls")
  17.457-    ))]
  17.458-    compile_error!("Must select a reqwest TLS backend");
  17.459-
  17.460-    use std::io;
  17.461-    use std::time::Duration;
  17.462+  #[cfg(all(
  17.463+    not(feature = "reqwest-rustls-tls"),
  17.464+    not(feature = "reqwest-default-tls")
  17.465+  ))]
  17.466+  compile_error!("Must select a reqwest TLS backend");
  17.467 
  17.468-    use anyhow::{anyhow, Context, Result};
  17.469-    #[cfg(any(feature = "reqwest-rustls-tls", feature = "reqwest-default-tls"))]
  17.470-    use once_cell::sync::Lazy;
  17.471-    use reqwest::blocking::{Client, ClientBuilder, Response};
  17.472-    use reqwest::{header, Proxy};
  17.473-    use url::Url;
  17.474-
  17.475-    use super::Event;
  17.476-    use super::TlsBackend;
  17.477-    use crate::errors::*;
  17.478+  use std::{io, time::Duration};
  17.479 
  17.480-    pub fn download(
  17.481-        url: &Url,
  17.482-        resume_from: u64,
  17.483-        callback: &dyn Fn(Event<'_>) -> Result<()>,
  17.484-        tls: TlsBackend,
  17.485-    ) -> Result<()> {
  17.486-        // Short-circuit reqwest for the "file:" URL scheme
  17.487-        if download_from_file_url(url, resume_from, callback)? {
  17.488-            return Ok(());
  17.489-        }
  17.490-
  17.491-        let mut res = request(url, resume_from, tls).context("failed to make network request")?;
  17.492-
  17.493-        if !res.status().is_success() {
  17.494-            let code: u16 = res.status().into();
  17.495-            return Err(anyhow!(DownloadError::HttpStatus(u32::from(code))));
  17.496-        }
  17.497+  use anyhow::{anyhow, Context, Result};
  17.498+  #[cfg(any(
  17.499+    feature = "reqwest-rustls-tls",
  17.500+    feature = "reqwest-default-tls"
  17.501+  ))]
  17.502+  use once_cell::sync::Lazy;
  17.503+  use reqwest::{
  17.504+    blocking::{Client, ClientBuilder, Response},
  17.505+    header, Proxy,
  17.506+  };
  17.507+  use url::Url;
  17.508 
  17.509-        let buffer_size = 0x10000;
  17.510-        let mut buffer = vec![0u8; buffer_size];
  17.511-
  17.512-        if let Some(len) = res.headers().get(header::CONTENT_LENGTH) {
  17.513-            // TODO possible issues during unwrap?
  17.514-            let len = len.to_str().unwrap().parse::<u64>().unwrap() + resume_from;
  17.515-            callback(Event::DownloadContentLengthReceived(len))?;
  17.516-        }
  17.517+  use super::{Event, TlsBackend};
  17.518+  use crate::errors::*;
  17.519 
  17.520-        loop {
  17.521-            let bytes_read = io::Read::read(&mut res, &mut buffer)?;
  17.522-
  17.523-            if bytes_read != 0 {
  17.524-                callback(Event::DownloadDataReceived(&buffer[0..bytes_read]))?;
  17.525-            } else {
  17.526-                return Ok(());
  17.527-            }
  17.528-        }
  17.529+  pub fn download(
  17.530+    url: &Url,
  17.531+    resume_from: u64,
  17.532+    callback: &dyn Fn(Event<'_>) -> Result<()>,
  17.533+    tls: TlsBackend,
  17.534+  ) -> Result<()> {
  17.535+    // Short-circuit reqwest for the "file:" URL scheme
  17.536+    if download_from_file_url(url, resume_from, callback)? {
  17.537+      return Ok(());
  17.538     }
  17.539 
  17.540-    fn client_generic() -> ClientBuilder {
  17.541-        Client::builder()
  17.542-            .gzip(false)
  17.543-            .user_agent(super::USER_AGENT)
  17.544-            .proxy(Proxy::custom(env_proxy))
  17.545-            .timeout(Duration::from_secs(30))
  17.546+    let mut res = request(url, resume_from, tls)
  17.547+      .context("failed to make network request")?;
  17.548+
  17.549+    if !res.status().is_success() {
  17.550+      let code: u16 = res.status().into();
  17.551+      return Err(anyhow!(DownloadError::HttpStatus(u32::from(code))));
  17.552+    }
  17.553+
  17.554+    let buffer_size = 0x10000;
  17.555+    let mut buffer = vec![0u8; buffer_size];
  17.556+
  17.557+    if let Some(len) = res.headers().get(header::CONTENT_LENGTH) {
  17.558+      // TODO possible issues during unwrap?
  17.559+      let len = len.to_str().unwrap().parse::<u64>().unwrap() + resume_from;
  17.560+      callback(Event::DownloadContentLengthReceived(len))?;
  17.561     }
  17.562 
  17.563-    #[cfg(feature = "reqwest-rustls-tls")]
  17.564-    static CLIENT_RUSTLS_TLS: Lazy<Client> = Lazy::new(|| {
  17.565-        let catcher = || client_generic().use_rustls_tls().build();
  17.566+    loop {
  17.567+      let bytes_read = io::Read::read(&mut res, &mut buffer)?;
  17.568+
  17.569+      if bytes_read != 0 {
  17.570+        callback(Event::DownloadDataReceived(&buffer[0..bytes_read]))?;
  17.571+      } else {
  17.572+        return Ok(());
  17.573+      }
  17.574+    }
  17.575+  }
  17.576 
  17.577-        // woah, an unwrap?!
  17.578-        // It's OK. This is the same as what is happening in curl.
  17.579-        //
  17.580-        // The curl::Easy::new() internally assert!s that the initialized
  17.581-        // Easy is not null. Inside reqwest, the errors here would be from
  17.582-        // the TLS library returning a null pointer as well.
  17.583-        catcher().unwrap()
  17.584-    });
  17.585+  fn client_generic() -> ClientBuilder {
  17.586+    Client::builder()
  17.587+      .gzip(false)
  17.588+      .user_agent(super::USER_AGENT)
  17.589+      .proxy(Proxy::custom(env_proxy))
  17.590+      .timeout(Duration::from_secs(30))
  17.591+  }
  17.592+
  17.593+  #[cfg(feature = "reqwest-rustls-tls")]
  17.594+  static CLIENT_RUSTLS_TLS: Lazy<Client> = Lazy::new(|| {
  17.595+    let catcher = || client_generic().use_rustls_tls().build();
  17.596+
  17.597+    // woah, an unwrap?!
  17.598+    // It's OK. This is the same as what is happening in curl.
  17.599+    //
  17.600+    // The curl::Easy::new() internally assert!s that the initialized
  17.601+    // Easy is not null. Inside reqwest, the errors here would be from
  17.602+    // the TLS library returning a null pointer as well.
  17.603+    catcher().unwrap()
  17.604+  });
  17.605+
  17.606+  #[cfg(feature = "reqwest-default-tls")]
  17.607+  static CLIENT_DEFAULT_TLS: Lazy<Client> = Lazy::new(|| {
  17.608+    let catcher = || client_generic().build();
  17.609 
  17.610-    #[cfg(feature = "reqwest-default-tls")]
  17.611-    static CLIENT_DEFAULT_TLS: Lazy<Client> = Lazy::new(|| {
  17.612-        let catcher = || client_generic().build();
  17.613+    // woah, an unwrap?!
  17.614+    // It's OK. This is the same as what is happening in curl.
  17.615+    //
  17.616+    // The curl::Easy::new() internally assert!s that the initialized
  17.617+    // Easy is not null. Inside reqwest, the errors here would be from
  17.618+    // the TLS library returning a null pointer as well.
  17.619+    catcher().unwrap()
  17.620+  });
  17.621+
  17.622+  fn env_proxy(url: &Url) -> Option<Url> {
  17.623+    env_proxy::for_url(url).to_url()
  17.624+  }
  17.625 
  17.626-        // woah, an unwrap?!
  17.627-        // It's OK. This is the same as what is happening in curl.
  17.628-        //
  17.629-        // The curl::Easy::new() internally assert!s that the initialized
  17.630-        // Easy is not null. Inside reqwest, the errors here would be from
  17.631-        // the TLS library returning a null pointer as well.
  17.632-        catcher().unwrap()
  17.633-    });
  17.634+  fn request(
  17.635+    url: &Url,
  17.636+    resume_from: u64,
  17.637+    backend: TlsBackend,
  17.638+  ) -> Result<Response, DownloadError> {
  17.639+    let client: &Client = match backend {
  17.640+      #[cfg(feature = "reqwest-rustls-tls")]
  17.641+      TlsBackend::Rustls => &CLIENT_RUSTLS_TLS,
  17.642+      #[cfg(not(feature = "reqwest-rustls-tls"))]
  17.643+      TlsBackend::Rustls => {
  17.644+        return Err(DownloadError::BackendUnavailable("reqwest rustls"));
  17.645+      }
  17.646+      #[cfg(feature = "reqwest-default-tls")]
  17.647+      TlsBackend::Default => &CLIENT_DEFAULT_TLS,
  17.648+      #[cfg(not(feature = "reqwest-default-tls"))]
  17.649+      TlsBackend::Default => {
  17.650+        return Err(DownloadError::BackendUnavailable("reqwest default TLS"));
  17.651+      }
  17.652+    };
  17.653+    let mut req = client.get(url.as_str());
  17.654 
  17.655-    fn env_proxy(url: &Url) -> Option<Url> {
  17.656-        env_proxy::for_url(url).to_url()
  17.657+    if resume_from != 0 {
  17.658+      req = req.header(header::RANGE, format!("bytes={resume_from}-"));
  17.659     }
  17.660 
  17.661-    fn request(
  17.662-        url: &Url,
  17.663-        resume_from: u64,
  17.664-        backend: TlsBackend,
  17.665-    ) -> Result<Response, DownloadError> {
  17.666-        let client: &Client = match backend {
  17.667-            #[cfg(feature = "reqwest-rustls-tls")]
  17.668-            TlsBackend::Rustls => &CLIENT_RUSTLS_TLS,
  17.669-            #[cfg(not(feature = "reqwest-rustls-tls"))]
  17.670-            TlsBackend::Rustls => {
  17.671-                return Err(DownloadError::BackendUnavailable("reqwest rustls"));
  17.672-            }
  17.673-            #[cfg(feature = "reqwest-default-tls")]
  17.674-            TlsBackend::Default => &CLIENT_DEFAULT_TLS,
  17.675-            #[cfg(not(feature = "reqwest-default-tls"))]
  17.676-            TlsBackend::Default => {
  17.677-                return Err(DownloadError::BackendUnavailable("reqwest default TLS"));
  17.678-            }
  17.679-        };
  17.680-        let mut req = client.get(url.as_str());
  17.681+    Ok(req.send()?)
  17.682+  }
  17.683 
  17.684-        if resume_from != 0 {
  17.685-            req = req.header(header::RANGE, format!("bytes={resume_from}-"));
  17.686-        }
  17.687-
  17.688-        Ok(req.send()?)
  17.689-    }
  17.690+  fn download_from_file_url(
  17.691+    url: &Url,
  17.692+    resume_from: u64,
  17.693+    callback: &dyn Fn(Event<'_>) -> Result<()>,
  17.694+  ) -> Result<bool> {
  17.695+    use std::fs;
  17.696 
  17.697-    fn download_from_file_url(
  17.698-        url: &Url,
  17.699-        resume_from: u64,
  17.700-        callback: &dyn Fn(Event<'_>) -> Result<()>,
  17.701-    ) -> Result<bool> {
  17.702-        use std::fs;
  17.703+    // The file scheme is mostly for use by tests to mock the dist server
  17.704+    if url.scheme() == "file" {
  17.705+      let src = url.to_file_path().map_err(|_| {
  17.706+        DownloadError::Message(format!("bogus file url: '{url}'"))
  17.707+      })?;
  17.708+      if !src.is_file() {
  17.709+        // Because some of rustup's logic depends on checking
  17.710+        // the error when a downloaded file doesn't exist, make
  17.711+        // the file case return the same error value as the
  17.712+        // network case.
  17.713+        return Err(anyhow!(DownloadError::FileNotFound));
  17.714+      }
  17.715 
  17.716-        // The file scheme is mostly for use by tests to mock the dist server
  17.717-        if url.scheme() == "file" {
  17.718-            let src = url
  17.719-                .to_file_path()
  17.720-                .map_err(|_| DownloadError::Message(format!("bogus file url: '{url}'")))?;
  17.721-            if !src.is_file() {
  17.722-                // Because some of rustup's logic depends on checking
  17.723-                // the error when a downloaded file doesn't exist, make
  17.724-                // the file case return the same error value as the
  17.725-                // network case.
  17.726-                return Err(anyhow!(DownloadError::FileNotFound));
  17.727-            }
  17.728+      let mut f =
  17.729+        fs::File::open(src).context("unable to open downloaded file")?;
  17.730+      io::Seek::seek(&mut f, io::SeekFrom::Start(resume_from))?;
  17.731 
  17.732-            let mut f = fs::File::open(src).context("unable to open downloaded file")?;
  17.733-            io::Seek::seek(&mut f, io::SeekFrom::Start(resume_from))?;
  17.734+      let mut buffer = vec![0u8; 0x10000];
  17.735+      loop {
  17.736+        let bytes_read = io::Read::read(&mut f, &mut buffer)?;
  17.737+        if bytes_read == 0 {
  17.738+          break;
  17.739+        }
  17.740+        callback(Event::DownloadDataReceived(&buffer[0..bytes_read]))?;
  17.741+      }
  17.742 
  17.743-            let mut buffer = vec![0u8; 0x10000];
  17.744-            loop {
  17.745-                let bytes_read = io::Read::read(&mut f, &mut buffer)?;
  17.746-                if bytes_read == 0 {
  17.747-                    break;
  17.748-                }
  17.749-                callback(Event::DownloadDataReceived(&buffer[0..bytes_read]))?;
  17.750-            }
  17.751-
  17.752-            Ok(true)
  17.753-        } else {
  17.754-            Ok(false)
  17.755-        }
  17.756+      Ok(true)
  17.757+    } else {
  17.758+      Ok(false)
  17.759     }
  17.760+  }
  17.761 }
  17.762 
  17.763 #[cfg(not(feature = "curl-backend"))]
  17.764 pub mod curl {
  17.765 
  17.766-    use anyhow::{anyhow, Result};
  17.767+  use anyhow::{anyhow, Result};
  17.768 
  17.769-    use super::Event;
  17.770-    use crate::errors::*;
  17.771-    use url::Url;
  17.772+  use super::Event;
  17.773+  use crate::errors::*;
  17.774+  use url::Url;
  17.775 
  17.776-    pub fn download(
  17.777-        _url: &Url,
  17.778-        _resume_from: u64,
  17.779-        _callback: &dyn Fn(Event<'_>) -> Result<()>,
  17.780-    ) -> Result<()> {
  17.781-        Err(anyhow!(DownloadError::BackendUnavailable("curl")))
  17.782-    }
  17.783+  pub fn download(
  17.784+    _url: &Url,
  17.785+    _resume_from: u64,
  17.786+    _callback: &dyn Fn(Event<'_>) -> Result<()>,
  17.787+  ) -> Result<()> {
  17.788+    Err(anyhow!(DownloadError::BackendUnavailable("curl")))
  17.789+  }
  17.790 }
  17.791 
  17.792 #[cfg(not(feature = "reqwest-backend"))]
  17.793 pub mod reqwest_be {
  17.794 
  17.795-    use anyhow::{anyhow, Result};
  17.796+  use anyhow::{anyhow, Result};
  17.797 
  17.798-    use super::Event;
  17.799-    use super::TlsBackend;
  17.800-    use crate::errors::*;
  17.801-    use url::Url;
  17.802+  use super::{Event, TlsBackend};
  17.803+  use crate::errors::*;
  17.804+  use url::Url;
  17.805 
  17.806-    pub fn download(
  17.807-        _url: &Url,
  17.808-        _resume_from: u64,
  17.809-        _callback: &dyn Fn(Event<'_>) -> Result<()>,
  17.810-        _tls: TlsBackend,
  17.811-    ) -> Result<()> {
  17.812-        Err(anyhow!(DownloadError::BackendUnavailable("reqwest")))
  17.813-    }
  17.814+  pub fn download(
  17.815+    _url: &Url,
  17.816+    _resume_from: u64,
  17.817+    _callback: &dyn Fn(Event<'_>) -> Result<()>,
  17.818+    _tls: TlsBackend,
  17.819+  ) -> Result<()> {
  17.820+    Err(anyhow!(DownloadError::BackendUnavailable("reqwest")))
  17.821+  }
  17.822 }
    18.1--- a/rust/lib/dl/tests/download-curl-resume.rs	Sun Dec 03 22:18:30 2023 -0500
    18.2+++ b/rust/lib/dl/tests/download-curl-resume.rs	Sun Dec 03 23:25:08 2023 -0500
    18.3@@ -1,7 +1,9 @@
    18.4 #![cfg(feature = "curl-backend")]
    18.5 
    18.6-use std::sync::atomic::{AtomicBool, Ordering};
    18.7-use std::sync::Mutex;
    18.8+use std::sync::{
    18.9+  atomic::{AtomicBool, Ordering},
   18.10+  Mutex,
   18.11+};
   18.12 
   18.13 use url::Url;
   18.14 
   18.15@@ -12,65 +14,71 @@
   18.16 
   18.17 #[test]
   18.18 fn partially_downloaded_file_gets_resumed_from_byte_offset() {
   18.19-    let tmpdir = tmp_dir();
   18.20-    let from_path = tmpdir.path().join("download-source");
   18.21-    write_file(&from_path, "xxx45");
   18.22+  let tmpdir = tmp_dir();
   18.23+  let from_path = tmpdir.path().join("download-source");
   18.24+  write_file(&from_path, "xxx45");
   18.25+
   18.26+  let target_path = tmpdir.path().join("downloaded");
   18.27+  write_file(&target_path, "123");
   18.28 
   18.29-    let target_path = tmpdir.path().join("downloaded");
   18.30-    write_file(&target_path, "123");
   18.31+  let from_url = Url::from_file_path(&from_path).unwrap();
   18.32+  download_to_path_with_backend(
   18.33+    Backend::Curl,
   18.34+    &from_url,
   18.35+    &target_path,
   18.36+    true,
   18.37+    None,
   18.38+  )
   18.39+  .expect("Test download failed");
   18.40 
   18.41-    let from_url = Url::from_file_path(&from_path).unwrap();
   18.42-    download_to_path_with_backend(Backend::Curl, &from_url, &target_path, true, None)
   18.43-        .expect("Test download failed");
   18.44-
   18.45-    assert_eq!(std::fs::read_to_string(&target_path).unwrap(), "12345");
   18.46+  assert_eq!(std::fs::read_to_string(&target_path).unwrap(), "12345");
   18.47 }
   18.48 
   18.49 #[test]
   18.50 fn callback_gets_all_data_as_if_the_download_happened_all_at_once() {
   18.51-    let tmpdir = tmp_dir();
   18.52-    let target_path = tmpdir.path().join("downloaded");
   18.53-    write_file(&target_path, "123");
   18.54+  let tmpdir = tmp_dir();
   18.55+  let target_path = tmpdir.path().join("downloaded");
   18.56+  write_file(&target_path, "123");
   18.57 
   18.58-    let addr = serve_file(b"xxx45".to_vec());
   18.59+  let addr = serve_file(b"xxx45".to_vec());
   18.60 
   18.61-    let from_url = format!("http://{addr}").parse().unwrap();
   18.62+  let from_url = format!("http://{addr}").parse().unwrap();
   18.63 
   18.64-    let callback_partial = AtomicBool::new(false);
   18.65-    let callback_len = Mutex::new(None);
   18.66-    let received_in_callback = Mutex::new(Vec::new());
   18.67+  let callback_partial = AtomicBool::new(false);
   18.68+  let callback_len = Mutex::new(None);
   18.69+  let received_in_callback = Mutex::new(Vec::new());
   18.70 
   18.71-    download_to_path_with_backend(
   18.72-        Backend::Curl,
   18.73-        &from_url,
   18.74-        &target_path,
   18.75-        true,
   18.76-        Some(&|msg| {
   18.77-            match msg {
   18.78-                Event::ResumingPartialDownload => {
   18.79-                    assert!(!callback_partial.load(Ordering::SeqCst));
   18.80-                    callback_partial.store(true, Ordering::SeqCst);
   18.81-                }
   18.82-                Event::DownloadContentLengthReceived(len) => {
   18.83-                    let mut flag = callback_len.lock().unwrap();
   18.84-                    assert!(flag.is_none());
   18.85-                    *flag = Some(len);
   18.86-                }
   18.87-                Event::DownloadDataReceived(data) => {
   18.88-                    for b in data.iter() {
   18.89-                        received_in_callback.lock().unwrap().push(*b);
   18.90-                    }
   18.91-                }
   18.92-            }
   18.93+  download_to_path_with_backend(
   18.94+    Backend::Curl,
   18.95+    &from_url,
   18.96+    &target_path,
   18.97+    true,
   18.98+    Some(&|msg| {
   18.99+      match msg {
  18.100+        Event::ResumingPartialDownload => {
  18.101+          assert!(!callback_partial.load(Ordering::SeqCst));
  18.102+          callback_partial.store(true, Ordering::SeqCst);
  18.103+        }
  18.104+        Event::DownloadContentLengthReceived(len) => {
  18.105+          let mut flag = callback_len.lock().unwrap();
  18.106+          assert!(flag.is_none());
  18.107+          *flag = Some(len);
  18.108+        }
  18.109+        Event::DownloadDataReceived(data) => {
  18.110+          for b in data.iter() {
  18.111+            received_in_callback.lock().unwrap().push(*b);
  18.112+          }
  18.113+        }
  18.114+      }
  18.115 
  18.116-            Ok(())
  18.117-        }),
  18.118-    )
  18.119-    .expect("Test download failed");
  18.120+      Ok(())
  18.121+    }),
  18.122+  )
  18.123+  .expect("Test download failed");
  18.124 
  18.125-    assert!(callback_partial.into_inner());
  18.126-    assert_eq!(*callback_len.lock().unwrap(), Some(5));
  18.127-    let observed_bytes = received_in_callback.into_inner().unwrap();
  18.128-    assert_eq!(observed_bytes, vec![b'1', b'2', b'3', b'4', b'5']);
  18.129-    assert_eq!(std::fs::read_to_string(&target_path).unwrap(), "12345");
  18.130+  assert!(callback_partial.into_inner());
  18.131+  assert_eq!(*callback_len.lock().unwrap(), Some(5));
  18.132+  let observed_bytes = received_in_callback.into_inner().unwrap();
  18.133+  assert_eq!(observed_bytes, vec![b'1', b'2', b'3', b'4', b'5']);
  18.134+  assert_eq!(std::fs::read_to_string(&target_path).unwrap(), "12345");
  18.135 }
    19.1--- a/rust/lib/dl/tests/download-reqwest-resume.rs	Sun Dec 03 22:18:30 2023 -0500
    19.2+++ b/rust/lib/dl/tests/download-reqwest-resume.rs	Sun Dec 03 23:25:08 2023 -0500
    19.3@@ -1,7 +1,9 @@
    19.4 #![cfg(feature = "reqwest-backend")]
    19.5 
    19.6-use std::sync::atomic::{AtomicBool, Ordering};
    19.7-use std::sync::Mutex;
    19.8+use std::sync::{
    19.9+  atomic::{AtomicBool, Ordering},
   19.10+  Mutex,
   19.11+};
   19.12 
   19.13 use url::Url;
   19.14 
   19.15@@ -12,71 +14,71 @@
   19.16 
   19.17 #[test]
   19.18 fn resume_partial_from_file_url() {
   19.19-    let tmpdir = tmp_dir();
   19.20-    let from_path = tmpdir.path().join("download-source");
   19.21-    write_file(&from_path, "xxx45");
   19.22+  let tmpdir = tmp_dir();
   19.23+  let from_path = tmpdir.path().join("download-source");
   19.24+  write_file(&from_path, "xxx45");
   19.25 
   19.26-    let target_path = tmpdir.path().join("downloaded");
   19.27-    write_file(&target_path, "123");
   19.28+  let target_path = tmpdir.path().join("downloaded");
   19.29+  write_file(&target_path, "123");
   19.30 
   19.31-    let from_url = Url::from_file_path(&from_path).unwrap();
   19.32-    download_to_path_with_backend(
   19.33-        Backend::Reqwest(TlsBackend::Default),
   19.34-        &from_url,
   19.35-        &target_path,
   19.36-        true,
   19.37-        None,
   19.38-    )
   19.39-    .expect("Test download failed");
   19.40+  let from_url = Url::from_file_path(&from_path).unwrap();
   19.41+  download_to_path_with_backend(
   19.42+    Backend::Reqwest(TlsBackend::Default),
   19.43+    &from_url,
   19.44+    &target_path,
   19.45+    true,
   19.46+    None,
   19.47+  )
   19.48+  .expect("Test download failed");
   19.49 
   19.50-    assert_eq!(std::fs::read_to_string(&target_path).unwrap(), "12345");
   19.51+  assert_eq!(std::fs::read_to_string(&target_path).unwrap(), "12345");
   19.52 }
   19.53 
   19.54 #[test]
   19.55 fn callback_gets_all_data_as_if_the_download_happened_all_at_once() {
   19.56-    let tmpdir = tmp_dir();
   19.57-    let target_path = tmpdir.path().join("downloaded");
   19.58-    write_file(&target_path, "123");
   19.59+  let tmpdir = tmp_dir();
   19.60+  let target_path = tmpdir.path().join("downloaded");
   19.61+  write_file(&target_path, "123");
   19.62 
   19.63-    let addr = serve_file(b"xxx45".to_vec());
   19.64+  let addr = serve_file(b"xxx45".to_vec());
   19.65 
   19.66-    let from_url = format!("http://{addr}").parse().unwrap();
   19.67+  let from_url = format!("http://{addr}").parse().unwrap();
   19.68 
   19.69-    let callback_partial = AtomicBool::new(false);
   19.70-    let callback_len = Mutex::new(None);
   19.71-    let received_in_callback = Mutex::new(Vec::new());
   19.72+  let callback_partial = AtomicBool::new(false);
   19.73+  let callback_len = Mutex::new(None);
   19.74+  let received_in_callback = Mutex::new(Vec::new());
   19.75 
   19.76-    download_to_path_with_backend(
   19.77-        Backend::Reqwest(TlsBackend::Default),
   19.78-        &from_url,
   19.79-        &target_path,
   19.80-        true,
   19.81-        Some(&|msg| {
   19.82-            match msg {
   19.83-                Event::ResumingPartialDownload => {
   19.84-                    assert!(!callback_partial.load(Ordering::SeqCst));
   19.85-                    callback_partial.store(true, Ordering::SeqCst);
   19.86-                }
   19.87-                Event::DownloadContentLengthReceived(len) => {
   19.88-                    let mut flag = callback_len.lock().unwrap();
   19.89-                    assert!(flag.is_none());
   19.90-                    *flag = Some(len);
   19.91-                }
   19.92-                Event::DownloadDataReceived(data) => {
   19.93-                    for b in data.iter() {
   19.94-                        received_in_callback.lock().unwrap().push(*b);
   19.95-                    }
   19.96-                }
   19.97-            }
   19.98+  download_to_path_with_backend(
   19.99+    Backend::Reqwest(TlsBackend::Default),
  19.100+    &from_url,
  19.101+    &target_path,
  19.102+    true,
  19.103+    Some(&|msg| {
  19.104+      match msg {
  19.105+        Event::ResumingPartialDownload => {
  19.106+          assert!(!callback_partial.load(Ordering::SeqCst));
  19.107+          callback_partial.store(true, Ordering::SeqCst);
  19.108+        }
  19.109+        Event::DownloadContentLengthReceived(len) => {
  19.110+          let mut flag = callback_len.lock().unwrap();
  19.111+          assert!(flag.is_none());
  19.112+          *flag = Some(len);
  19.113+        }
  19.114+        Event::DownloadDataReceived(data) => {
  19.115+          for b in data.iter() {
  19.116+            received_in_callback.lock().unwrap().push(*b);
  19.117+          }
  19.118+        }
  19.119+      }
  19.120 
  19.121-            Ok(())
  19.122-        }),
  19.123-    )
  19.124-    .expect("Test download failed");
  19.125+      Ok(())
  19.126+    }),
  19.127+  )
  19.128+  .expect("Test download failed");
  19.129 
  19.130-    assert!(callback_partial.into_inner());
  19.131-    assert_eq!(*callback_len.lock().unwrap(), Some(5));
  19.132-    let observed_bytes = received_in_callback.into_inner().unwrap();
  19.133-    assert_eq!(observed_bytes, vec![b'1', b'2', b'3', b'4', b'5']);
  19.134-    assert_eq!(std::fs::read_to_string(&target_path).unwrap(), "12345");
  19.135+  assert!(callback_partial.into_inner());
  19.136+  assert_eq!(*callback_len.lock().unwrap(), Some(5));
  19.137+  let observed_bytes = received_in_callback.into_inner().unwrap();
  19.138+  assert_eq!(observed_bytes, vec![b'1', b'2', b'3', b'4', b'5']);
  19.139+  assert_eq!(std::fs::read_to_string(&target_path).unwrap(), "12345");
  19.140 }
    20.1--- a/rust/lib/dl/tests/read-proxy-env.rs	Sun Dec 03 22:18:30 2023 -0500
    20.2+++ b/rust/lib/dl/tests/read-proxy-env.rs	Sun Dec 03 23:25:08 2023 -0500
    20.3@@ -1,12 +1,16 @@
    20.4 #![cfg(feature = "reqwest-backend")]
    20.5 
    20.6-use std::env::{remove_var, set_var};
    20.7-use std::error::Error;
    20.8-use std::net::TcpListener;
    20.9-use std::sync::atomic::{AtomicUsize, Ordering};
   20.10-use std::sync::Mutex;
   20.11-use std::thread;
   20.12-use std::time::Duration;
   20.13+use std::{
   20.14+  env::{remove_var, set_var},
   20.15+  error::Error,
   20.16+  net::TcpListener,
   20.17+  sync::{
   20.18+    atomic::{AtomicUsize, Ordering},
   20.19+    Mutex,
   20.20+  },
   20.21+  thread,
   20.22+  time::Duration,
   20.23+};
   20.24 
   20.25 use env_proxy::for_url;
   20.26 use reqwest::{blocking::Client, Proxy};
   20.27@@ -15,69 +19,69 @@
   20.28 static SERIALISE_TESTS: Mutex<()> = Mutex::new(());
   20.29 
   20.30 fn scrub_env() {
   20.31-    remove_var("http_proxy");
   20.32-    remove_var("https_proxy");
   20.33-    remove_var("HTTPS_PROXY");
   20.34-    remove_var("ftp_proxy");
   20.35-    remove_var("FTP_PROXY");
   20.36-    remove_var("all_proxy");
   20.37-    remove_var("ALL_PROXY");
   20.38-    remove_var("no_proxy");
   20.39-    remove_var("NO_PROXY");
   20.40+  remove_var("http_proxy");
   20.41+  remove_var("https_proxy");
   20.42+  remove_var("HTTPS_PROXY");
   20.43+  remove_var("ftp_proxy");
   20.44+  remove_var("FTP_PROXY");
   20.45+  remove_var("all_proxy");
   20.46+  remove_var("ALL_PROXY");
   20.47+  remove_var("no_proxy");
   20.48+  remove_var("NO_PROXY");
   20.49 }
   20.50 
   20.51 // Tests for correctly retrieving the proxy (host, port) tuple from $https_proxy
   20.52 #[test]
   20.53 fn read_basic_proxy_params() {
   20.54-    let _guard = SERIALISE_TESTS
   20.55-        .lock()
   20.56-        .expect("Unable to lock the test guard");
   20.57-    scrub_env();
   20.58-    set_var("https_proxy", "http://proxy.example.com:8080");
   20.59-    let u = Url::parse("https://www.example.org").ok().unwrap();
   20.60-    assert_eq!(
   20.61-        for_url(&u).host_port(),
   20.62-        Some(("proxy.example.com".to_string(), 8080))
   20.63-    );
   20.64+  let _guard = SERIALISE_TESTS
   20.65+    .lock()
   20.66+    .expect("Unable to lock the test guard");
   20.67+  scrub_env();
   20.68+  set_var("https_proxy", "http://proxy.example.com:8080");
   20.69+  let u = Url::parse("https://www.example.org").ok().unwrap();
   20.70+  assert_eq!(
   20.71+    for_url(&u).host_port(),
   20.72+    Some(("proxy.example.com".to_string(), 8080))
   20.73+  );
   20.74 }
   20.75 
   20.76 // Tests to verify if socks feature is available and being used
   20.77 #[test]
   20.78 fn socks_proxy_request() {
   20.79-    static CALL_COUNT: AtomicUsize = AtomicUsize::new(0);
   20.80-    let _guard = SERIALISE_TESTS
   20.81-        .lock()
   20.82-        .expect("Unable to lock the test guard");
   20.83+  static CALL_COUNT: AtomicUsize = AtomicUsize::new(0);
   20.84+  let _guard = SERIALISE_TESTS
   20.85+    .lock()
   20.86+    .expect("Unable to lock the test guard");
   20.87 
   20.88-    scrub_env();
   20.89-    set_var("all_proxy", "socks5://127.0.0.1:1080");
   20.90+  scrub_env();
   20.91+  set_var("all_proxy", "socks5://127.0.0.1:1080");
   20.92 
   20.93-    thread::spawn(move || {
   20.94-        let listener = TcpListener::bind("127.0.0.1:1080").unwrap();
   20.95-        let incoming = listener.incoming();
   20.96-        for _ in incoming {
   20.97-            CALL_COUNT.fetch_add(1, Ordering::SeqCst);
   20.98-        }
   20.99-    });
  20.100+  thread::spawn(move || {
  20.101+    let listener = TcpListener::bind("127.0.0.1:1080").unwrap();
  20.102+    let incoming = listener.incoming();
  20.103+    for _ in incoming {
  20.104+      CALL_COUNT.fetch_add(1, Ordering::SeqCst);
  20.105+    }
  20.106+  });
  20.107 
  20.108-    let env_proxy = |url: &Url| for_url(url).to_url();
  20.109-    let url = Url::parse("http://192.168.0.1/").unwrap();
  20.110+  let env_proxy = |url: &Url| for_url(url).to_url();
  20.111+  let url = Url::parse("http://192.168.0.1/").unwrap();
  20.112 
  20.113-    let client = Client::builder()
  20.114-        .proxy(Proxy::custom(env_proxy))
  20.115-        .timeout(Duration::from_secs(1))
  20.116-        .build()
  20.117-        .unwrap();
  20.118-    let res = client.get(url.as_str()).send();
  20.119+  let client = Client::builder()
  20.120+    .proxy(Proxy::custom(env_proxy))
  20.121+    .timeout(Duration::from_secs(1))
  20.122+    .build()
  20.123+    .unwrap();
  20.124+  let res = client.get(url.as_str()).send();
  20.125 
  20.126-    if let Err(e) = res {
  20.127-        let s = e.source().unwrap();
  20.128-        assert!(
  20.129-            s.to_string().contains("socks connect error"),
  20.130-            "Expected socks connect error, got: {s}",
  20.131-        );
  20.132-        assert_eq!(CALL_COUNT.load(Ordering::SeqCst), 1);
  20.133-    } else {
  20.134-        panic!("Socks proxy was ignored")
  20.135-    }
  20.136+  if let Err(e) = res {
  20.137+    let s = e.source().unwrap();
  20.138+    assert!(
  20.139+      s.to_string().contains("socks connect error"),
  20.140+      "Expected socks connect error, got: {s}",
  20.141+    );
  20.142+    assert_eq!(CALL_COUNT.load(Ordering::SeqCst), 1);
  20.143+  } else {
  20.144+    panic!("Socks proxy was ignored")
  20.145+  }
  20.146 }
    21.1--- a/rust/lib/dl/tests/support/mod.rs	Sun Dec 03 22:18:30 2023 -0500
    21.2+++ b/rust/lib/dl/tests/support/mod.rs	Sun Dec 03 23:25:08 2023 -0500
    21.3@@ -1,119 +1,126 @@
    21.4-use std::convert::Infallible;
    21.5-use std::fs;
    21.6-use std::io;
    21.7-use std::net::SocketAddr;
    21.8-use std::path::Path;
    21.9-use std::sync::mpsc::{channel, Sender};
   21.10-use std::thread;
   21.11+use std::{
   21.12+  convert::Infallible,
   21.13+  fs, io,
   21.14+  net::SocketAddr,
   21.15+  path::Path,
   21.16+  sync::mpsc::{channel, Sender},
   21.17+  thread,
   21.18+};
   21.19 
   21.20 use http_body_util::Full;
   21.21-use hyper::body::Bytes;
   21.22-use hyper::server::conn::http1;
   21.23-use hyper::service::service_fn;
   21.24-use hyper::Request;
   21.25+use hyper::{body::Bytes, server::conn::http1, service::service_fn, Request};
   21.26 use tempfile::TempDir;
   21.27 
   21.28 pub fn tmp_dir() -> TempDir {
   21.29-    tempfile::Builder::new()
   21.30-        .prefix("rustup-download-test-")
   21.31-        .tempdir()
   21.32-        .expect("creating tempdir for test")
   21.33+  tempfile::Builder::new()
   21.34+    .prefix("rustup-download-test-")
   21.35+    .tempdir()
   21.36+    .expect("creating tempdir for test")
   21.37 }
   21.38 
   21.39 pub fn write_file(path: &Path, contents: &str) {
   21.40-    let mut file = fs::OpenOptions::new()
   21.41-        .write(true)
   21.42-        .truncate(true)
   21.43-        .create(true)
   21.44-        .open(path)
   21.45-        .expect("writing test data");
   21.46+  let mut file = fs::OpenOptions::new()
   21.47+    .write(true)
   21.48+    .truncate(true)
   21.49+    .create(true)
   21.50+    .open(path)
   21.51+    .expect("writing test data");
   21.52 
   21.53-    io::Write::write_all(&mut file, contents.as_bytes()).expect("writing test data");
   21.54+  io::Write::write_all(&mut file, contents.as_bytes())
   21.55+    .expect("writing test data");
   21.56 
   21.57-    file.sync_data().expect("writing test data");
   21.58+  file.sync_data().expect("writing test data");
   21.59 }
   21.60 
   21.61 // A dead simple hyper server implementation.
   21.62 // For more info, see:
   21.63 // https://hyper.rs/guides/1/server/hello-world/
   21.64-async fn run_server(addr_tx: Sender<SocketAddr>, addr: SocketAddr, contents: Vec<u8>) {
   21.65-    let svc = service_fn(move |req: Request<hyper::body::Incoming>| {
   21.66-        let contents = contents.clone();
   21.67-        async move {
   21.68-            let res = serve_contents(req, contents);
   21.69-            Ok::<_, Infallible>(res)
   21.70-        }
   21.71-    });
   21.72+async fn run_server(
   21.73+  addr_tx: Sender<SocketAddr>,
   21.74+  addr: SocketAddr,
   21.75+  contents: Vec<u8>,
   21.76+) {
   21.77+  let svc = service_fn(move |req: Request<hyper::body::Incoming>| {
   21.78+    let contents = contents.clone();
   21.79+    async move {
   21.80+      let res = serve_contents(req, contents);
   21.81+      Ok::<_, Infallible>(res)
   21.82+    }
   21.83+  });
   21.84 
   21.85-    let listener = tokio::net::TcpListener::bind(&addr)
   21.86-        .await
   21.87-        .expect("can not bind");
   21.88+  let listener = tokio::net::TcpListener::bind(&addr)
   21.89+    .await
   21.90+    .expect("can not bind");
   21.91 
   21.92-    let addr = listener.local_addr().unwrap();
   21.93-    addr_tx.send(addr).unwrap();
   21.94+  let addr = listener.local_addr().unwrap();
   21.95+  addr_tx.send(addr).unwrap();
   21.96 
   21.97-    loop {
   21.98-        let (stream, _) = listener
   21.99-            .accept()
  21.100-            .await
  21.101-            .expect("could not accept connection");
  21.102-        let io = hyper_util::rt::TokioIo::new(stream);
  21.103+  loop {
  21.104+    let (stream, _) = listener
  21.105+      .accept()
  21.106+      .await
  21.107+      .expect("could not accept connection");
  21.108+    let io = hyper_util::rt::TokioIo::new(stream);
  21.109 
  21.110-        let svc = svc.clone();
  21.111-        tokio::spawn(async move {
  21.112-            if let Err(err) = http1::Builder::new().serve_connection(io, svc).await {
  21.113-                eprintln!("failed to serve connection: {:?}", err);
  21.114-            }
  21.115-        });
  21.116-    }
  21.117+    let svc = svc.clone();
  21.118+    tokio::spawn(async move {
  21.119+      if let Err(err) = http1::Builder::new().serve_connection(io, svc).await {
  21.120+        eprintln!("failed to serve connection: {:?}", err);
  21.121+      }
  21.122+    });
  21.123+  }
  21.124 }
  21.125 
  21.126 pub fn serve_file(contents: Vec<u8>) -> SocketAddr {
  21.127-    let addr = ([127, 0, 0, 1], 0).into();
  21.128-    let (addr_tx, addr_rx) = channel();
  21.129+  let addr = ([127, 0, 0, 1], 0).into();
  21.130+  let (addr_tx, addr_rx) = channel();
  21.131 
  21.132-    thread::spawn(move || {
  21.133-        let server = run_server(addr_tx, addr, contents);
  21.134-        let rt = tokio::runtime::Runtime::new().expect("could not creating Runtime");
  21.135-        rt.block_on(server);
  21.136-    });
  21.137+  thread::spawn(move || {
  21.138+    let server = run_server(addr_tx, addr, contents);
  21.139+    let rt =
  21.140+      tokio::runtime::Runtime::new().expect("could not creating Runtime");
  21.141+    rt.block_on(server);
  21.142+  });
  21.143 
  21.144-    let addr = addr_rx.recv();
  21.145-    addr.unwrap()
  21.146+  let addr = addr_rx.recv();
  21.147+  addr.unwrap()
  21.148 }
  21.149 
  21.150 fn serve_contents(
  21.151-    req: hyper::Request<hyper::body::Incoming>,
  21.152-    contents: Vec<u8>,
  21.153+  req: hyper::Request<hyper::body::Incoming>,
  21.154+  contents: Vec<u8>,
  21.155 ) -> hyper::Response<Full<Bytes>> {
  21.156-    let mut range_header = None;
  21.157-    let (status, body) = if let Some(range) = req.headers().get(hyper::header::RANGE) {
  21.158-        // extract range "bytes={start}-"
  21.159-        let range = range.to_str().expect("unexpected Range header");
  21.160-        assert!(range.starts_with("bytes="));
  21.161-        let range = range.trim_start_matches("bytes=");
  21.162-        assert!(range.ends_with('-'));
  21.163-        let range = range.trim_end_matches('-');
  21.164-        assert_eq!(range.split('-').count(), 1);
  21.165-        let start: u64 = range.parse().expect("unexpected Range header");
  21.166+  let mut range_header = None;
  21.167+  let (status, body) =
  21.168+    if let Some(range) = req.headers().get(hyper::header::RANGE) {
  21.169+      // extract range "bytes={start}-"
  21.170+      let range = range.to_str().expect("unexpected Range header");
  21.171+      assert!(range.starts_with("bytes="));
  21.172+      let range = range.trim_start_matches("bytes=");
  21.173+      assert!(range.ends_with('-'));
  21.174+      let range = range.trim_end_matches('-');
  21.175+      assert_eq!(range.split('-').count(), 1);
  21.176+      let start: u64 = range.parse().expect("unexpected Range header");
  21.177 
  21.178-        range_header = Some(format!("bytes {}-{len}/{len}", start, len = contents.len()));
  21.179-        (
  21.180-            hyper::StatusCode::PARTIAL_CONTENT,
  21.181-            contents[start as usize..].to_vec(),
  21.182-        )
  21.183+      range_header =
  21.184+        Some(format!("bytes {}-{len}/{len}", start, len = contents.len()));
  21.185+      (
  21.186+        hyper::StatusCode::PARTIAL_CONTENT,
  21.187+        contents[start as usize..].to_vec(),
  21.188+      )
  21.189     } else {
  21.190-        (hyper::StatusCode::OK, contents)
  21.191+      (hyper::StatusCode::OK, contents)
  21.192     };
  21.193 
  21.194-    let mut res = hyper::Response::builder()
  21.195-        .status(status)
  21.196-        .header(hyper::header::CONTENT_LENGTH, body.len())
  21.197-        .body(Full::new(Bytes::from(body)))
  21.198-        .unwrap();
  21.199-    if let Some(range) = range_header {
  21.200-        res.headers_mut()
  21.201-            .insert(hyper::header::CONTENT_RANGE, range.parse().unwrap());
  21.202-    }
  21.203+  let mut res = hyper::Response::builder()
  21.204+    .status(status)
  21.205+    .header(hyper::header::CONTENT_LENGTH, body.len())
  21.206+    .body(Full::new(Bytes::from(body)))
  21.207+    .unwrap();
  21.208+  if let Some(range) = range_header {
  21.209     res
  21.210+      .headers_mut()
  21.211+      .insert(hyper::header::CONTENT_RANGE, range.parse().unwrap());
  21.212+  }
  21.213+  res
  21.214 }
    22.1--- a/rust/lib/util/src/bs/version.rs	Sun Dec 03 22:18:30 2023 -0500
    22.2+++ b/rust/lib/util/src/bs/version.rs	Sun Dec 03 23:25:08 2023 -0500
    22.3@@ -29,11 +29,7 @@
    22.4     get_version_short(&commit)
    22.5   );
    22.6 
    22.7-  println!(
    22.8-    "cargo:rustc-env=CORE_TARGET={}",
    22.9-    get_platform()
   22.10-  );
   22.11-
   22.12+  println!("cargo:rustc-env=CORE_TARGET={}", get_platform());
   22.13 }
   22.14 
   22.15 pub fn get_platform() -> String {
    23.1--- a/rust/lib/util/src/lib.rs	Sun Dec 03 22:18:30 2023 -0500
    23.2+++ b/rust/lib/util/src/lib.rs	Sun Dec 03 23:25:08 2023 -0500
    23.3@@ -1,6 +1,6 @@
    23.4 //! util library
    23.5 #[cfg(feature = "anyhow")]
    23.6-pub use anyhow::{Result,Context};
    23.7+pub use anyhow::{Context, Result};
    23.8 #[cfg(feature = "bs")]
    23.9 pub mod bs;
   23.10 #[cfg(feature = "cli")]