From 4447709ac85fba020fb1f49738a6b7d89189efb4 Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Mon, 7 Aug 2023 17:49:14 -0700 Subject: [PATCH] add readmes --- packages/generational-box/README.md | 2 +- packages/generational-box/src/lib.rs | 11 ++++++ packages/signals/README.md | 56 ++++++++++++++++++++++++++++ packages/signals/src/lib.rs | 3 ++ 4 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 packages/signals/README.md diff --git a/packages/generational-box/README.md b/packages/generational-box/README.md index d4600dd53..5ab7926ba 100644 --- a/packages/generational-box/README.md +++ b/packages/generational-box/README.md @@ -2,7 +2,7 @@ Generational Box is a runtime for Rust that allows any static type to implement `Copy`. It can be combined with a global runtime to create an ergonomic state solution like `dioxus-signals`. This crate contains no `unsafe` code. -There are three main types that manage state in Generational Box: +Three main types manage state in Generational Box: - Store: Handles recycling generational boxes that have been dropped. Your application should have one store or one store per thread. - Owner: Handles dropping generational boxes. The owner acts like a runtime lifetime guard. Any states that you create with an owner will be dropped when that owner is dropped. diff --git a/packages/generational-box/src/lib.rs b/packages/generational-box/src/lib.rs index dedd62d75..29c7ebdb2 100644 --- a/packages/generational-box/src/lib.rs +++ b/packages/generational-box/src/lib.rs @@ -1,3 +1,6 @@ +#![doc = include_str!("../README.md")] +#![warn(missing_docs)] + use std::{ cell::{Cell, Ref, RefCell, RefMut}, fmt::Debug, @@ -180,6 +183,7 @@ impl GenerationalBox { } } + /// Try to read the value. Returns None if the value is no longer valid. pub fn try_read(&self) -> Option> { self.validate() .then(|| { @@ -191,10 +195,12 @@ impl GenerationalBox { .flatten() } + /// Read the value. Panics if the value is no longer valid. pub fn read(&self) -> Ref<'_, T> { self.try_read().unwrap() } + /// Try to write the value. Returns None if the value is no longer valid. pub fn try_write(&self) -> Option> { self.validate() .then(|| { @@ -206,16 +212,19 @@ impl GenerationalBox { .flatten() } + /// Write the value. Panics if the value is no longer valid. pub fn write(&self) -> RefMut<'_, T> { self.try_write().unwrap() } + /// Set the value. Panics if the value is no longer valid. pub fn set(&self, value: T) { self.validate().then(|| { *self.raw.data.borrow_mut() = Some(Box::new(value)); }); } + /// Returns true if the pointer is equal to the other pointer. pub fn ptr_eq(&self, other: &Self) -> bool { #[cfg(any(debug_assertions, feature = "check_generation"))] { @@ -304,6 +313,7 @@ impl Store { } } + /// Create a new owner. The owner will be responsible for dropping all of the generational boxes that it creates. pub fn owner(&self) -> Owner { Owner { store: self.clone(), @@ -319,6 +329,7 @@ pub struct Owner { } impl Owner { + /// Insert a value into the store. The value will be dropped when the owner is dropped. pub fn insert(&self, value: T) -> GenerationalBox { let mut location = self.store.claim(); let key = location.replace(value); diff --git a/packages/signals/README.md b/packages/signals/README.md new file mode 100644 index 000000000..e65c613fe --- /dev/null +++ b/packages/signals/README.md @@ -0,0 +1,56 @@ +# Dioxus Signals + +Dioxus Signals is an ergonomic Copy runtime for data with local subscriptions in Dioxus. + +## Copy Data + +All signals implement Copy, even if the inner value does not implement copy. This makes it easy to move any data into futures or children. + +```rust +fn App(cx: Scope) -> Element { + let signal = use_signal(cx, || "hello world".to_string()); + + spawn(async move { + // signal is Copy even though String is not copy + signal + }); + + render! { + "{signal}" + } +} +``` + +## Local Subscriptions + +Signals will only subscribe to components when you read from the signal in that component. It will never subscribe to a component when reading data in a future or event handler. + +```rust +fn app(cx: Scope) -> Element { + // Because signal is never read in this component, this component will not rerun when the signal changes + let signal = use_signal(cx, || 0); + + render! { + onclick: move |_| { + *signal.write() += 1; + } + for id in 0..10 { + Child { + signal: signal, + } + } + } +} + +#[derive(Props, Clone, PartialEq)] +struct ChildProps { + signal: Signal, +} + +fn Child(cx: Scope) -> Element { + // This component does read from the signal, so when the signal changes it will rerun + render! { + "{cx.props.signal}" + } +} +``` diff --git a/packages/signals/src/lib.rs b/packages/signals/src/lib.rs index b667fe074..1c67ab462 100644 --- a/packages/signals/src/lib.rs +++ b/packages/signals/src/lib.rs @@ -1,3 +1,6 @@ +#![doc = include_str!("../README.md")] +#![warn(missing_docs)] + mod rt; pub use rt::*; mod effect;