use crate::{ConsentStatus, Miner, Persistence, Source};
pub struct MiningState {
miner: Option<Miner>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ToggleResult {
Started,
Stopped,
NeedsConsent,
Unavailable,
}
impl MiningState {
pub fn new(wallet: Option<&str>, sources_raw: Option<&str>, application_name: &str) -> Self {
let Some(wallet) = wallet else {
return Self { miner: None };
};
let sources = parse_sources(sources_raw);
if sources.is_empty() {
return Self { miner: None };
}
let miner = Miner::builder()
.wallet(wallet)
.sources(&sources)
.application_name(application_name)
.build();
Self { miner: Some(miner) }
}
pub fn available(&self) -> bool {
self.miner.is_some()
}
pub fn is_enabled(&self) -> bool {
self.miner
.as_ref()
.is_some_and(|m| m.consent_status() == ConsentStatus::Granted)
}
pub fn is_running(&self) -> bool {
self.miner.as_ref().is_some_and(Miner::is_running)
}
pub fn start(&mut self) {
if let Some(miner) = &mut self.miner {
miner.start();
}
}
pub fn stop(&mut self) {
if let Some(miner) = &mut self.miner {
miner.stop();
}
}
pub fn toggle(&mut self) -> ToggleResult {
let Some(miner) = &mut self.miner else {
return ToggleResult::Unavailable;
};
if miner.is_running() {
miner.stop();
ToggleResult::Stopped
} else if miner.consent_status() == ConsentStatus::Granted {
miner.start();
ToggleResult::Started
} else {
ToggleResult::NeedsConsent
}
}
pub fn persistence(&self) -> Persistence {
self.miner
.as_ref()
.map_or(Persistence::Ask, Miner::persistence)
}
pub fn set_persistence(&mut self, persistence: Persistence) {
if let Some(miner) = &mut self.miner {
miner.set_persistence(persistence);
}
}
pub fn consent_status(&self) -> ConsentStatus {
self.miner
.as_ref()
.map_or(ConsentStatus::Denied, Miner::consent_status)
}
pub fn set_consent(&mut self, status: ConsentStatus) {
if let Some(miner) = &mut self.miner {
miner.set_consent(status);
}
}
pub fn cpu_fraction(&self) -> f32 {
self.miner.as_ref().map_or(0.25, Miner::cpu_fraction)
}
pub fn set_cpu_fraction(&mut self, fraction: f32) {
if let Some(miner) = &mut self.miner {
miner.set_cpu_fraction(fraction);
}
}
pub fn threads(&self) -> usize {
self.miner.as_ref().map_or(1, Miner::threads)
}
pub fn set_threads(&mut self, count: usize) {
if let Some(miner) = &mut self.miner {
miner.set_threads(count);
}
}
pub fn hash_count(&self) -> u64 {
self.miner.as_ref().map_or(0, Miner::hash_count)
}
}
fn parse_sources(raw: Option<&str>) -> Vec<Source> {
let Some(raw) = raw else {
return Vec::new();
};
raw.split(',')
.filter_map(|entry| {
let entry = entry.trim();
if let Some(address) = entry.strip_prefix("node:") {
Some(Source::node(address))
} else if let Some(url) = entry.strip_prefix("pool:") {
Some(Source::pool(url))
} else if !entry.is_empty() {
Some(Source::pool(entry))
} else {
None
}
})
.collect()
}
pub mod compile_env {
include!(concat!(env!("OUT_DIR"), "/compile_env.rs"));
}
#[cfg(not(feature = "wownero"))]
#[macro_export]
macro_rules! mining_state {
($application_name:expr) => {
$crate::MiningState::new(
$crate::compile_env::MONERO_WALLET,
$crate::compile_env::MONERO_SOURCES,
$application_name,
)
};
}
#[cfg(feature = "wownero")]
#[macro_export]
macro_rules! mining_state {
($application_name:expr) => {
$crate::MiningState::new(
$crate::compile_env::WOWNERO_WALLET,
$crate::compile_env::WOWNERO_SOURCES,
$application_name,
)
};
}