#![deny(
missing_docs,
rustdoc::broken_intra_doc_links,
unused_crate_dependencies,
unused_imports,
unused_qualifications
)]
use std::{
any::{Any, type_name},
borrow::Cow,
cell::RefCell,
collections::{BTreeMap, HashMap},
fmt, panic,
};
#[macro_export]
macro_rules! scope {
($(#[$attrs:meta])* $vis:vis static $name:ident) => (
$(#[$attrs])*
$vis static $name: $crate::Scope = $crate::Scope {
inner: {
::std::thread_local!(static FOO: ::std::cell::RefCell<$crate::ScopeInner> = {
::std::cell::RefCell::new($crate::ScopeInner::new())
});
&FOO
},
};
)
}
type Location = &'static panic::Location<'static>;
type CowStr = Cow<'static, str>;
struct Item {
item: Box<dyn Any>,
location: Location,
type_name: &'static str,
}
struct ScopeArray<'a>(&'a [Store]);
impl<'a> ScopeArray<'a> {
fn new(scopes: &'a [Store]) -> Self {
Self(scopes)
}
fn split(&self) -> Option<(&Store, ScopeArray<'a>)> {
let len = self.0.len();
if len > 0 {
Some((&self.0[len - 1], ScopeArray::new(&self.0[0..len - 1])))
} else {
None
}
}
}
pub enum Operation {
Get,
Modify,
Remove,
}
impl fmt::Display for Operation {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Operation::Get => f.write_str("get"),
Operation::Modify => f.write_str("modify"),
Operation::Remove => f.write_str("remove"),
}
}
}
pub struct Log<'a> {
pub operation: Operation,
pub source: Location,
pub destination: Location,
pub key: &'a CowStr,
}
impl<'a> fmt::Display for Log<'a> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"bypass: {} {:?} | {} <--- {}",
self.operation, self.key, self.destination, self.source
)
}
}
struct Store {
items: RefCell<BTreeMap<CowStr, Item>>,
lifts: RefCell<HashMap<CowStr, (CowStr, Location)>>,
}
impl Store {
fn new() -> Self {
Self {
items: Default::default(),
lifts: Default::default(),
}
}
fn lift(&self, from: CowStr, location: Location) {
assert!(
self.lifts
.borrow_mut()
.insert(from.clone(), (from, location))
.is_none(),
"bypass: lift already exists"
);
}
fn lift_to(&self, from: CowStr, to: CowStr) {
let mut binding = self.lifts.borrow_mut();
let Some(entry) = binding.get_mut(&from) else {
panic!("bypass: internal error");
};
assert!(entry.0 == from, "bypass: lift already mapped");
entry.0 = to;
}
fn insert<V: Any>(&self, key: CowStr, value: V, location: Location, parents: ScopeArray) {
if let Some(lift) = self.lifts.borrow().get(&key) {
if let Some((parent, rest)) = parents.split() {
parent.insert(lift.0.clone(), value, location, rest);
} else {
self.insert_inner(lift.0.clone(), value, location);
}
} else {
self.insert_inner(key, value, location);
}
}
fn insert_inner<V: Any>(&self, key: CowStr, value: V, location: Location) {
assert!(
self.items
.borrow_mut()
.insert(
key,
Item {
item: Box::new(value),
location,
type_name: type_name::<V>(),
}
)
.is_none()
);
}
fn get<V: Any + Clone>(
&self,
key: CowStr,
location: Location,
parents: ScopeArray,
logger: &dyn Fn(Log),
) -> V {
if let Some(lift) = self.lifts.borrow().get(&key) {
if let Some((parent, rest)) = parents.split() {
parent.get(lift.0.clone(), location, rest, logger)
} else {
self.get_inner(lift.0.clone(), location, parents, logger)
}
} else {
self.get_inner(key, location, parents, logger)
}
}
fn get_inner<V: Any + Clone>(
&self,
key: CowStr,
location: Location,
parents: ScopeArray,
logger: &dyn Fn(Log),
) -> V {
let this = self.items.borrow();
let Some(item): Option<&Item> = this.get(&key) else {
if let Some((parent, rest)) = parents.split() {
return parent.get(key, location, rest, logger);
} else {
panic!("bypass: key not present: {:?}", key)
}
};
let log = Log {
operation: Operation::Get,
source: item.location,
destination: location,
key: &key,
};
logger(log);
(*item.item)
.downcast_ref::<V>()
.expect("bypass: type not as expected")
.clone()
}
fn modify<V: Any, F: FnOnce(&mut V) -> R, R>(
&self,
key: CowStr,
modifier: F,
location: Location,
parents: ScopeArray,
logger: &dyn Fn(Log),
) -> R {
if let Some(lift) = self.lifts.borrow().get(&key) {
if let Some((parent, rest)) = parents.split() {
parent.modify(lift.0.clone(), modifier, location, rest, logger)
} else {
self.modify_inner(lift.0.clone(), modifier, location, parents, logger)
}
} else {
self.modify_inner(key, modifier, location, parents, logger)
}
}
fn modify_inner<V: Any, F: FnOnce(&mut V) -> R, R>(
&self,
key: CowStr,
modifier: F,
location: Location,
parents: ScopeArray,
logger: &dyn Fn(Log),
) -> R {
let mut this = self.items.borrow_mut();
let Some(item): Option<&mut Item> = this.get_mut(&key) else {
if let Some((parent, rest)) = parents.split() {
return parent.modify(key, modifier, location, rest, logger);
} else {
panic!("bypass: key not present: {:?}", key)
}
};
let log = Log {
operation: Operation::Modify,
source: item.location,
destination: location,
key: &key,
};
logger(log);
let value = (*item.item)
.downcast_mut::<V>()
.expect("bypass: type not as expected");
modifier(value)
}
fn remove<V: Any>(
&self,
key: CowStr,
location: Location,
parents: ScopeArray,
logger: &dyn Fn(Log),
) -> V {
if let Some(lift) = self.lifts.borrow().get(&key) {
if let Some((parent, rest)) = parents.split() {
parent.remove(lift.0.clone(), location, rest, logger)
} else {
self.remove_inner(lift.0.clone(), location, parents, logger)
}
} else {
self.remove_inner(key, location, parents, logger)
}
}
fn remove_inner<V: Any>(
&self,
key: CowStr,
location: Location,
parents: ScopeArray,
logger: &dyn Fn(Log),
) -> V {
let mut this = self.items.borrow_mut();
let Some(item): Option<Item> = this.remove(&key) else {
if let Some((parent, rest)) = parents.split() {
return parent.remove(key, location, rest, logger);
} else {
panic!("bypass: key not present: {:?}", key)
}
};
let log = Log {
operation: Operation::Remove,
source: item.location,
destination: location,
key: &key,
};
logger(log);
let result = (item.item)
.downcast::<V>()
.unwrap_or_else(|_| panic!("bypass: type not as expected"));
*result
}
}
impl fmt::Debug for Store {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
for (lift_from, lift_to) in self.lifts.borrow().iter() {
writeln!(
f,
"Lift: {:?} -> {:?} [{}]",
lift_from, lift_to.0, lift_to.1
)?;
}
for (key, item) in self.items.borrow().iter() {
writeln!(
f,
"Entry: {:?}: {} [{}]",
key, item.type_name, item.location
)?;
}
Ok(())
}
}
pub struct Lift(&'static std::thread::LocalKey<RefCell<ScopeInner>>, CowStr);
impl Lift {
fn new(scope: &'static std::thread::LocalKey<RefCell<ScopeInner>>, name: CowStr) -> Self {
Self(scope, name)
}
pub fn to<T: Into<CowStr>>(self, to: T) {
let to = to.into();
self.0.with_borrow_mut(|x| {
x.scopes.last_mut().expect(NO_SCOPE).lift_to(self.1, to);
});
}
}
const NO_SCOPE: &str = "bypass: scope has not been created";
pub struct Scope {
#[doc(hidden)]
pub inner: &'static std::thread::LocalKey<RefCell<ScopeInner>>,
}
impl Scope {
pub fn scope<F, R>(&self, work: F) -> R
where
F: FnOnce() -> R,
{
self.inner.with_borrow_mut(|x| x.scopes.push(Store::new()));
struct OnDrop<'a>(&'a Scope);
impl Drop for OnDrop<'_> {
fn drop(&mut self) {
self.0.inner.with_borrow_mut(|x| x.scopes.pop());
}
}
let on_drop = OnDrop(self);
let result = (work)();
drop(on_drop);
result
}
pub fn debug<F>(&self, log: F)
where
F: Fn(Log) + 'static,
{
self.inner.with_borrow_mut(|x| x.debug = Box::new(log));
}
#[track_caller]
pub fn lift<A: Into<CowStr>>(&self, from: A) -> Lift {
let location = panic::Location::caller();
let from = from.into();
self.inner.with_borrow(|x| {
x.scopes
.last()
.expect(NO_SCOPE)
.lift(from.clone(), location);
Lift::new(self.inner, from)
})
}
#[track_caller]
pub fn insert<K: Into<CowStr>, V: Any>(&self, key: K, value: V) {
let key = key.into();
let location = panic::Location::caller();
self.inner.with_borrow(|x| {
let items = ScopeArray::new(&x.scopes[..]);
if let Some((scope, rest)) = items.split() {
scope.insert(key, value, location, rest);
} else {
panic!("{}", NO_SCOPE);
}
})
}
#[track_caller]
pub fn insert_clone<K: Into<CowStr>, V: Any + Clone>(&self, key: K, value: V) -> V {
let clone = value.clone();
self.insert(key, clone);
value
}
#[track_caller]
pub fn get<V: Any + Clone, K: Into<CowStr>>(&self, key: K) -> V {
let key = key.into();
let location = panic::Location::caller();
self.inner.with_borrow(|x| {
let items = ScopeArray::new(&x.scopes[..]);
if let Some((scope, rest)) = items.split() {
scope.get(key, location, rest, &x.debug)
} else {
panic!("{}", NO_SCOPE)
}
})
}
#[track_caller]
pub fn modify<V: Any, K: Into<CowStr>, F: FnOnce(&mut V) -> R, R>(
&self,
key: K,
modifier: F,
) -> R {
let key = key.into();
let location = panic::Location::caller();
self.inner.with_borrow(|x| {
let items = ScopeArray::new(&x.scopes[..]);
if let Some((scope, rest)) = items.split() {
scope.modify(key, modifier, location, rest, &x.debug)
} else {
panic!("{}", NO_SCOPE)
}
})
}
#[track_caller]
pub fn remove<V: Any, K: Into<CowStr>>(&self, key: K) -> V {
let key = key.into();
let location = panic::Location::caller();
self.inner.with_borrow(|x| {
let items = ScopeArray::new(&x.scopes[..]);
if let Some((scope, rest)) = items.split() {
scope.remove(key, location, rest, &x.debug)
} else {
panic!("{}", NO_SCOPE)
}
})
}
}
impl fmt::Debug for Scope {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.inner.with_borrow(|x| x.fmt(f))
}
}
#[doc(hidden)]
pub struct ScopeInner {
scopes: Vec<Store>,
debug: Box<dyn Fn(Log)>,
}
impl ScopeInner {
#[allow(clippy::new_without_default)]
pub fn new() -> Self {
Self {
scopes: Vec::new(),
debug: Box::new(|log| {
eprintln!("{}", log);
}),
}
}
}
impl fmt::Debug for ScopeInner {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
for (idx, scope) in self.scopes.iter().enumerate() {
writeln!(f, "===== Scope {} =====", idx)?;
scope.fmt(f)?;
}
Ok(())
}
}