eclectic
eclectic copied to clipboard
Redesign entry traits
The current design is nonsensical. With some future-Rust features, we could have:
pub trait EntryMap: Map {
type Occupied<'a>: Occupied<'a = 'a, Key = Self::Key, Value = Self::Value>;
type Vacant<'a>: Vacant<'a = 'a, Key = Self::Key, Value = Self::Value>;
fn entry<'a>(&'a mut self, key: Self::Key)
-> Entry<Self::Occupied<'a>, Self::Vacant<'a>>;
}
pub enum Entry<O, V>
where
O: Occupied,
V: Vacant<'a = O::'a, Key = O::Key, Value = O::Value>,
{
Occupied(O),
Vacant(V),
}
pub trait Occupied {
lifetime 'a;
type Key: Self::'a;
type Value: Self::'a;
fn into_mut(self) -> &Self::'a mut Self::Value;
// ...
}
pub trait Vacant {
lifetime 'a;
type Key: Self::'a;
type Value: Self::'a;
fn insert(self, value: Self::Value) -> &Self::'a mut Self::Value;
// ...
}
I'd also be fine keeping the lifetime parameter on EntryMap but removing it from {Occupied, Vacant}, at least until we get higher-kinded types:
pub trait EntryMap<'a>: Map {
type Occupied: Occupied<'a = 'a, Key = Self::Key, Value = Self::Value>;
type Vacant: Vacant<'a = 'a, Key = Self::Key, Value = Self::Value>;
fn entry(&'a mut self, key: Self::Key) -> Entry<Self::Occupied, Self::Vacant>;
}
pub enum Entry<O, V>
where
O: Occupied,
V: Vacant<'a = O::'a, Key = O::Key, Value = O::Value>,
{
Occupied(O),
Vacant(V),
}
pub trait Occupied {
lifetime 'a;
type Key: Self::'a;
type Value: Self::'a;
fn into_mut(self) -> &Self::'a mut Self::Value;
// ...
}
pub trait Vacant {
lifetime 'a;
type Key: Self::'a;
type Value: Self::'a;
fn insert(self, value: Self::Value) -> &Self::'a mut Self::Value;
// ...
}
This also needs to take object-safety into account. It would be nice to be able to use these traits with objects.
The current formulation only works for maps that contain 'static data.
The new formulation solves the problems of the original without higher-kinded types or associated lifetimes, but instead uses trait objects.