limit_cli/tools/browser/
client.rs1use super::config::BrowserConfig;
7use super::executor::{BrowserError, BrowserExecutor};
8use std::sync::Arc;
9
10pub struct BrowserClient {
12 executor: Arc<dyn BrowserExecutor>,
13}
14
15impl BrowserClient {
16 pub fn new(executor: Arc<dyn BrowserExecutor>) -> Self {
18 Self { executor }
19 }
20
21 pub fn with_default_config() -> Self {
23 let config = BrowserConfig::default();
24 let executor = Arc::new(super::executor::CliExecutor::new(config));
25 Self::new(executor)
26 }
27
28 pub fn executor(&self) -> &Arc<dyn BrowserExecutor> {
30 &self.executor
31 }
32
33 pub async fn open(&self, url: &str) -> Result<(), BrowserError> {
35 self.validate_url(url)?;
36
37 let output = self.executor.execute(&["open", url]).await?;
38
39 if output.success {
40 Ok(())
41 } else {
42 Err(BrowserError::Other(format!(
43 "Failed to open URL: {}",
44 output.stderr
45 )))
46 }
47 }
48
49 pub async fn close(&self) -> Result<(), BrowserError> {
51 let output = self.executor.execute(&["close"]).await?;
52
53 if output.success {
54 Ok(())
55 } else {
56 Err(BrowserError::Other(format!(
57 "Failed to close browser: {}",
58 output.stderr
59 )))
60 }
61 }
62
63 pub fn is_daemon_running(&self) -> bool {
65 self.executor.is_daemon_running()
66 }
67
68 fn validate_url(&self, url: &str) -> Result<(), BrowserError> {
70 if url.is_empty() {
71 return Err(BrowserError::InvalidArguments(
72 "URL cannot be empty".to_string(),
73 ));
74 }
75
76 if !url.starts_with("http://") && !url.starts_with("https://") {
77 return Err(BrowserError::InvalidArguments(
78 "URL must start with http:// or https://".to_string(),
79 ));
80 }
81
82 Ok(())
83 }
84
85 pub(crate) fn extract_field(content: &str, field_name: &str) -> Option<String> {
87 for line in content.lines() {
88 if let Some(stripped) = line.strip_prefix(field_name) {
89 return Some(stripped.trim().to_string());
90 }
91 }
92 None
93 }
94}
95
96#[cfg(test)]
97mod tests {
98 use super::*;
99
100 #[test]
101 fn test_extract_field() {
102 let content = "Title: Example\nURL: https://example.com\nOther content";
103 assert_eq!(
104 BrowserClient::extract_field(content, "Title:"),
105 Some("Example".to_string())
106 );
107 assert_eq!(
108 BrowserClient::extract_field(content, "URL:"),
109 Some("https://example.com".to_string())
110 );
111 assert_eq!(BrowserClient::extract_field(content, "Missing:"), None);
112 }
113}