browser_agent/
agent.rs

1use anyhow::{anyhow, bail, Result};
2
3/// Actions that can be taken by the browser.
4#[derive(Debug)]
5pub enum Action {
6    /// Click on an element.
7    /// The usize is the id of the element.
8    Click(usize),
9    /// Respond to the user with the given text.
10    /// The String is the text to respond with.
11    Answer(String),
12
13    /// Type the given text into the given element and press ENTER.
14    /// The usize is the id of the element, and the String is the text to type.
15    Type(usize, String),
16}
17
18impl TryFrom<String> for Action {
19    type Error = anyhow::Error;
20
21    fn try_from(value: String) -> Result<Self> {
22        let mut parts = value.split_whitespace();
23        let command = parts.next().ok_or_else(|| anyhow!("No command."))?;
24
25        match command {
26            "CLICK" => {
27                let id = parts.next().unwrap().parse()?;
28
29                Ok(Self::Click(id))
30            }
31            "TYPE" => {
32                let id = parts.next().unwrap().parse()?;
33
34                let text = parts
35                    .collect::<Vec<_>>()
36                    .join(" ")
37                    .trim_matches('"')
38                    .to_string();
39
40                Ok(Self::Type(id, text))
41            }
42            "ANSWER" => {
43                let text = parts
44                    .collect::<Vec<_>>()
45                    .join(" ")
46                    .trim_matches('"')
47                    .to_string();
48
49                Ok(Self::Answer(text))
50            }
51            _ => bail!("Unknown command, got {command}"),
52        }
53    }
54}