没有实现`dyn std :: error :: error == dyn std :: error :: error`

发布于 2025-02-07 12:48:59 字数 2371 浏览 5 评论 0原文

我有一个异步函数,该功能在完成所有Web解析后返回结构。运行测试时,我会遇到错误:`dyn std :: error :: error == dyn std :: error :: error :: error` rover。我该如何解决这个问题,或者我在做什么错?

#[derive(Debug, PartialEq, Eq)]
pub struct ParsingResult<'a> {
    title: &'a str,
    content: String,
}
impl<'a> ParsingResult<'a> {
    pub fn new(title: &'a str, content: String) -> Self {
        ParsingResult { title, content }
    }
}
pub async fn yahoo_template<'a>(
    link_to_the_article: &str,
) -> Result<ParsingResult<'a>, Box<dyn error::Error>> {
    let resp = reqwest::get(link_to_the_article).await?.text().await?;

    let mut final_res: Vec<String> = Vec::new();
    Document::from(resp.as_str())
        .find(Name("a"))
        .filter_map(|n| n.attr("href"))
        .for_each(|x| {
            if x.contains("http") || x.contains("https") {
                final_res.push(String::from(x));
            }
        });
    // println!("{:?}", final_res);
    Ok(ParsingResult::new("Title", String::from("String")))
}

#[cfg(test)]
mod templates_tests {
    use super::*;
    #[tokio::test]
    async fn make_it_work() {
        let expected = Ok(ParsingResult::new("Title", String::from("String")));
        assert_eq!(
            expected,
            yahoo_template("https://ro.wikipedia.org/wiki/Guy_de_Maupassant").await
        );
    }
}

错误输出:

error[E0277]: can't compare `dyn std::error::Error` with `dyn std::error::Error`
  --> src/scraper/scraping_templates.rs:47:3
   |
47 | /         assert_eq!(
48 | |             expected,
49 | |             yahoo_template("https://ro.wikipedia.org/wiki/Guy_de_Maupassant").await
50 | |         );
   | |_________^ no implementation for `dyn std::error::Error == dyn std::error::Error`
   |
   = help: the trait `PartialEq` is not implemented for `dyn std::error::Error`
   = note: required because of the requirements on the impl of `PartialEq` for `Box<dyn std::error::Error>`
   = note: 1 redundant requirement hidden
   = note: required because of the requirements on the impl of `PartialEq` for `Result<scraping_templates::ParsingResult<'_>, Box<dyn std::error::Error>>`
   = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)

I have an async function that returns a struct after all the web parsing is done. When running the tests I'm getting the error: no implementation for `dyn std::error::Error == dyn std::error::Error`. How can I solve this or what am I doing wrong?

#[derive(Debug, PartialEq, Eq)]
pub struct ParsingResult<'a> {
    title: &'a str,
    content: String,
}
impl<'a> ParsingResult<'a> {
    pub fn new(title: &'a str, content: String) -> Self {
        ParsingResult { title, content }
    }
}
pub async fn yahoo_template<'a>(
    link_to_the_article: &str,
) -> Result<ParsingResult<'a>, Box<dyn error::Error>> {
    let resp = reqwest::get(link_to_the_article).await?.text().await?;

    let mut final_res: Vec<String> = Vec::new();
    Document::from(resp.as_str())
        .find(Name("a"))
        .filter_map(|n| n.attr("href"))
        .for_each(|x| {
            if x.contains("http") || x.contains("https") {
                final_res.push(String::from(x));
            }
        });
    // println!("{:?}", final_res);
    Ok(ParsingResult::new("Title", String::from("String")))
}

#[cfg(test)]
mod templates_tests {
    use super::*;
    #[tokio::test]
    async fn make_it_work() {
        let expected = Ok(ParsingResult::new("Title", String::from("String")));
        assert_eq!(
            expected,
            yahoo_template("https://ro.wikipedia.org/wiki/Guy_de_Maupassant").await
        );
    }
}

Error output:

error[E0277]: can't compare `dyn std::error::Error` with `dyn std::error::Error`
  --> src/scraper/scraping_templates.rs:47:3
   |
47 | /         assert_eq!(
48 | |             expected,
49 | |             yahoo_template("https://ro.wikipedia.org/wiki/Guy_de_Maupassant").await
50 | |         );
   | |_________^ no implementation for `dyn std::error::Error == dyn std::error::Error`
   |
   = help: the trait `PartialEq` is not implemented for `dyn std::error::Error`
   = note: required because of the requirements on the impl of `PartialEq` for `Box<dyn std::error::Error>`
   = note: 1 redundant requirement hidden
   = note: required because of the requirements on the impl of `PartialEq` for `Result<scraping_templates::ParsingResult<'_>, Box<dyn std::error::Error>>`
   = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

〆一缕阳光ご 2025-02-14 12:49:01

此错误来自assert_eq!()async fn make_it_work()中的调用。

该断言试图比较两个结果&lt; parsingResult&lt;'a&gt; box&lt; dyn error :: error&gt;&gt; equality的值。 结果仅在ok okerr变体的类型时,才实现平等比较。这意味着parsingResult&lt;'a&gt;必须为自己实现partialeq(它是由于您的##[derive])和box&lt ; dyn error :: error&gt;也必须实现partialeq - 但是box,例如result,仅在当时实现等式比较值包含的值可以进行比较,并且error ::错误不需要partialeq(如果它做到了,则error :: error :: error :: error无论如何都不会是对象安全,因此您将无法使用dyn)。

可以说,err案例无法进行平等测试,因此结果的特定实例也无法进行平等测试。编译器不在乎您要检查ok值,这意味着它不必比较err变体值,它只是看到两个<代码>结果正在比较平等,并且找不到partialeq实现。

要解决此问题,您可以修改主张:

let expected = ParsingResult::new("Title", String::from("String"));
let actual = yahoo_template("https://ro.wikipedia.org/wiki/Guy_de_Maupassant").await;

assert_eq!(actual.ok(), Some(expected));

.ok()方法将A result&lt; v,e&gt;变成option&lt; v&gt; 通过映射OK(V) to 某些(V)err(_) to none。这有效地丢弃了错误,绕过了错误类型具有相等性比较实现的需求。


如果要保留显示错误信息以防测试失败的错误信息,请考虑将错误映射到具有相等性操作的类型。例如,只需将误差映射到字符串的调试表示。这将把err变体变成字符串,显然确实提供了平等比较。

let expected = ParsingResult::new("Title", String::from("String"));
let actual = yahoo_template("https://ro.wikipedia.org/wiki/Guy_de_Maupassant").await;

assert_eq!(actual.map_err(|e| format!("{:?}", e)), Ok(expected));

This error comes from the assert_eq!() invocation in async fn make_it_work().

This assertion attempts to compare two Result<ParsingResult<'a>, Box<dyn error::Error>> values for equality. Result only implements equality comparison when the types for the Ok and Err variants can be compared for equality with themselves. This means that ParsingResult<'a> must implement PartialEq for itself (it does due to your #[derive]) and Box<dyn error::Error> must also implement PartialEq -- but Box, like Result, only implements equality comparison when the value it contains can be compared for equality, and error::Error doesn't require PartialEq (and if it did then error::Error wouldn't be object-safe anyway, so you wouldn't be able to use dyn).

All that to say, the Err case can't be tested for equality, and so this particular instantiation of Result can't be tested for equality either. The compiler doesn't care that you're checking an Ok value, which means that it won't ever have to compare the Err variant values, it just sees two Results being compared for equality and can't find a PartialEq implementation.

To work around this, you can modify your assertion:

let expected = ParsingResult::new("Title", String::from("String"));
let actual = yahoo_template("https://ro.wikipedia.org/wiki/Guy_de_Maupassant").await;

assert_eq!(actual.ok(), Some(expected));

The .ok() method turns a Result<V, E> into an Option<V> by mapping Ok(v) to Some(v) and Err(_) to None. This effectively discards the error, bypassing the need for the error type to have an equality comparison implementation.


If you want to retain the error information for display in case the test fails, consider mapping the error to a type that does have an equality operation. For example, just map the error to the stringified debug representation. This will turn the Err variant into String, which obviously does provide equality comparison.

let expected = ParsingResult::new("Title", String::from("String"));
let actual = yahoo_template("https://ro.wikipedia.org/wiki/Guy_de_Maupassant").await;

assert_eq!(actual.map_err(|e| format!("{:?}", e)), Ok(expected));
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文