I'm trying to implement a key-value SettingsDatabase
abstraction for saved app settings. It would have implementations for backends like Apple's "user defaults", Sqlite, Android preferences, etc. It would be able to save different kinds of simple values (i64, bool, lists of String, etc). So I was thinking I would have two traits - SettingsDatabase
and SettingsValue
.
trait SettingsValue { ?? }
trait SettingsDatabase {
fn set<V: SettingsValue>(&mut self, key: &str, value: V);
}
My confusion comes when I try to implement this, because within an impl for a SettingsDatabase
, I need the V
type to have more traits, which would allow me to save it to that specific backend. For example, I tried:
struct AppleSettings {
// NSUserDefaults is the Apple-specific thing
ud: Retained<NSUserDefaults>
}
trait UDValue : SettingsValue {
fn save(ud: &NSUserDefaults, key: Key, value: Self);
}
impl SettingsDatabase for AppleSettings {
fn set<V: UDValue>(&mut self, key: &str, value: V);
V::save(self.ud, key, value);
}
}
impl UDValue for i64 {
fn set(&self, ud: &NSUserDefaults, key: &str) {
// save the int in the user defaults
}
}
As you can probably guess, it didn't like me changing the generic parameter bound on set
:
error[E0276]: impl has stricter requirements than trait
--> settings/src/apple.rs:64:15
|
64 | fn set<V: UDValue>(&mut self, key: Key, value: V) {
| ^^^^^^^ impl has extra requirement `V: UDValue`
How does one properly express this? What am I doing here?