1use std::collections::HashMap;
2use std::sync::Arc;
3
4use eoka::{Browser, Page};
5
6use crate::protocol::ServerError;
7
8#[derive(Default)]
9pub struct AppState {
10 pub operations: crate::operations::OperationManager,
11 browser: Option<Arc<Browser>>,
12 pages: HashMap<String, Page>,
13 shutdown: bool,
14}
15
16impl AppState {
17 pub fn new() -> Self {
18 Self::default()
19 }
20
21 pub fn set_browser(&mut self, browser: Browser) {
22 self.browser = Some(Arc::new(browser));
23 }
24
25 pub fn take_browser(&mut self) -> Option<Arc<Browser>> {
26 self.browser.take()
27 }
28
29 pub fn is_launched(&self) -> bool {
30 self.browser.is_some()
31 }
32
33 pub fn browser(&self) -> Result<&Arc<Browser>, ServerError> {
34 self.browser
35 .as_ref()
36 .ok_or_else(|| ServerError::internal("browser not launched; call browser.launch first"))
37 }
38
39 pub fn insert_page(&mut self, id: String, page: Page) {
40 self.pages.insert(id, page);
41 }
42
43 pub fn remove_page(&mut self, id: &str) -> Option<Page> {
44 self.pages.remove(id)
45 }
46
47 pub fn page(&self, id: &str) -> Result<&Page, ServerError> {
48 self.pages
49 .get(id)
50 .ok_or_else(|| ServerError::invalid_page(id))
51 }
52
53 pub fn pages(&self) -> impl Iterator<Item = &Page> {
54 self.pages.values()
55 }
56
57 pub fn clear_pages(&mut self) {
58 self.pages.clear();
59 }
60
61 pub fn mark_shutdown(&mut self) {
62 self.shutdown = true;
63 }
64
65 pub fn should_shutdown(&self) -> bool {
66 self.shutdown
67 }
68}