dioxus_keys/lib.rs
1use std::ops::{Deref, DerefMut};
2
3use dioxus_lib::prelude::*;
4
5mod macros;
6
7#[allow(async_fn_in_trait)]
8pub trait DataKey {
9 type Value: Clone + 'static;
10 async fn init();
11 async fn on_change();
12 async fn on_drop();
13 fn read() -> impl Deref<Target = Self::Value> {
14 Self::try_read().unwrap()
15 }
16 fn peek() -> impl Deref<Target = Self::Value> {
17 Self::try_read().unwrap()
18 }
19 fn write() -> impl DerefMut<Target = Self::Value> {
20 Self::try_write().unwrap()
21 }
22 fn try_read() -> Option<impl Deref<Target = Self::Value>>;
23 fn try_peek() -> Option<impl Deref<Target = Self::Value>>;
24 fn try_write() -> Option<impl DerefMut<Target = Self::Value>>;
25}
26
27pub fn use_init_key<K: DataKey<Value = V>, V>(_key: K) -> Resource<()> {
28 use_effect(move || {
29 let val = K::try_read();
30 if val.is_some() {
31 spawn(async { K::on_change().await });
32 }
33 });
34
35 use_drop(|| {
36 spawn(async { K::on_drop().await });
37 });
38
39 use_resource(|| async { K::init().await })
40}
41
42//
43// struct ExampleKey;
44//
45// type Val = Vec<u8>;
46// const PATH: &str = "some path";
47// const SERIALIZE: fn(&Val) -> &[u8] = |val| val;
48// const DESERIALIZE: fn(&[u8]) -> Val = |contents| contents.to_vec();
49//
50// static DATA: Global<Signal<Option<Option<Val>>, SyncStorage>> =
51// Global::new(|| Signal::new_maybe_sync(None));
52//
53// impl DataKey for ExampleKey {
54// type Value = Option<Val>;
55//
56// async fn init() {
57// let path = PathBuf::from(PATH);
58// if path.try_exists().unwrap() {
59// let mut file = File::open(path).await.unwrap();
60// let mut contents = Vec::new();
61// file.read_to_end(&mut contents).await.unwrap();
62// *DATA.resolve().write() = Some(Some((DESERIALIZE)(&contents)));
63// } else {
64// *DATA.resolve().write() = Some(None);
65// }
66// }
67//
68// async fn on_change() {
69// let resolve = DATA.resolve();
70// let read = resolve.read();
71// let Some(data) = read.deref().as_ref() else {
72// return;
73// };
74//
75// if let Some(data) = data {
76// let mut file = File::create(PathBuf::from(PATH)).await.unwrap();
77// file.write_all((SERIALIZE)(data)).await.unwrap();
78// } else {
79// let _ = remove_file(PATH).await;
80// }
81// }
82//
83// async fn on_drop() {}
84//
85// fn try_read() -> Option<impl Deref<Target = Self::Value>> {
86// SyncStorage::try_map(DATA.resolve().read_unchecked(), |v| v.as_ref())
87// }
88//
89// fn try_write() -> Option<impl DerefMut<Target = Self::Value>> {
90// Signal::<Option<Self::Value>, SyncStorage>::try_map_mut(
91// DATA.resolve().write_unchecked(),
92// |v| v.as_mut(),
93// )
94// }
95// }