totally sync variables
init
| -rw-r--r-- | .gitignore | 1 | ||||
| -rw-r--r-- | Cargo.lock | 47 | ||||
| -rw-r--r-- | Cargo.toml | 11 | ||||
| -rw-r--r-- | README.md | 1 | ||||
| -rw-r--r-- | src/lib.rs | 109 |
5 files changed, 169 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..ddcdbeb --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,47 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "itoa" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b02a5381cc465bd3041d84623d0fa3b66738b52b8e2fc3bab8ad63ab032f4a" + +[[package]] +name = "paste" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4b27ab7be369122c218afc2079489cdcb4b517c0a3fc386ff11e1fedfcc2b35" + +[[package]] +name = "ryu" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe232bdf6be8c8de797b22184ee71118d63780ea42ac85b61d1baa6d3b782ae9" + +[[package]] +name = "serde" +version = "1.0.171" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30e27d1e4fd7659406c492fd6cfaf2066ba8773de45ca75e855590f856dc34a9" + +[[package]] +name = "serde_json" +version = "1.0.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f1e14e89be7aa4c4b78bdbdc9eb5bf8517829a600ae8eaa39a6e1d960b5185c" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "totally-sync-variable" +version = "0.1.0" +dependencies = [ + "paste", + "serde", + "serde_json", +] diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..bfae105 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "totally-sync-variable" +version = "0.1.0" +edition = "2021" +authors = ["bendn <[email protected]>"] +homepage = "https://github.com/bend-n/totally-sync-variable" + +[dependencies] +paste = "1.0" +serde = "1" +serde_json = "1.0" diff --git a/README.md b/README.md new file mode 100644 index 0000000..cff8a58 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +# totally sync variable diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..51fdcef --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,109 @@ +//! # 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 🔐) +#[doc(hidden)] +pub struct Var<T>(&'static str, PhantomData<T>); + +impl<T> Var<T> { + /// create a var + pub fn new(name: &'static str) -> Self { + Self(name, PhantomData::default()) + } +} + +impl<T: Serialize> Var<T> { + /// 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<T: DeserializeOwned> Var<T> { + /// 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<T: [<$op>]<T, Output = T> + Clone + DeserializeOwned + Serialize> [<$op Assign>] for Var<T> { + fn [<$op:lower _assign>](&mut self, rhs: Self) { + self.set(&(self.get().clone() $char rhs.get().clone())); + } + } + }}; +} + +op!(Add, +); +op!(Sub, -); +op!(Mul, *); +op!(Div, /); +op!(BitAnd, &); +op!(BitOr, |); +op!(BitXor, ^); +op!(Shl, <<); +op!(Shr, >>); + +#[macro_export] +/// lil macro to define variables. +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. +macro_rules! refer { + ($name:ident) => { + $crate::Var::new(stringify!($name)).get() + }; +} + +#[test] +fn it_works() { + { + let mut x = def!(x = 4u8); + x += def!(tmp = 4u8); + assert_eq!(x.get(), 8); + } + let v: u8 = refer!(x); + assert_eq!(v, 8) +} |