-
Notifications
You must be signed in to change notification settings - Fork 154
/
Copy pathlib.rs
127 lines (105 loc) · 2.49 KB
/
lib.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#![allow(clippy::must_use_candidate)]
use seed::{prelude::*, *};
mod page;
const ADMIN: &str = "admin";
// ------ ------
// Init
// ------ ------
fn init(url: Url, orders: &mut impl Orders<Msg>) -> Model {
let base_url = url.to_base_url();
orders
.subscribe(Msg::UrlChanged)
.notify(subs::UrlChanged(url));
Model {
ctx: Context {
logged_user: "John Doe",
},
base_url,
page_id: None,
admin_model: None,
}
}
// ------ ------
// Model
// ------ ------
struct Model {
ctx: Context,
base_url: Url,
page_id: Option<PageId>,
admin_model: Option<page::admin::Model>,
}
// ------ Context ------
pub struct Context {
pub logged_user: &'static str,
}
// ------ PageId ------
#[derive(Copy, Clone, Eq, PartialEq)]
enum PageId {
Home,
Admin,
}
// ------ ------
// Urls
// ------ ------
struct_urls!();
impl<'a> Urls<'a> {
pub fn home(self) -> Url {
self.base_url()
}
pub fn admin_urls(self) -> page::admin::Urls<'a> {
page::admin::Urls::new(self.base_url().add_path_part(ADMIN))
}
}
// ------ ------
// Update
// ------ ------
enum Msg {
UrlChanged(subs::UrlChanged),
}
fn update(msg: Msg, model: &mut Model, _: &mut impl Orders<Msg>) {
match msg {
Msg::UrlChanged(subs::UrlChanged(mut url)) => {
model.page_id = match url.next_path_part() {
None => Some(PageId::Home),
Some(ADMIN) => {
page::admin::init(url, &mut model.admin_model).map(|_| PageId::Admin)
}
Some(_) => None,
};
}
}
}
// ------ ------
// View
// ------ ------
fn view(model: &Model) -> Vec<Node<Msg>> {
vec![
header(&model.base_url),
match model.page_id {
Some(PageId::Home) => div!["Welcome home!"],
Some(PageId::Admin) => {
page::admin::view(model.admin_model.as_ref().expect("admin model"), &model.ctx)
}
None => div!["404"],
},
]
}
fn header(base_url: &Url) -> Node<Msg> {
ul![
li![a![
attrs! { At::Href => Urls::new(base_url).home() },
"Home",
]],
li![a![
attrs! { At::Href => Urls::new(base_url).admin_urls().report_urls().root() },
"Report",
]],
]
}
// ------ ------
// Start
// ------ ------
#[wasm_bindgen(start)]
pub fn start() {
App::start("app", init, update, view);
}