リポジトリは zaneli-sandbox/rssss。
RSS の URL を入力してその場で内容を表示できるだけのもので、特に面白みもないが練習用という事で。
とりあえず、以下のRSSには対応できていそう。
- Qiita: http://qiita.com/tags/rust/feed.atom
- はてなブログ: http://staff.hatenablog.com/rss, http://staff.hatenablog.com/feed
- GitHub: https://github.com/zaneli-sandbox/rssss/commits/master.atom
- medium: https://medium.com/feed/@medium
- note: https://note.mu/info/rss
- Tumblr: https://staff.tumblr.com/rss
- YouTube: https://www.youtube.com/feeds/videos.xml?channel_id=UC4QobU6STFB0P71PMvOGN5A
- ニコニコ動画: https://www.nicovideo.jp/newarrival?rss=2.0
- 私の個人ブログ: https://www.zaneli.com/blog/rss
使ったものは
- Rust
- actix-web: Rust で Web アプリを書くならデファクトスタンダードかな、と思い。まだデファクトというほどのものが確立していないのかもしれないけれど。
-
xml-rs: XMLプルパーサ。serde_json のように
from_str()
とかで struct を作ってくれるようなやつが見つからなかったので面倒だったけど、各サービスによって微妙に要素名や構造が違っていたりしていたので取り回しが効いて良かったかもしれない。 -
scraper: RSSの
<description>
の値はHTMLタグを含んでいるので、そこから雑にテキストだけを取り出すために使用。
- Elm
- Create Elm App: Elm はもとよりフロントエンド・js文化も不慣れだったので雰囲気で使って雰囲気で動かしているが助かっている。
- CSS
以下、作っていてハマった事などをつらつらと。
[Rust] future の型合わせ
レスポンスステータスによって、RSSをパースするか否かを分ける処理をこのように書こうとしていたが、
let status = res.status();
if status.is_success() {
res.body()
.from_err()
.and_then(|b| match rss::parse_rss(b) {
Ok(r) => Ok(HttpResponse::Ok().json(r)),
Err(e) => Ok(e.into()),
})
} else {
future::ok::<HttpResponse, Error>(
HttpResponse::build(res.status()).finish(),
)
}
返す型が futures::AndThen
と futures::FutureResult
で異なるためコンパイルエラーとなった。
このあたり、 Scala と同じような感覚で書こうとしていてなかなかコンパイルを通すのに苦戦した。
Box
でくるんで何とかコンパイルを通したが、これが正攻法なのかどうかがイマイチよく分かっていない。
Future
に対する操作がそれぞれの型を返すのは、コンパイル時にサイズが決まっていないといけないとか、その辺の兼ね合いだろうか?
[Rust] エラーの型合わせ
以下の記事が参考になった。
…が、何とも面倒だなー、という印象が拭えない。
この辺は発展途上な部分なのかもしれないが。
[Rust] actix_web::client
の使い勝手
30x を返す際にリダイレクトに対応していなかった。
reqwest とかを使えばもう少し楽になったのかもしれないが、今回は練習という事で自分でリダイレクトを解決する処理を書いてみた。
(余談だが、せいぜいリダイレクト1回のみに対応すればええやろと思っていたところ、http://qiita.com/tags/Docker/feed.atom
には2回リダイレクトが必要だったため3回まで許容するようにした。)
また、Cargo.toml の dependencies に actix-web = { version="0.7", features=["ssl"] }
と指定しておかないと https リクエストが投げられなかったり。
この辺はまぁ、知ってしまえばそれまで系だが。
[Elm] ステータスコードによって Json Decoder を分けたい
200なら通常の型、40x系ならエラーメッセージ用の型、のように分けたかったが、
標準のexpectJsonは20x系しか扱えないようだった。
Twitterでも助言をもらい、Http.expectStringResponse
を呼んで Http.BadStatus_
, Http.GoodStatus_
を扱う処理を書く事で対処した。
[Elm] バージョン0.19未満の情報がヒットしたり、使えそうなライブラリが0.19対応してなかったり
悲しい。
…と、色々書いてはみたが、普段使わない言語で何か動くものを書いてみるのは凄く楽しかったし、書いてみて初めて躓く事も分かり良かった。
次は、DBアクセスしたり複数画面に渡る何かを作ってみようかな。
今回は Main.elm に全部押し込んだけど、ソースファイルの分け方もまだあまり分かっていない。
Rust や Elm の強い人の目に止まって、何かしら助言などいただけると幸いです。