◇rustで時刻処理をするcargo,crateプロジェクト
単純コンパイル
rustで標準入力から1行ずつ読むには次の様にします。
// readStdin.rs
use std::io::{BufRead,BufReader};
fn main() {
let _file = std::io::stdin();
for _result in BufReader::new(_file).lines(){
if let Ok(_line) = _result {
let _chars: Vec = _line.chars().collect();
for _c in _chars {
print!("{}",_c);
}
println!("{}","");
}
}
}
このプログラムでは読み込んだ1行の文字列を文字配列にして1文字ずつ標準出力に表示しています。
次の手続きでコンパイルできます。
rustc readStdin.rs
rustコンパイラのインストール法は以前の記事
rustコンパイラ・メモ
を参照してください。
プロジェクト(パッケージ)を作りコンパイルする
極めて単純なプログラムの場合rustcコンパイラのみで作成できますが、通常はクレートと呼ばれるライブラリをリンクする必要があり、その為にはcargoコマンドを用いてプロジェクトフォルダ(パッケージフォルダ)を作成し、ビルドします。
ここでは、標準入力から読み込んだテキスト中の10桁の数値をunixEpochと解釈し時刻文字列に変換するプログラムをビルドする例を載せます。
プログラムは次のものです。
#![allow(non_snake_case)] use std::io::{BufRead,BufReader}; extern crate chrono; use chrono::prelude::*; fn printNumber(numbers_:&mut Vec<char>){ if numbers_.len() > 0 { let _num: String = numbers_.iter().collect(); if numbers_.len()==10 { let _timestamp:i64 = _num.parse::<i64>().unwrap(); let _naive:NaiveDateTime = NaiveDateTime::from_timestamp(_timestamp+9*3600, 0); print!("{}",_naive); } else{ print!("{}",_num); } } } fn main() { let _file = std::io::stdin(); for _result in BufReader::new(_file).lines(){ let mut _numbers:Vec<char>=Vec::new(); if let Ok(_line) = _result { let _chars: Vec<char> = _line.chars().collect(); for _c in _chars { if _c >= '0' && _c <= '9'{ _numbers.push(_c); } else{ printNumber(&mut _numbers); print!("{}",_c); _numbers.clear(); } } printNumber(&mut _numbers); println!("{}",""); } } }
プロジェクトフォルダを作る;cargo new
ここでは名前convUnixEpochでプロジェクトフォルダを作成します。なお、最終的な実行形式ファイルも同じ名前とします。
$ cargo new convUnixEpoch Created binary (application) `convUnixEpoch` package $ tree convUnixEpoch convUnixEpoch |-- Cargo.toml `-- src `-- main.rs
指定名のフォルダの下に
が作成されます。
設定ファイル : Cargo.tom ソースファイル : src/main.rs
Cargo.tomlの編集
chronoクレートを使用するのでCargo.tomlの[dependencies]にchronoを追加します。
[package]
name = "convUnixEpoch"
version = "0.1.0"
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
chrono = "0.4"
0.4はおまじないです。
main.rsを修正しコンパイル
main.rsには初期状態で次のコードが入っています。
fn main() { println!("Hello, world!"); }
これを実際のプログラムに置き替えます。
cargo build --releaseコマンドでコンパイルします。
$ cargo build --release Compiling convUnixEpoch v0.1.0 (/tmp/convUnixEpoch) Building [ ] 0/1: convUnixEpoch(bin) warning: crate `convUnixEpoch` should have a snake case name | = note: `#[warn(non_snake_case)]` on by default = help: convert the identifier to snake case: `conv_unix_epoch` Building [ ] 0/1: convUnixEpoch(bin) warning: 1 warning emitted Building [ ] 0/1: convUnixEpoch(bin) Finished release [optimized] target(s) in 0.43s
targetフォルダが生成され、実行形式convUnixEpochが生成されます。
ここで生成される"convUnixEpoch"という名はCargo.tomlの"name"で指定した名です。
$ tree convUnixEpoch
convUnixEpoch
|-- Cargo.lock
|-- Cargo.toml
|-- src
| `-- main.rs
`-- target
|-- CACHEDIR.TAG
`-- release
|-- build
|-- convUnixEpoch
|-- convUnixEpoch.d
|-- deps
| |-- convUnixEpoch-ee50e58cbc8026cb
| `-- convUnixEpoch-ee50e58cbc8026cb.d
|-- examples
`-- incremental
実行形式をビルドしリリース
生成されたtarget/release/convUnixEpochは別途ライブラリなどを用意せずそれだけで実行できます。
ここではビルドを行い実行形式をbinフォルダに移動、不要なファイルを削除するスクリプトを示します。
#!/bin/bash # UTF-8,LF cargo build --release if [ $? -ne 0 ];then echo "エラー発生" exit 1 fi mkdir -p bin echo convUnixEpoch を bin/ へ移動 mv target/release/convUnixEpoch bin rm -rf target
次のフォルダ構造となります。
$ tree convUnixEpoch convUnixEpoch |-- A00_clear.sh |-- A01_build.sh |-- A05_test.sh |-- Cargo.lock |-- Cargo.toml |-- bin | `-- convUnixEpoch |-- reference.txt `-- src `-- main.rs
単純な試験スクリプトを用意しました。予め作成しておいたreference.txtと結果を比較します、
#!/bin/bash # A05_test.sh # UTF-8,LF bin/convUnixEpoch << EOF | tee kekka.txt abcd1621491776eof1621491738xyz 16214917411621491745 1621491741#1621491745 ABC123XYZ EOF echo diff kekka.txt reference.txt diff kekka.txt reference.txt if [ $? -eq 0 ];then echo OK else echo NG fi
ソースセットのダウンロード
この記事の本旨は、cargo newによりプロジェクトフォルダを生成する所からビルドすることですが、念のためconvUnixEpochの内容をzip化しました。
次のリンクでダウンロードできます。
convunixepoch.zip
内容は次のものです。
convUnixEpoch/ |-- A00_clear.sh |-- A01_build.sh |-- A05_test.sh |-- Cargo.lock |-- Cargo.toml |-- reference.txt `-- src `-- main.rs
| 固定リンク