Use async_trait to fix issues with Chain type inference

This commit is contained in:
Matthias Endler 2024-03-20 17:46:17 +01:00 committed by Thomas Zahner
parent d92d3ba733
commit 0f012f3035
7 changed files with 25 additions and 12 deletions

5
Cargo.lock generated
View file

@ -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",

View file

@ -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"

View file

@ -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<T, R> Chain<T, R> {
self.0.lock().unwrap().append(&mut other.0.lock().unwrap());
}
pub(crate) fn traverse(&mut self, mut input: T) -> ChainResult<T, R> {
pub(crate) async fn traverse(&mut self, mut input: T) -> ChainResult<T, R> {
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<T, R> Chain<T, R> {
}
}
#[async_trait]
pub(crate) trait Chainable<T, R>: Debug {
async fn chain(&mut self, input: T) -> ChainResult<T, R>;
}
@ -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<Result, Result> for Add {
async fn chain(&mut self, req: Result) -> ChainResult<Result, Result> {
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<Result, Result> = 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<Result, Result> =
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)));
}
}

View file

@ -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<Request, Status> for Checker {
async fn chain(&mut self, input: Request) -> ChainResult<Request, Status> {
ChainResult::Done(self.retry_request(input).await)

View file

@ -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<Request, Status> for ExampleHandler {
async fn chain(&mut self, _: Request) -> ChainResult<Request, Status> {
ChainResult::Done(Status::Excluded)

View file

@ -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<Request, Status> for Quirks {
async fn chain(&mut self, input: Request) -> ChainResult<Request, Status> {
ChainResult::Next(self.apply(input))

View file

@ -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<Request, Status> for BasicAuthCredentials {
async fn chain(&mut self, mut request: Request) -> ChainResult<Request, Status> {
request