//! # the totally sync variables. //! ## features //! - make any variable, pass it round! //! - scoping? who needs it! //! - only one mutable reference? pshaw! //! - any numer of mutable references are allowed. // //! ## data races? //! dont know what your talking about. //! //! its *fearless concurrency* remember? and theres no unsafe code! //! //! besides, miri says its fiine. #![deny(unsafe_code)] #![allow(dead_code)] use serde::{de::DeserializeOwned, Serialize}; use std::fs; use std::io::{BufReader, BufWriter}; use std::marker::PhantomData; use std::ops::*; use std::path::Path; /// a variable stored on the filesystem (very secure 🔐) pub struct Var(&'static str, PhantomData); impl Var { /// create a var pub fn new(name: &'static str) -> Self { Self(name, PhantomData::default()) } } impl Var { /// interior mutability! /// ``` /// # use totally_sync_variable::*; /// let x = def!(x = 5u8); /// x.set(&3u8); /// ``` pub fn set(&self, v: &T) { let f = BufWriter::new( fs::File::create(Path::new("/tmp/").join(self.0)).expect("become linux!"), ); serde_json::to_writer(f, v).unwrap(); } } impl Var { /// procure the stored variable /// ``` /// # use totally_sync_variable::*; /// let y = def!(y = 5u8); /// assert_eq!(y.get(), 5u8); /// ``` pub fn get(&self) -> T { let f = BufReader::new(fs::File::open(Path::new("/tmp/").join(self.0)).expect("oh no")); serde_json::from_reader(f).unwrap() } } macro_rules! op { ($op: ident, $char: tt) => {paste::paste! { impl] + Clone + DeserializeOwned + Serialize> [<$op Assign>] for Var { fn [<$op:lower _assign>](&mut self, rhs: Self) { self.set(&(self.get().clone() $char rhs.get().clone())); } } impl] + Clone + DeserializeOwned + Serialize> [<$op Assign>] for Var { fn [<$op:lower _assign>](&mut self, rhs: T) { self.set(&(self.get().clone() $char rhs)); } } }}; } op!(Add, +); op!(Sub, -); op!(Mul, *); op!(Div, /); op!(BitAnd, &); op!(BitOr, |); op!(BitXor, ^); op!(Shl, <<); op!(Shr, >>); op!(Rem, %); #[macro_export] /// lil macro to define variables. /// ``` /// # use totally_sync_variable::*; /// let v = def!(example = String::from("def!()")); /// ``` macro_rules! def { ($name:ident = $value:expr) => {{ let v = $crate::Var::new(stringify!($name)); v.set(&$value); v }}; } #[macro_export] /// macro to reference variables from anywhere. /// ``` /// # use totally_sync_variable::*; /// { /// let x = def!(cant_touch_this = 0u128); /// } /// let it_exists: u128 = refer!(cant_touch_this); /// assert_eq!(it_exists, 0); // yes i can! /// ``` macro_rules! refer { ($name:ident) => { $crate::Var::new(stringify!($name)).get() }; } #[test] fn it_works() { { let mut x = def!(x = 4u8); x += 4; assert_eq!(x.get(), 8); } let v: u8 = refer!(x); assert_eq!(v, 8) }