Skip to main content

dioxus_native_dom/
write_once_attr.rs

1use std::{cell::RefCell, rc::Rc, sync::atomic::AtomicUsize};
2
3use blitz_dom::{Document, Widget};
4use dioxus_core::{AttributeValue, IntoAttributeValue};
5
6#[derive(Clone, PartialEq)]
7pub struct SubDocumentAttr(WriteOnceAttr<Box<dyn Document>>);
8
9impl SubDocumentAttr {
10    /// Accepts any [`Document`] implementation, e.g. a plain [`BaseDocument`](blitz_dom::BaseDocument).
11    pub fn new(doc: impl Document) -> Self {
12        let id = doc.id();
13        Self(WriteOnceAttr::new(id, Box::new(doc) as Box<dyn Document>))
14    }
15}
16
17impl IntoAttributeValue for SubDocumentAttr {
18    fn into_value(self) -> AttributeValue {
19        AttributeValue::Any(Rc::new(self.0))
20    }
21}
22
23static ID_COUNTER: AtomicUsize = AtomicUsize::new(0);
24
25#[derive(Clone, PartialEq)]
26pub struct CustomWidgetAttr(WriteOnceAttr<Box<dyn Widget>>);
27
28impl CustomWidgetAttr {
29    pub fn new<T: Widget + 'static>(widget: T) -> Self {
30        let id = ID_COUNTER.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
31        let boxed = Box::new(widget) as Box<dyn Widget>;
32        Self(WriteOnceAttr::new(id, boxed))
33    }
34}
35
36impl IntoAttributeValue for CustomWidgetAttr {
37    fn into_value(self) -> AttributeValue {
38        AttributeValue::Any(Rc::new(self.0))
39    }
40}
41
42pub(crate) struct WriteOnceAttr<T> {
43    id: usize,
44    value: Rc<RefCell<Option<T>>>,
45}
46
47impl<T> WriteOnceAttr<T> {
48    pub(crate) fn new(id: usize, value: T) -> Self {
49        let value = Rc::new(RefCell::new(Some(value)));
50        Self { id, value }
51    }
52    pub(crate) fn take(&self) -> Option<T> {
53        self.value.borrow_mut().take()
54    }
55}
56
57impl<T> Clone for WriteOnceAttr<T> {
58    fn clone(&self) -> Self {
59        Self {
60            id: self.id,
61            value: Rc::clone(&self.value),
62        }
63    }
64}
65
66impl<T> PartialEq for WriteOnceAttr<T> {
67    fn eq(&self, other: &Self) -> bool {
68        self.id == other.id
69    }
70}