将字节转换为字符串rust

pepwfjgg  于 2023-05-22  发布在  其他
关注(0)|答案(2)|浏览(211)

我用这段代码解析http响应,服务器会返回一个json字符串,这是rust代码:

use reqwest::Client;

#[tokio::main]
async fn main() {
    let client = Client::new();
    let url = "https://jsonplaceholder.typicode.com/todos/1";
    let response = client.get(url).send().await;
    if response.is_ok() {
        let wrap_response = response.expect("msg");
        let resp_bytes = wrap_response.bytes().await;
        let json_str = std::str::from_utf8(resp_bytes.unwrap()).unwrap();
        println!("{}", "wrap_response");
    } else {
        println!("Error: {}", response.unwrap_err());
    }
}

这一行let json_str = std::str::from_utf8(resp_bytes.unwrap()).unwrap();显示预期&[u8],发现Bytes。可以将Bytes转换为String吗?这是我的cargo配置:

[package]
name = "rust-learn"
version = "0.1.0"
edition = "2018"

[dependencies]
num-bigint = "0.2.1"
reqwest = { version = "0.11", features = ["json"] }
tokio = { version = "1.17.0", features = ["full"] }
serde = { version = "1.0.64", features = ["derive"] }
serde_json = "1.0.64"

来自服务器的响应可能看起来像这样:

{
   "result":{
      "id":4,
      "name":"template",
      "remark":"template",
      "created_time":0,
      "updated_time":0,
      "template_status":0,
      "template_id":1,
      "preview_url":"1",
      "template_code":null
   },
   "statusCode":"200",
   "resultCode":"200",
   "msg":"ok"
}

result/statusCode/resultCode/msg不可变,结果数据是动态的。

j2datikz

j2datikz1#

由于Bytes实现了Deref<Target = [u8]>,因此可以通过引用获得&[u8]

std::str::from_utf8(&resp_bytes.unwrap())

但是,这对于reqwest的内置JSON支持来说是多余的。

if response.is_ok() {
    let wrap_response = response.expect("msg");
    let json: serde_json::Value = wrap_response.json().await.expect("Response was not json");
    println!("{:?}", json);
}
plicqrtu

plicqrtu2#

可以将Bytes转换为String吗?这是我的cargo配置:
from_utf8是将字节转换为字符串,问题是将字节转换为字节。Bytes deref'到&[u8],所以你只需要&它:https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=83c784cd012b5e7db03bf1cf06763464

let json_str = std::str::from_utf8(&resp_bytes.unwrap()).unwrap();

虽然这比必要的要复杂得多,但reqwest::Responsetext()json()两个助手,所以如果你不需要原始字节,你可以直接使用它。
您还可以简化许多错误处理:

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = Client::new();
    let url = "https://jsonplaceholder.typicode.com/todos/1";
    let response = client.get(url).send().await;
    match response {
        Ok(r) => {
            // the return type of json() would normally be inferred
            // but I obviously don't have the schema so a generic 
            // value works well enough for now
            let r: serde_json::Value = r.json().await?;
            println!("{:?}", r);
        }
        Err(e) => println!("Error: {}", e)
    }
    Ok(())
}

相关问题