本文目錄:
- 簡介
- 快速通道
- 翻譯--curl庫
- easy模塊
- multi模塊
1. 簡介
雖然這個系列是屬於Rust使用庫翻譯計劃的系列之一,可是因爲該庫官網提供的使用文檔幾乎等於沒有,因此本文其實是簡單翻譯一下api文檔後小生本身寫的使用文檔,Orz。html
2. 快速通道
全部的翻譯文章將集中導航於:Rust經常使用庫翻譯計劃git
3.翻譯——curl庫
curl庫github快速通道
配套翻譯之curl中文apigithub
該庫主要實現了網絡通訊中做爲客戶端會使用到的幾乎全部的函數,其中經常使用的遇到的需求,幾乎均可以使用easy模塊來實現。在easy模塊中總共定義了八個Struct,十個枚舉以及數不清的函數,其中函數按照功能大概能夠分爲如下幾類:api
- 配置類函數
- 構建類函數
- 信息獲取類
- 純粹操做類
- 回調類函數
其中配置類函數佔了絕大多數,這類函數主要用於設置發送請求時的請求頭、驗證信息等等一系列的配置選項,幾乎所有是返回 Result<(), Error>,因此幾乎等於沒有返回值,直接每一個函數調用後unwrap一下就能夠了。構建類函數主要就是new和transfer,返回一個結構體實例。信息獲取類函數即調用後獲取頭信息之類的相關信息的函數.純粹操做類的函數即相似於perform這類,調用後會直接將請求發出,返回無心義的Result<(), Error>,也不須要傳入參數,只是單純的提示系統該執行某個操做了。最後回調類函數即便相似write_function這類,接受一個閉包做爲參數,在執行固定操做完成後便會調用該閉包函數。服務器
示例一:簡單入門
extern crate curl; use curl::easy::Easy; use std::io::{ Write, stdout }; fn main() { let mut easy = Easy::new(); easy.url("http://juejin.im").unwrap(); easy.write_function(|data| { Ok(stdout().write(data).unwrap()) }).unwrap(); easy.perform().unwrap(); }
這個例子中使用了curl庫,而且使用了easy模塊的命名空間,首先使用new函數新建了一個easy實例,而後經過url函數設置了訪問的主機地址,而後繼續設置了拉取到數據後的回調函數write_function,傳入一個閉包函數,參數data即爲服務器返回的數據,該閉包返回一個Result<usize, WriteError> + Send + 'static,因此直接一條語句順便輸出了服務器返回的data,而後調用perform函數,讓請求正式發出。結果以下: 網絡
能夠看出確實獲取到了服務器的返回的數據,不過因爲服務器作了3xx重定向,致使拉取到了一個無心義的重定向之前的頁面,因此要設置讓系統跟隨頭文件的設置一塊兒跳轉閉包
示例二:跟隨重定向
extern crate curl; use curl::easy::Easy; use std::io::{ Write, stdout }; fn main() { let mut easy = Easy::new(); easy.nobody(true).unwrap(); easy.url("http://juejin.im").unwrap(); easy.follow_location(true).unwrap(); easy.write_function(|data| { Ok(stdout().write(data).unwrap()) }).unwrap(); easy.perform().unwrap(); println!("last_Url:{:?}",easy.effective_url().unwrap().unwrap()); println!("response_code:{:?}",easy.response_code().unwrap()); println!("http_connectcode:{:?}",easy.http_connectcode().unwrap()); println!("filetime:{:?}",easy.filetime().unwrap()); println!("total_time:{:?}",easy.total_time().unwrap()); }
這個例子中,經過follow_location配置設置了跟隨重定向跳轉,因此能夠獲取到掘金首頁的html,不過因爲內容過大,影響觀看,因此這裏調用了nobody函數,配置不返回body體,而後順便在結束後打印出一部分相關的信息。curl
示例三:關於回調函數
fn main() { let mut easy = Easy::new(); easy.url("http://www.yzyxw.online/api/round/getQuestion").unwrap(); easy.post(true).unwrap(); //easy.nobody(true).unwrap(); easy.header_function(|data| { print!("header: {}", str::from_utf8(data).unwrap()); true }).unwrap(); easy.write_function(|data| { Ok(stdout().write(data).unwrap()) }).unwrap(); easy.read_function(|into| { Ok(stdin().read(into).unwrap()) }).unwrap(); easy.perform().unwrap(); }
這裏分別實現了讀寫和頭三個回調,其中頭回調函數會在得到http頭的是後將頭信息做爲參數傳入閉包中,這裏打印出了頭信息,write回調會在得到服務器返回數據後調用閉包,將服務器返回數據傳入閉包參數中。特別說明:若是設置了show_header(true),那麼返回信息中會同時包含頭信息。。關於讀回調,主要是用於設置訪問服務器時攜帶數據的方式之一,將標準輸入數據拷貝僅回調的參數中,該數據將會被攜帶至服務器,爲了能攜帶數據,這裏將訪問模式這是成了post。函數
固然,因爲這裏的操做都是從標準輸入輸出中讀取的,在回調閉包中,對外部變量的借用是不被容許的,在回調外定義一個數據,在讀回調中使用時不容許的,就像這樣: {% codeblock lang:rust %} let mut info = &b"tasdasdadad"[..]; easy.read_function(|data| { Ok(info.read(data).unwrap()) }).unwrap(); easy.perform().unwrap(); {% endcodeblock %} 結果: post
對於這種狀況,該庫引入了Transfer,使用transfer()會返回一個transfer實例,該實例擁有着對easy實例的一個可變借用,因此在調用該函數後一直到transfer生命週期結束前都不能夠再使用easy句柄來進行一些操做,因此能夠選擇用大括弧將對應語句段包括起來,人爲控制其生命週期。transfer一樣實現了easy中全部的回調函數,用transfer能夠實現上述不能實現的功能:
關於Transfer:
fn main() { let mut easy = Easy::new(); easy.url("http://www.yzyxw.online/api/round/getQuestion").unwrap(); easy.post(true).unwrap(); //easy.nobody(true).unwrap(); easy.header_function(|data| { print!("header: {}", str::from_utf8(data).unwrap()); true }).unwrap(); easy.write_function(|data| { Ok(stdout().write(data).unwrap()) }).unwrap(); let mut info = &b"tasdasdadad"[..]; let mut tran=easy.transfer(); tran.read_function(|data| { Ok(info.read(data).unwrap()) }).unwrap(); tran.perform().unwrap(); }
這時即可以在閉包內獲取外部上下文引用
僞結語
在easy模塊中共定義了七個回調設置函數,使用方式大同小異,剩下即是相關ssl驗證,代理設置等等一系列的操做,基本全是經過一系列的設置函數實現的,就不一一贅述了。感興趣的pong友們能夠參考我簡單翻譯的api傳送門,也能夠參考官網比較詳盡的英文api傳送門. 對於該庫另外一個模塊multi將在本文的下篇部分詳細解釋,同時也將整合各個api製做一份綜合實例給喜歡Rust這門目前比較小衆的語言的pong友們。 另外,更多Rust庫翻譯請關注Rust實用庫翻譯計劃