use crate::{Error, Result};
use async_std::sync::{Arc, Mutex};
use extended_primitives::Buffer;
use serde::{Deserialize, Serialize};
use std::fmt;
pub const EX_MAGIC_NUMBER: u8 = 0x7F;
#[derive(Clone, Default)]
pub struct ReadyIndicator(Arc<Mutex<bool>>);
impl ReadyIndicator {
pub fn new(ready: bool) -> Self {
ReadyIndicator(Arc::new(Mutex::new(ready)))
}
pub async fn ready(&self) {
*self.0.lock().await = true;
}
pub async fn not_ready(&self) {
*self.0.lock().await = false;
}
pub async fn inner(&self) -> bool {
*self.0.lock().await
}
}
#[derive(Serialize, Deserialize, Clone, Debug)]
#[serde(untagged)]
pub enum ID {
Num(u64),
Str(String),
Null(serde_json::Value),
}
impl std::fmt::Display for ID {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
ID::Num(ref e) => write!(f, "{}", e),
ID::Str(ref e) => write!(f, "{}", e),
ID::Null(ref _e) => write!(f, "null"),
}
}
}
#[derive(Clone, Debug)]
pub enum MessageValue {
StratumV1(serde_json::map::Map<String, serde_json::Value>),
ExMessage(ExMessageGeneric),
}
#[derive(Clone, Eq, PartialEq, Debug)]
pub enum MessageTypes {
RegisterWorker,
SubmitShare,
SubmitShareWithTime,
SubmitShareWithVersion,
SubmitShareWithTimeAndVersion,
UnregisterWorker,
MiningSetDiff,
Unknown(u8),
}
impl MessageTypes {
pub fn from_u8(cmd: u8) -> Self {
match cmd {
0x01 => MessageTypes::RegisterWorker,
0x02 => MessageTypes::SubmitShare,
0x03 => MessageTypes::SubmitShareWithTime,
0x04 => MessageTypes::UnregisterWorker,
0x05 => MessageTypes::MiningSetDiff,
0x12 => MessageTypes::SubmitShareWithVersion,
0x13 => MessageTypes::SubmitShareWithTimeAndVersion,
_ => MessageTypes::Unknown(cmd),
}
}
pub fn to_string(&self) -> String {
match *self {
MessageTypes::RegisterWorker => String::from("exMessageRegisterWorker"),
MessageTypes::SubmitShare => String::from("exMessageSubmitShare"),
MessageTypes::SubmitShareWithTime => String::from("exMessageSubmitShare"),
MessageTypes::UnregisterWorker => String::from("exMessageUnregisterWorker"),
MessageTypes::MiningSetDiff => String::from("exMessageMiningSetDiff"),
MessageTypes::SubmitShareWithVersion => String::from("exMessageSubmitShare"),
MessageTypes::SubmitShareWithTimeAndVersion => String::from("exMessageSubmitShare"),
_ => String::from(""),
}
}
}
#[derive(Clone, Debug)]
pub struct ExMessageGeneric {
pub magic_number: u8,
pub cmd: MessageTypes,
pub length: u16,
pub body: Buffer,
}
impl ExMessageGeneric {
pub fn from_buffer(buffer: &mut Buffer) -> Result<Self> {
let magic_number = buffer.read_u8().map_err(|_| Error::BrokenExHeader)?;
let cmd = buffer.read_u8().map_err(|_| Error::BrokenExHeader)?;
let length = buffer.read_u16().map_err(|_| Error::BrokenExHeader)?;
let body = buffer.clone();
let cmd = MessageTypes::from_u8(cmd);
if length as usize != body.len() {
return Err(Error::BrokenExHeader);
}
match cmd {
MessageTypes::Unknown(_) => {
return Err(Error::BrokenExHeader);
}
_ => {}
}
Ok(ExMessageGeneric {
magic_number,
cmd,
length,
body,
})
}
}