2017-02-20 90 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沒有很高的學習曲線;相反,它以簡單的方式解決問題,迫使我們思考新的可能性。 –

相關問題