use serde::{Deserialize, Serialize};
use serialport::{
ClearBuffer as SerialClearBuffer, DataBits as SerialDataBits, FlowControl as SerialFlowControl,
Parity as SerialParity, StopBits as SerialStopBits,
};
use std::sync::{Mutex, OnceLock};
pub const UNKNOWN: &str = "Unknown";
pub const USB: &str = "USB";
pub const BLUETOOTH: &str = "Bluetooth";
pub const PCI: &str = "PCI";
#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum DataBits {
Five,
Six,
Seven,
Eight,
}
impl From<DataBits> for SerialDataBits {
fn from(bits: DataBits) -> Self {
match bits {
DataBits::Five => SerialDataBits::Five,
DataBits::Six => SerialDataBits::Six,
DataBits::Seven => SerialDataBits::Seven,
DataBits::Eight => SerialDataBits::Eight,
}
}
}
impl DataBits {
pub fn as_u8(&self) -> u8 {
match self {
DataBits::Five => 5,
DataBits::Six => 6,
DataBits::Seven => 7,
DataBits::Eight => 8,
}
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum FlowControl {
None,
Software,
Hardware,
}
impl From<FlowControl> for SerialFlowControl {
fn from(flow: FlowControl) -> Self {
match flow {
FlowControl::None => SerialFlowControl::None,
FlowControl::Software => SerialFlowControl::Software,
FlowControl::Hardware => SerialFlowControl::Hardware,
}
}
}
impl FlowControl {
pub fn as_u8(&self) -> u8 {
match self {
FlowControl::None => 0,
FlowControl::Software => 1,
FlowControl::Hardware => 2,
}
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum Parity {
None,
Odd,
Even,
}
impl From<Parity> for SerialParity {
fn from(parity: Parity) -> Self {
match parity {
Parity::None => SerialParity::None,
Parity::Odd => SerialParity::Odd,
Parity::Even => SerialParity::Even,
}
}
}
impl Parity {
pub fn as_u8(&self) -> u8 {
match self {
Parity::None => 0,
Parity::Odd => 1,
Parity::Even => 2,
}
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum StopBits {
One,
Two,
}
impl From<StopBits> for SerialStopBits {
fn from(bits: StopBits) -> Self {
match bits {
StopBits::One => SerialStopBits::One,
StopBits::Two => SerialStopBits::Two,
}
}
}
impl StopBits {
pub fn as_u8(&self) -> u8 {
match self {
StopBits::One => 1,
StopBits::Two => 2,
}
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum ClearBuffer {
Input,
Output,
All,
}
impl From<ClearBuffer> for SerialClearBuffer {
fn from(buffer: ClearBuffer) -> Self {
match buffer {
ClearBuffer::Input => SerialClearBuffer::Input,
ClearBuffer::Output => SerialClearBuffer::Output,
ClearBuffer::All => SerialClearBuffer::All,
}
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
pub enum LogLevel {
None,
Error,
Warn,
#[default]
Info,
Debug,
}
impl LogLevel {
pub fn should_log_error(&self) -> bool {
matches!(
self,
LogLevel::Error | LogLevel::Warn | LogLevel::Info | LogLevel::Debug
)
}
pub fn should_log_warn(&self) -> bool {
matches!(self, LogLevel::Warn | LogLevel::Info | LogLevel::Debug)
}
pub fn should_log_info(&self) -> bool {
matches!(self, LogLevel::Info | LogLevel::Debug)
}
pub fn should_log_debug(&self) -> bool {
matches!(self, LogLevel::Debug)
}
}
static LOG_LEVEL: OnceLock<Mutex<LogLevel>> = OnceLock::new();
fn get_log_level_mutex() -> &'static Mutex<LogLevel> {
LOG_LEVEL.get_or_init(|| Mutex::new(LogLevel::Info))
}
pub fn set_log_level(level: LogLevel) {
if let Ok(mut log_level) = get_log_level_mutex().lock() {
*log_level = level;
}
}
pub fn get_log_level() -> LogLevel {
*get_log_level_mutex().lock().unwrap_or_else(|e| {
eprintln!("Failed to lock log level: {}", e);
e.into_inner()
})
}