use std::{cmp::Eq, fmt::Debug};
use crate::prelude::*;
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum Key {
Number(isize),
String(CowArc<str>),
Pointer(*const ()),
}
impl<T: ?Sized> From<*const T> for Key {
fn from(p: *const T) -> Self { Key::Pointer(p as *const ()) }
}
impl From<isize> for Key {
fn from(value: isize) -> Self { Key::Number(value) }
}
impl From<String> for Key {
fn from(s: String) -> Self { Key::String(s.into()) }
}
impl From<&str> for Key {
fn from(s: &str) -> Self { Key::String(s.to_string().into()) }
}
#[simple_declare(stateless)]
pub struct KeyWidget {
pub(crate) key: Key,
}
impl KeyWidget {
pub fn with_child<'c, const M: usize, W>(self, child: W) -> (Key, Widget<'c>)
where
W: IntoWidget<'c, M>,
{
(self.key, child.into_widget())
}
}
#[cfg(test)]
mod tests {
use crate::{prelude::*, reset_test_env, test_helper::*};
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
#[test]
fn key_widget() {
reset_test_env!();
struct IdGen {
id: usize,
}
impl IdGen {
fn new() -> Self { Self { id: 0 } }
fn next(&mut self) -> usize {
let id = self.id;
self.id += 1;
id
}
}
let mut id_gen = IdGen::new();
let (items_reader, items) = split_value(vec![]);
let (mounts_id, mounts) = split_value(vec![]);
items.write().push(id_gen.next());
items.write().push(id_gen.next());
let w = fn_widget! {
@MockMulti {
@ {
pipe!($items_reader;).map(move |_| {
move || {
$items_reader.clone().into_iter().map(move |id| {
@KeyWidget {
key: id as isize,
@Void {
on_mounted: move |_| {$mounts.write().push(id);}
}
}
})
}
})
}
}
};
let mut wnd = TestWindow::new(w);
wnd.draw_frame();
assert_eq!(*mounts_id.read(), vec![0, 1]);
items.write().push(id_gen.next());
wnd.draw_frame();
assert_eq!(*mounts_id.read(), vec![0, 1, 2]);
items.write().remove(1);
wnd.draw_frame();
assert_eq!(*mounts_id.read(), vec![0, 1, 2]);
}
}