Trying to create a method in a trait that use general type parameter, and got an error, did not understand what the compiler means by type parameters must be constrained to match other types
My code is:
use std::hash::Hash;
use std::collections::HashMap;
use crate::modules::models::transactions::{Transaction, TransactionBuffer};
use crate::modules::models::inventory::Inventory;
use std::path::Path;
pub(crate) struct Inventory<'a, Warehouse: Eq + Hash, Item: Eq + Hash> {
pub(crate) table: HashMap<Warehouse, HashMap<Item, Transaction<'a>>>
}
pub(crate) trait Memory<'a, A: Eq + Hash, B: Eq + Hash> {
fn get(&self, a: &A, b: &B) -> Option<&Transaction<'a>>;
fn set(&mut self, a: A, b: B, v: Transaction<'a>);
}
impl<'a, A: Eq + Hash, B: Eq + Hash> Inventory<'a, A, B> {
pub(crate) fn new() -> Inventory<'a, A, B> {
Inventory {
table: HashMap::new(),
}
}
pub(crate) fn collect(&mut self, file: &str, records: &'a mut Vec<TransactionBuffer>) {
let file_path = Path::new(file);
let mut rdr = csv::ReaderBuilder::new()
.has_headers(true)
.delimiter(b',')
.from_path(file_path)
.unwrap();
for result in rdr.records() {
records.push(result.unwrap().deserialize(None).unwrap());
}
for record in &*records {
let trx = Transaction {
warehouse: &record.warehouse,
movement: &record.movement,
item: &record.item,
date: &record.date,
batch: &record.batch,
quantity: record.quantity
};
self.set(record.warehouse.as_str(), record.item.as_str(), trx);
}
}
}
impl<'a, A: Eq + Hash, B: Eq + Hash> Memory<'a, A, B> for Inventory<'a, A, B> {
fn get(&self, a: &A, b: &B) -> Option<&Transaction<'a>> {
self.table.get(a)?.get(b)
}
fn set(&mut self, a: A, b: B, v: Transaction<'a>) {
let inner = self.table.entry(a).or_insert(HashMap::new());
inner.insert(b, v);
}
}
And getting this error:
error[E0308]: mismatched types
--> src\modules\traits\inventory.rs:39:22
|
13 | impl<'a, A: Eq + Hash, B: Eq + Hash> Inventory<'a, A, B> {
| - this type parameter
...
39 | self.set(record.warehouse.as_str(), record.item.as_str(), trx);
| ^^^^^^^^^^^^^^^^^^^^^^^^^ expected type parameter `A`, found `&str`
|
= note: expected type parameter `A`
found reference `&str`
= help: type parameters must be constrained to match other types
= note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
error[E0308]: mismatched types
--> src\modules\traits\inventory.rs:39:49
|
13 | impl<'a, A: Eq + Hash, B: Eq + Hash> Inventory<'a, A, B> {
| - this type parameter
...
39 | self.set(record.warehouse.as_str(), record.item.as_str(), trx);
| ^^^^^^^^^^^^^^^^^^^^ expected type parameter `B`, found `&str`
|
= note: expected type parameter `B`
found reference `&str`
= help: type parameters must be constrained to match other types
= note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
error: aborting due to 2 previous errors; 2 warnings emitted
Knowing that before my trial in creating the collect
method, set
method worked smoothly as in the below code:
fn main() {
let mut inv: Inventory<&str, &str> = Inventory::new();
let mut inv_holding: Vec<TransactionBuffer> = Vec::new();
let input_file = "data/transactions.csv";
// inv.collect(input_file, inv_holding.as_mut());
let t = Transaction {
warehouse: "",
movement: "",
item: "A",
date: "1/1/2020",
batch: "A-1",
quantity: 100
};
inv.set("x", "y", t);
println!("t: {:#?}", inv.get(&"x", &"y")); */
}