## 目的
- [[Rust]]の理解を深める
- [[GTFS]]データを取得するCLIツールを作る
## ベース作成
- [[📜2021-02-28 RustのCLIツール開発用ベースプロジェクトを作る]]
- [x] CLIフレームワーク
- [x] Logger
- [x] Progressbar
- [x] Error Handling
- Tests
## CSVデータの読込
DBを使うかどうかによって方針は変わるが..、ひとまず[[RustでCSVをparseする]]を参考に[[GTFS-JP routes.txt]]を読み込んでみる。
```rust
use anyhow::{Context, Result};
use clap::Clap;
use env_logger::Env;
use log::{debug, info};
use serde::Deserialize;
use std::path::PathBuf;
// 中略。。
#[derive(Clap, Debug)]
struct ShowOpts {
#[clap(parse(from_os_str))]
input: PathBuf,
}
fn main() -> Result<()> {
env_logger::Builder::from_env(Env::default().default_filter_or("info")).init();
let opts: Opts = Opts::parse();
debug!("Options: {:?}", opts);
match opts.subcmd {
SubCommand::Show(op) => {
info!("Execute command show");
cmd_show(&op)?
}
}
Ok(())
}
#[derive(Debug, Deserialize)]
struct Route {
route_id: String,
agency_id: String,
route_short_name: Option<String>,
route_long_name: Option<String>,
route_desc: Option<String>,
route_type: String,
route_url: Option<String>,
route_color: Option<String>,
route_text_color: Option<String>,
jp_parent_route_id: Option<String>,
}
fn cmd_show(op: &ShowOpts) -> Result<()> {
let mut reader = csv::Reader::from_path(&op.input)
.with_context(|| format!("Could not read file {:?}", &op.input.to_str()))?;
for result in reader.deserialize() {
let route: Route = result?;
println!("{:?}", route);
}
Ok(())
}
```
使いやすいように関数にしておく。
```rust
fn read_routes(path: &PathBuf) -> Result<Vec<Route>> {
let mut reader = csv::Reader::from_path(path)
.with_context(|| format!("Could not read file {:?}", &path.to_str()))?;
let r = reader
.deserialize()
.map(|result| {
let route: Route = result.unwrap();
route
})
.collect::<Vec<_>>();
Ok(r)
}
```
より一般化したもの。
```rust
pub fn read<T>(path: &PathBuf) -> Result<Vec<T>>
where
T: DeserializeOwned,
{
let mut reader = csv::Reader::from_path(path)
.with_context(|| format!("Could not read file {:?}", &path.to_str()))?;
let r = reader
.deserialize()
.map(|result| {
let r: T = result.unwrap();
r
})
.collect::<Vec<_>>();
Ok(r)
}
```
## SQLiteに登録
[[RustでSQLiteを使う]]で紹介したlibraryを使う。ファイルが増えてきたので別ファイルに分ける。
## リポジトリを作った