asic_rs/data/device/models/
mod.rs

1use super::{MinerFirmware, MinerMake};
2use antminer::AntMinerModel;
3use avalon::AvalonMinerModel;
4use bitaxe::BitaxeModel;
5use braiins::BraiinsModel;
6use epic::EPicModel;
7use serde::{Deserialize, Serialize};
8use std::{fmt::Display, str::FromStr};
9use whatsminer::WhatsMinerModel;
10
11pub mod antminer;
12pub mod avalon;
13pub mod bitaxe;
14pub mod braiins;
15pub mod epic;
16pub mod whatsminer;
17
18#[derive(Debug, Clone)]
19pub struct ModelParseError;
20
21impl Display for ModelParseError {
22    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
23        write!(f, "Failed to parse model")
24    }
25}
26
27impl std::error::Error for ModelParseError {}
28
29impl FromStr for WhatsMinerModel {
30    type Err = ModelParseError;
31
32    fn from_str(s: &str) -> Result<Self, Self::Err> {
33        serde_json::from_value(serde_json::Value::String(s.to_string()))
34            .map_err(|_| ModelParseError)
35    }
36}
37impl FromStr for AntMinerModel {
38    type Err = ModelParseError;
39
40    fn from_str(s: &str) -> Result<Self, Self::Err> {
41        serde_json::from_value(serde_json::Value::String(s.to_string()))
42            .map_err(|_| ModelParseError)
43    }
44}
45impl FromStr for BitaxeModel {
46    type Err = ModelParseError;
47
48    fn from_str(s: &str) -> Result<Self, Self::Err> {
49        serde_json::from_value(serde_json::Value::String(s.to_string()))
50            .map_err(|_| ModelParseError)
51    }
52}
53
54impl FromStr for BraiinsModel {
55    type Err = ModelParseError;
56
57    fn from_str(s: &str) -> Result<Self, Self::Err> {
58        serde_json::from_value(serde_json::Value::String(s.to_string()))
59            .map_err(|_| ModelParseError)
60    }
61}
62
63impl FromStr for AvalonMinerModel {
64    type Err = ModelParseError;
65
66    fn from_str(s: &str) -> Result<Self, Self::Err> {
67        serde_json::from_value(serde_json::Value::String(s.to_string()))
68            .map_err(|_| ModelParseError)
69    }
70}
71
72impl FromStr for EPicModel {
73    type Err = ModelParseError;
74
75    fn from_str(s: &str) -> Result<Self, Self::Err> {
76        serde_json::from_value(serde_json::Value::String(s.to_string()))
77            .map_err(|_| ModelParseError)
78    }
79}
80
81#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, Serialize, Deserialize)]
82#[serde(untagged)]
83pub enum MinerModel {
84    AntMiner(AntMinerModel),
85    WhatsMiner(WhatsMinerModel),
86    Braiins(BraiinsModel),
87    Bitaxe(BitaxeModel),
88    Avalon(AvalonMinerModel),
89    EPic(EPicModel),
90}
91
92impl Display for MinerModel {
93    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
94        match self {
95            MinerModel::AntMiner(m) => Ok(m.fmt(f)?),
96            MinerModel::WhatsMiner(m) => Ok(m.fmt(f)?),
97            MinerModel::Braiins(m) => Ok(m.fmt(f)?),
98            MinerModel::Bitaxe(m) => Ok(m.fmt(f)?),
99            MinerModel::EPic(m) => Ok(m.fmt(f)?),
100            MinerModel::Avalon(m) => Ok(m.fmt(f)?),
101        }
102    }
103}
104
105pub(crate) struct MinerModelFactory {
106    make: Option<MinerMake>,
107    firmware: Option<MinerFirmware>,
108}
109
110impl MinerModelFactory {
111    pub fn new() -> Self {
112        MinerModelFactory {
113            make: None,
114            firmware: None,
115        }
116    }
117
118    pub(crate) fn with_make(&mut self, make: MinerMake) -> &Self {
119        self.make = Some(make);
120        self
121    }
122    pub(crate) fn with_firmware(&mut self, firmware: MinerFirmware) -> &Self {
123        self.firmware = Some(firmware);
124        self
125    }
126
127    pub(crate) fn parse_model(&self, model_str: &str) -> Option<MinerModel> {
128        match self.make {
129            Some(MinerMake::AntMiner) => {
130                let model = AntMinerModel::from_str(model_str).ok();
131                model.map(MinerModel::AntMiner)
132            }
133            Some(MinerMake::WhatsMiner) => {
134                let model = WhatsMinerModel::from_str(model_str).ok();
135                model.map(MinerModel::WhatsMiner)
136            }
137            Some(MinerMake::BitAxe) => {
138                let model = BitaxeModel::from_str(model_str).ok();
139                model.map(MinerModel::Bitaxe)
140            }
141            Some(MinerMake::AvalonMiner) => {
142                let model = AvalonMinerModel::from_str(model_str).ok();
143                model.map(MinerModel::Avalon)
144            }
145            None => match self.firmware {
146                Some(MinerFirmware::BraiinsOS) => {
147                    if let Ok(model) = AntMinerModel::from_str(model_str) {
148                        return Some(MinerModel::AntMiner(model));
149                    }
150                    if let Ok(model) = BraiinsModel::from_str(model_str) {
151                        return Some(MinerModel::Braiins(model));
152                    }
153                    None
154                }
155                Some(MinerFirmware::EPic) => {
156                    if let Ok(model) = AntMinerModel::from_str(model_str) {
157                        return Some(MinerModel::AntMiner(model));
158                    }
159                    if let Ok(model) = EPicModel::from_str(model_str) {
160                        return Some(MinerModel::EPic(model));
161                    }
162                    None
163                }
164                Some(MinerFirmware::LuxOS) => {
165                    if let Ok(model) = AntMinerModel::from_str(model_str) {
166                        return Some(MinerModel::AntMiner(model));
167                    }
168                    None
169                }
170                None => None,
171                _ => None,
172            },
173            _ => None,
174        }
175    }
176}