mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-03 01:40:21 +08:00
55 lines
1.8 KiB
Rust
55 lines
1.8 KiB
Rust
|
|
use std::collections::BTreeSet;
|
||
|
|
|
||
|
|
use thiserror::Error;
|
||
|
|
|
||
|
|
use crate::model::RoutingGroupConfig;
|
||
|
|
use crate::mutations::{validate_header_patch, validate_json_patch_operations};
|
||
|
|
use crate::RoutingAction;
|
||
|
|
|
||
|
|
#[derive(Debug, Error, Clone, PartialEq, Eq)]
|
||
|
|
pub enum RoutingValidationError {
|
||
|
|
#[error("routing rule id is empty")]
|
||
|
|
EmptyRuleId,
|
||
|
|
#[error("duplicate routing rule id: {0}")]
|
||
|
|
DuplicateRuleId(String),
|
||
|
|
#[error("routing model policy selector is empty")]
|
||
|
|
EmptyModelSelector,
|
||
|
|
#[error("invalid mutation action: {0}")]
|
||
|
|
InvalidMutation(String),
|
||
|
|
}
|
||
|
|
|
||
|
|
pub fn validate_routing_group_config(
|
||
|
|
config: &RoutingGroupConfig,
|
||
|
|
) -> Result<(), RoutingValidationError> {
|
||
|
|
let mut rule_ids = BTreeSet::new();
|
||
|
|
for model_policy in &config.model_policies {
|
||
|
|
if model_policy.model.trim().is_empty() {
|
||
|
|
return Err(RoutingValidationError::EmptyModelSelector);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
for rule in &config.rules {
|
||
|
|
if rule.id.trim().is_empty() {
|
||
|
|
return Err(RoutingValidationError::EmptyRuleId);
|
||
|
|
}
|
||
|
|
if !rule_ids.insert(rule.id.clone()) {
|
||
|
|
return Err(RoutingValidationError::DuplicateRuleId(rule.id.clone()));
|
||
|
|
}
|
||
|
|
for action in &rule.actions {
|
||
|
|
match action {
|
||
|
|
RoutingAction::JsonPatchBody { patch } => {
|
||
|
|
validate_json_patch_operations(patch).map_err(|error| {
|
||
|
|
RoutingValidationError::InvalidMutation(error.to_string())
|
||
|
|
})?;
|
||
|
|
}
|
||
|
|
RoutingAction::PatchHeaders { patch } => {
|
||
|
|
validate_header_patch(patch).map_err(|error| {
|
||
|
|
RoutingValidationError::InvalidMutation(error.to_string())
|
||
|
|
})?;
|
||
|
|
}
|
||
|
|
_ => {}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
Ok(())
|
||
|
|
}
|