文字列型に対して FooBarArray のような名前を付けるのはやっぱり違和感あるな……
可変長の文字列に対して FooStr (unsized) と FooString (ヒープ使用) を用意するのはいいんだけど。
固定長の (しかも短い) 文字列に対して BarString (内部的に [u8; N]) というのを用意するのはあまりよろしくない気がしている
何故よろしくないかというと、 string slice に対して &BarString のような型を使うことになるけど、これ名前から受ける印象として &[u8] や &str よりは &Vec<u8> や &String のようなものに見えてしまうのよね
かといって BarArray というのも Bar そのものの配列のように見えるし、 〜Buf でも PathBuf の例があるから変わらないし、 BarStringFixedLen みたいな名前にすると冗長だしあまり改善されているようにも感じないし……
さらにややこしい問題に気付いてしまった。
unsized な struct BarStr([u8]); をなくして fixed length な struct BarString([u8; N]); に統合すると、 &[u8] から &BarString が欲しい場合と BarString が欲しい場合の区別が面倒になる……
・BarStr が文字列やバイト列の所有権を持たないことを明確化したい
・BarStr が固定長であることを明示して最適化や検査を行いたい
・ToOwned / Borrow のためには (BarStr でなく) &BarStr がポインタであってほしい
一体どうすれば……
struct BarStr([u8; N]); に対して Clone と Copy を実装しないという手はどうだ?
しかしなぁ、うーん……
let s: &BarStr = BarStr::from_bytes("12:34");
から
let v: BarStr = *s;
ができないでほしいんだけど、こればかりは Clone と Copy を外しても防げないんだよなぁ
struct BarStr([u8]);
するとその辺りの問題は回避できる (つまり所有権を持たないことは保証できる) んだけど、今度は逆に &BarStr が fat pointer になるので Box<BarStr> が必要なサイズの倍になるのよね。
文字列長とかコンパイル前に確定してるのでそんなものを実行時に保持したくないんだけど
根本的なデザインとして、 &BarStr は何らかの既存のバッファの部分バイト列に対する view であってほしいという前提があって、だからこそ勝手に値がコピーされて「気付けば与えられたバッファでなく自前で持ってるメモリ領域を弄っていた」みたいなことが起きてほしくない