ldpc_toolbox/simulation/
factory.rs1use super::{
7 ber::{BerTest, BerTestParameters, Statistics},
8 modulation::{Bpsk, Psk8},
9};
10use crate::decoder::factory::{DecoderFactory, DecoderImplementation};
11use clap::ValueEnum;
12
13pub trait Ber {
17 fn run(self: Box<Self>) -> Result<Vec<Statistics>, Box<dyn std::error::Error>>;
22
23 fn n(&self) -> usize;
27
28 fn n_cw(&self) -> usize;
32
33 fn k(&self) -> usize;
35
36 fn rate(&self) -> f64;
38}
39
40#[derive(Debug)]
44pub struct BerTestBuilder<'a, Dec = DecoderImplementation> {
45 pub parameters: BerTestParameters<'a, Dec>,
47 pub modulation: Modulation,
49}
50
51#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, ValueEnum)]
55#[clap(rename_all = "UPPER")]
56pub enum Modulation {
57 Bpsk,
59 Psk8,
61}
62
63impl std::str::FromStr for Modulation {
64 type Err = String;
65
66 fn from_str(s: &str) -> Result<Modulation, String> {
67 Ok(match s {
68 "BPSK" => Modulation::Bpsk,
69 "8PSK" => Modulation::Psk8,
70 _ => Err(format!("invalid modulation {s}"))?,
71 })
72 }
73}
74
75impl std::fmt::Display for Modulation {
76 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
77 write!(
78 f,
79 "{}",
80 match self {
81 Modulation::Bpsk => "BPSK",
82 Modulation::Psk8 => "8PSK",
83 }
84 )
85 }
86}
87
88impl<Dec: DecoderFactory> BerTestBuilder<'_, Dec> {
89 pub fn build(self) -> Result<Box<dyn Ber>, Box<dyn std::error::Error>> {
94 macro_rules! impl_match {
95 ($($modulation:ident),*) => {
96 match self.modulation {
97 $(
98 Modulation::$modulation => Box::new(BerTest::<$modulation, Dec>::new(
99 self.parameters
100 )?),
101 )*
102 }
103 }
104 }
105
106 Ok(impl_match!(Bpsk, Psk8))
107 }
108}