limit_cli/tools/browser/client_ext/
tabs.rs1use crate::tools::browser::executor::BrowserError;
4use crate::tools::browser::types::TabInfo;
5
6pub trait TabsExt {
8 fn tab_list(
10 &self,
11 ) -> impl std::future::Future<Output = Result<Vec<TabInfo>, BrowserError>> + Send;
12
13 fn tab_new(
15 &self,
16 url: Option<&str>,
17 ) -> impl std::future::Future<Output = Result<(), BrowserError>> + Send;
18
19 fn tab_close(
21 &self,
22 index: Option<usize>,
23 ) -> impl std::future::Future<Output = Result<(), BrowserError>> + Send;
24
25 fn tab_select(
27 &self,
28 index: usize,
29 ) -> impl std::future::Future<Output = Result<(), BrowserError>> + Send;
30
31 fn dialog_accept(
33 &self,
34 text: Option<&str>,
35 ) -> impl std::future::Future<Output = Result<(), BrowserError>> + Send;
36
37 fn dialog_dismiss(&self) -> impl std::future::Future<Output = Result<(), BrowserError>> + Send;
39}
40
41impl TabsExt for super::super::BrowserClient {
42 async fn tab_list(&self) -> Result<Vec<TabInfo>, BrowserError> {
43 let output = self.executor().execute(&["tab", "list"]).await?;
44
45 if output.success {
46 let tabs = output
47 .stdout
48 .lines()
49 .filter(|line| !line.is_empty())
50 .enumerate()
51 .map(|(i, line)| TabInfo {
52 index: i,
53 title: line.to_string(),
54 })
55 .collect();
56 Ok(tabs)
57 } else {
58 Err(BrowserError::Other(format!(
59 "Failed to list tabs: {}",
60 output.stderr
61 )))
62 }
63 }
64
65 async fn tab_new(&self, url: Option<&str>) -> Result<(), BrowserError> {
66 let output = if let Some(u) = url {
67 self.executor().execute(&["tab", "new", u]).await?
68 } else {
69 self.executor().execute(&["tab", "new"]).await?
70 };
71
72 if output.success {
73 Ok(())
74 } else {
75 Err(BrowserError::Other(format!(
76 "Failed to open new tab: {}",
77 output.stderr
78 )))
79 }
80 }
81
82 async fn tab_close(&self, index: Option<usize>) -> Result<(), BrowserError> {
83 let output = if let Some(i) = index {
84 let idx = i.to_string();
85 self.executor().execute(&["tab", "close", &idx]).await?
86 } else {
87 self.executor().execute(&["tab", "close"]).await?
88 };
89
90 if output.success {
91 Ok(())
92 } else {
93 Err(BrowserError::Other(format!(
94 "Failed to close tab: {}",
95 output.stderr
96 )))
97 }
98 }
99
100 async fn tab_select(&self, index: usize) -> Result<(), BrowserError> {
101 let idx = index.to_string();
102 let output = self.executor().execute(&["tab", "select", &idx]).await?;
103
104 if output.success {
105 Ok(())
106 } else {
107 Err(BrowserError::Other(format!(
108 "Failed to select tab: {}",
109 output.stderr
110 )))
111 }
112 }
113
114 async fn dialog_accept(&self, text: Option<&str>) -> Result<(), BrowserError> {
115 let output = if let Some(t) = text {
116 self.executor().execute(&["dialog", "accept", t]).await?
117 } else {
118 self.executor().execute(&["dialog", "accept"]).await?
119 };
120
121 if output.success {
122 Ok(())
123 } else {
124 Err(BrowserError::Other(format!(
125 "Failed to accept dialog: {}",
126 output.stderr
127 )))
128 }
129 }
130
131 async fn dialog_dismiss(&self) -> Result<(), BrowserError> {
132 let output = self.executor().execute(&["dialog", "dismiss"]).await?;
133
134 if output.success {
135 Ok(())
136 } else {
137 Err(BrowserError::Other(format!(
138 "Failed to dismiss dialog: {}",
139 output.stderr
140 )))
141 }
142 }
143}