use crate::validation::{Context, ValidateWithContext};
use serde::{Deserialize, Serialize};
use std::collections::BTreeMap;
#[derive(Clone, Copy, Debug, Deserialize, Serialize, PartialEq, Eq, Default)]
#[serde(rename_all = "lowercase")]
pub enum ParameterLocation {
#[default]
Path,
Query,
Header,
Cookie,
}
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Default)]
pub struct Parameter {
pub name: String,
#[serde(rename = "in", skip_serializing_if = "Option::is_none")]
pub in_: Option<ParameterLocation>,
pub value: serde_json::Value,
#[serde(flatten)]
#[serde(with = "crate::common::extensions")]
#[serde(skip_serializing_if = "Option::is_none")]
pub extensions: Option<BTreeMap<String, serde_json::Value>>,
}
impl ValidateWithContext for Parameter {
fn validate_with_context(&self, ctx: &mut Context) {
ctx.require_non_empty("name", &self.name);
}
}
#[cfg(test)]
mod tests {
use super::*;
use enumset::EnumSet;
use serde_json::json;
#[test]
fn deserialize_round_trips() {
let p: Parameter = serde_json::from_value(json!({
"name": "petId",
"in": "path",
"value": "$inputs.petId",
}))
.unwrap();
assert_eq!(p.name, "petId");
assert_eq!(p.in_, Some(ParameterLocation::Path));
assert_eq!(p.value, json!("$inputs.petId"));
let v = serde_json::to_value(&p).unwrap();
assert_eq!(v["in"], json!("path"));
}
#[test]
fn value_accepts_any_json_type() {
let p: Parameter =
serde_json::from_value(json!({ "name": "flags", "value": [1, 2, 3] })).unwrap();
assert_eq!(p.value, json!([1, 2, 3]));
assert!(p.in_.is_none());
}
#[test]
fn validate_rejects_empty_name() {
let mut c = Context::with_path(EnumSet::empty(), "#.p");
Parameter::default().validate_with_context(&mut c);
assert!(c.errors.iter().any(|e| e == "#.p.name: must not be empty"));
}
#[test]
fn all_locations_round_trip() {
for (s, loc) in [
("path", ParameterLocation::Path),
("query", ParameterLocation::Query),
("header", ParameterLocation::Header),
("cookie", ParameterLocation::Cookie),
] {
let p: Parameter =
serde_json::from_value(json!({ "name": "n", "in": s, "value": 1 })).unwrap();
assert_eq!(p.in_, Some(loc));
}
}
}