## 目的 - [[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を使う。ファイルが増えてきたので別ファイルに分ける。 ## リポジトリを作った