Skip to content

Commit 6de9a99

Browse files
committed
Preserve server spec extensions
1 parent 7070839 commit 6de9a99

File tree

1 file changed

+55
-0
lines changed

1 file changed

+55
-0
lines changed

crates/oas3/src/spec/server.rs

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ use std::collections::BTreeMap;
22

33
use serde::{Deserialize, Serialize};
44

5+
use super::spec_extensions;
6+
57
/// An object representing a Server.
68
///
79
/// See <https://spec.openapis.org/oas/v3.1.1#server-object>.
@@ -25,6 +27,14 @@ pub struct Server {
2527
/// The value is used for substitution in the server's URL template.
2628
#[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
2729
pub variables: BTreeMap<String, ServerVariable>,
30+
31+
/// Specification extensions.
32+
///
33+
/// Only "x-" prefixed keys are collected, and the prefix is stripped.
34+
///
35+
/// See <https://spec.openapis.org/oas/v3.1.1#specification-extensions>.
36+
#[serde(flatten, with = "spec_extensions")]
37+
pub extensions: BTreeMap<String, serde_json::Value>,
2838
}
2939

3040
/// An object representing a Server Variable for server URL template substitution.
@@ -49,4 +59,49 @@ pub struct ServerVariable {
4959
/// [CommonMark]: https://spec.commonmark.org/
5060
#[serde(skip_serializing_if = "Option::is_none")]
5161
pub description: Option<String>,
62+
63+
/// Specification extensions.
64+
///
65+
/// Only "x-" prefixed keys are collected, and the prefix is stripped.
66+
///
67+
/// See <https://spec.openapis.org/oas/v3.1.1#specification-extensions>.
68+
#[serde(flatten, with = "spec_extensions")]
69+
pub extensions: BTreeMap<String, serde_json::Value>,
70+
}
71+
72+
#[cfg(test)]
73+
mod tests {
74+
use super::{Server, ServerVariable};
75+
use serde_json::json;
76+
77+
#[test]
78+
fn server_extensions_round_trip() {
79+
let payload = r#"{
80+
"url": "https://example.com",
81+
"x-test": "alpha"
82+
}"#;
83+
84+
let server: Server = serde_json::from_str(payload).expect("server parses");
85+
assert_eq!(server.extensions.get("test"), Some(&json!("alpha")));
86+
87+
let value = serde_json::to_value(server).expect("server serializes");
88+
assert_eq!(value.get("x-test"), Some(&json!("alpha")));
89+
}
90+
91+
#[test]
92+
fn server_variable_extensions_round_trip() {
93+
let payload = r#"{
94+
"default": "example",
95+
"x-meta": {"enabled": true}
96+
}"#;
97+
98+
let variable: ServerVariable = serde_json::from_str(payload).expect("variable parses");
99+
assert_eq!(
100+
variable.extensions.get("meta"),
101+
Some(&json!({"enabled": true}))
102+
);
103+
104+
let value = serde_json::to_value(variable).expect("variable serializes");
105+
assert_eq!(value.get("x-meta"), Some(&json!({"enabled": true})));
106+
}
52107
}

0 commit comments

Comments
 (0)