Mac の人気なランチャーアプリ Alfred のワークフローを Rust を使って作成する方法についてご紹介します。
今回は Qiita の記事を検索するワークフローを作成します。以下の記事を参考にさせていただきました。
プログラムを作成する
alfred というクレートを使用します。これは Alfred が読み込める形の JSON を簡単に作成できるクレートです。キーワードをコマンドライン引数で受け取って、Alfred が読み込める形の JSON を標準出力に出力するコードを作成します。
use chrono::{DateTime, FixedOffset};
use serde::Deserialize;
# [derive(Deserialize, Debug)]
struct QiitaItem {
title: String,
user: QiitaUser,
url: String,
created_at: String,
}
# [derive(Deserialize, Debug)]
struct QiitaUser {
id: String,
}
// Qiita から返ってきた日時(文字列)を日本時間(文字列)にフォーマット
fn format_date(date_string: &str) -> String {
DateTime::parse_from_rfc3339(date_string)
.ok()
.map(|date| {
date.with_timezone(&FixedOffset::east(9 * 3600)) // +9時間
.format("%Y/%m/%d %H:%M")
.to_string()
})
.unwrap_or("".to_owned())
}
fn main() {
let args: Vec<String> = std::env::args().skip(1).collect();
if args.len() == 0 {
return;
}
let search_word = args.join(" ");
let access_token = match std::env::var("QIITA_ACCESS_TOKEN") {
Ok(x) => x,
_ => return,
};
// Qiita の検索 API を実行
let qiita_items: Vec<QiitaItem> = ureq::get(&format!(
"https://qiita.com/api/v2/items?query=body:{}",
search_word
))
.set("Authorization", &format!("Bearer {}", access_token))
.call()
.ok()
.and_then(|res| res.into_json().ok())
.unwrap_or(vec![]);
// 取得したデータを Alfred が読み込めるように変換
let alfred_items: Vec<_> = qiita_items
.into_iter()
.map(|qiita_item| {
alfred::ItemBuilder::new(qiita_item.title)
.subtitle(format!(
"@{} {}",
qiita_item.user.id,
format_date(&qiita_item.created_at)
))
.arg(qiita_item.url)
.icon_path("./icon.png") // ワークフローに設定されているアイコンを使用する
.into_item()
})
.collect();
// JSON データを標準出力へ出力
alfred::json::write_items(std::io::stdout(), &alfred_items).ok();
}
- 軽量な HTTP クライアント ureq を使用しています。
- ワークフローには環境変数を設定することができます。アクセストークンは環境変数から受け取るようにしています。
[package]
name = "alfred-qiita-search"
version = "0.1.0"
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
alfred = "4.0.2"
ureq = { version = "2.1.1", features = ["json"] }
serde = { version = "1.0.126", features = ["derive"] }
chrono = "0.4"
Alfred でワークフローを作成する
空ワークフローを新規作成します。
ワークフローの情報を記述します(ここでアイコンも設定しておきます)。
ワークフローに Inputs > Script Filter
を追加します。
キーワードなどと一緒に以下のスクリプトを入力します。
query=$1
./alfred-qiita-search $query
ワークフローに Actions > Open URL
を追加します(何も設定せずそのまま保存します)。
Script Filter
と Open URL
を接続します。
環境変数を設定します(右上の [Χ]
のようなアイコンから設定できます)。
バイナリを配置する
リリースビルドしてバイナリをワークフローのディレクトリ下に配置します。
$ cargo build --release
$ cp ./target/release/alfred-qiita-search ~/Library/Application\ Support/Alfred/Alfred.alfredpreferences/workflows/user.workflow.{上で作成したワークフローのUUID}/
※ワークフローのディレクトリは以下からターミナルで開くことができます。
以上でワークフローの作成は完了です。qiita
のプレフィックスの後にキーワードを入力するとその内容で検索をしてくれます。