gpui_router/state.rs
1use gpui::{App, Global, SharedString};
2use hashbrown::HashMap;
3use matchit::Params;
4
5/// A Location represents a URL-like location in the router.
6/// It contains a pathname and an optional state object.
7#[derive(PartialEq, Eq, Ord, PartialOrd, Clone, Debug)]
8pub struct Location {
9 /// A URL pathname, beginning with a `/`.
10 pub pathname: SharedString,
11 /// A value of arbitrary data associated with this location.
12 pub state: Params<'static, 'static>,
13}
14
15impl Default for Location {
16 /// Creates a default Location with pathname `/` and empty state.
17 fn default() -> Self {
18 Self {
19 pathname: "/".into(),
20 state: Params::default(),
21 }
22 }
23}
24
25/// A PathMatch contains info about how a PathPattern matched on a URL-like pathname.
26#[derive(PartialEq, Eq, Ord, PartialOrd, Clone, Debug)]
27pub struct PathMatch {
28 /// The portion of the URL-like pathname that was matched.
29 pub pathname: SharedString,
30 /// The portion of the URL-like pathname that was matched before child routes.
31 pub pathname_base: SharedString,
32 /// The route pattern that was matched.
33 pub pattern: SharedString,
34 /// The names and values of dynamic parameters in the URL-like.
35 /// For example, if the route pattern is `/users/{id}`, and the URL pathname is `/users/123`,
36 /// then the `params` would be `{"id": "123"}`.
37 pub params: Params<'static, 'static>,
38}
39
40/// The global state of the router, including the current location, path match, and parameters.
41/// This state is stored globally within the GPUI application context.
42#[derive(PartialEq, Clone)]
43pub struct RouterState {
44 /// The current location in the router.
45 pub location: Location,
46 /// The path match information for the current location.
47 pub path_match: Option<PathMatch>,
48 /// The dynamic parameters for the current location.
49 pub params: HashMap<SharedString, SharedString>,
50}
51
52impl Global for RouterState {}
53
54impl RouterState {
55 /// Initializes the RouterState within the GPUI application context.
56 /// This function sets up the initial state of the router.
57 pub fn init(cx: &mut App) {
58 let state = Self {
59 location: Location::default(),
60 path_match: None,
61 params: HashMap::new(),
62 };
63 cx.set_global::<RouterState>(state);
64 }
65
66 /// Sets the current pathname in the router state.
67 pub fn with_path(&mut self, pathname: SharedString) -> &mut Self {
68 self.location.pathname = pathname;
69 self
70 }
71
72 /// Retrieves an immutable reference to the global RouterState from the GPUI application context.
73 pub fn global(cx: &App) -> &Self {
74 cx.global::<Self>()
75 }
76
77 /// Retrieves a mutable reference to the global RouterState from the GPUI application context.
78 pub fn global_mut(cx: &mut App) -> &mut Self {
79 cx.global_mut::<Self>()
80 }
81}