2017-02-20 98 views
-1

我有测试,我需要发送JSON数据到我的服务器。我有以下测试:如何将结构或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 

如果我掉落结构和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()]); 

    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转换为原始字符串,仅此而已。谢谢。

+0

我建议你对这个错误信息的含义做进一步的研究。 – Shepmaster

+0

我刚刚添加了更多完整的示例。如果我可以将JSON或Struct对象转换为原始字符串,那么我不需要实现hyper :: client :: Body <'_>的特征。问题是关于转换。 –

回答

2

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

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

你看,一旦源代码已经被解析不存在“原始字符串” - 他们只是源代码的自负。没有办法将任何东西转换成原始字符串,因为它不存在将转换为

所有存在的都是字符串切片(&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,你知道你可以通过任何实施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` 

这是问题 - 实际上,有转换为Body的方式,和文档不显示他们!检查出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(); 

我打算查看这是否已提交的问题已经存在或不存在,因为这肯定看起来不正确。

+0

令人惊叹的答案。我今晚会尝试这个。直到现在,对我而言,Rust没有很高的学习曲线;相反,它以简单的方式解决问题,迫使我们思考新的可能性。 –

相关问题