use super::GwPlane;
use super::window::Window;
use super::withhold::{self, Policy};
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum KeyKind {
Service,
User,
}
#[derive(Clone, Debug, PartialEq)]
pub enum InventoryRead {
ApiKeysList {
kind: KeyKind,
workspace: String,
},
ApiKeysGet {
kind: KeyKind,
id: String,
},
AuditLogs {
window: Window,
reveal: bool,
},
ConfigsList {
workspace: String,
},
ConfigsGet {
id: String,
},
ConfigsVersions {
id: String,
},
DeploymentsList,
DeploymentsGet {
id: String,
},
DeploymentsPing {
id: String,
},
GuardrailsList {
workspace: String,
},
GuardrailsGet {
id: String,
},
GuardrailsCatalog,
IntegrationsList,
IntegrationsGet {
id: String,
},
IntegrationsProviders,
IntegrationModels {
id: String,
},
IntegrationWorkspaces {
id: String,
},
McpList,
McpGet {
id: String,
},
McpCapabilities {
id: String,
},
McpMetadata {
id: String,
},
McpWorkspaces {
id: String,
},
OrganisationInfo {
tsg: Option<String>,
},
OrganisationSelf,
AuthSettings {
tsg: Option<String>,
},
PluginsList,
ProvidersList {
workspace: String,
},
ProvidersGet {
id: String,
},
AdminGuardrailsList(AdminPaging),
AdminGuardrailsGet {
id: String,
},
AdminMcpMappings {
id: String,
},
}
#[derive(Clone, Debug, Default, PartialEq, Eq)]
pub struct AdminPaging {
pub workspace: Option<String>,
pub page_size: Option<u64>,
pub current_page: Option<u64>,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Shape {
List(&'static str),
Models(&'static str),
Detail,
}
impl InventoryRead {
pub fn plane(&self) -> GwPlane {
match self {
Self::ApiKeysList { .. }
| Self::ApiKeysGet { .. }
| Self::ConfigsList { .. }
| Self::ConfigsGet { .. }
| Self::ConfigsVersions { .. }
| Self::GuardrailsList { .. }
| Self::GuardrailsGet { .. }
| Self::ProvidersList { .. }
| Self::ProvidersGet { .. } => GwPlane::Data,
_ => GwPlane::Admin,
}
}
pub fn shape(&self) -> Shape {
match self {
Self::ApiKeysList {
kind: KeyKind::Service,
..
} => Shape::List("service API keys"),
Self::ApiKeysList {
kind: KeyKind::User,
..
} => Shape::List("user API keys"),
Self::AuditLogs { .. } => Shape::List("audit logs"),
Self::ConfigsList { .. } => Shape::List("configs"),
Self::ConfigsVersions { .. } => Shape::List("config versions"),
Self::DeploymentsList => Shape::List("deployments"),
Self::GuardrailsList { .. } => Shape::List("guardrails"),
Self::IntegrationsList => Shape::List("integrations"),
Self::IntegrationsProviders => Shape::List("catalog providers"),
Self::IntegrationModels { .. } => Shape::Models("integration models"),
Self::McpList => Shape::List("MCP integrations"),
Self::PluginsList => Shape::List("plugins"),
Self::ProvidersList { .. } => Shape::List("providers"),
Self::AdminGuardrailsList(_) => Shape::List("Admin guardrails"),
Self::AdminMcpMappings { .. } => Shape::List("MCP mappings"),
_ => Shape::Detail,
}
}
pub fn policy(&self) -> &'static Policy {
match self {
Self::ApiKeysList { .. } | Self::ApiKeysGet { .. } => &withhold::API_KEYS,
Self::DeploymentsList | Self::DeploymentsGet { .. } | Self::DeploymentsPing { .. } => {
&withhold::DEPLOYMENTS
}
Self::IntegrationsList | Self::IntegrationsGet { .. } => &withhold::INTEGRATIONS,
Self::McpList
| Self::McpGet { .. }
| Self::McpCapabilities { .. }
| Self::McpMetadata { .. }
| Self::McpWorkspaces { .. } => &withhold::MCP,
Self::OrganisationInfo { .. } => &withhold::ORGANISATION_INFO,
Self::AuthSettings { .. } => &withhold::AUTH_SETTINGS,
Self::PluginsList => &withhold::PLUGINS,
Self::ProvidersList { .. } | Self::ProvidersGet { .. } => &withhold::PROVIDERS,
_ => &withhold::PLAIN,
}
}
pub fn tsg(&self) -> Option<&str> {
match self {
Self::OrganisationInfo { tsg } | Self::AuthSettings { tsg } => tsg.as_deref(),
_ => None,
}
}
pub fn detail_rows(&self) -> Option<&'static str> {
match self {
Self::McpCapabilities { .. } => Some("data"),
Self::IntegrationWorkspaces { .. } => Some("workspaces"),
_ => None,
}
}
pub fn detail_label(&self) -> &'static str {
match self {
Self::McpCapabilities { .. } => "MCP capabilities",
_ => "workspace bindings",
}
}
}
pub fn admin_status(rows: usize, total: Option<f64>, paging: &AdminPaging) -> Option<String> {
let total = crate::walk::total_of(total)?;
let returned = u128::try_from(rows).unwrap_or(u128::MAX);
let page = paging.current_page.unwrap_or(0);
let size = paging.page_size.map_or(returned, u128::from);
let seen = u128::from(page)
.saturating_mul(size)
.saturating_add(returned);
(u128::from(total) > seen).then(|| {
format!("Returned {rows} of {total} admin guardrails (page {page}); this is one page.")
})
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn planes_shapes_and_policies() {
let id = || "11111111-1111-4111-8111-000000000001".to_owned();
assert_eq!(
InventoryRead::ApiKeysGet {
kind: KeyKind::User,
id: id()
}
.plane(),
GwPlane::Data
);
assert_eq!(InventoryRead::PluginsList.plane(), GwPlane::Admin);
assert_eq!(InventoryRead::GuardrailsCatalog.plane(), GwPlane::Admin);
assert_eq!(
InventoryRead::AdminGuardrailsList(AdminPaging::default()).shape(),
Shape::List("Admin guardrails")
);
assert_eq!(
InventoryRead::IntegrationModels { id: id() }.shape(),
Shape::Models("integration models")
);
assert_eq!(
InventoryRead::McpWorkspaces { id: id() }.shape(),
Shape::Detail
);
assert_eq!(
InventoryRead::McpWorkspaces { id: id() }.policy(),
&withhold::MCP
);
assert_eq!(
InventoryRead::AuthSettings {
tsg: Some("100".into())
}
.tsg(),
Some("100")
);
}
#[test]
fn admin_status_lines() {
let paging = AdminPaging {
page_size: Some(2),
current_page: Some(1),
..AdminPaging::default()
};
assert_eq!(
admin_status(2, Some(10.0), &paging).unwrap(),
"Returned 2 of 10 admin guardrails (page 1); this is one page."
);
assert_eq!(admin_status(2, Some(4.0), &paging), None, "the last page");
assert_eq!(admin_status(1, Some(1.0), &AdminPaging::default()), None);
assert_eq!(
admin_status(1, Some(3.0), &AdminPaging::default()).unwrap(),
"Returned 1 of 3 admin guardrails (page 0); this is one page."
);
assert_eq!(admin_status(1, Some(2.5), &AdminPaging::default()), None);
}
}