I am writing a command line Task management app to teach myself Rust.
So far I have a sqllite and a memory datasource.
pub struct TaskManager {
source: Datasource, // here rustc complains
}
The manager has a reference to a Datasource
, which is a trait:
pub trait Datasource {
type Settings;
fn start(&self) -> Result<bool>;
}
Main reads cli args and decides based on them what datasource should be instantiated.
However, Rust tells me
"- rustc: the value of the associated type
Settings
insource::Datasource
must be specified [E0191]"
I understand that types must be specified at compile time, and both sources so far have their types specified.
impl Datasource for SqlLiteDataSource {
type Settings = SqlLiteSettings;
}
impl Datasource for MemoryDataSource {
type Settings = MemorySettings;
}
And when parsing the cli args, all arms are evaluated:
pub fn new(datasource: Datasources) -> Self {
let ds: Datasource = match datasource {
Datasources::SqlLite { path } => SqlLiteDataSource::new(path.to_string()),
_ => MemoryDataSource::new(),
};
}
In fact rustc is complaining here as well with the same error.
The idea was that each concrete implementation would have their own settings. How can I then assign a generic trait variable to the TaskManager
, so that a backend completes task management depending on the supplied source?
The issue is that you can't put a trait with a type directly into a struct. You would need to use a Boxed trait inside of the TaskManager, because the Rust compiler needs to know a specific type (in this case Settings) for the Datasource. Change the line source: Datasource
to either define the Boxed trait with a default Settings type, or another boxed trait. If you have a specific default Settings type you could set it to for compilation you could just change the line to source: Box<dyn Datasource<Settings=ChosenType>>
or you could set Settings to a boxed trait as well using the line source: Box<dyn Datasource<Settings=Box<dyn Settings>>>
This will clarify to the Rust compiler a specified type for the Datasource trait inside of the TaskManager struct.