Skip to main content

domi_server/tools/
types.rs

1//! Shared types and constants for the `domi` CLI subcommands.
2//!
3//! Task 1 ships this as a minimal placeholder so the `cli.rs` clap derive can
4//! reference the same shared `default-server` constant. Tasks 2-5 will extend
5//! it with URL parsing helpers, response types, and shared error reporting.
6
7use url::Url;
8
9/// Default server URL when `--server` is not provided.
10///
11/// Matches the 2c-γ server's default bind of `127.0.0.1:4173`.
12pub const DEFAULT_SERVER: &str = "http://127.0.0.1:4173";
13
14/// Parse a user-supplied server URL, falling back to [`DEFAULT_SERVER`] on
15/// empty input.
16///
17/// Returns `Err(String)` with a human-readable message on parse failure —
18/// `cli.rs` converts that into a clap-style error and exit code `2`.
19pub fn parse_server(input: &str) -> Result<Url, String> {
20    let trimmed = input.trim();
21    if trimmed.is_empty() {
22        return Url::parse(DEFAULT_SERVER).map_err(|e| e.to_string());
23    }
24    Url::parse(trimmed).map_err(|e| format!("invalid --server URL {trimmed:?}: {e}"))
25}
26
27#[cfg(test)]
28mod tests {
29    use super::*;
30
31    #[test]
32    fn default_server_is_local_4173() {
33        let u = Url::parse(DEFAULT_SERVER).unwrap();
34        assert_eq!(u.scheme(), "http");
35        assert_eq!(u.host_str(), Some("127.0.0.1"));
36        assert_eq!(u.port(), Some(4173));
37    }
38
39    #[test]
40    fn empty_input_falls_back_to_default() {
41        let u = parse_server("").unwrap();
42        // `Url` normalizes by appending a trailing `/` when serializing.
43        assert_eq!(u.as_str(), format!("{DEFAULT_SERVER}/"));
44    }
45
46    #[test]
47    fn valid_url_round_trips() {
48        let u = parse_server("https://example.com:9000/").unwrap();
49        assert_eq!(u.scheme(), "https");
50        assert_eq!(u.host_str(), Some("example.com"));
51        assert_eq!(u.port(), Some(9000));
52    }
53
54    #[test]
55    fn invalid_url_returns_err() {
56        assert!(parse_server("not a url").is_err());
57    }
58}