use serde::Deserialize;
use super::filters::FilterEntry;
#[derive(Debug, Clone, Deserialize, serde::Serialize)]
#[serde(untagged)]
pub enum ChainRef {
Inline {
name: String,
filters: Vec<FilterEntry>,
},
Named(String),
}
#[cfg(test)]
#[expect(clippy::allow_attributes, reason = "blanket test suppressions")]
#[allow(
clippy::unwrap_used,
clippy::expect_used,
clippy::indexing_slicing,
clippy::needless_raw_strings,
clippy::needless_raw_string_hashes,
clippy::panic,
reason = "tests use unwrap/expect/indexing/raw strings for brevity"
)]
mod tests {
use super::*;
#[test]
fn parse_named_ref() {
let chain_ref: ChainRef = serde_yaml::from_str(r#""my_chain""#).unwrap();
assert!(
matches!(chain_ref, ChainRef::Named(s) if s == "my_chain"),
"should parse as Named variant"
);
}
#[test]
fn parse_inline_ref() {
let yaml = r#"
name: inline_chain
filters:
- filter: headers
"#;
let chain_ref: ChainRef = serde_yaml::from_str(yaml).unwrap();
match chain_ref {
ChainRef::Inline { name, filters } => {
assert_eq!(name, "inline_chain", "inline chain name mismatch");
assert_eq!(filters.len(), 1, "inline chain should have 1 filter");
},
ChainRef::Named(_) => panic!("should parse as Inline variant"),
}
}
#[test]
fn parse_inline_with_multiple_filters() {
let yaml = r#"
name: multi
filters:
- filter: headers
- filter: cors
"#;
let chain_ref: ChainRef = serde_yaml::from_str(yaml).unwrap();
match chain_ref {
ChainRef::Inline { filters, .. } => {
assert_eq!(filters.len(), 2, "should have 2 filters");
},
ChainRef::Named(_) => panic!("should parse as Inline variant"),
}
}
#[test]
fn parse_named_in_sequence() {
let yaml = r#"
- chain_a
- chain_b
"#;
let refs: Vec<ChainRef> = serde_yaml::from_str(yaml).unwrap();
assert_eq!(refs.len(), 2, "should have 2 chain refs");
assert!(
matches!(&refs[0], ChainRef::Named(s) if s == "chain_a"),
"first ref should be Named 'chain_a'"
);
assert!(
matches!(&refs[1], ChainRef::Named(s) if s == "chain_b"),
"second ref should be Named 'chain_b'"
);
}
#[test]
fn parse_mixed_sequence() {
let yaml = r#"
- chain_a
- name: inline
filters:
- filter: router
"#;
let refs: Vec<ChainRef> = serde_yaml::from_str(yaml).unwrap();
assert_eq!(refs.len(), 2, "should have 2 chain refs");
assert!(
matches!(&refs[0], ChainRef::Named(s) if s == "chain_a"),
"first should be Named"
);
assert!(matches!(&refs[1], ChainRef::Inline { .. }), "second should be Inline");
}
}