「Rust」カテゴリーアーカイブ

RUST勉強中、5/4の積み上げ

前回の続き。

前回作成したプログラムをテストするコードを書いていきます。

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_ok() {
        let calc = RpnCalculator::new(false);
        assert_eq!(calc.eval("5"), 5);
        assert_eq!(calc.eval("50"), 50);
        assert_eq!(calc.eval("-50"), -50);

        assert_eq!(calc.eval("2 3 +"), 5);
        assert_eq!(calc.eval("2 3 *"), 6);
        assert_eq!(calc.eval("2 3 -"), -1);
        assert_eq!(calc.eval("2 3 /"), 0);
        assert_eq!(calc.eval("2 3 %"), 2);
    }

    #[test]
    #[should_panic]
    fn test_ng() {
        let calc = RpnCalculator::new(false);
        calc.eval("1 1 ^");
    }
}

#[cfg(test)]はテストコードであることを示すアノテーション。

modはモジュールの意味。

#[test]がついた関数がテストコードとなる。

#[should_panic]をつけるとパニックを起こすことを確認するテストになる。

RUST勉強中、4/3の積み上げ

前回の続き。

コマンドラインで取得したファイルを読み出す処理、パラメータが無かったら標準入力から入力するコードです。

use clap::Parser;
use std::fs::File;
use std::io::{stdin, BufRead, BufReader};

#[derive(Parser, Debug)]
#[clap(
    name = "My RPM program",
    version = "1.0.0",
    author = "Your name",
    about = "Super awesome sample RPM calculator"
)]
struct Opts {
    #[clap(short, long)]
    verbose: bool,

    #[clap(name = "FILE")]
    formula_file: Option<String>,
}

fn main() {
    let opts = Opts::parse();

    if let Some(path) = opts.formula_file {
        // ファイルから読み出す
        let f = File::open(path).unwrap();
        let reader = BufReader::new(f);
        run(reader, opts.verbose);
    } else {
        // 標準入力から読み出す
        let stdin = stdin();
        let reader = stdin.lock();
        run(reader, opts.verbose);
    }
}

fn run<R: BufRead>(reader: R, verbose: bool) {
    for line in reader.lines() {
        let line = line.unwrap();
        println!("{}", line);
    }
}

Some()は変数がエラーを許容する書き方らしい。

つまりは、formula_fileに値があっても無くてもpathに挿入され、その値をif文で評価する、という作りになっている(と思う。)

unwrap()は関数の結果(Option<T>やResult<T>)からTの値を取り出す処理。

まぁ、これでも不完全の様なんだが、とりあえずここはテキストに従う。

Rust勉強中、3/27の積み上げ

この本を使用して勉強しています。

本日はコマンドラインから引数を取得する処理。

Clapを使用する方法が紹介されていたが、サンプルが古いのでそのまま使えず、結局公式のサンプルコードを見るハメに。

https://docs.rs/clap/latest/clap/

[dependencies]
clap = { version = "3.1.6", features = ["derive"] }
use clap::Parser;

#[derive(Parser, Debug)]
#[clap(
    name = "My RPM program",
    version = "1.0.0",
    author = "Your name",
    about = "Super awesome sample RPM calculator"
)]
struct Opts {
    #[clap(short, long)]
    verbose: bool,

    #[clap(name = "FILE")]
    formula_file: Option<String>,
}

fn main() {
    let opts = Opts::parse();
    match opts.formula_file {
        Some(file) => println!("File specified: {}", file),
        None => println!("No file specified."),
    }
    println!("Is verbosity specified?: {}", opts.verbose);
}

Clapを適用するには、Cargo.tomlの[dependencies]に一文を追加するだけでOK。

また、テキストではclap::Clapと書かれていたが、最新版ではclap::Parserが正解らしい。

置き換えたのはそれくらいか?

~/rust/samplecli$ cargo run
    Finished dev [unoptimized + debuginfo] target(s) in 0.01s
     Running `target/debug/samplecli`
No file specified.
Is verbosity specified?: false

~/rust/samplecli$ cargo run -- input.txt
    Finished dev [unoptimized + debuginfo] target(s) in 0.01s
     Running `target/debug/samplecli input.txt`
File specified: input.txt
Is verbosity specified?: false

~/rust/samplecli$ cargo run -- -v input.txt
    Finished dev [unoptimized + debuginfo] target(s) in 0.01s
     Running `target/debug/samplecli -v input.txt`
File specified: input.txt
Is verbosity specified?: true

~/rust/samplecli$ cargo run -- -h
    Finished dev [unoptimized + debuginfo] target(s) in 0.01s
     Running `target/debug/samplecli -h`
My RPM program 1.0.0
Your name
Super awesome sample RPM calculator

USAGE:
    samplecli [OPTIONS] [FILE]

ARGS:
    <FILE>    

OPTIONS:
    -h, --help       Print help information
    -v, --verbose    
    -V, --version    Print version information

~/rust/samplecli$ cargo run -- -d
    Finished dev [unoptimized + debuginfo] target(s) in 0.01s
     Running `target/debug/samplecli -d`
error: Found argument '-d' which wasn't expected, or isn't valid in this context

        If you tried to supply `-d` as a value rather than a flag, use `-- -d`

USAGE:
    samplecli [OPTIONS] [FILE]

For more information try --help

~/rust/samplecli$ cargo run -- input.txt input2.txt
    Finished dev [unoptimized + debuginfo] target(s) in 0.01s
     Running `target/debug/samplecli input.txt input2.txt`
error: Found argument 'input2.txt' which wasn't expected, or isn't valid in this context

USAGE:
    samplecli [OPTIONS] [FILE]

For more information try --help