Skip to main content

waremax_storage/
rack.rs

1//! Rack and bin storage structures
2
3use rkyv::{Archive, Deserialize, Serialize};
4use serde::{Deserialize as SerdeDeserialize, Serialize as SerdeSerialize};
5use waremax_core::{NodeId, RackId};
6
7/// A storage rack in the warehouse
8#[derive(Archive, Deserialize, Serialize, Clone, Debug)]
9pub struct Rack {
10    pub id: RackId,
11    pub string_id: String,
12    pub access_node: NodeId,
13    pub levels: u32,
14    pub bins_per_level: u32,
15    pub zone: Option<String>,
16    /// Base time to access level 0 (seconds)
17    pub base_access_time_s: f64,
18    /// Additional time per level above 0 (seconds)
19    pub per_level_time_s: f64,
20}
21
22impl Rack {
23    pub fn new(
24        id: RackId,
25        string_id: String,
26        access_node: NodeId,
27        levels: u32,
28        bins_per_level: u32,
29    ) -> Self {
30        Self {
31            id,
32            string_id,
33            access_node,
34            levels,
35            bins_per_level,
36            zone: None,
37            base_access_time_s: 0.0,
38            per_level_time_s: 0.0,
39        }
40    }
41
42    /// Create a rack with level-specific access times
43    pub fn with_access_times(mut self, base_access_time_s: f64, per_level_time_s: f64) -> Self {
44        self.base_access_time_s = base_access_time_s;
45        self.per_level_time_s = per_level_time_s;
46        self
47    }
48
49    pub fn total_bins(&self) -> u32 {
50        self.levels * self.bins_per_level
51    }
52
53    pub fn bin_exists(&self, level: u32, bin: u32) -> bool {
54        level < self.levels && bin < self.bins_per_level
55    }
56
57    /// Calculate the access time for a specific level
58    ///
59    /// Higher levels take longer to access (e.g., reaching higher shelves)
60    pub fn access_time(&self, level: u32) -> f64 {
61        self.base_access_time_s + (level as f64 * self.per_level_time_s)
62    }
63}
64
65/// Address of a specific bin within a rack
66#[derive(
67    Archive,
68    Deserialize,
69    Serialize,
70    SerdeDeserialize,
71    SerdeSerialize,
72    Clone,
73    Debug,
74    PartialEq,
75    Eq,
76    Hash,
77)]
78pub struct BinAddress {
79    pub rack_id: RackId,
80    pub level: u32,
81    pub bin: u32,
82}
83
84impl BinAddress {
85    pub fn new(rack_id: RackId, level: u32, bin: u32) -> Self {
86        Self {
87            rack_id,
88            level,
89            bin,
90        }
91    }
92}
93
94impl std::fmt::Display for BinAddress {
95    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
96        write!(f, "R{}-L{}-B{}", self.rack_id.0, self.level, self.bin)
97    }
98}