0

我有测试,我需要将 JSON 数据发送到我的服务器。我有以下测试:

extern crate hyper;
extern crate rustc_serialize;

use std::io::Read;
use hyper::*;

#[derive(RustcDecodable, RustcEncodable)]
struct LegacyJsonRequest {
    jsonrpc: String,
    method: String,
    params: String,
    id: i32,
    auth: String,
}

#[test]
fn apiinfo_jsonrpc_tests() {
    let client = Client::new();

    let url = "http://localhost:6767/api_jsonrpc.php";

    let mut http_reader = header::Headers::new();
    http_reader.set_raw("Content-Type", vec![b"application/json".to_vec()]);

    //TODO: How to use a struct and 'export' it to a raw string literal???
    let request_data = LegacyJsonRequest {
        jsonrpc: "2.0".to_string(),
        method: "apiinfo.version".to_string(),
        params: "[]".to_string(),
        auth: "[]".to_string(),
        id: 1,
    };

    let encoded_request = rustc_serialize::json::encode(&request_data).unwrap();

    let mut response = client.post(url)
        .body(encoded_request)
        .send()
        .unwrap();

}

使用此代码,将返回以下错误:

error[E0277]: the trait bound `hyper::client::Body<'_>: std::convert::From<std::string::String>` is not satisfied

如果我删除 struct 和 JSON 编码的代码并创建一个简单的原始字符串文字并在 body 方法上引用它,它就可以工作。例子:

extern crate hyper;
extern crate rustc_serialize;

use std::io::Read;
use hyper::*;

#[derive(RustcDecodable, RustcEncodable)]
struct LegacyJsonRequest {
    jsonrpc: String,
    method: String,
    params: String,
    id: i32,
    auth: String,
}

#[test]
fn apiinfo_jsonrpc_tests() {
    let client = Client::new();

    let url = "http://localhost:6767/api_jsonrpc.php";

    let mut http_reader = header::Headers::new();
    http_reader.set_raw("Content-Type", vec![b"application/json".to_vec()]);

    let request_data =
        r#"{"jsonrpc":"2.0", "method": "apiinfo.version", "params": {}, "auth": {}, "id": "1"}"#;

    let mut response = client.post(url)
        .body(request_data)
        .send()
        .unwrap();

}

那么:如何将我的结构或 JSON 转换为原始字符串

我知道错误 E0277 是关于“Hyper::client::Body<'_>”的特征的实现,但是看,这不是问题;问题是:如何将结构或 JSON 转换为原始字符串,仅此而已。谢谢。

4

1 回答 1

2

我知道错误 E0277 是关于“Hyper::client::Body<'_>”的特征的实现,但是看,这不是问题;问题是:如何将结构或 JSON 转换为原始字符串,仅此而已。

100%不可能转换为原始字符串。

你看,一旦源代码被解析,“原始字符串”就不存在了——它们只是源代码的自负。无法将任何内容转换为原始字符串,因为它不存在可转换.

存在的只是字符串切片 ( &str) 和拥有的字符串 ( String)。

根据要求,这解决了 OP 的问题,仅此而已。欢迎任何对潜在问题的解决方案感兴趣的人继续阅读。


检查文档RequestBuilder::body,您可以看到它接受任何可以转换为的类型Body

impl<'a> RequestBuilder<'a> {
    fn body<B: Into<Body<'a>>>(self, body: B) -> RequestBuilder<'a>;
}

如果您随后查看 的文档Body,您将看到它存在哪些实现From

impl<'a, R: Read> From<&'a mut R> for Body<'a> {
    fn from(r: &'a mut R) -> Body<'a>;
}

再加上From暗示Into的知识,你知道你可以将任何实现的东西传递Readbody。实际上,编译器会在错误消息中告诉您这一点

error[E0277]: the trait bound `hyper::client::Body<'_>: std::convert::From<std::string::String>` is not satisfied
  --> src/main.rs:37:10
   |
37 |         .body(encoded_request)
   |          ^^^^ the trait `std::convert::From<std::string::String>` is not implemented for `hyper::client::Body<'_>`
   |
   = help: the following implementations were found:
   = help:   <hyper::client::Body<'a> as std::convert::From<&'a mut R>>
   = note: required because of the requirements on the impl of `std::convert::Into<hyper::client::Body<'_>>` for `std::string::String`

这就是问题所在 - 实际上有更多的方法可以转换为 a Body,并且文档没有显示它们1!查看源代码,您可以看到:

impl<'a> Into<Body<'a>> for &'a str {
    #[inline]
    fn into(self) -> Body<'a> {
        self.as_bytes().into()
    }
}

impl<'a> Into<Body<'a>> for &'a String {
    #[inline]
    fn into(self) -> Body<'a> {
        self.as_bytes().into()
    }
}

这意味着您可以传入对字符串的引用,然后将其转换为 a Body,就像vitalyd 猜测的一样:

let mut response = client.post(url)
    .body(&encoded_request)
    .send()
    .unwrap();

1我要看看这是否是已提交的问题,因为这肯定看起来不正确。

于 2017-02-20T21:44:56.897 回答