use std::collections::HashSet;
use crate::{
Map,
model::{
parameter::{
Parameter, ParameterIn,
header::{Header, is_ignored_header, is_ignored_header_parameter},
},
reference::RefOr,
},
validate::{
rules::extensions::check_extensions,
violation::{SpecError, Violation, pointer_token},
},
};
pub(in crate::validate) fn check_parameter_list(
location: &str,
parameters: &[RefOr<Parameter>],
violations: &mut Vec<Violation>,
) {
let mut seen: HashSet<(String, ParameterIn)> = HashSet::new();
for parameter in parameters.iter().filter_map(RefOr::as_item) {
let key = (parameter.name.clone(), parameter.location);
if !seen.insert(key) {
violations.push(Violation::error(
location,
SpecError::DuplicateParameter {
name: parameter.name.clone(),
location: format!("{:?}", parameter.location).to_lowercase(),
},
));
}
if parameter.location == ParameterIn::Header && is_ignored_header_parameter(¶meter.name)
{
violations.push(Violation::error(
location,
SpecError::IgnoredHeaderParameter {
name: parameter.name.clone(),
},
));
}
if parameter.location == ParameterIn::Path && parameter.required != Some(true) {
violations.push(Violation::error(
location,
SpecError::PathParameterNotRequired {
name: parameter.name.clone(),
},
));
}
if let Some(style) = parameter.style() {
if !style.is_valid_for(parameter.location) {
violations.push(Violation::error(
location,
SpecError::IllegalStyle {
style: format!("{style:?}").to_lowercase(),
location: format!("{:?}", parameter.location).to_lowercase(),
},
));
}
}
check_extensions(location, ¶meter.extensions, violations);
}
}
pub(in crate::validate) fn check_header_map(
location: &str,
headers: &Map<RefOr<Header>>,
violations: &mut Vec<Violation>,
) {
for (name, header) in headers {
if is_ignored_header(name) {
violations.push(Violation::error(
location,
SpecError::IgnoredHeader { name: name.clone() },
));
}
if let Some(header) = header.as_item() {
check_extensions(
&format!("{location}/{}", pointer_token(name)),
&header.extensions,
violations,
);
}
}
}