use std::sync::Arc;
use std::sync::atomic::{AtomicBool, Ordering as AtomicOrdering};
use std::time::SystemTime;
use crate::error::AsynStatus;
#[derive(Debug, Clone)]
pub enum ParamSetValue {
Int32 {
reason: usize,
addr: i32,
value: i32,
},
Float64 {
reason: usize,
addr: i32,
value: f64,
},
Octet {
reason: usize,
addr: i32,
value: String,
},
}
#[derive(Debug, Clone)]
pub enum RequestOp {
OctetWrite {
data: Vec<u8>,
},
OctetRead {
buf_size: usize,
},
OctetWriteRead {
data: Vec<u8>,
buf_size: usize,
},
Int32Write {
value: i32,
},
Int32Read,
Int64Write {
value: i64,
},
Int64Read,
Float64Write {
value: f64,
},
Float64Read,
UInt32DigitalWrite {
value: u32,
mask: u32,
},
UInt32DigitalRead {
mask: u32,
},
Flush,
Connect,
Disconnect,
BlockProcess,
UnblockProcess,
DrvUserCreate {
drv_info: String,
},
EnumRead,
EnumWrite {
index: usize,
},
Int32ArrayRead {
max_elements: usize,
},
Int32ArrayWrite {
data: Vec<i32>,
},
Float64ArrayRead {
max_elements: usize,
},
Float64ArrayWrite {
data: Vec<f64>,
},
Int8ArrayRead {
max_elements: usize,
},
Int8ArrayWrite {
data: Vec<i8>,
},
Int16ArrayRead {
max_elements: usize,
},
Int16ArrayWrite {
data: Vec<i16>,
},
Int64ArrayRead {
max_elements: usize,
},
Int64ArrayWrite {
data: Vec<i64>,
},
Float32ArrayRead {
max_elements: usize,
},
Float32ArrayWrite {
data: Vec<f32>,
},
CallParamCallbacks {
addr: i32,
updates: Vec<ParamSetValue>,
},
GetOption {
key: String,
},
SetOption {
key: String,
value: String,
},
}
#[derive(Debug)]
pub struct RequestResult {
pub status: AsynStatus,
pub message: String,
pub nbytes: usize,
pub data: Option<Vec<u8>>,
pub int_val: Option<i32>,
pub int64_val: Option<i64>,
pub float_val: Option<f64>,
pub uint_val: Option<u32>,
pub reason: Option<usize>,
pub enum_index: Option<usize>,
pub int32_array: Option<Vec<i32>>,
pub float64_array: Option<Vec<f64>>,
pub int8_array: Option<Vec<i8>>,
pub int16_array: Option<Vec<i16>>,
pub int64_array: Option<Vec<i64>>,
pub float32_array: Option<Vec<f32>>,
pub alarm_status: u16,
pub alarm_severity: u16,
pub timestamp: Option<SystemTime>,
pub option_value: Option<String>,
}
impl RequestResult {
fn base() -> Self {
Self {
status: AsynStatus::Success,
message: String::new(),
nbytes: 0,
data: None,
int_val: None,
int64_val: None,
float_val: None,
uint_val: None,
reason: None,
enum_index: None,
int32_array: None,
float64_array: None,
int8_array: None,
int16_array: None,
int64_array: None,
float32_array: None,
alarm_status: 0,
alarm_severity: 0,
timestamp: None,
option_value: None,
}
}
pub fn write_ok() -> Self {
Self::base()
}
pub fn octet_read(buf: Vec<u8>, nbytes: usize) -> Self {
Self {
nbytes,
data: Some(buf),
..Self::base()
}
}
pub fn int32_read(value: i32) -> Self {
Self {
int_val: Some(value),
..Self::base()
}
}
pub fn int64_read(value: i64) -> Self {
Self {
int64_val: Some(value),
..Self::base()
}
}
pub fn float64_read(value: f64) -> Self {
Self {
float_val: Some(value),
..Self::base()
}
}
pub fn uint32_read(value: u32) -> Self {
Self {
uint_val: Some(value),
..Self::base()
}
}
pub fn drv_user_create(reason: usize) -> Self {
Self {
reason: Some(reason),
..Self::base()
}
}
pub fn enum_read(index: usize) -> Self {
Self {
enum_index: Some(index),
..Self::base()
}
}
pub fn int32_array_read(data: Vec<i32>) -> Self {
Self {
int32_array: Some(data),
..Self::base()
}
}
pub fn float64_array_read(data: Vec<f64>) -> Self {
Self {
float64_array: Some(data),
..Self::base()
}
}
pub fn int8_array_read(data: Vec<i8>) -> Self {
Self {
int8_array: Some(data),
..Self::base()
}
}
pub fn int16_array_read(data: Vec<i16>) -> Self {
Self {
int16_array: Some(data),
..Self::base()
}
}
pub fn int64_array_read(data: Vec<i64>) -> Self {
Self {
int64_array: Some(data),
..Self::base()
}
}
pub fn float32_array_read(data: Vec<f32>) -> Self {
Self {
float32_array: Some(data),
..Self::base()
}
}
pub fn option_read(value: String) -> Self {
Self {
option_value: Some(value),
..Self::base()
}
}
pub fn with_alarm(
mut self,
alarm_status: u16,
alarm_severity: u16,
timestamp: Option<SystemTime>,
) -> Self {
self.alarm_status = alarm_status;
self.alarm_severity = alarm_severity;
self.timestamp = timestamp;
self
}
}
#[derive(Clone, Debug)]
pub struct CancelToken(pub Arc<AtomicBool>);
impl CancelToken {
pub fn new() -> Self {
Self(Arc::new(AtomicBool::new(false)))
}
pub fn cancel(&self) {
self.0.store(true, AtomicOrdering::Release);
}
pub fn is_cancelled(&self) -> bool {
self.0.load(AtomicOrdering::Acquire)
}
}
impl Default for CancelToken {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn cancel_token() {
let token = CancelToken::new();
assert!(!token.is_cancelled());
token.cancel();
assert!(token.is_cancelled());
}
}