プログラミング言語の Rust をインストールすると、 Cargo というライブラリ管理ツールが付いてくる。 Cargo はイマドキに言うとパッケージ・マネージャーというやつで、 Rust ではそのパッケージのことを crate (クレート) と呼んでいる。 crate は英語で木箱という意味で、 cargo は積み荷という意味らしい。

Cargo
Cargo

Cargo は新しくプログラムを書き始めるときにも有用で、 cargo コマンドを実行することでプロジェクトの雛形を作ることができる。 cargo コマンドはいくつかのファイルを自動で生成してくれる。

今回の環境

Mac OS X El Capitan + Rust 1.9.0

参考: [ヅ] プログラミング言語 Rust のインストールと Hello World (Mac OS X) (2016-04-04)

Cargo でプロジェクトの雛形をつくる

今回は、 hello という名前でプロジェクトを作って、ビルド&実行してみる。

まずは cargo new コマンドを打ってプロジェクトの雛形をつくる。


$ cargo new hello --bin

$ cd hello/

$ tree
.
├── Cargo.toml
└── src
    └── main.rs

Cargo.toml には、作成するプログラムの名称やバージョンを記述できる。 authors の項目には Git の設定ファイル ~/.gitconfig の情報が自動的に入るようだ(たぶん)。外部ライブラリ (crate) を使いたい場合は [dependencies] セクションに書く。


$ cat Cargo.toml 
[package]
name = "hello"
version = "0.1.0"
authors = ["Nick Labadie <info@nilab.info>"]

[dependencies]

src/main.rs ファイルにメイン処理が書かれている。


$ cat src/main.rs 
fn main() {
    println!("Hello, world!");
}

cargo run コマンドを打つと、ビルドしてから実行してくれる。 hello world が表示された。


$ cargo run
   Compiling hello v0.1.0 (file:///Users/hoge/hello)
     Running `target/debug/hello`
Hello, world!

プロジェクトに外部ライブラリを導入してみる

HTTP通信がしたいと思ったが、ざっと見たところ Rust にはそのあたりのライブラリが無さそう。Socket ライブラリはあったけど、さすがにそこから書くのはしんどい。

調べてみると、HTTP 通信には hyper という crate がよく使われているらしい。

cargo search コマンドで検索。


$ cargo search "hyper"
    Updating registry `https://github.com/rust-lang/crates.io-index`
hyper (0.9.6)             A modern HTTP library.
hyper-router (0.1.2)      Simple routing middleware for Hyper http library.
hyper-socks (0.2.1)       SOCKS proxy support for Hyper clients

Cargo の Web サイト hyper - Cargo にも情報がある。

Cargo.toml の [dependencies] セクションに「hyper = "0.9.6"」を追加。


$ cat Cargo.toml 
[package]
name = "hello"
version = "0.1.0"
authors = ["Nick Labadie <info@nilab.info>"]

[dependencies]
hyper = "0.9.6"

HTTP 通信するサンプルコードを用意する。はてブのホッテントリの RSS フィードを取得して出力するだけのプログラム。


$ cat src/main.rs

extern crate hyper;
use std::io::Read;
use hyper::Client;
use hyper::client::response::Response;
use hyper::error::Result;

fn get_feed(url: &str) -> Result<Response> {
    let client = Client::new();
    let rb = client.get(url);
    let result = rb.send();
    return result;
}

fn main() {
    let url = "http://feeds.feedburner.com/hatena/b/hotentry";
    let feed = get_feed(url);
    match feed {
        Ok(mut v) => {
            println!("Status Code: {}", v.status);
            println!("Headers:\n{}", v.headers);
            let mut body = String::new();
            v.read_to_string(&mut body).unwrap();
            println!("Body:\n{}", body);
        }
        Err(e) => {
            println!("Error: {}", e);
        }
    }
}

cargo build コマンドを実行すると、依存ライブラリを自動でダウンロードしてコンパイルしてくれる。自分の hello プロジェクトもビルドされる。


$ cargo build
    Updating registry `https://github.com/rust-lang/crates.io-index`
 Downloading hyper v0.9.6
 Downloading cookie v0.2.4
 Downloading log v0.3.6
(中略)
   Compiling lazy_static v0.2.1
   Compiling matches v0.1.2
   Compiling rustc-serialize v0.3.19
(中略)
   Compiling cookie v0.2.4
   Compiling openssl-verify v0.1.0
   Compiling hyper v0.9.6
   Compiling hello v0.1.0 (file:///Users/hoge/hello)

cargo run コマンドを打つ。今回は cargo build コマンドでビルド済みなので、ビルド処理は走らずに、プログラムが実行される。


$ cargo run
     Running `target/debug/hello`
Status Code: 200 OK
Headers:
X-Content-Type-Options: nosniff
Server: GSE
Vary: Accept-Encoding
Last-Modified: Tue, 07 Jun 2016 22:44:58 GMT
Cache-Control: private, max-age=0
Accept-Ranges: none
Expires: Tue, 07 Jun 2016 22:45:01 GMT
Content-Type: application/xml; charset=UTF-8
X-XSS-Protection: 1; mode=block
Transfer-Encoding: chunked
Date: Tue, 07 Jun 2016 22:45:01 GMT

Body:
<?xml version="1.0" encoding="UTF-8"?>
(以下略)

ここまでできれば、外部ライブラリを利用した Rust のプログラム開発が可能になるはず。

tags: rust

Posted by NI-Lab. (@nilab)