use std::fmt::Display;
pub const AMBIENT_WEB_APP_URL: &str = "https://ambient.run";
pub const ASSETS_URL: &str = "https://assets.ambient.run";
pub const API_URL: &str = "https://api.ambient.run";
pub fn web_package_url(package_id: &str, version: Option<&str>) -> String {
let mut output = format!("{AMBIENT_WEB_APP_URL}/packages/{package_id}");
if let Some(version) = version {
output.push_str(&format!("/version/{version}"));
}
output
}
pub fn deployment_url(deployment_id: &str) -> String {
format!("{ASSETS_URL}/{deployment_id}")
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum ServerSelector<'a> {
Deployment(&'a str),
Package {
id: &'a str,
version: Option<&'a str>,
},
}
impl Display for ServerSelector<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
ServerSelector::Deployment(id) => write!(f, "deployment_id={id}"),
ServerSelector::Package { id, version } => {
write!(f, "package_id={id}")?;
if let Some(version) = version {
write!(f, "&version={version}")?;
}
Ok(())
}
}
}
}
pub fn ensure_running_url(selector: ServerSelector) -> String {
format!("{API_URL}/servers/ensure-running?{selector}")
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum PackageContent {
Playable,
Example,
NotExample,
Asset,
Models,
Animations,
Textures,
Materials,
Fonts,
Code,
Schema,
Audio,
Other,
Tool,
Mod,
}
#[derive(Default, Copy, Clone)]
pub struct PackageListParams<'a> {
pub created_after: Option<&'a str>,
pub updated_after: Option<&'a str>,
pub name: Option<&'a str>,
pub content_contains: &'a [PackageContent],
pub owner_id: Option<&'a str>,
pub for_playable: Option<&'a str>,
}
pub fn package_list_url(params: PackageListParams) -> String {
let url = format!("{API_URL}/packages/list");
let mut segments = vec![];
if let Some(created_after) = params.created_after {
segments.push(format!("created_after={}", created_after));
}
if let Some(updated_after) = params.updated_after {
segments.push(format!("updated_after={}", updated_after));
}
if let Some(name) = params.name {
segments.push(format!("name={}", name));
}
if !params.content_contains.is_empty() {
segments.push(format!(
"content_contains={}",
params
.content_contains
.iter()
.map(|content| format!("{:?}", content))
.collect::<Vec<_>>()
.join(",")
));
}
if let Some(owner_id) = params.owner_id {
segments.push(format!("owner_id={}", owner_id));
}
if let Some(for_playable) = params.for_playable {
segments.push(format!("for_playable={}", for_playable));
}
if segments.is_empty() {
url
} else {
format!("{url}?{}", segments.join("&"))
}
}