use std::fmt;
pub mod alpide;
pub mod data_words;
pub mod lane_data_frame;
pub mod status_words;
#[derive(Debug, PartialEq, Clone, Copy)]
pub enum Layer {
Inner,
Middle,
Outer,
}
impl fmt::Display for Layer {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Layer::Inner => write!(f, "IL"),
Layer::Middle => write!(f, "ML"),
Layer::Outer => write!(f, "OL"),
}
}
}
impl Layer {
pub fn from_stave(stave: &Stave) -> Self {
match stave {
Stave::InnerLayer { .. } => Layer::Inner,
Stave::MiddleLayer { .. } => Layer::Middle,
Stave::OuterLayer { .. } => Layer::Outer,
}
}
}
#[derive(Debug, PartialEq, Clone, Copy)]
pub enum Stave {
InnerLayer {
layer: u8,
stave: u8,
},
MiddleLayer {
layer: u8,
stave: u8,
},
OuterLayer {
layer: u8,
stave: u8,
},
}
impl fmt::Display for Stave {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Stave::InnerLayer { layer, stave } => write!(f, "L{layer}_{stave}"),
Stave::MiddleLayer { layer, stave } => write!(f, "L{layer}_{stave}"),
Stave::OuterLayer { layer, stave } => write!(f, "L{layer}_{stave}"),
}
}
}
impl Stave {
pub fn from_feeid(fee_id: u16) -> Self {
let layer = layer_from_feeid(fee_id);
let stave = stave_number_from_feeid(fee_id);
match layer {
0..=2 => Stave::InnerLayer { layer, stave },
3 | 4 => Stave::MiddleLayer { layer, stave },
5 | 6 => Stave::OuterLayer { layer, stave },
_ => panic!("Invalid layer number"),
}
}
pub fn layer(&self) -> u8 {
match self {
Stave::InnerLayer { layer, .. } => *layer,
Stave::MiddleLayer { layer, .. } => *layer,
Stave::OuterLayer { layer, .. } => *layer,
}
}
pub fn stave(&self) -> u8 {
match self {
Stave::InnerLayer { stave, .. } => *stave,
Stave::MiddleLayer { stave, .. } => *stave,
Stave::OuterLayer { stave, .. } => *stave,
}
}
}
pub fn stave_number_from_feeid(fee_id: u16) -> u8 {
let stave_number_mask: u16 = 0b11_1111;
(fee_id & stave_number_mask) as u8
}
pub fn layer_from_feeid(fee_id: u16) -> u8 {
let layer_mask: u16 = 0b0111;
let layer_lsb_idx: u8 = 12;
((fee_id >> layer_lsb_idx) & layer_mask) as u8
}
pub fn feeid_from_layer_stave(layer: u8, stave: u8) -> u16 {
let layer_mask: u16 = 0b0111;
let stave_mask: u16 = 0b11_1111;
let layer_lsb_idx: u8 = 12;
let stave_lsb_idx: u8 = 0;
((layer as u16 & layer_mask) << layer_lsb_idx) | (stave as u16 & stave_mask) << stave_lsb_idx
}
pub fn is_match_feeid_layer_stave(a_fee_id: u16, b_fee_id: u16) -> bool {
let layer_stave_mask: u16 = 0b0111_0000_0011_1111;
(a_fee_id & layer_stave_mask) == (b_fee_id & layer_stave_mask)
}
pub fn layer_stave_string_to_feeid(layer_stave_str: &str) -> Option<u16> {
let split_fee = layer_stave_str.split('_').collect::<Vec<&str>>();
debug_assert!(split_fee.len() == 2);
if let Ok(layer_num) = split_fee[0].get(1..)?.parse::<u8>() {
if let Ok(stave_num) = split_fee[1].parse::<u8>() {
Some(feeid_from_layer_stave(layer_num, stave_num))
} else {
None
}
} else {
None
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn layer_stave_feeid_coversions() {
let layer = 2;
let stave = 0;
println!("Layer/stave L{layer}_{stave}");
let feeid = feeid_from_layer_stave(layer, stave);
println!("feeid: {feeid}");
assert_eq!(layer, layer_from_feeid(feeid));
assert_eq!(stave, stave_number_from_feeid(feeid));
}
#[test]
fn feeid_layer_stave_conversion() {
let feeid = 20522;
let layer = layer_from_feeid(feeid);
let stave = stave_number_from_feeid(feeid);
println!("Layer/stave L{layer}_{stave}");
assert_eq!(feeid, feeid_from_layer_stave(layer, stave));
}
#[test]
fn test_layer_stave_string_to_feeid() {
let fee_id = layer_stave_string_to_feeid(&String::from("L5_42"));
println!("feeid: {:?}", fee_id);
assert_eq!(fee_id, Some(20522));
}
}