1use std::any::TypeId;
2use std::borrow::Borrow;
3use std::fmt::{Debug, Formatter};
4use std::hash::Hash;
5use std::marker::PhantomData;
6use std::ops::{BitAnd, BitOr, Deref};
7use std::rc::Rc;
8
9use crate::context::{CURRENT, MAPS, MAP_MANAGER};
10
11use super::{MapId, StoreId};
12
13pub trait Lens: 'static + Copy + Debug {
19 type Source;
20 type Target;
21
22 fn view<'a>(&self, source: &'a Self::Source) -> Option<LensValue<'a, Self::Target>>;
23 fn id(&self) -> StoreId {
24 StoreId::Source(TypeId::of::<Self>())
25 }
26}
27
28pub enum LensValue<'a, T> {
30 Borrowed(&'a T),
32 Owned(T),
34}
35
36impl<T: Clone> Clone for LensValue<'_, T> {
37 fn clone(&self) -> Self {
38 match self {
39 LensValue::Borrowed(v) => LensValue::Borrowed(*v),
40 LensValue::Owned(v) => LensValue::Owned(v.clone()),
41 }
42 }
43}
44
45impl<T: Copy> Copy for LensValue<'_, T> {}
46
47impl<T: Clone> LensValue<'_, T> {
48 pub fn into_owned(self) -> T {
49 match self {
50 LensValue::Borrowed(t) => t.clone(),
51 LensValue::Owned(t) => t,
52 }
53 }
54}
55
56impl<T> AsRef<T> for LensValue<'_, T> {
57 fn as_ref(&self) -> &T {
58 self
59 }
60}
61
62impl<B> Deref for LensValue<'_, B>
63where
64 B: Borrow<B>,
65{
66 type Target = B;
67
68 fn deref(&self) -> &B {
69 match *self {
70 LensValue::Borrowed(borrowed) => borrowed,
71 LensValue::Owned(ref owned) => owned.borrow(),
72 }
73 }
74}
75
76pub trait LensExt: Lens {
78 fn or<Other>(self, other: Other) -> OrLens<Self, Other>
79 where
80 Other: Lens<Target = bool>,
81 Self: Lens<Target = bool>,
82 {
83 OrLens::new(self, other)
84 }
85
86 fn and<Other>(self, other: Other) -> AndLens<Self, Other>
87 where
88 Other: Lens<Target = bool>,
89 Self: Lens<Target = bool>,
90 {
91 AndLens::new(self, other)
92 }
93
94 fn then<Other>(self, other: Other) -> Then<Self, Other>
104 where
105 Other: Lens<Source = Self::Target>,
106 {
107 Then::new(self, other)
108 }
109
110 fn idx<T>(self, index: usize) -> Index<Self, T>
111 where
112 T: 'static,
113 Self::Target: Deref<Target = [T]>,
114 {
115 Index::new(self, index)
116 }
117
118 fn map<O: 'static, F: 'static + Fn(&Self::Target) -> O>(self, map: F) -> Map<Self, O> {
119 let id = MAP_MANAGER.with_borrow_mut(|f| f.create());
120 let entity = CURRENT.with_borrow(|f| *f);
121 MAPS.with_borrow_mut(|f| {
122 f.insert(id, (entity, Box::new(MapState { closure: Rc::new(map) })))
123 });
124 Map { id, lens: self, o: PhantomData }
125 }
126
127 fn map_ref<O: 'static, F: 'static + Fn(&Self::Target) -> &O>(self, map: F) -> MapRef<Self, O> {
128 let id = MAP_MANAGER.with_borrow_mut(|f| f.create());
129 let entity = CURRENT.with_borrow(|f| *f);
130 MAPS.with_borrow_mut(|f| {
131 f.insert(id, (entity, Box::new(MapRefState { closure: Rc::new(map) })))
132 });
133 MapRef { id, lens: self, o: PhantomData }
134 }
135
136 fn unwrap<T: 'static>(self) -> Then<Self, UnwrapLens<T>>
137 where
138 Self: Lens<Target = Option<T>>,
139 {
140 self.then(UnwrapLens::new())
141 }
142
143 fn into_lens<T: 'static>(self) -> Then<Self, IntoLens<Self::Target, T>>
144 where
145 Self::Target: Clone + Into<T>,
146 {
147 self.then(IntoLens::new())
148 }
149}
150
151impl<T: Lens> LensExt for T {}
153
154pub struct MapState<T, O> {
155 closure: Rc<dyn Fn(&T) -> O>,
156}
157
158pub struct MapRefState<T, O> {
159 closure: Rc<dyn Fn(&T) -> &O>,
160}
161
162pub struct Map<L: Lens, O> {
163 id: MapId,
164 lens: L,
165 o: PhantomData<O>,
166}
167
168impl<L: Lens, O: 'static> Copy for Map<L, O> {}
169
170impl<L: Lens, O: 'static> Clone for Map<L, O> {
171 fn clone(&self) -> Self {
172 *self
173 }
174}
175
176impl<L: Lens, O: 'static> Lens for Map<L, O> {
177 type Source = L::Source;
178 type Target = O;
179
180 fn view<'a>(&self, source: &'a Self::Source) -> Option<LensValue<'a, Self::Target>> {
181 let target = self.lens.view(source)?;
182 let closure = MAPS.with_borrow(|f| {
183 let (_, any) = f.get(&self.id)?;
184 let MapState { closure } = any.downcast_ref()?;
185 Some(closure.clone())
186 })?;
187 Some(LensValue::Owned(closure(&*target)))
188 }
189
190 fn id(&self) -> StoreId {
191 StoreId::Map(self.id.0)
192 }
193}
194
195impl<L: Lens, O: 'static> Debug for Map<L, O> {
196 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
197 f.write_fmt(format_args!("{:?}.map(?)", self.lens))
198 }
199}
200
201pub struct MapRef<L: Lens, O> {
202 id: MapId,
203 lens: L,
204 o: PhantomData<O>,
205}
206
207impl<L: Lens, O: 'static> Copy for MapRef<L, O> {}
208
209impl<L: Lens, O: 'static> Clone for MapRef<L, O> {
210 fn clone(&self) -> Self {
211 *self
212 }
213}
214
215impl<L: Lens, O: 'static + Clone> Lens for MapRef<L, O> {
216 type Source = L::Source;
217 type Target = O;
218
219 fn view<'a>(&self, source: &'a Self::Source) -> Option<LensValue<'a, Self::Target>> {
220 let closure = MAPS.with_borrow(|f| {
221 let (_, any) = f.get(&self.id)?;
222 let MapRefState { closure } = any.downcast_ref()?;
223 Some(closure.clone())
224 })?;
225
226 match self.lens.view(source)? {
227 LensValue::Borrowed(target) => Some(LensValue::Borrowed(closure(target))),
228 LensValue::Owned(target) => Some(LensValue::Owned(closure(&target).clone())),
229 }
230 }
231
232 fn id(&self) -> StoreId {
233 StoreId::Map(self.id.0)
234 }
235}
236
237impl<L: Lens, O: 'static> Debug for MapRef<L, O> {
238 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
239 f.write_fmt(format_args!("{:?}.map(?)", self.lens))
240 }
241}
242
243pub struct Then<A, B> {
245 a: A,
246 b: B,
247}
248
249impl<A, B> Then<A, B> {
250 pub fn new(a: A, b: B) -> Self
251 where
252 A: Lens,
253 B: Lens,
254 {
255 Self { a, b }
256 }
257}
258
259impl<A, B> Lens for Then<A, B>
260where
261 A: Lens,
262 B: Lens<Source = A::Target>,
263{
264 type Source = A::Source;
265 type Target = B::Target;
266
267 fn view<'a>(&self, source: &'a Self::Source) -> Option<LensValue<'a, Self::Target>> {
268 if let Some(val) = self.a.view(source) {
269 let val = match val {
270 LensValue::Borrowed(val) => return self.b.view(val),
271 LensValue::Owned(ref val) => val,
272 };
273 match self.b.view(val) {
274 Some(LensValue::Owned(val)) => return Some(LensValue::Owned(val)),
275 _ => unreachable!(),
276 }
277 }
278
279 None
280 }
281
282 fn id(&self) -> StoreId {
283 StoreId::Recursive((self.a.id(), self.b.id()).into())
284 }
285}
286
287impl<T: Clone, U: Clone> Clone for Then<T, U> {
288 fn clone(&self) -> Self {
289 Self { a: self.a.clone(), b: self.b.clone() }
290 }
291}
292
293impl<A: Lens, B: Lens> Debug for Then<A, B> {
294 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
295 f.write_fmt(format_args!("{:?}.then({:?})", self.a, self.b))
296 }
297}
298
299impl<T: Copy, U: Copy> Copy for Then<T, U> {}
300
301pub struct Index<L, T> {
302 lens: L,
303 index: usize,
304 pt: PhantomData<T>,
305}
306
307impl<L, T> Index<L, T> {
308 pub fn new(lens: L, index: usize) -> Self {
309 Self { lens, index, pt: PhantomData }
310 }
311
312 pub fn idx(&self) -> usize {
313 self.index
314 }
315}
316
317impl<L: Lens, T> Clone for Index<L, T> {
318 fn clone(&self) -> Self {
319 *self
320 }
321}
322
323impl<L: Lens, T> Copy for Index<L, T> {}
324
325impl<L: Lens, T> Debug for Index<L, T> {
326 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
327 f.write_fmt(format_args!("{:?}.index({:?})", self.lens, self.index))
328 }
329}
330
331impl<L, T> Lens for Index<L, T>
332where
333 L: Lens<Target: Deref<Target = [T]>>,
334 T: 'static + Clone,
335{
336 type Source = L::Source;
337 type Target = T;
338
339 fn view<'a>(&self, source: &'a Self::Source) -> Option<LensValue<'a, Self::Target>> {
340 self.lens.view(source).and_then(|v| match v {
341 LensValue::Borrowed(v) => v.get(self.index).map(LensValue::Borrowed),
342 LensValue::Owned(v) => v.get(self.index).cloned().map(LensValue::Owned),
343 })
344 }
345
346 fn id(&self) -> StoreId {
347 StoreId::Index(TypeId::of::<Self>(), self.index)
348 }
349}
350
351pub struct StaticLens<T: 'static> {
352 data: &'static T,
353}
354
355impl<T> Clone for StaticLens<T> {
356 fn clone(&self) -> Self {
357 *self
358 }
359}
360
361impl<T> Copy for StaticLens<T> {}
362
363impl<T> Debug for StaticLens<T> {
364 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
365 f.write_str("Static Lens: ")?;
366 TypeId::of::<T>().fmt(f)?;
367 Ok(())
368 }
369}
370
371impl<T> Lens for StaticLens<T> {
372 type Source = ();
373 type Target = T;
374
375 fn view<'a>(&self, _: &'a Self::Source) -> Option<LensValue<'a, Self::Target>> {
376 Some(LensValue::Borrowed(self.data))
377 }
378}
379
380impl<T> StaticLens<T> {
381 pub fn new(data: &'static T) -> Self {
382 StaticLens { data }
383 }
384}
385
386#[derive(Default)]
387pub struct UnwrapLens<T> {
388 t: PhantomData<T>,
389}
390
391impl<T> Clone for UnwrapLens<T> {
392 fn clone(&self) -> Self {
393 *self
394 }
395}
396
397impl<T> UnwrapLens<T> {
398 pub fn new() -> Self {
399 Self { t: PhantomData }
400 }
401}
402
403impl<T> Copy for UnwrapLens<T> {}
404
405impl<T: 'static> Lens for UnwrapLens<T> {
406 type Source = Option<T>;
407 type Target = T;
408
409 fn view<'a>(&self, source: &'a Self::Source) -> Option<LensValue<'a, Self::Target>> {
410 source.as_ref().map(LensValue::Borrowed)
411 }
412}
413
414impl<T: 'static> Debug for UnwrapLens<T> {
415 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
416 f.write_str("unwrap")
417 }
418}
419
420#[derive(Default)]
421pub struct IntoLens<T, U> {
422 t: PhantomData<T>,
423 u: PhantomData<U>,
424}
425
426impl<T, U> IntoLens<T, U> {
427 pub fn new() -> Self {
428 Self { t: Default::default(), u: Default::default() }
429 }
430}
431
432impl<T, U> Clone for IntoLens<T, U> {
433 fn clone(&self) -> Self {
434 *self
435 }
436}
437
438impl<T, U> Copy for IntoLens<T, U> {}
439
440impl<T: 'static + Clone + TryInto<U>, U: 'static> Lens for IntoLens<T, U> {
441 type Source = T;
442 type Target = U;
443
444 fn view<'a>(&self, source: &'a Self::Source) -> Option<LensValue<'a, Self::Target>> {
445 source.clone().try_into().ok().map(|t| LensValue::Owned(t))
446 }
447}
448
449impl<T, U> Debug for IntoLens<T, U> {
450 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
451 f.write_str("into")
452 }
453}
454
455#[derive(Copy, Clone, Debug)]
456pub struct RatioLens<L1, L2> {
457 numerator: L1,
458 denominator: L2,
459}
460
461impl<L1, L2> RatioLens<L1, L2> {
462 pub fn new(numerator: L1, denominator: L2) -> Self {
463 Self { numerator, denominator }
464 }
465}
466
467impl<L1, L2> Lens for RatioLens<L1, L2>
468where
469 L1: 'static + Clone + Lens<Target = f32>,
470 L2: 'static + Clone + Lens<Target = f32, Source = <L1 as Lens>::Source>,
471{
472 type Source = L1::Source;
473 type Target = f32;
474
475 fn view<'a>(&self, source: &'a Self::Source) -> Option<LensValue<'a, f32>> {
476 let num = self.numerator.view(source)?.into_owned();
477 let den = self.denominator.view(source)?.into_owned();
478 Some(LensValue::Owned(num / den))
479 }
480}
481
482#[derive(Debug, Copy)]
483pub struct OrLens<L1, L2> {
484 lens1: L1,
485 lens2: L2,
486}
487
488impl<L1, L2> OrLens<L1, L2> {
489 pub fn new(lens1: L1, lens2: L2) -> Self
490 where
491 L1: Lens<Target = bool>,
492 L2: Lens<Target = bool>,
493 {
494 Self { lens1, lens2 }
495 }
496}
497
498impl<L1, L2> Lens for OrLens<L1, L2>
499where
500 L1: Lens<Source = L2::Source, Target = bool>,
501 L2: Lens<Target = bool>,
502{
503 type Source = L1::Source;
504 type Target = bool;
505
506 fn view<'a>(&self, source: &'a Self::Source) -> Option<LensValue<'a, Self::Target>> {
507 let v1 = self.lens1.view(source)?.into_owned();
508 let v2 = self.lens2.view(source)?.into_owned();
509
510 Some(LensValue::Owned(v1 | v2))
511 }
512}
513
514impl<L1: Clone, L2: Clone> Clone for OrLens<L1, L2> {
515 fn clone(&self) -> Self {
516 Self { lens1: self.lens1.clone(), lens2: self.lens2.clone() }
517 }
518}
519
520#[derive(Clone)]
521pub struct Wrapper<L>(pub L);
522
523impl<L: Copy> Copy for Wrapper<L> {}
524
525impl<L: Lens> Lens for Wrapper<L> {
526 type Source = L::Source;
527 type Target = L::Target;
528
529 fn view<'a>(&self, source: &'a Self::Source) -> Option<LensValue<'a, Self::Target>> {
530 self.0.view(source)
531 }
532}
533
534impl<L: Lens> Debug for Wrapper<L> {
535 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
536 self.0.fmt(f)
537 }
538}
539
540impl<L1: Lens<Target = bool>, L2: Lens<Target = bool>> BitOr<L2> for Wrapper<L1>
541where
542 L1: Lens<Source = L2::Source>,
543{
544 type Output = OrLens<Self, L2>;
545 fn bitor(self, rhs: L2) -> Self::Output {
546 OrLens::new(self, rhs)
547 }
548}
549
550impl<L1, L2, L3: Lens<Target = bool>> BitOr<L3> for OrLens<L1, L2>
551where
552 Self: Lens<Target = bool>,
553 Self: Lens<Source = L3::Source>,
554{
555 type Output = OrLens<Self, L3>;
556 fn bitor(self, rhs: L3) -> Self::Output {
557 OrLens::new(self, rhs)
558 }
559}
560
561impl<A: Lens, L1: Lens<Target = bool>, L2: Lens<Target = bool>> BitOr<L2> for Then<A, L1>
562where
563 A: Lens<Source = L2::Source>,
564 L1: Lens<Source = A::Target>,
565{
566 type Output = OrLens<Self, L2>;
567 fn bitor(self, rhs: L2) -> Self::Output {
568 OrLens::new(self, rhs)
569 }
570}
571
572impl<L, L2: Lens<Target = bool>> BitOr<L2> for Map<L, bool>
573where
574 L: Lens<Source = L2::Source>,
575{
576 type Output = OrLens<Self, L2>;
577 fn bitor(self, rhs: L2) -> Self::Output {
578 OrLens::new(self, rhs)
579 }
580}
581
582#[derive(Debug, Copy)]
583pub struct AndLens<L1, L2> {
584 lens1: L1,
585 lens2: L2,
586}
587
588impl<L1, L2> AndLens<L1, L2> {
589 pub fn new(lens1: L1, lens2: L2) -> Self
590 where
591 L1: Lens<Target = bool>,
592 L2: Lens<Target = bool>,
593 {
594 Self { lens1, lens2 }
595 }
596}
597
598impl<L1, L2> Lens for AndLens<L1, L2>
599where
600 L1: Lens<Source = L2::Source, Target = bool>,
601 L2: Lens<Target = bool>,
602{
603 type Source = L1::Source;
604 type Target = bool;
605
606 fn view<'a>(&self, source: &'a Self::Source) -> Option<LensValue<'a, Self::Target>> {
607 let v1 = self.lens1.view(source)?.into_owned();
608 let v2 = self.lens2.view(source)?.into_owned();
609
610 Some(LensValue::Owned(v1 | v2))
611 }
612}
613
614impl<L1: Clone, L2: Clone> Clone for AndLens<L1, L2> {
615 fn clone(&self) -> Self {
616 Self { lens1: self.lens1.clone(), lens2: self.lens2.clone() }
617 }
618}
619
620impl<L1: Lens<Target = bool>, L2: Lens<Target = bool>> BitAnd<L2> for Wrapper<L1>
621where
622 L1: Lens<Source = L2::Source>,
623{
624 type Output = AndLens<Self, L2>;
625 fn bitand(self, rhs: L2) -> Self::Output {
626 AndLens::new(self, rhs)
627 }
628}
629
630impl<L1, L2, L3: Lens<Target = bool>> BitAnd<L3> for AndLens<L1, L2>
631where
632 Self: Lens<Target = bool>,
633 Self: Lens<Source = L3::Source>,
634{
635 type Output = AndLens<Self, L3>;
636 fn bitand(self, rhs: L3) -> Self::Output {
637 AndLens::new(self, rhs)
638 }
639}
640
641impl<A: Lens, L1: Lens<Target = bool>, L2: Lens<Target = bool>> BitAnd<L2> for Then<A, L1>
642where
643 A: Lens<Source = L2::Source>,
644 L1: Lens<Source = A::Target>,
645{
646 type Output = AndLens<Self, L2>;
647 fn bitand(self, rhs: L2) -> Self::Output {
648 AndLens::new(self, rhs)
649 }
650}
651
652impl<L, L2: Lens<Target = bool>> BitAnd<L2> for Map<L, bool>
653where
654 L: Lens<Source = L2::Source>,
655{
656 type Output = AndLens<Self, L2>;
657 fn bitand(self, rhs: L2) -> Self::Output {
658 AndLens::new(self, rhs)
659 }
660}
661
662impl<T> Lens for &'static T
663where
664 T: 'static + Copy + Debug + Hash,
665{
666 type Source = ();
667 type Target = T;
668
669 fn view<'a>(&self, _source: &'a Self::Source) -> Option<LensValue<'a, Self::Target>> {
670 Some(LensValue::Borrowed(*self))
671 }
672}