rust-script(https://rust-script.org/)を使うとRustのソースコードをスクリプトとして実行できます。Rust 1.54以上が必要です。
今回は公式のマニュアル(上記URL)からいくつか抜粋して説明します。
以下の説明はUNIX系OSで実行することを前提としています。
インストール
cargo
をインストールしていれば、1コマンドで済みます。
$ cargo install rust-script
スクリプトを書く
cargo new
でプロジェクトを作ってRustを書くときは依存クレートをCargo.toml
に記載しますが、rust-script
の場合は//!
から始まる行に記載します以下にコード例を示します。
1ファイルで完結するので気軽です。
#!/usr/bin/env rust-script //! 2つの塩基配列をコマンドライン引数をとして受け取りローカルアラインメントするプログラム //! //! ```cargo //! [dependencies] //! bio = "1.1.0" //! ``` //! //! use bio::alignment::pairwise::Aligner; fn main() { let args: Vec<String> = std::env::args().collect(); if args.len() < 3 { panic!("Please specify two arguments"); } let seq1 = args[1].as_bytes(); let seq2 = args[2].as_bytes(); let score = |a: u8, b: u8| if a == b { 1i32 } else { -1i32 }; let mut aligner = Aligner::new(-5, -1, &score); let alignment = aligner.local(seq1, seq2); println!("{}", alignment.pretty(seq1, seq2)); }
実行する
あとは他のスクリプト言語のスクリプトと同じようにファイルに実行権限を付与するまたはrust-script
コマンドに渡してあげれば実行できます。
コードを編集して一回目の実行はコンパイルが発生するので多少時間がかかりますが、コンパイル結果はキャッシュされるので二回目以降ははやいです。
$ chmod +x main.rs $ ./main.rs AATGGCAGGACCA ATGGACCAGGA # rust-script main.rs でもOK AATGGCA GGACCA |||||| ATGGACCAGGA
ワンライナー
ワンライナーも-e
オプションで書けます。依存関係は --dep
で指定します。
$ rust-script -e '2_f32.sqrt()' 1.4142135 $ rust-script --dep rand -e 'rand::random::<i32>()' 610692028
フィルター
Perlで標準入力の正規表現マッチ行だけを出力するといったことをする場合、
$ cat main.rs | perl -ne 'print if /^\/\/!/' //! ```cargo //! [dependencies] //! bio = "1.1.0" //! ``` //!
となると思います。
これをrust-script
でやると、--loop
オプションとクロージャを用いて、
$ cat main.rs | rust-script --dep regex --loop 'let re = regex::Regex::new(r"^//! ").unwrap(); move |l| if re.is_match(l) { print!("{l}") }' //! ```cargo //! [dependencies] //! bio = "1.1.0" //! ``` //!
となります。
Perlの方が簡潔ですが場合によってはRustの方が便利といったことがあるかもしれません。ただしTemplate機能を使えば多少は簡潔に書けるかもしれません。詳しくは公式マニュアルを参照してください。
snakemakeとの連携
rust-script
で実行できるファイルはsnakemake
のスクリプトとしても使用できます。このとき、Rustコード側ではsnakemake
インスタンスからinput
やoutput
、params
等で指定した値を参照できます。詳しくはこちら。
rule all: input: "some_input.txt", output: "some_input.txt", params: "some_params", script: "rust_code_for_some_analysis.rs"