#![deny(missing_docs)]
pub mod error;
pub use error::{Error, ErrorExt, Result};
use std::sync::{Arc, Weak};
pub mod memindex;
pub type BoxFut<'lt, T> =
std::pin::Pin<Box<dyn std::future::Future<Output = T> + 'lt + Send>>;
pub fn safe_now() -> f64 {
static A: std::sync::atomic::AtomicU64 =
std::sync::atomic::AtomicU64::new(0);
let mut now = std::time::SystemTime::UNIX_EPOCH
.elapsed()
.unwrap()
.as_secs_f64();
let _ = A.fetch_update(
std::sync::atomic::Ordering::SeqCst,
std::sync::atomic::Ordering::SeqCst,
|stored| {
let mut stored = f64::from_le_bytes(stored.to_le_bytes());
stored += 0.000001;
if stored > now {
now = stored;
}
Some(u64::from_le_bytes(now.to_le_bytes()))
},
);
now
}
fn safe_str(s: &str) -> Result<()> {
for b in s.as_bytes() {
if (*b >= b'a' && *b <= b'z')
|| (*b >= b'A' && *b <= b'Z')
|| (*b >= b'0' && *b <= b'9')
|| *b == b'-'
|| *b == b'_'
|| *b == b'.'
|| *b == b'~'
{
continue;
}
return Err(Error::other(
"Invalid string (can only contain [a-z], [A-Z], [0-9], '-', '_', '.', and '~')",
));
}
Ok(())
}
#[derive(Default)]
struct RuntimeInner {
pub obj: std::sync::OnceLock<obj::ObjWrap>,
pub js: std::sync::OnceLock<js::DynJsExec>,
pub msg: std::sync::OnceLock<msg::DynMsg>,
}
#[derive(Debug, Clone)]
pub struct Runtime(Weak<RuntimeInner>, u64);
impl std::hash::Hash for Runtime {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.1.hash(state);
}
}
impl PartialEq for Runtime {
fn eq(&self, oth: &Self) -> bool {
self.1 == oth.1
}
}
impl Eq for Runtime {}
impl Runtime {
pub fn obj(&self) -> Result<obj::ObjWrap> {
Ok(self
.0
.upgrade()
.ok_or_else(|| Error::other("closing"))?
.obj
.get()
.ok_or_else(|| Error::other("closing"))?
.clone())
}
pub fn js(&self) -> Result<js::DynJsExec> {
Ok(self
.0
.upgrade()
.ok_or_else(|| Error::other("closing"))?
.js
.get()
.ok_or_else(|| Error::other("closing"))?
.clone())
}
pub fn msg(&self) -> Result<msg::DynMsg> {
Ok(self
.0
.upgrade()
.ok_or_else(|| Error::other("closing"))?
.msg
.get()
.ok_or_else(|| Error::other("closing"))?
.clone())
}
}
pub struct RuntimeHandle(Arc<RuntimeInner>, u64);
impl Default for RuntimeHandle {
fn default() -> Self {
static UNIQ: std::sync::atomic::AtomicU64 =
std::sync::atomic::AtomicU64::new(1);
Self(
Default::default(),
UNIQ.fetch_add(1, std::sync::atomic::Ordering::Relaxed),
)
}
}
impl RuntimeHandle {
pub fn set_obj(&self, obj: obj::ObjWrap) {
let _ = self.0.obj.set(obj);
}
pub fn set_js(&self, js: js::DynJsExec) {
let _ = self.0.js.set(js);
}
pub fn set_msg(&self, msg: msg::DynMsg) {
let _ = self.0.msg.set(msg);
}
pub fn runtime(&self) -> Runtime {
Runtime(Arc::downgrade(&self.0), self.1)
}
}
pub mod bytes_ext;
pub(crate) mod ctx;
pub mod http_client;
#[cfg(feature = "http-server")]
pub mod http_server;
pub mod js;
pub mod meter;
pub mod msg;
pub mod obj;
pub mod server;
use bytes_ext::BytesExt;