asic_rs/data/device/models/
mod.rs1use 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}