#[derive(Debug, Clone)]
pub struct StaticContainer<T> {
value: T,
}
impl<T> StaticContainer<T> {
pub fn new(value: T) -> Self {
Self { value }
}
pub fn get(&self) -> &T {
&self.value
}
pub fn get_mut(&mut self) -> &mut T {
&mut self.value
}
pub fn into_inner(self) -> T {
self.value
}
pub fn map<U, F: FnOnce(T) -> U>(self, f: F) -> StaticContainer<U> {
StaticContainer {
value: f(self.value),
}
}
}
#[derive(Debug, Clone, Copy)]
pub struct StaticBuilder<T, F>
where
F: FnOnce() -> T,
{
factory: F,
}
impl<T, F> StaticBuilder<T, F>
where
F: FnOnce() -> T,
{
pub fn new(factory: F) -> Self {
Self { factory }
}
pub fn build(self) -> StaticContainer<T> {
StaticContainer {
value: (self.factory)(),
}
}
}
#[macro_export]
macro_rules! hex_static {
($block:block) => {{
let value = (|| $block)();
$crate::static_di::StaticContainer::new(value)
}};
}
#[cfg(test)]
mod tests {
use super::*;
#[derive(Clone, Debug, PartialEq, Eq)]
struct A(u8);
#[derive(Clone, Debug, PartialEq, Eq)]
struct B {
a: A,
}
#[test]
fn builds_static_graph() {
let app = crate::hex_static!({
let a = A(7);
let b = B { a: a.clone() };
(a, b)
});
let (a, b) = app.into_inner();
assert_eq!(b.a, a);
}
#[test]
fn builder_works() {
let c = StaticBuilder::new(|| 42).build();
assert_eq!(*c.get(), 42);
let d = c.map(|x| x + 1);
assert_eq!(d.into_inner(), 43);
}
}