Skip to main content

ratatui_reactive/runtime/
router.rs

1use crate::runtime::delay::DelayedSet;
2use crate::{Render, delayed_signal};
3use ratatui::buffer::Buffer;
4use ratatui::layout::Rect;
5use std::rc::Rc;
6use sycamore_reactive::{create_memo, provide_context};
7
8#[derive(Debug)]
9pub struct Router<R: 'static> {
10    route: DelayedSet<R>,
11}
12
13impl<T: 'static> Clone for Router<T> {
14    #[inline]
15    fn clone(&self) -> Self {
16        *self
17    }
18}
19
20impl<T: 'static> Copy for Router<T> {}
21
22#[derive(Clone)]
23pub struct Route {
24    inner: Rc<dyn Render>,
25}
26
27impl Route {
28    #[inline]
29    pub fn new<R: Render + 'static>(route: R) -> Self {
30        Self {
31            inner: Rc::new(route),
32        }
33    }
34}
35
36#[inline]
37#[cfg_attr(debug_assertions, track_caller)]
38pub fn provide_router<R: 'static + Default>(
39    mut mapping: impl FnMut(R) -> Route + 'static,
40) -> (Router<R>, impl Render) {
41    let (route, delayed_route) = delayed_signal(R::default());
42    let router = Router { route };
43    provide_context(router);
44    let component = create_memo(move || mapping(delayed_route.get()));
45    let render = move |area: Rect, buf: &mut Buffer| {
46        component.get_clone().inner.render(area, buf);
47    };
48    (router, render)
49}
50
51impl<R> Router<R> {
52    #[inline]
53    #[cfg_attr(debug_assertions, track_caller)]
54    pub fn goto(&self, route: R) {
55        self.route.set(route);
56    }
57}