|
1 | | -use std::{collections::HashMap, fs, path::Path}; |
| 1 | +use std::{fs, path::Path}; |
2 | 2 |
|
3 | | -use anyhow::{Result, bail}; |
| 3 | +use anyhow::{Context, Result, bail}; |
| 4 | +use serde_json::Value; |
| 5 | + |
| 6 | +fn editor_url(port: u16) -> String { |
| 7 | + format!("http://127.0.0.1:{port}") |
| 8 | +} |
| 9 | + |
| 10 | +fn openapi_url(port: u16) -> String { |
| 11 | + format!("{}/openapi.json", editor_url(port)) |
| 12 | +} |
4 | 13 |
|
5 | 14 | fn command_url(port: u16, command: Option<String>) -> String { |
6 | 15 | format!( |
7 | | - "http://127.0.0.1:{port}/command/{}", |
| 16 | + "{}/command/{}", |
| 17 | + editor_url(port), |
8 | 18 | command.unwrap_or_default() |
9 | 19 | ) |
10 | 20 | } |
@@ -32,23 +42,35 @@ pub fn find_port(game_root: &Path) -> Option<u16> { |
32 | 42 | #[must_use] |
33 | 43 | pub fn is_editor_port(port: u16) -> bool { |
34 | 44 | reqwest::blocking::Client::new() |
35 | | - .head(command_url(port, None)) |
| 45 | + .head(editor_url(port)) |
36 | 46 | .send() |
37 | 47 | .is_ok_and(|r| r.status().is_success()) |
38 | 48 | } |
39 | 49 |
|
40 | | -pub fn list_commands(port: u16) -> Result<HashMap<String, String>> { |
41 | | - let url = command_url(port, None); |
| 50 | +pub fn list_commands(port: u16) -> Result<Vec<String>> { |
| 51 | + let url = openapi_url(port); |
42 | 52 |
|
43 | 53 | let res = reqwest::blocking::get(url)?; |
44 | 54 |
|
45 | 55 | if !res.status().is_success() { |
46 | 56 | bail!("could not list commands, status: {:?}", res.status()); |
47 | 57 | } |
48 | 58 |
|
49 | | - let content = res.text()?.clone(); |
| 59 | + let root: Value = res.json().context("Failed to parse OpenAPI JSON")?; |
50 | 60 |
|
51 | | - serde_json::from_str(&content).map_err(anyhow::Error::from) |
| 61 | + let enum_values = |
| 62 | + &root["paths"]["/command/{command}"]["post"]["parameters"][0]["schema"]["enum"]; |
| 63 | + |
| 64 | + if let Some(list) = enum_values.as_array() { |
| 65 | + let commands = list |
| 66 | + .iter() |
| 67 | + .filter_map(|v| v.as_str().map(|s| s.to_string())) |
| 68 | + .collect(); |
| 69 | + |
| 70 | + Ok(commands) |
| 71 | + } else { |
| 72 | + bail!("Could not find command values in the OpenAPI specification") |
| 73 | + } |
52 | 74 | } |
53 | 75 |
|
54 | 76 | pub fn send_command(port: u16, cmd: &str) -> Result<()> { |
|
0 commit comments