It's cumbersome (especially because the trait solver does not realize that if const B: bool
, then either B == true
, or B == false
), but it can be done:
trait RecordKeyType { type Key : ?Sized; }
struct __<const UNICODE_KEYS: bool>;
impl RecordKeyType for __<true> {
type Key = String;
}
impl RecordKeyType for __<false> {
type Key = Box<[u8]>;
}
struct Record<const UNICODE_KEYS: bool>
where
__<UNICODE_KEYS> : RecordKeyType,
{
key: <__<UNICODE_KEYS> as RecordKeyType>::Key,
}
fn _checks (
yes: Record::<true>,
no: Record::<false>,
)
{
let _: String = yes.key;
let _: Box<[u8]> = no.key;
}
EDIT: Actually, we can use the Record
type as the one given as input to the trait, removing the need for the __<…>
"const-to-type lifter":
trait ResolveKeyType { type T : ?Sized; }
impl ResolveKeyType for Record<true> {
type T = String;
}
impl ResolveKeyType for Record<false> {
type T = Box<[u8]>;
}
struct Record<const UNICODE_KEYS: bool>
where
Self : ResolveKeyType, // where `UNICODE_KEYS` is `true` or `false`
{
key: <Self as ResolveKeyType>::T,
}