どこに需要があるのか全くわからない。
1. 勝手にいい感じに条件で分けて、勝手にいい感じにデフォルト値のフィルターしてくれる子
まあ、割とコンセプトとしては条件分岐がめんどくさかったから、と言う感じ。公式 Repo のソースにはないけど、以下のような感じを想定した。
timelines - Mastodon documentation
func compareVersion(_ target: String, greaterThanOrEqualTo value: String) -> Bool { value.compare(target, options: .numeric) != .orderedDescending } @HttpParameterBuilder func getParameterDefines(version: String) -> [HttpParameter] { HPBool("local", default: false) if compareVersion(version, greaterThanOrEqualTo: "3.1.4") { HPBool("remote", default: false) } if compareVersion(version, greaterThanOrEqualTo: "2.3.0") { HPBool("only_media", default: false) } HPInt("limit", default: 20, in: 1...40) HPString("test", default: "日本語<も>\t含めてみます。", suppressDefault: false) HPPattern { HPSet { HPString("since_id") } optionals: { HPString("max_id") } if compareVersion(version, greaterThanOrEqualTo: "3.3.0") { HPSet { HPString("min_id") } optionals: { HPString("max_id") } } else if compareVersion(version, greaterThanOrEqualTo: "2.6.0") { HPSet { HPString("min_id") } } HPSet { HPString("max_id") } } } let def220 = getParameterDefines(version: "2.2.0") let def300 = getParameterDefines(version: "3.0.0") let def330 = getParameterDefines(version: "3.3.0") let params: [String: AnyHashable] = [ "local": true, "only_media": true, "limit": 40, "since_id": "1234", "max_id": "3456", "min_id": "3456", ] do { let q = try def300.query(params) let x = try def300.xml(params, root: "params") let j = try def300.json(params) let n = try def300.msgpack(params) } catch { print(error.localizedDescription) }
なぜか知らないけど、Query だけ必要だけど、気がついたら、XML も JSON も MessagePack も実装してた。まあ気が向いたら、BSON とか CBOR、BinaryMesasge とか手当たり次第対応するかも。
まあその前に、HPArray で Array 構造ブチ込めるようにすべきなんだろうけど、まだ未対応です。
2. 3 日ぐらいで書いた
元々の構想自体はあって、事前検証を組んで、あとはパラメーターをくみ出すっていう流れだったんですけど、途中で
.o0(モノトーンよ、SwiftUI
でも使っている resultBuilder 使ってみないか)
※ Swift 5.4? あたりで _functionBuilder
から resultBuilder
に名前変わったっぽいです。
っていう声が聞こえてきたんですよ。まあそれからずっと本題からそれで書いてました。最初は playground ベースで書いてたんですけど、いい感じにまとまってきたので、Swift Package 化しておきました。
3. 色々と危うい実装
本当は、HPPattern
の場合、不必要な変数がある場合、例外とか投げれればよかったんですが、設計的にだるかったので、何も応答なしで、ただ単に出力として吐き出さない形になってます。個人的にこれ以上、このプロジェクトに時間を取られたくなかったので、公開するにあたって必死にテスト書いてましたw
あとは、本当は内部構造的に共通化できる部分があるので、綺麗に書きたかったんですが、まあ上でも述べた通り時間取られたくなかったので、割と共通化できるのにしてないところあります。
内部には、Query のエンコード、XML の String
エンコード、JSON の String
エンコード、そして MessagePack のエンコードが実装されていますが、一応 spec 参照しましたが、テスト書いてないので、ちゃんと動くか知りません。まあ手元では動いてるので、大丈夫って感じで通してます。
と言うことで、言い訳を並べてみましたが、PR 大歓迎です。ポータブルで取り回しやすさを意識して書いた割には結構デカくなってしまいました。デコードはまあ、Codable
ですると思うので、ないです。一応 Codable に対応してる、フォーマット類のリンク貼っておきますね。
MessagePack
CBOR
最後に
作ったのはいいけど、やっぱり捨てるかもしれないレベルのプロダクトです。
もっといい感じの書き方ありますかねぇ? なんかデータ構造で上手く条件も表現しつつ、かつコンパイル時検証可能みたいな感じのコードがパッと思いつかなくて、もっといい方法があると思うんですけどね。
そんな疑問を思いながらコードを書き続けてたらできたものでした。