如何将struct或JSON转换为原始字符串?

时间:2017-02-20 19:09:55

标签: string struct rust hyper

我有测试,我需要将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();

}

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

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

1 个答案:

答案 0 :(得分:2)

  

我知道错误E0277是关于&#34; Hyper :: client :: Body&lt;&#39; _&gt;&#34;的特性的实现,但是看,这不是问题;问题是:如何将结构或JSON转换为原始字符串,仅此而已。

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

你看,&#34;原始字符串&#34;一旦解析了源代码,就不存在 - 它们只是源代码的自负。无法将任何转换为原始字符串,因为将转换为并不存在。

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

这解决了OP的问题,仅此而已,如要求的那样。任何对解决潜在问题感兴趣的人都欢迎继续阅读。

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

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

如果您随后查看了documentation for Body,您会看到From的实现存在:

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

加上From implies Into的知识,您知道可以将实现Read的任何内容传递给body。实际上,编译器会在错误消息中告诉您

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`

这是问题 - 实际上更多转换为Body的方式,文档没有显示它们 1 !签出the source,您可以看到:

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()
    }
}

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

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

1 我要查看这是否已经存在问题,因为这肯定是不正确的。