diff --git a/Cargo.toml b/Cargo.toml index 4da0e5dd..f701da8c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -53,6 +53,7 @@ output-json = [ "dep:mime", "dep:serde", "dep:serde_json", + "dep:serde_with", "timestamps", ] # Enables support for outputting JUnit XML report. @@ -65,7 +66,7 @@ tracing = ["dep:crossbeam-utils", "dep:tracing", "dep:tracing-subscriber"] [dependencies] clap = { version = "4.3.2", features = ["derive", "wrap_help"] } console = "0.15" -derive_more = { version = "0.99.17", features = ["as_ref", "deref", "deref_mut", "display", "error", "from", "from_str", "into"], default-features = false } +derive_more = { version = "2.0", features = ["as_ref", "debug", "deref", "deref_mut", "display", "error", "from", "from_str", "into"] } drain_filter_polyfill = "0.1.2" either = "1.6" futures = "0.3.17" @@ -92,6 +93,7 @@ Inflector = { version = "0.11", default-features = false, optional = true } mime = { version = "0.3.16", optional = true } serde = { version = "1.0.157", features = ["derive"], optional = true } serde_json = { version = "1.0.18", optional = true } +serde_with = { version = "3.0", optional = true } # "output-junit" feature dependencies. junit-report = { version = "0.8", optional = true } @@ -102,7 +104,6 @@ tracing = { version = "0.1", optional = true } tracing-subscriber = { version = "0.3.16", optional = true } [dev-dependencies] -derive_more = "0.99.17" rand = "0.9" tempfile = "3.2" tokio = { version = "1.40", features = ["macros", "rt-multi-thread", "sync", "time"] } diff --git a/codegen/Cargo.toml b/codegen/Cargo.toml index e26984d3..1d49dbbd 100644 --- a/codegen/Cargo.toml +++ b/codegen/Cargo.toml @@ -32,7 +32,7 @@ synthez = "0.3" [dev-dependencies] cucumber = { path = "..", features = ["libtest", "macros"] } -derive_more = "0.99.17" +derive_more = { version = "2.0", features = ["deref", "from_str"] } futures = "0.3.17" tempfile = "3.2" tokio = { version = "1.12", features = ["macros", "rt-multi-thread", "time"] } diff --git a/src/cucumber.rs b/src/cucumber.rs index b6415ee8..dfd43fe8 100644 --- a/src/cucumber.rs +++ b/src/cucumber.rs @@ -12,15 +12,9 @@ //! //! [Cucumber]: https://cucumber.io -use std::{ - borrow::Cow, - fmt::{self, Debug}, - marker::PhantomData, - mem, - path::Path, - time::Duration, -}; +use std::{borrow::Cow, marker::PhantomData, mem, path::Path, time::Duration}; +use derive_more::with_trait::Debug; use futures::{future::LocalBoxFuture, StreamExt as _}; use gherkin::tagexpr::TagOperation; use regex::Regex; @@ -40,7 +34,7 @@ use crate::{ /// [`World::run()`] or [`World::cucumber()`] on your [`World`] deriver to get /// [Cucumber] up and running. /// -/// Otherwise use [`Cucumber::new()`] to get the default [Cucumber] executor, +/// Otherwise, use [`Cucumber::new()`] to get the default [Cucumber] executor, /// provide [`Step`]s with [`World::collection()`] or by hand with /// [`Cucumber::given()`], [`Cucumber::when()`] and [`Cucumber::then()`]. /// @@ -50,6 +44,7 @@ use crate::{ /// [`Cucumber::with_writer()`] to construct your dream [Cucumber] executor! /// /// [Cucumber]: https://cucumber.io +#[derive(Debug)] pub struct Cucumber where W: World, @@ -77,9 +72,11 @@ where cli: Option>, /// Type of the [`World`] this [`Cucumber`] run on. + #[debug(ignore)] _world: PhantomData, /// Type of the input consumed by [`Cucumber::parser`]. + #[debug(ignore)] _parser_input: PhantomData, } @@ -814,27 +811,6 @@ where } } -impl Debug for Cucumber -where - W: World, - P: Debug + Parser, -

>::Cli: Debug, - R: Debug + Runner, - >::Cli: Debug, - Wr: Debug + Writer, - >::Cli: Debug, - Cli: clap::Args + Debug, -{ - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("Cucumber") - .field("parser", &self.parser) - .field("runner", &self.runner) - .field("writer", &self.writer) - .field("cli", &self.cli) - .finish() - } -} - /// Shortcut for the [`Cucumber`] type returned by its [`Default`] impl. pub(crate) type DefaultCucumber = Cucumber< W, diff --git a/src/event.rs b/src/event.rs index 8fe616ff..1634adcf 100644 --- a/src/event.rs +++ b/src/event.rs @@ -23,12 +23,13 @@ use std::time::SystemTime; use std::{ any::Any, - fmt, hash::{Hash, Hasher}, sync::Arc, }; -use derive_more::{AsRef, Deref, DerefMut, Display, Error, From, Into}; +use derive_more::with_trait::{ + AsRef, Debug, Deref, DerefMut, Display, Error, From, Into, +}; use ref_cast::RefCast; use crate::{step, writer::basic::coerce_error}; @@ -409,20 +410,20 @@ pub enum StepError { /// /// [`Regex`]: regex::Regex /// [`fail_on_skipped()`]: crate::WriterExt::fail_on_skipped() - #[display(fmt = "Step doesn't match any function")] + #[display("Step doesn't match any function")] NotFound, /// [`Step`] matches multiple [`Regex`]es. /// /// [`Regex`]: regex::Regex /// [`Step`]: gherkin::Step - #[display(fmt = "Step match is ambiguous: {}", _0)] + #[display("Step match is ambiguous: {_0}")] AmbiguousMatch(step::AmbiguousMatchError), /// [`Step`] panicked. /// /// [`Step`]: gherkin::Step - #[display(fmt = "Step panicked. Captured output: {}", "coerce_error(_0)")] + #[display("Step panicked. Captured output: {}", coerce_error(_0))] Panic(#[error(not(source))] Info), } @@ -430,7 +431,8 @@ pub enum StepError { /// /// [`Scenario`]: gherkin::Scenario /// [`Step`]: gherkin::Step -#[derive(Clone, Copy, Debug)] +#[derive(Clone, Copy, Debug, Display)] +#[display("{self:?}")] pub enum HookType { /// Executing on each [`Scenario`] before running all [`Step`]s. /// @@ -445,13 +447,6 @@ pub enum HookType { After, } -#[expect(clippy::use_debug, reason = "intentional")] -impl fmt::Display for HookType { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{self:?}") - } -} - /// Event of running [`Before`] or [`After`] hook. /// /// [`After`]: HookType::After @@ -713,8 +708,10 @@ pub enum ScenarioFinished { /// Wrappers around a [`gherkin`] type ([`gherkin::Feature`], /// [`gherkin::Scenario`], etc.), providing cheap [`Clone`], [`Hash`] and /// [`PartialEq`] implementations for using it extensively in [`Event`]s. -#[derive(AsRef, Deref, Display, From, Into, RefCast)] +#[derive(AsRef, Debug, Deref, Display, From, Into, RefCast)] #[as_ref(forward)] +#[debug("{:?}", **_0)] +#[debug(bound(T: Debug))] #[deref(forward)] #[repr(transparent)] pub struct Source(Arc); @@ -727,12 +724,6 @@ impl Source { } } -impl fmt::Debug for Source { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Debug::fmt(&**self, f) - } -} - // Manual implementation is required to omit the redundant `T: Clone` trait // bound imposed by `#[derive(Clone)]`. impl Clone for Source { diff --git a/src/feature.rs b/src/feature.rs index 0e41dcb6..38f4abc1 100644 --- a/src/feature.rs +++ b/src/feature.rs @@ -16,7 +16,7 @@ use std::{ sync::LazyLock, }; -use derive_more::{Display, Error}; +use derive_more::with_trait::{Display, Error}; use regex::Regex; use sealed::sealed; @@ -231,11 +231,10 @@ fn expand_scenario( /// [1]: https://cucumber.io/docs/gherkin/reference#scenario-outline #[derive(Clone, Debug, Display, Error)] #[display( - fmt = "Failed to resolve <{}> at {}:{}:{}", - name, - "path.as_deref().and_then(Path::to_str).map(trim_path).unwrap_or_default()", - "pos.line", - "pos.col" + "Failed to resolve <{name}> at {}:{}:{}", + path.as_deref().and_then(Path::to_str).map(trim_path).unwrap_or_default(), + pos.line, + pos.col, )] pub struct ExpandExamplesError { /// Position of the unknown template. diff --git a/src/lib.rs b/src/lib.rs index c9cfbcb8..03446968 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -165,8 +165,6 @@ unused_results, variant_size_differences )] -// TODO: Remove on next `derive_more` major version. -#![expect(clippy::uninlined_format_args, reason = "`derive_more` expansion")] pub mod cli; mod cucumber; diff --git a/src/parser/basic.rs b/src/parser/basic.rs index b1f29747..15a5e7a1 100644 --- a/src/parser/basic.rs +++ b/src/parser/basic.rs @@ -17,7 +17,7 @@ use std::{ vec, }; -use derive_more::{Display, Error}; +use derive_more::with_trait::{Display, Error}; use futures::stream; use gherkin::GherkinEnv; use globwalk::{GlobWalker, GlobWalkerBuilder}; @@ -164,7 +164,7 @@ impl Basic { /// Error of [`gherkin`] not supporting keywords in some language. #[derive(Clone, Debug, Display, Error)] -#[display(fmt = "Language {} isn't supported", _0)] +#[display("Language {_0} isn't supported")] pub struct UnsupportedLanguageError( #[error(not(source))] pub Cow<'static, str>, ); diff --git a/src/parser/mod.rs b/src/parser/mod.rs index d9c1926e..7eaf5cfb 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -16,7 +16,7 @@ pub mod basic; use std::sync::Arc; -use derive_more::{Display, Error}; +use derive_more::with_trait::{Display, Error as StdError}; use futures::Stream; use crate::feature::ExpandExamplesError; @@ -57,18 +57,18 @@ pub trait Parser { pub type Result = std::result::Result; /// [`Parser`] error. -#[derive(Clone, Debug, Display, Error)] +#[derive(Clone, Debug, Display, StdError)] pub enum Error { /// Failed to parse a [`Feature`]. /// /// [`Feature`]: gherkin::Feature - #[display(fmt = "Failed to parse feature: {}", _0)] + #[display("Failed to parse feature: {_0}")] Parsing(Arc), /// Failed to expand [`Examples`] /// /// [`Examples`]: gherkin::Examples - #[display(fmt = "Failed to expand examples: {}", _0)] + #[display("Failed to expand examples: {_0}")] ExampleExpansion(Arc), } diff --git a/src/runner/basic.rs b/src/runner/basic.rs index 374e1a21..0394cc39 100644 --- a/src/runner/basic.rs +++ b/src/runner/basic.rs @@ -14,7 +14,7 @@ use std::{ any::Any, cmp, collections::HashMap, - fmt, iter, mem, + iter, mem, ops::ControlFlow, panic::{self, AssertUnwindSafe}, sync::{ @@ -27,7 +27,7 @@ use std::{ #[cfg(feature = "tracing")] use crossbeam_utils::atomic::AtomicCell; -use derive_more::{Display, FromStr}; +use derive_more::with_trait::{Debug, Display, FromStr}; use drain_filter_polyfill::VecExt; use futures::{ channel::{mpsc, oneshot}, @@ -323,6 +323,7 @@ type IsRetried = bool; /// /// [1]: Runner#order-guarantees /// [`Scenario`]: gherkin::Scenario +#[derive(Debug)] pub struct Basic< World, F = WhichScenarioFn, @@ -360,11 +361,13 @@ pub struct Basic< /// [`Concurrent`]: ScenarioType::Concurrent /// [`Serial`]: ScenarioType::Serial /// [`Scenario`]: gherkin::Scenario + #[debug(ignore)] which_scenario: F, /// Function determining [`Scenario`]'s [`RetryOptions`]. /// /// [`Scenario`]: gherkin::Scenario + #[debug(ignore)] retry_options: RetryOptionsFn, /// Function, executed on each [`Scenario`] before running all [`Step`]s, @@ -373,6 +376,7 @@ pub struct Basic< /// [`Background`]: gherkin::Background /// [`Scenario`]: gherkin::Scenario /// [`Step`]: gherkin::Step + #[debug(ignore)] before_hook: Option, /// Function, executed on each [`Scenario`] after running all [`Step`]s. @@ -380,6 +384,7 @@ pub struct Basic< /// [`Background`]: gherkin::Background /// [`Scenario`]: gherkin::Scenario /// [`Step`]: gherkin::Step + #[debug(ignore)] after_hook: Option, /// Indicates whether execution should be stopped after the first failure. @@ -387,6 +392,7 @@ pub struct Basic< #[cfg(feature = "tracing")] /// [`TracingCollector`] for [`event::Scenario::Log`]s forwarding. + #[debug(ignore)] pub(crate) logs_collector: Arc>>>, } @@ -420,21 +426,6 @@ impl Clone for Basic { } } -// Implemented manually to omit redundant trait bounds on `World` and to omit -// outputting `F`. -impl fmt::Debug for Basic { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("Basic") - .field("max_concurrent_scenarios", &self.max_concurrent_scenarios) - .field("retries", &self.retries) - .field("retry_after", &self.retry_after) - .field("retry_filter", &self.retry_filter) - .field("steps", &self.steps) - .field("fail_fast", &self.fail_fast) - .finish_non_exhaustive() - } -} - impl Default for Basic { fn default() -> Self { let which_scenario: WhichScenarioFn = |feature, rule, scenario| { diff --git a/src/step.rs b/src/step.rs index be7cc1f1..6e84f383 100644 --- a/src/step.rs +++ b/src/step.rs @@ -21,7 +21,7 @@ use std::{ iter, }; -use derive_more::{Deref, DerefMut, Display, Error}; +use derive_more::with_trait::{Debug, Deref, DerefMut, Display, Error}; use futures::future::LocalBoxFuture; use gherkin::StepType; use itertools::Itertools as _; @@ -43,54 +43,39 @@ pub type WithContext<'me, World> = ( /// Collection of [`Step`]s. /// /// Every [`Step`] has to match with exactly 1 [`Regex`]. +#[derive(Debug)] pub struct Collection { /// Collection of [Given] [`Step`]s. /// /// [Given]: https://cucumber.io/docs/gherkin/reference#given + #[debug("{:?}", + given.iter() + .map(|(re, step)| (re, format!("{step:p}"))) + .collect::>(), + )] given: HashMap<(HashableRegex, Option), Step>, /// Collection of [When] [`Step`]s. /// /// [When]: https://cucumber.io/docs/gherkin/reference#when + #[debug("{:?}", + when.iter() + .map(|(re, step)| (re, format!("{step:p}"))) + .collect::>(), + )] when: HashMap<(HashableRegex, Option), Step>, /// Collection of [Then] [`Step`]s. /// /// [Then]: https://cucumber.io/docs/gherkin/reference#then + #[debug("{:?}", + then.iter() + .map(|(re, step)| (re, format!("{step:p}"))) + .collect::>(), + )] then: HashMap<(HashableRegex, Option), Step>, } -impl fmt::Debug for Collection { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("Collection") - .field( - "given", - &self - .given - .iter() - .map(|(re, step)| (re, format!("{step:p}"))) - .collect::>(), - ) - .field( - "when", - &self - .when - .iter() - .map(|(re, step)| (re, format!("{step:p}"))) - .collect::>(), - ) - .field( - "then", - &self - .then - .iter() - .map(|(re, step)| (re, format!("{step:p}"))) - .collect::>(), - ) - .finish() - } -} - // Implemented manually to omit redundant `World: Clone` trait bound, imposed by // `#[derive(Clone)]`. impl Clone for Collection { @@ -259,7 +244,7 @@ pub struct AmbiguousMatchError { pub possible_matches: Vec<(HashableRegex, Option)>, } -impl fmt::Display for AmbiguousMatchError { +impl Display for AmbiguousMatchError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "Possible matches:")?; for (reg, loc_opt) in &self.possible_matches { @@ -274,7 +259,7 @@ impl fmt::Display for AmbiguousMatchError { /// Location of a [`Step`] [`fn`] automatically filled by a proc macro. #[derive(Clone, Copy, Debug, Display, Eq, Hash, Ord, PartialEq, PartialOrd)] -#[display(fmt = "{}:{}:{}", path, line, column)] +#[display("{path}:{line}:{column}")] pub struct Location { /// Path to the file where [`Step`] [`fn`] is located. pub path: &'static str, diff --git a/src/tracing.rs b/src/tracing.rs index 34b6f8a2..4d76c350 100644 --- a/src/tracing.rs +++ b/src/tracing.rs @@ -2,6 +2,7 @@ use std::{collections::HashMap, fmt, io, iter}; +use derive_more::with_trait::Debug; use futures::channel::{mpsc, oneshot}; use itertools::Either; use tracing::{ @@ -454,7 +455,7 @@ impl Visit for GetScenarioId { } } - fn record_debug(&mut self, _: &Field, _: &dyn fmt::Debug) {} + fn record_debug(&mut self, _: &Field, _: &dyn Debug) {} } /// [`FormatFields`] wrapper skipping [`Span`]s with a [`ScenarioId`]. @@ -482,7 +483,7 @@ impl<'w, F: FormatFields<'w>> FormatFields<'w> for SkipScenarioIdSpan { struct IsScenarioIdSpan(bool); impl Visit for IsScenarioIdSpan { - fn record_debug(&mut self, field: &Field, _: &dyn fmt::Debug) { + fn record_debug(&mut self, field: &Field, _: &dyn Debug) { if field.name() == ScenarioId::SPAN_FIELD_NAME { self.0 = true; } diff --git a/src/writer/basic.rs b/src/writer/basic.rs index a925a7bd..ca5c11ca 100644 --- a/src/writer/basic.rs +++ b/src/writer/basic.rs @@ -19,7 +19,7 @@ use std::{ sync::LazyLock, }; -use derive_more::{Deref, DerefMut}; +use derive_more::with_trait::{Deref, DerefMut}; use itertools::Itertools as _; use regex::CaptureLocations; use smart_default::SmartDefault; diff --git a/src/writer/discard.rs b/src/writer/discard.rs index dc78de89..57b29ae6 100644 --- a/src/writer/discard.rs +++ b/src/writer/discard.rs @@ -10,14 +10,14 @@ //! Wrappers providing no-op implementations. -use derive_more::{Deref, DerefMut}; +use derive_more::with_trait::{Deref, DerefMut}; use crate::{event::Cucumber, parser, writer, Event, World, Writer}; /// Wrapper providing a no-op [`ArbitraryWriter`] implementation. /// /// Intended to be used for feeding a non-[`ArbitraryWriter`] [`Writer`] into a -/// [`writer::Tee`], as the later accepts only [`ArbitraryWriter`]s. +/// [`writer::Tee`], as the latter accepts only [`ArbitraryWriter`]s. /// /// [`ArbitraryWriter`]: writer::Arbitrary #[derive(Clone, Copy, Debug, Deref, DerefMut)] diff --git a/src/writer/fail_on_skipped.rs b/src/writer/fail_on_skipped.rs index 7496d1bd..14ae761d 100644 --- a/src/writer/fail_on_skipped.rs +++ b/src/writer/fail_on_skipped.rs @@ -14,7 +14,7 @@ //! [`Skipped`]: event::Step::Skipped //! [`Step`]: gherkin::Step -use derive_more::Deref; +use derive_more::with_trait::Deref; use crate::{ event::{self, Source}, diff --git a/src/writer/json.rs b/src/writer/json.rs index 208ace8b..8d7ab765 100644 --- a/src/writer/json.rs +++ b/src/writer/json.rs @@ -12,18 +12,14 @@ //! //! [1]: https://github.com/cucumber/cucumber-json-schema -use std::{ - fmt::{self, Debug}, - io, mem, - sync::LazyLock, - time::SystemTime, -}; +use std::{fmt::Debug, io, mem, sync::LazyLock, time::SystemTime}; use base64::Engine as _; -use derive_more::Display; +use derive_more::with_trait::Display; use inflector::Inflector as _; use mime::Mime; -use serde::{Serialize, Serializer}; +use serde::Serialize; +use serde_with::{serde_as, DisplayFromStr}; use crate::{ cli, event, @@ -431,13 +427,14 @@ impl Base64 { /// Data embedded to [Cucumber JSON format][1] output. /// /// [1]: https://github.com/cucumber/cucumber-json-schema +#[serde_as] #[derive(Clone, Debug, Serialize)] pub struct Embedding { /// [`base64`] encoded data. pub data: Base64, /// [`Mime`] of this [`Embedding::data`]. - #[serde(serialize_with = "serialize_display")] + #[serde_as(as = "DisplayFromStr")] pub mime_type: Mime, /// Optional name of the [`Embedding`]. @@ -814,13 +811,3 @@ impl PartialEq for Feature { && self.name == other.name } } - -/// Helper to use `#[serde(serialize_with = "serialize_display")]` with any type -/// implementing [`fmt::Display`]. -fn serialize_display(display: &T, ser: S) -> Result -where - T: fmt::Display, - S: Serializer, -{ - format_args!("{display}").serialize(ser) -} diff --git a/src/writer/libtest.rs b/src/writer/libtest.rs index 00c62228..8719cffd 100644 --- a/src/writer/libtest.rs +++ b/src/writer/libtest.rs @@ -19,7 +19,7 @@ use std::{ time::{Duration, SystemTime}, }; -use derive_more::From; +use derive_more::with_trait::From; use either::Either; use itertools::Itertools as _; use serde::Serialize; diff --git a/src/writer/normalize.rs b/src/writer/normalize.rs index a5a5c6c8..7566d41d 100644 --- a/src/writer/normalize.rs +++ b/src/writer/normalize.rs @@ -12,7 +12,7 @@ use std::{future::Future, hash::Hash, mem}; -use derive_more::Deref; +use derive_more::with_trait::Deref; use either::Either; use linked_hash_map::LinkedHashMap; diff --git a/src/writer/out.rs b/src/writer/out.rs index a513dc66..21c635a9 100644 --- a/src/writer/out.rs +++ b/src/writer/out.rs @@ -17,7 +17,7 @@ use std::{ }; use console::Style; -use derive_more::{Deref, DerefMut, Display, From, Into}; +use derive_more::with_trait::{Deref, DerefMut, Display, From, Into}; use super::Coloring; diff --git a/src/writer/repeat.rs b/src/writer/repeat.rs index feac72ce..8592c1b9 100644 --- a/src/writer/repeat.rs +++ b/src/writer/repeat.rs @@ -12,7 +12,7 @@ use std::mem; -use derive_more::Deref; +use derive_more::with_trait::Deref; use crate::{event, parser, writer, Event, World, Writer}; diff --git a/src/writer/summarize.rs b/src/writer/summarize.rs index 49c78eb6..7021d554 100644 --- a/src/writer/summarize.rs +++ b/src/writer/summarize.rs @@ -12,7 +12,7 @@ use std::{borrow::Cow, collections::HashMap}; -use derive_more::Deref; +use derive_more::with_trait::Deref; use itertools::Itertools as _; use crate::{ diff --git a/tests/after_hook.rs b/tests/after_hook.rs index 0d2cc1f8..fb028646 100644 --- a/tests/after_hook.rs +++ b/tests/after_hook.rs @@ -6,7 +6,7 @@ use std::{ }; use cucumber::{given, then, when, Parameter, World as _}; -use derive_more::{Deref, FromStr}; +use derive_more::with_trait::{Deref, FromStr}; use futures::FutureExt as _; use tokio::time; diff --git a/tests/tracing.rs b/tests/tracing.rs index c24dd5fb..3e9abaff 100644 --- a/tests/tracing.rs +++ b/tests/tracing.rs @@ -1,7 +1,7 @@ use std::{fs, io, panic::AssertUnwindSafe, time::Duration}; use cucumber::{given, writer, writer::Coloring, World as _, WriterExt as _}; -use derive_more::Display; +use derive_more::with_trait::Display; use futures::FutureExt as _; use regex::Regex; use tokio::{spawn, time}; diff --git a/tests/wait.rs b/tests/wait.rs index 79273689..5fe08f6b 100644 --- a/tests/wait.rs +++ b/tests/wait.rs @@ -1,7 +1,7 @@ use std::{panic::AssertUnwindSafe, time::Duration}; use cucumber::{cli, given, then, when, writer, Parameter, World as _}; -use derive_more::{Deref, FromStr}; +use derive_more::with_trait::{Deref, FromStr}; use futures::FutureExt as _; use tokio::time;