Items from traits can only be used if the trait is implemented and in scope

I've this work smoothly if defined in single '.rs' file.

If I split them into 2 files, one for the struct:

  1. Inventory.rs
use std::collections::HashMap;
use std::hash::Hash;
use crate::modules::models::transactions::Transaction;

pub(crate) struct Inventory<'a, Warehouse: Eq + Hash, Item: Eq + Hash> {
    pub(crate) table: HashMap<Warehouse, HashMap<Item, Transaction<'a>>>
}
  1. Inventory_trai.rs
use std::collections::VecDeque;
use std::collections::HashMap;
use std::hash::Hash;
use crate::modules::models::transactions::Transaction;
use crate::modules::models::inventory::Inventory;

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(),
        }
    }
}

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);
    }
}
  1. main.rs
mod modules; // use modules::models::incoming::Received;
use crate::modules::models::transactions::{Transactions, TransactionBuffer, Transaction};
use crate::modules::models::inventory::Inventory

fn main() {
    let mut inv: Inventory<&str, &str> = Inventory::new();
    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"));
}

I get the below error:

error[E0599]: no method named `set` found for struct `modules::models::inventory::Inventory<'_, &str, &str>` in the current scope
  --> src\main.rs:34:9
   |
34 |     inv.set("x", "y", t);
   |         ^^^ method not found in `modules::models::inventory::Inventory<'_, &str, &str>`
   | 
  ::: src\modules\models\inventory.rs:5:1
   |
5  | pub(crate) struct Inventory<'a, Warehouse: Eq + Hash, Item: Eq + Hash> {
   | ---------------------------------------------------------------------- method `set` not found for this
   |
   = help: items from traits can only be used if the trait is implemented and in scope
note: `modules::traits::inventory::Memory` defines an item `set`, perhaps you need to implement it
  --> src\modules\traits\inventory.rs:24:1
   |
24 | trait Memory<'a, A: Eq + Hash, B: Eq + Hash> {
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to previous error; 1 warning emitted

I did not get what implementation of set the compiler want me to do, and where?

Comparing your imports and the file names, it's quite clear that

  1. There are files you have not included in your post.
  2. The file names you said they have are not the actual file names.

I'm guessing you have multiple mod inventory statements, or perhaps multiple mod modules statements?

This is the structure I've:

main.rs:

mod modules; // use modules::models::incoming::Received;
use crate::modules::models::transactions::Transaction;
use crate::modules::models::inventory::Inventory;


fn main() {
let mut inv: Inventory<&str, &str> = Inventory::new();
    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"));

}

modules/models/inventory.rs

use std::collections::HashMap;
use std::hash::Hash;
use crate::modules::models::transactions::Transaction;

pub(crate) struct Inventory<'a, Warehouse: Eq + Hash, Item: Eq + Hash> {
    pub(crate) table: HashMap<Warehouse, HashMap<Item, Transaction<'a>>>
}

modules/models/transactions.rs

use serde::Deserialize;

#[derive(Debug, Default, Deserialize)]
pub(crate) struct Transaction<'a> {
    pub(crate) warehouse: &'a str,
    pub(crate) movement: &'a str,
    pub(crate) item: &'a str,
    pub(crate) date: &'a str,
    pub(crate) batch: &'a str,
    pub(crate) quantity: i64
}

modules/traits/inventory_trait.rs

use std::hash::Hash;
use crate::modules::models::transactions::Transaction;
use std::collections::HashMap;
use crate::modules::models::inventory::Inventory;

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(),
        }
    }
}

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 the error:

The Memory trait is not visible in main.rs. Tray adding
use crate::modules::traits::inventory::Memory
in main.rs

1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.