use std::rc::Rc;
use std::sync::atomic::{AtomicBool, AtomicI64};
use std::sync::{Arc, Mutex};
use super::{VmError, VmValue};
pub type VmJoinHandle = tokio::task::JoinHandle<Result<(VmValue, String), VmError>>;
pub struct VmTaskHandle {
pub handle: VmJoinHandle,
pub cancel_token: Arc<AtomicBool>,
}
#[derive(Debug, Clone)]
pub struct VmChannelHandle {
pub name: Rc<str>,
pub sender: Arc<tokio::sync::mpsc::Sender<VmValue>>,
pub receiver: Arc<tokio::sync::Mutex<tokio::sync::mpsc::Receiver<VmValue>>>,
pub closed: Arc<AtomicBool>,
}
#[derive(Debug, Clone)]
pub struct VmAtomicHandle {
pub value: Arc<AtomicI64>,
}
#[derive(Clone)]
pub struct VmRngHandle {
pub rng: Arc<Mutex<rand::rngs::StdRng>>,
}
impl std::fmt::Debug for VmRngHandle {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str("VmRngHandle { .. }")
}
}
#[derive(Debug, Clone)]
pub struct VmSyncPermitHandle {
pub(crate) lease: Arc<crate::synchronization::VmSyncLease>,
}
impl VmSyncPermitHandle {
pub(crate) fn release(&self) -> bool {
self.lease.release()
}
pub(crate) fn kind(&self) -> &str {
self.lease.kind()
}
pub(crate) fn key(&self) -> &str {
self.lease.key()
}
}
#[derive(Debug, Clone, Copy)]
pub struct VmRange {
pub start: i64,
pub end: i64,
pub inclusive: bool,
}
impl VmRange {
pub fn len(&self) -> i64 {
if self.inclusive {
if self.start > self.end {
0
} else {
self.end.saturating_sub(self.start).saturating_add(1)
}
} else if self.start >= self.end {
0
} else {
self.end.saturating_sub(self.start)
}
}
pub fn is_empty(&self) -> bool {
self.len() == 0
}
pub fn get(&self, idx: i64) -> Option<i64> {
if idx < 0 || idx >= self.len() {
None
} else {
self.start.checked_add(idx)
}
}
pub fn first(&self) -> Option<i64> {
if self.is_empty() {
None
} else {
Some(self.start)
}
}
pub fn last(&self) -> Option<i64> {
if self.is_empty() {
None
} else if self.inclusive {
Some(self.end)
} else {
Some(self.end - 1)
}
}
pub fn contains(&self, v: i64) -> bool {
if self.is_empty() {
return false;
}
if self.inclusive {
v >= self.start && v <= self.end
} else {
v >= self.start && v < self.end
}
}
pub fn to_vec(&self) -> Vec<VmValue> {
let len = self.len();
if len <= 0 {
return Vec::new();
}
let cap = len as usize;
let mut out = Vec::with_capacity(cap);
for i in 0..len {
match self.start.checked_add(i) {
Some(v) => out.push(VmValue::Int(v)),
None => break,
}
}
out
}
}
#[derive(Debug, Clone)]
pub struct VmGenerator {
pub done: Rc<std::cell::Cell<bool>>,
pub receiver: Rc<tokio::sync::Mutex<tokio::sync::mpsc::Receiver<Result<VmValue, VmError>>>>,
}
#[derive(Debug, Clone)]
pub struct VmStream {
pub done: Rc<std::cell::Cell<bool>>,
pub receiver: Rc<tokio::sync::Mutex<tokio::sync::mpsc::Receiver<Result<VmValue, VmError>>>>,
}