ブログエンジンPlumeの日本語全文検索対応をします。
先週はプルーフオブコンセプトまで行ったので、今日は設定などでトークナイザーを切り替え可能にするのが目標です。
の続き。
目標
Plumeのトークナイザーを環境変数で切り替えられるようにする できれば、日本語全文検索が不要な人は、インストールしないで済むようにしたい
特定のトークナイザーが入ったやつと全部入りのDockerイメージができるのがいいのではないかと思ってる
設定方法
plume-models/src/config.rsでやる
タグ、本文、プロパティそれぞれのトークナイザーが設定可能にする
プロパティはいらないかも
SearchTokenizerConfig構造体を作って、タグ、本文、プロパティそれぞれのトークナイザーを持たせることにする
内容を環境変数で設定する時って、どういう関数名がいいんだろう。
env_logger::init();だった。
SearchTokenizerConfig::init()でいいだろうか。
構造体のフィールドの型にトレイトを指定したい
code:plume-models/src/config.rs
struct SearchTokenizerConfig {
pub tag_tokenizer: dyn tokenizer::Tokenizer,
pub content_tokenizer: dyn tokenizer::Tokenizer,
pub property_tokenizer: dyn tokenizer::Tokenizer,
}
とかやると怒られる。
code:shell
errorE0277: the size for values of type (dyn tantivy::tokenizer::Tokenizer + 'static) cannot be known at compilation time --> plume-models/src/config.rs:194:5
|
194 | pub tag_tokenizer: dyn tokenizer::Tokenizer,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait std::marker::Sized is not implemented for (dyn tantivy::tokenizer::Tokenizer + 'static)
= note: only the last field of a struct may have a dynamically sized type
error: aborting due to previous error
error: could not compile plume-models.
怒られるのは分かるがどう直したらいいものか。
と思ったけど、TokenizerトレイトじゃなくてTextAnalyzer構造体でよかった。
plume-models/src/config.rs内でトークナイザーを初期化したかったけど、plume-models/src/search/tokenizer.rsがプライベートだなあ。そっち側で初期化したほうがいいんだろうか。
pub(crate)にして解決できたけど、configとsearchが同じクレートなのは殆ど偶然で、いつ壊れてもおかしくない関係なのではと思っている。
あと、実際使う時は各トークナイザーをclone()しないといけないので無駄感がある。
文字列で設定を保存しておいて、実際使う時にそれを元に初期化するようにしよう
感想
Resultとパターンマッチの組み合わせで時間を食った
Clone、Copyの違いなど基本的な知識で時間を食った
列挙型にトレイトを実装する方法を覚えた
あまりよくない方法でも、一度動くまで実装しておくと、直後のリファクタリングは素早くできる
Fromみたいな基本的なトレイトを実装できると、Rustレベルが上がった感じがする