command_autocomplete/
complete.rs

1use crate::{
2    connection::{ConnRequest, SendError, Transport},
3    types::{CompleteParams, CompleteResult, CompletionValue, Error, ShutdownResult},
4};
5
6pub fn run_complete() -> anyhow::Result<()> {
7    let (transport, join_handle) = Transport::stdio();
8    {
9        let (_, receiver) = crate::connection::new_connection(transport);
10        while let Some(req) = receiver.next_request() {
11            match handle_request(req) {
12                Ok(LoopAction::Continue) => continue,
13                Ok(LoopAction::Stop) => break,
14                Err(_) => {
15                    log::warn!("the connection closed unexpectedly, stopping the receving loop");
16                    break;
17                }
18            }
19        }
20    }
21    join_handle.join()?;
22    Ok(())
23}
24
25enum LoopAction {
26    Continue,
27    Stop,
28}
29
30fn handle_request(req: ConnRequest) -> Result<LoopAction, SendError> {
31    match req.inner().method.as_str() {
32        "complete" => match serde_json::from_value(req.inner().params.clone()) {
33            Ok(params) => {
34                req.reply(handle_complete_request(params))?;
35            }
36            Err(err) => {
37                req.reply_err(Error::invalid_request(format!(
38                    "invalid params for complete request: {err}"
39                )))?;
40            }
41        },
42        "shutdown" => {
43            req.reply_ok(ShutdownResult {})?;
44            return Ok(LoopAction::Stop);
45        }
46        _ => {
47            let method = req.inner().method.clone();
48            req.reply_err(Error {
49                code: "UNKNOWN_REQUEST".to_string(),
50                message: format!("method {} is not recognized", method),
51            })?;
52        }
53    }
54    Ok(LoopAction::Continue)
55}
56
57fn handle_complete_request(params: CompleteParams) -> Result<CompleteResult, Error> {
58    let mut completions = vec![];
59    if params.args.len() == 2 {
60        completions = vec![
61            CompletionValue {
62                value: "shell ".into(),
63                description: None,
64            },
65            CompletionValue {
66                value: "router ".into(),
67                description: None,
68            },
69            CompletionValue {
70                value: "bridge ".into(),
71                description: None,
72            },
73            CompletionValue {
74                value: "complete ".into(),
75                description: None,
76            },
77        ];
78    }
79    Ok(CompleteResult {
80        values: completions,
81    })
82}