use crate::behaviors::ResponseBehaviors;
use crate::predicate::{BodyMatcher, HeaderMatcher, QueryMatcher};
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct Rule {
pub id: String,
#[serde(rename = "match")]
pub match_config: MatchConfig,
pub fault: FaultConfig,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub upstream: Option<String>,
}
#[derive(Debug, Clone, Deserialize, Serialize, Default)]
pub struct MatchConfig {
#[serde(default)]
pub methods: Vec<String>,
#[serde(default)]
pub path: PathMatch,
#[serde(default)]
pub headers: Vec<super::routing::HeaderMatch>,
#[serde(
default,
rename = "headerPredicates",
skip_serializing_if = "Vec::is_empty"
)]
pub header_predicates: Vec<HeaderMatcher>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub query: Vec<QueryMatcher>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub body: Option<BodyMatcher>,
#[serde(default = "default_case_sensitive", rename = "caseSensitive")]
pub case_sensitive: bool,
}
fn default_case_sensitive() -> bool {
true
}
#[derive(Debug, Clone, Deserialize, Serialize, Default)]
#[serde(untagged)]
pub enum PathMatch {
#[default]
Any,
Exact {
exact: String,
},
Prefix {
prefix: String,
},
Regex {
regex: String,
},
Contains {
contains: String,
},
EndsWith {
#[serde(rename = "endsWith")]
ends_with: String,
},
}
#[derive(Debug, Clone, Deserialize, Serialize, Default)]
pub struct FaultConfig {
#[serde(default)]
pub latency: Option<LatencyFault>,
#[serde(default)]
pub error: Option<ErrorFault>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub tcp_fault: Option<TcpFault>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum TcpFault {
ConnectionResetByPeer,
RandomDataThenClose,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct LatencyFault {
pub probability: f64,
pub min_ms: u64,
pub max_ms: u64,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct ErrorFault {
pub probability: f64,
pub status: u16,
#[serde(default)]
pub body: String,
#[serde(default, skip_serializing_if = "std::collections::HashMap::is_empty")]
pub headers: std::collections::HashMap<String, String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub behaviors: Option<ResponseBehaviors>,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct ScriptRule {
pub id: String,
pub script: String, #[serde(default, rename = "match")]
pub match_config: MatchConfig,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub upstream: Option<String>,
}