Repository: argmin-rs/argmin (language: rust)

Issue:
RUSTSEC-2024-0384: `instant` is unmaintained

> `instant` is unmaintained

| Details             |                                                |
| ------------------- | ---------------------------------------------- |
| Status              | unmaintained                |
| Package             | `instant`                      |
| Version             | `0.1.13`                   |
| URL                 | []() |
| Date                | 2024-09-01                         |

This crate is no longer maintained, and the author recommends using the maintained [`web-time`] crate instead.

[`web-time`]: https://crates.io/crates/web-time

See [advisory page](https://rustsec.org/advisories/RUSTSEC-2024-0384.html) for additional details.



Discussion / hints:

Fix patch:
diff --git a/crates/argmin/Cargo.toml b/crates/argmin/Cargo.toml
index f0948cb90..02d74f9b7 100644
--- a/crates/argmin/Cargo.toml
+++ b/crates/argmin/Cargo.toml
@@ -16,12 +16,12 @@ exclude = []
 [dependencies]
 # Required
 anyhow = "1.0"
-instant = "0.1"
 paste = "1"
 num-traits = "0.2"
 rand = "0.8.5"
 rand_xoshiro = "0.6.0"
 thiserror = "1.0"
+web-time = "1.1.0"
 argmin-math = { path = "../argmin-math", version = "0.4", default-features = false, features = ["primitives"] }
 # optional
 ctrlc = { version = "3.2.4", features = ["termination"], optional = true }
@@ -42,7 +42,7 @@ argmin-checkpointing-file = { path = "../argmin-checkpointing-file" }
 
 [features]
 default = []
-wasm-bindgen = ["instant/wasm-bindgen", "getrandom/js"]
+wasm-bindgen = ["getrandom/js"]
 serde1 = ["serde", "rand_xoshiro/serde1"]
 _ndarrayl = ["argmin-math/ndarray_latest"]
 # When adding new features, please consider adding them to either `full` (for users)
diff --git a/crates/argmin/src/core/executor.rs b/crates/argmin/src/core/executor.rs
index f5290afad..c75608136 100644
--- a/crates/argmin/src/core/executor.rs
+++ b/crates/argmin/src/core/executor.rs
@@ -12,6 +12,7 @@ use crate::core::{
 };
 use std::sync::atomic::{AtomicBool, Ordering};
 use std::sync::Arc;
+use web_time::Instant;
 
 /// Solves an optimization problem with a solver
 pub struct Executor<O, S, I> {
@@ -137,7 +138,7 @@ where
             }
         }
         let total_time = if self.timer {
-            Some(instant::Instant::now())
+            Some(Instant::now())
         } else {
             None
         };
@@ -213,7 +214,7 @@ where
 
             // Start time measurement
             let start = if self.timer {
-                Some(instant::Instant::now())
+                Some(Instant::now())
             } else {
                 None
             };
diff --git a/crates/argmin/src/core/state/iterstate.rs b/crates/argmin/src/core/state/iterstate.rs
index 75cfb687f..8a0ef6557 100644
--- a/crates/argmin/src/core/state/iterstate.rs
+++ b/crates/argmin/src/core/state/iterstate.rs
@@ -9,6 +9,7 @@ use crate::core::{ArgminFloat, Problem, State, TerminationReason, TerminationSta
 #[cfg(feature = "serde1")]
 use serde::{Deserialize, Serialize};
 use std::collections::HashMap;
+use web_time::Duration;
 
 /// Maintains the state from iteration to iteration of a solver
 ///
@@ -84,7 +85,7 @@ pub struct IterState<P, G, J, H, R, F> {
     /// Update evaluation counts?
     pub counting_enabled: bool,
     /// Time required so far
-    pub time: Option<instant::Duration>,
+    pub time: Option<Duration>,
     /// Status of optimization execution
     pub termination_status: TerminationStatus,
 }
@@ -1002,8 +1003,8 @@ where
     /// # Example
     ///
     /// ```
-    /// # extern crate instant;
-    /// # use instant;
+    /// # extern crate web_time;
+    /// # use web_time::Duration;
     /// # use argmin::core::{IterState, State, ArgminFloat, TerminationStatus};
     /// let state: IterState<Vec<f64>, Vec<f64>, Vec<Vec<f64>>, Vec<Vec<f64>>, Vec<f64>, f64> = IterState::new();
     /// # assert!(state.param.is_none());
@@ -1027,7 +1028,7 @@ where
     /// # assert_eq!(state.last_best_iter, 0);
     /// # assert_eq!(state.max_iters, u64::MAX);
     /// # assert_eq!(state.counts.len(), 0);
-    /// # assert_eq!(state.time.unwrap(), instant::Duration::new(0, 0));
+    /// # assert_eq!(state.time.unwrap(), Duration::ZERO);
     /// # assert_eq!(state.termination_status, TerminationStatus::NotTerminated);
     /// ```
     fn new() -> Self {
@@ -1056,7 +1057,7 @@ where
             max_iters: u64::MAX,
             counts: HashMap::new(),
             counting_enabled: false,
-            time: Some(instant::Duration::new(0, 0)),
+            time: Some(Duration::ZERO),
             termination_status: TerminationStatus::NotTerminated,
         }
     }
@@ -1186,14 +1187,14 @@ where
     /// # Example
     ///
     /// ```
-    /// # extern crate instant;
-    /// # use instant;
+    /// # extern crate web_time;
+    /// # use web_time::Duration;
     /// # use argmin::core::{IterState, State, ArgminFloat, TerminationReason};
     /// # let mut state: IterState<Vec<f64>, (), (), (), (), f64> = IterState::new();
-    /// let state = state.time(Some(instant::Duration::new(0, 12)));
-    /// # assert_eq!(state.time.unwrap(), instant::Duration::new(0, 12));
+    /// let state = state.time(Some(Duration::from_nanos(12)));
+    /// # assert_eq!(state.time.unwrap(), Duration::from_nanos(12));
     /// ```
-    fn time(&mut self, time: Option<instant::Duration>) -> &mut Self {
+    fn time(&mut self, time: Option<Duration>) -> &mut Self {
         self.time = time;
         self
     }
@@ -1324,14 +1325,14 @@ where
     /// # Example
     ///
     /// ```
-    /// # extern crate instant;
-    /// # use instant;
+    /// # extern crate web_time;
+    /// # use web_time::Duration;
     /// # use argmin::core::{IterState, State, ArgminFloat};
     /// # let mut state: IterState<Vec<f64>, (), (), (), (), f64> = IterState::new();
     /// let time = state.get_time();
-    /// # assert_eq!(time.unwrap(), instant::Duration::new(0, 0));
+    /// # assert_eq!(time.unwrap(), Duration::ZERO);
     /// ```
-    fn get_time(&self) -> Option<instant::Duration> {
+    fn get_time(&self) -> Option<Duration> {
         self.time
     }
 
diff --git a/crates/argmin/src/core/state/linearprogramstate.rs b/crates/argmin/src/core/state/linearprogramstate.rs
index 5920ec039..e201e50aa 100644
--- a/crates/argmin/src/core/state/linearprogramstate.rs
+++ b/crates/argmin/src/core/state/linearprogramstate.rs
@@ -9,6 +9,7 @@ use crate::core::{ArgminFloat, Problem, State, TerminationReason, TerminationSta
 #[cfg(feature = "serde1")]
 use serde::{Deserialize, Serialize};
 use std::collections::HashMap;
+use web_time::Duration;
 
 /// Maintains the state from iteration to iteration of a solver
 ///
@@ -59,7 +60,7 @@ pub struct LinearProgramState<P, F> {
     /// Update evaluation counts?
     pub counting_enabled: bool,
     /// Time required so far
-    pub time: Option<instant::Duration>,
+    pub time: Option<Duration>,
     /// Status of optimization execution
     pub termination_status: TerminationStatus,
 }
@@ -183,8 +184,8 @@ where
     /// # Example
     ///
     /// ```
-    /// # extern crate instant;
-    /// # use instant;
+    /// # extern crate web_time;
+    /// # use web_time::Duration;
     /// # use std::collections::HashMap;
     /// # use argmin::core::TerminationStatus;
     /// use argmin::core::{LinearProgramState, State};
@@ -203,7 +204,7 @@ where
     /// # assert_eq!(state.last_best_iter, 0);
     /// # assert_eq!(state.max_iters, u64::MAX);
     /// # assert_eq!(state.counts, HashMap::new());
-    /// # assert_eq!(state.time.unwrap(), instant::Duration::new(0, 0));
+    /// # assert_eq!(state.time.unwrap(), Duration::ZERO);
     /// # assert_eq!(state.termination_status, TerminationStatus::NotTerminated);
     /// ```
     fn new() -> Self {
@@ -222,7 +223,7 @@ where
             max_iters: u64::MAX,
             counts: HashMap::new(),
             counting_enabled: false,
-            time: Some(instant::Duration::new(0, 0)),
+            time: Some(Duration::ZERO),
             termination_status: TerminationStatus::NotTerminated,
         }
     }
@@ -351,14 +352,14 @@ where
     /// # Example
     ///
     /// ```
-    /// # extern crate instant;
-    /// # use instant;
+    /// # extern crate web_time;
+    /// # use web_time::Duration;
     /// # use argmin::core::{LinearProgramState, State, ArgminFloat, TerminationReason};
     /// # let mut state: LinearProgramState<Vec<f64>, f64> = LinearProgramState::new();
-    /// let state = state.time(Some(instant::Duration::new(0, 12)));
-    /// # assert_eq!(state.time.unwrap(), instant::Duration::new(0, 12));
+    /// let state = state.time(Some(Duration::from_nanos(12)));
+    /// # assert_eq!(state.time.unwrap(), Duration::from_nanos(12));
     /// ```
-    fn time(&mut self, time: Option<instant::Duration>) -> &mut Self {
+    fn time(&mut self, time: Option<Duration>) -> &mut Self {
         self.time = time;
         self
     }
@@ -489,14 +490,14 @@ where
     /// # Example
     ///
     /// ```
-    /// # extern crate instant;
-    /// # use instant;
+    /// # extern crate web_time;
+    /// # use web_time::Duration;
     /// # use argmin::core::{LinearProgramState, State, ArgminFloat};
     /// # let mut state: LinearProgramState<Vec<f64>, f64> = LinearProgramState::new();
     /// let time = state.get_time();
-    /// # assert_eq!(time.unwrap(), instant::Duration::new(0, 0));
+    /// # assert_eq!(time.unwrap(), Duration::ZERO);
     /// ```
-    fn get_time(&self) -> Option<instant::Duration> {
+    fn get_time(&self) -> Option<Duration> {
         self.time
     }
 
diff --git a/crates/argmin/src/core/state/mod.rs b/crates/argmin/src/core/state/mod.rs
index 924d61e09..9ac698662 100644
--- a/crates/argmin/src/core/state/mod.rs
+++ b/crates/argmin/src/core/state/mod.rs
@@ -15,6 +15,7 @@ pub use populationstate::PopulationState;
 
 use crate::core::{ArgminFloat, Problem, TerminationReason, TerminationStatus};
 use std::collections::HashMap;
+use web_time::Duration;
 
 /// Minimal interface which struct used for managing state in solvers have to implement.
 ///
@@ -91,10 +92,10 @@ pub trait State {
     fn get_func_counts(&self) -> &HashMap<String, u64>;
 
     /// Set time required since the beginning of the optimization until the current iteration
-    fn time(&mut self, time: Option<instant::Duration>) -> &mut Self;
+    fn time(&mut self, time: Option<Duration>) -> &mut Self;
 
     /// Get time passed since the beginning of the optimization until the current iteration
-    fn get_time(&self) -> Option<instant::Duration>;
+    fn get_time(&self) -> Option<Duration>;
 
     /// Returns iteration number where the last best parameter vector was found
     fn get_last_best_iter(&self) -> u64;
diff --git a/crates/argmin/src/core/state/populationstate.rs b/crates/argmin/src/core/state/populationstate.rs
index cc0996e04..541cfa71b 100644
--- a/crates/argmin/src/core/state/populationstate.rs
+++ b/crates/argmin/src/core/state/populationstate.rs
@@ -9,6 +9,7 @@ use crate::core::{ArgminFloat, Problem, State, TerminationReason, TerminationSta
 #[cfg(feature = "serde1")]
 use serde::{Deserialize, Serialize};
 use std::collections::HashMap;
+use web_time::Duration;
 
 /// Maintains the state from iteration to iteration of a population-based solver
 ///
@@ -61,7 +62,7 @@ pub struct PopulationState<P, F> {
     /// Update evaluation counts?
     pub counting_enabled: bool,
     /// Time required so far
-    pub time: Option<instant::Duration>,
+    pub time: Option<Duration>,
     /// Status of optimization execution
     pub termination_status: TerminationStatus,
 }
@@ -462,8 +463,8 @@ where
     /// # Example
     ///
     /// ```
-    /// # extern crate instant;
-    /// # use instant;
+    /// # extern crate web_time;
+    /// # use web_time::Duration;
     /// # use argmin::core::{PopulationState, State, ArgminFloat, TerminationStatus};
     /// let state: PopulationState<Vec<f64>, f64> = PopulationState::new();
     /// # assert!(state.individual.is_none());
@@ -480,7 +481,7 @@ where
     /// # assert_eq!(state.last_best_iter, 0);
     /// # assert_eq!(state.max_iters, u64::MAX);
     /// # assert_eq!(state.counts.len(), 0);
-    /// # assert_eq!(state.time.unwrap(), instant::Duration::new(0, 0));
+    /// # assert_eq!(state.time.unwrap(), Duration::ZERO);
     /// # assert_eq!(state.termination_status, TerminationStatus::NotTerminated);
     /// ```
     fn new() -> Self {
@@ -500,7 +501,7 @@ where
             max_iters: u64::MAX,
             counts: HashMap::new(),
             counting_enabled: false,
-            time: Some(instant::Duration::new(0, 0)),
+            time: Some(Duration::ZERO),
             termination_status: TerminationStatus::NotTerminated,
         }
     }
@@ -630,14 +631,14 @@ where
     /// # Example
     ///
     /// ```
-    /// # extern crate instant;
-    /// # use instant;
+    /// # extern crate web_time;
+    /// # use web_time::Duration;
     /// # use argmin::core::{PopulationState, State, ArgminFloat, TerminationReason};
     /// # let mut state: PopulationState<Vec<f64>, f64> = PopulationState::new();
-    /// let state = state.time(Some(instant::Duration::new(0, 12)));
-    /// # assert_eq!(state.time.unwrap(), instant::Duration::new(0, 12));
+    /// let state = state.time(Some(Duration::from_nanos(12)));
+    /// # assert_eq!(state.time.unwrap(), Duration::from_nanos(12));
     /// ```
-    fn time(&mut self, time: Option<instant::Duration>) -> &mut Self {
+    fn time(&mut self, time: Option<Duration>) -> &mut Self {
         self.time = time;
         self
     }
@@ -768,14 +769,14 @@ where
     /// # Example
     ///
     /// ```
-    /// # extern crate instant;
-    /// # use instant;
+    /// # extern crate web_time;
+    /// # use web_time::Duration;
     /// # use argmin::core::{PopulationState, State, ArgminFloat};
     /// # let mut state: PopulationState<Vec<f64>, f64> = PopulationState::new();
     /// let time = state.get_time();
-    /// # assert_eq!(time.unwrap(), instant::Duration::new(0, 0));
+    /// # assert_eq!(time.unwrap(), Duration::ZERO);
     /// ```
-    fn get_time(&self) -> Option<instant::Duration> {
+    fn get_time(&self) -> Option<Duration> {
         self.time
     }
 
diff --git a/deny.toml b/deny.toml
index 355c41c1f..e6f47214b 100644
--- a/deny.toml
+++ b/deny.toml
@@ -85,6 +85,7 @@ allow = [
     "Apache-2.0 WITH LLVM-exception",
     "BSD-2-Clause",
     "BSD-3-Clause",
+    "Unicode-3.0",
     "Unicode-DFS-2016",
     "MPL-2.0",
     "ISC",
diff --git a/examples/observer/Cargo.toml b/examples/observer/Cargo.toml
index d5f238c3b..f17820999 100644
--- a/examples/observer/Cargo.toml
+++ b/examples/observer/Cargo.toml
@@ -10,4 +10,4 @@ argmin = { version = "*", path = "../../crates/argmin" }
 argmin-math = { version = "*", features = ["vec"], path = "../../crates/argmin-math" }
 argmin_testfunctions = { version = "*", path = "../../crates/argmin-testfunctions" }
 gnuplot = "0.0.43"
-instant = "0.1.12"
+web-time = "1.1.0"
diff --git a/examples/observer/src/main.rs b/examples/observer/src/main.rs
index 77da4302f..e4c189fad 100644
--- a/examples/observer/src/main.rs
+++ b/examples/observer/src/main.rs
@@ -11,6 +11,7 @@ use argmin::solver::particleswarm::{Particle, ParticleSwarm};
 use argmin_testfunctions::himmelblau;
 use gnuplot::{Color, PointSize};
 use std::sync::Mutex;
+use web_time::Duration;
 
 /// Visualize iterations of a solver for cost functions of type
 /// (x,y) -> cost
@@ -35,7 +36,7 @@ pub struct Visualizer3d {
     /// Optional visualized surface of cost function
     surface: Option<Surface>,
     /// Optional delay between iterations
-    delay: Option<instant::Duration>,
+    delay: Option<Duration>,
 }
 
 impl Visualizer3d {
@@ -56,7 +57,7 @@ impl Visualizer3d {
 
     /// Set delay
     #[must_use]
-    pub fn delay(mut self, duration: instant::Duration) -> Self {
+    pub fn delay(mut self, duration: Duration) -> Self {
         self.delay = Some(duration);
         self
     }
@@ -229,7 +230,7 @@ fn run() -> Result<(), Error> {
     let cost_function = Himmelblau {};
 
     let visualizer = Visualizer3d::new()
-        .delay(std::time::Duration::from_secs(1))
+        .delay(Duration::from_secs(1))
         .surface(Surface::new(Himmelblau {}, (-4.0, -4.0, 4.0, 4.0), 0.1));
 
     {


Test patch: