freya_core/lifecycle/
readable.rs1use std::rc::Rc;
4
5use crate::prelude::*;
6
7pub struct Readable<T: 'static> {
49 pub(crate) read_fn: Rc<dyn Fn() -> ReadableRef<T>>,
50 pub(crate) peek_fn: Rc<dyn Fn() -> ReadableRef<T>>,
51 pub(crate) equal_fn: Rc<dyn Fn(&T) -> bool>,
52}
53
54impl<T: 'static> Clone for Readable<T> {
55 fn clone(&self) -> Self {
56 Self {
57 read_fn: self.read_fn.clone(),
58 peek_fn: self.peek_fn.clone(),
59 equal_fn: self.equal_fn.clone(),
60 }
61 }
62}
63
64impl<T: 'static> PartialEq for Readable<T> {
65 fn eq(&self, other: &Self) -> bool {
66 (self.equal_fn)(&*other.peek())
67 }
68}
69
70impl<T: PartialEq> From<T> for Readable<T> {
71 fn from(value: T) -> Self {
72 Readable::from_value(value)
73 }
74}
75
76impl<T: 'static + PartialEq> Readable<T> {
77 pub fn from_value(value: T) -> Self {
79 let value = Rc::new(value);
80 Self {
81 read_fn: Rc::new({
82 let value = value.clone();
83 move || ReadableRef::Borrowed(value.clone())
84 }),
85 peek_fn: Rc::new({
86 let value = value.clone();
87 move || ReadableRef::Borrowed(value.clone())
88 }),
89 equal_fn: Rc::new(move |other| other == &*value),
90 }
91 }
92}
93impl<T: 'static> Readable<T> {
94 pub fn from_state(state: State<T>) -> Self {
96 Self {
97 read_fn: Rc::new(move || ReadableRef::Ref(state.read())),
98 peek_fn: Rc::new(move || ReadableRef::Ref(state.peek())),
99 equal_fn: Rc::new(move |_| true),
100 }
101 }
102
103 pub fn new(
105 read_fn: Box<dyn Fn() -> ReadableRef<T>>,
106 peek_fn: Box<dyn Fn() -> ReadableRef<T>>,
107 equal_fn: Box<dyn Fn(&T) -> bool>,
108 ) -> Self {
109 Self {
110 read_fn: Rc::from(read_fn),
111 peek_fn: Rc::from(peek_fn),
112 equal_fn: Rc::from(equal_fn),
113 }
114 }
115
116 pub fn read(&self) -> ReadableRef<T> {
123 (self.read_fn)()
124 }
125
126 pub fn peek(&self) -> ReadableRef<T> {
128 (self.peek_fn)()
129 }
130}
131
132pub trait IntoReadable<T: 'static> {
133 fn into_readable(self) -> Readable<T>;
134}
135
136impl<T: 'static> IntoReadable<T> for State<T> {
137 fn into_readable(self) -> Readable<T> {
138 Readable::from_state(self)
139 }
140}
141
142impl<T: 'static + PartialEq> IntoReadable<T> for T {
143 fn into_readable(self) -> Readable<T> {
144 Readable::from_value(self)
145 }
146}
147
148impl<T: 'static> IntoReadable<T> for Memo<T> {
149 fn into_readable(self) -> Readable<T> {
150 Readable::from_state(self.state)
151 }
152}
153
154impl<T> From<State<T>> for Readable<T> {
155 fn from(value: State<T>) -> Self {
156 value.into_readable()
157 }
158}
159
160impl<T> From<Memo<T>> for Readable<T> {
161 fn from(value: Memo<T>) -> Self {
162 value.into_readable()
163 }
164}