#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub enum ServerUrl {
#[default]
Prod,
Dev,
Custom(String),
}
impl ServerUrl {
pub const PROD: &'static str = "https://code.aretta.ai";
pub const DEV: &'static str = "https://dev.aretta.ai";
pub fn as_str(&self) -> &str {
match self {
Self::Prod => Self::PROD,
Self::Dev => Self::DEV,
Self::Custom(s) => s,
}
}
pub fn parse(raw: &str) -> Self {
let trimmed = raw.trim();
match trimmed {
"prod" | "production" => Self::Prod,
"dev" | "development" | "staging" => Self::Dev,
"" => Self::Prod,
other if other.starts_with("http://") || other.starts_with("https://") => {
Self::Custom(other.trim_end_matches('/').to_string())
}
other => Self::Custom(format!("https://{}", other.trim_end_matches('/'))),
}
}
pub fn is_well_known(&self) -> bool {
matches!(self, Self::Prod | Self::Dev)
}
}
impl std::fmt::Display for ServerUrl {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(self.as_str())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn prod_resolves_to_code_aretta_ai() {
assert_eq!(ServerUrl::Prod.as_str(), "https://code.aretta.ai");
}
#[test]
fn dev_resolves_to_dev_aretta_ai() {
assert_eq!(ServerUrl::Dev.as_str(), "https://dev.aretta.ai");
}
#[test]
fn parse_prod_aliases() {
assert_eq!(ServerUrl::parse("prod"), ServerUrl::Prod);
assert_eq!(ServerUrl::parse("production"), ServerUrl::Prod);
assert_eq!(ServerUrl::parse(" prod "), ServerUrl::Prod);
}
#[test]
fn parse_dev_aliases() {
assert_eq!(ServerUrl::parse("dev"), ServerUrl::Dev);
assert_eq!(ServerUrl::parse("development"), ServerUrl::Dev);
assert_eq!(ServerUrl::parse("staging"), ServerUrl::Dev);
}
#[test]
fn parse_full_url_passes_through_as_custom() {
let s = ServerUrl::parse("https://aretta.example.com");
assert_eq!(s, ServerUrl::Custom("https://aretta.example.com".into()));
assert_eq!(s.as_str(), "https://aretta.example.com");
}
#[test]
fn parse_http_url_is_accepted_for_self_hosted() {
let s = ServerUrl::parse("http://aretta.internal");
assert_eq!(s, ServerUrl::Custom("http://aretta.internal".into()));
}
#[test]
fn parse_strips_trailing_slash_for_clean_format_strings() {
let s = ServerUrl::parse("https://example.com/");
assert_eq!(s.as_str(), "https://example.com");
}
#[test]
fn parse_bare_host_defaults_to_https() {
let s = ServerUrl::parse("aretta.example.com");
assert_eq!(s, ServerUrl::Custom("https://aretta.example.com".into()));
}
#[test]
fn parse_empty_string_falls_back_to_prod() {
assert_eq!(ServerUrl::parse(""), ServerUrl::Prod);
assert_eq!(ServerUrl::parse(" "), ServerUrl::Prod);
}
#[test]
fn default_is_prod() {
assert_eq!(ServerUrl::default(), ServerUrl::Prod);
}
#[test]
fn is_well_known_matches_prod_and_dev_only() {
assert!(ServerUrl::Prod.is_well_known());
assert!(ServerUrl::Dev.is_well_known());
assert!(!ServerUrl::Custom("https://example.com".into()).is_well_known());
}
#[test]
fn display_renders_full_url() {
assert_eq!(format!("{}", ServerUrl::Prod), "https://code.aretta.ai");
assert_eq!(format!("{}", ServerUrl::Dev), "https://dev.aretta.ai");
assert_eq!(
format!("{}", ServerUrl::Custom("https://x.example.com".into())),
"https://x.example.com"
);
}
}