如何返回包含serde_json :: Value的结果?

时间:2019-04-03 15:56:44

标签: rust serde

这就是我所拥有的,但是我想避免在我的reqwest值上使用unwrap

extern crate base64;
extern crate reqwest;

use serde_json;

use serde_json::json;

pub fn perform_get(id: String) -> serde_json::value::Value {
    let client = reqwest::Client::builder().build().unwrap();

    let url = String::from("SomeURL");

    let res = client.get(&url).send().unwrap().text();

    let mut v = json!(null);
    match res {
        Ok(n) => {
            v = serde_json::from_str(&n).unwrap();
        }
        Err(r) => {
            println!("Something wrong happened {:?}", r);
        }
    }

    v
}

fn main() {
    println!("Hi there! i want the function above to return a result instead of a Serde value so I can handle the error in main!");
}

Here is a link to a rust playground example

3 个答案:

答案 0 :(得分:4)

Rust的官方书籍The Rust Programming Language可在线免费获得。它有一个entire chapter on using Result,解释了诸如Result枚举之类的介绍性主题以及如何使用它。

  

如何返回包含Result的{​​{1}}?

与返回{em> any 类型的serde_json::Value的方法相同; Result没什么特别的:

Value

如果您有一个返回use serde_json::json; // 1.0.38 pub fn ok_example() -> Result<serde_json::value::Value, i32> { Ok(json! { "success" }) } pub fn err_example() -> Result<serde_json::value::Value, i32> { Err(42) } 的函数,则可以使用问号运算符(Result)在出现错误时从函数中提前退出,并返回错误。这是避免使用?unwrap的简洁方法:

expect

这只是一个基本示例。

应用于您的MCVE,它看起来像:

fn use_them() -> Result<(), i32> {
    let ok = ok_example()?;
    println!("{:?}", ok);

    let err = err_example()?;
    println!("{:?}", err); // Never executed, we always exit due to the `?`

    Ok(()) // Never executed
}

在这里,我正在使用 trait对象 use reqwest; // 0.9.10 use serde_json::Value; // 1.0.38 type Error = Box<dyn std::error::Error>; pub fn perform_get(_id: String) -> Result<Value, Error> { let client = reqwest::Client::builder().build()?; let url = String::from("SomeURL"); let res = client.get(&url).send()?.text()?; let v = serde_json::from_str(&res)?; Ok(v) } 处理任何类型的错误(适用于快速程序和示例)。然后,我将Box<dyn std::error::Error>撒在每个可能失败的方法上(即返回一个?),并以一个明确的Result作为最终值的函数结束。

请注意,可以使用此样式删除Ok和从未使用的panic值。

另请参阅:

  

更好的做法是返回null

另请参阅:

答案 1 :(得分:3)

如果您在用户方面,我建议使用Box<dyn std::error::Error>,这允许返回实现Error的每种类型,?会将具体的错误类型转换为动态框特质,这会在出现错误时增加一些开销,但是当没有预料到的错误或确实很少发生错误时,这并不是什么大问题。

use reqwest;

use serde_json::value::Value;
use std::error::Error;

fn perform_get(_id: String) -> Result<Value, Box<dyn Error>> {
    let client = reqwest::Client::builder().build()?;

    let url = String::from("SomeURL");

    let res = client.get(&url).send()?.text()?;

    let v = serde_json::from_str(&res)?;

    Ok(v)

    // last two line could be serde_json::from_str(&res).map_err(std::convert::Into::into)
}

fn main() {
    println!("{:?}", perform_get("hello".to_string()));
}

这会产生以下错误:

Err(Error { kind: Url(RelativeUrlWithoutBase), url: None })

答案 2 :(得分:-1)

Rust Discord的善良聪明的人帮助我解决了这个问题。 (noc用户)

extern crate base64;
extern crate reqwest;

pub fn get_jira_ticket() -> Result<serde_json::value::Value, reqwest::Error> {
    let client = reqwest::Client::builder().build().unwrap();

    let url = String::from("SomeURL");

    let res = client.get(&url).send().and_then(|mut r| r.json());

    res
}

fn main() {
    println!("This works");
}

关键部分是返回标题中的

-> Result<serde_json::value::Value, reqwest::Error>

这实际上是返回数据。

client.get(&url).send().and_then(|mut r| r.json());