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