From 0f012f3035a137d97622e04abfe98cdd89d90415 Mon Sep 17 00:00:00 2001 From: Matthias Endler Date: Wed, 20 Mar 2024 17:46:17 +0100 Subject: [PATCH] Use `async_trait` to fix issues with `Chain` type inference --- Cargo.lock | 5 +++-- lychee-lib/Cargo.toml | 1 + lychee-lib/src/chain/mod.rs | 20 +++++++++++-------- lychee-lib/src/checker.rs | 4 +++- lychee-lib/src/client.rs | 3 ++- lychee-lib/src/quirks/mod.rs | 2 ++ .../src/types/basic_auth/credentials.rs | 2 ++ 7 files changed, 25 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4b3a458..1ab49f0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -435,9 +435,9 @@ checksum = "fbb36e985947064623dbd357f727af08ffd077f93d696782f3c56365fa2e2799" [[package]] name = "async-trait" -version = "0.1.77" +version = "0.1.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9" +checksum = "461abc97219de0eaaf81fe3ef974a540158f3d079c2ab200f891f1a2ef201e85" dependencies = [ "proc-macro2", "quote", @@ -2394,6 +2394,7 @@ name = "lychee-lib" version = "0.14.3" dependencies = [ "async-stream", + "async-trait", "cached", "check-if-email-exists", "doc-comment", diff --git a/lychee-lib/Cargo.toml b/lychee-lib/Cargo.toml index 917266c..0007424 100644 --- a/lychee-lib/Cargo.toml +++ b/lychee-lib/Cargo.toml @@ -13,6 +13,7 @@ version.workspace = true [dependencies] async-stream = "0.3.5" +async-trait = "0.1.78" cached = "0.46.1" check-if-email-exists = { version = "0.9.1", optional = true } email_address = "0.2.4" diff --git a/lychee-lib/src/chain/mod.rs b/lychee-lib/src/chain/mod.rs index 3f0a8f0..573aeb8 100644 --- a/lychee-lib/src/chain/mod.rs +++ b/lychee-lib/src/chain/mod.rs @@ -1,4 +1,5 @@ use crate::Status; +use async_trait::async_trait; use core::fmt::Debug; use std::sync::{Arc, Mutex}; @@ -34,10 +35,10 @@ impl Chain { self.0.lock().unwrap().append(&mut other.0.lock().unwrap()); } - pub(crate) fn traverse(&mut self, mut input: T) -> ChainResult { + pub(crate) async fn traverse(&mut self, mut input: T) -> ChainResult { use ChainResult::{Done, Next}; for e in self.0.lock().unwrap().iter_mut() { - match e.chain(input) { + match e.chain(input).await { Next(r) => input = r, Done(r) => { return Done(r); @@ -53,6 +54,7 @@ impl Chain { } } +#[async_trait] pub(crate) trait Chainable: Debug { async fn chain(&mut self, input: T) -> ChainResult; } @@ -63,6 +65,7 @@ mod test { ChainResult::{Done, Next}, Chainable, }; + use async_trait::async_trait; #[derive(Debug)] struct Add(usize); @@ -70,6 +73,7 @@ mod test { #[derive(Debug, PartialEq, Eq)] struct Result(usize); + #[async_trait] impl Chainable for Add { async fn chain(&mut self, req: Result) -> ChainResult { let added = req.0 + self.0; @@ -81,20 +85,20 @@ mod test { } } - #[test] - fn simple_chain() { + #[tokio::test] + async fn simple_chain() { use super::Chain; let mut chain: Chain = Chain::new(vec![Box::new(Add(7)), Box::new(Add(3))]); - let result = chain.traverse(Result(0)); + let result = chain.traverse(Result(0)).await; assert_eq!(result, Next(Result(10))); } - #[test] - fn early_exit_chain() { + #[tokio::test] + async fn early_exit_chain() { use super::Chain; let mut chain: Chain = Chain::new(vec![Box::new(Add(80)), Box::new(Add(30)), Box::new(Add(1))]); - let result = chain.traverse(Result(0)); + let result = chain.traverse(Result(0)).await; assert_eq!(result, Done(Result(80))); } } diff --git a/lychee-lib/src/checker.rs b/lychee-lib/src/checker.rs index 598884f..c6b76d3 100644 --- a/lychee-lib/src/checker.rs +++ b/lychee-lib/src/checker.rs @@ -1,8 +1,9 @@ use crate::{ - chain::{Chain, ChainResult, Chainable}, + chain::{ChainResult, Chainable}, retry::RetryExt, Status, }; +use async_trait::async_trait; use http::StatusCode; use reqwest::Request; use std::{collections::HashSet, time::Duration}; @@ -58,6 +59,7 @@ impl Checker { } } +#[async_trait] impl Chainable for Checker { async fn chain(&mut self, input: Request) -> ChainResult { ChainResult::Done(self.retry_request(input).await) diff --git a/lychee-lib/src/client.rs b/lychee-lib/src/client.rs index 1707171..49499a3 100644 --- a/lychee-lib/src/client.rs +++ b/lychee-lib/src/client.rs @@ -35,7 +35,6 @@ use crate::{ filter::{Excludes, Filter, Includes}, quirks::Quirks, remap::Remaps, - retry::RetryExt, types::uri::github::GithubUri, utils::fragment_checker::FragmentChecker, BasicAuthCredentials, ErrorKind, Request, Response, Result, Status, Uri, @@ -743,6 +742,7 @@ mod tests { time::{Duration, Instant}, }; + use async_trait::async_trait; use http::{header::HeaderMap, StatusCode}; use reqwest::header; use tempfile::tempdir; @@ -1085,6 +1085,7 @@ mod tests { #[derive(Debug)] struct ExampleHandler(); + #[async_trait] impl Chainable for ExampleHandler { async fn chain(&mut self, _: Request) -> ChainResult { ChainResult::Done(Status::Excluded) diff --git a/lychee-lib/src/quirks/mod.rs b/lychee-lib/src/quirks/mod.rs index bf0e758..333b921 100644 --- a/lychee-lib/src/quirks/mod.rs +++ b/lychee-lib/src/quirks/mod.rs @@ -2,6 +2,7 @@ use crate::{ chain::{ChainResult, Chainable}, Status, }; +use async_trait::async_trait; use header::HeaderValue; use http::header; use once_cell::sync::Lazy; @@ -90,6 +91,7 @@ impl Quirks { } } +#[async_trait] impl Chainable for Quirks { async fn chain(&mut self, input: Request) -> ChainResult { ChainResult::Next(self.apply(input)) diff --git a/lychee-lib/src/types/basic_auth/credentials.rs b/lychee-lib/src/types/basic_auth/credentials.rs index 9c2ab3e..2bdf19e 100644 --- a/lychee-lib/src/types/basic_auth/credentials.rs +++ b/lychee-lib/src/types/basic_auth/credentials.rs @@ -1,3 +1,4 @@ +use async_trait::async_trait; use std::str::FromStr; use headers::authorization::Credentials; @@ -73,6 +74,7 @@ impl BasicAuthCredentials { } } +#[async_trait] impl Chainable for BasicAuthCredentials { async fn chain(&mut self, mut request: Request) -> ChainResult { request