1use openapiv3::{OpenAPI, Operation, ReferenceOr};
2
3pub struct OpenAPIExt<'a> {
5 pub openapi: &'a mut OpenAPI,
6}
7
8impl OpenAPIExt<'_> {
9 pub fn new(openapi: &mut OpenAPI) -> OpenAPIExt {
10 OpenAPIExt { openapi }
11 }
12
13 pub fn operations_mut(&mut self) -> impl Iterator<Item = (&str, &str, &mut Operation)> {
20 self.openapi
21 .paths
22 .paths
23 .iter_mut()
24 .filter_map(|(path, item)| match *item {
25 ReferenceOr::Item(ref mut path_item) => Some((path, path_item)),
26 ReferenceOr::Reference { .. } => None,
27 })
28 .flat_map(|(path, path_item)| {
29 vec![
30 (path.as_str(), "get", &mut path_item.get),
31 (path.as_str(), "put", &mut path_item.put),
32 (path.as_str(), "post", &mut path_item.post),
33 (path.as_str(), "delete", &mut path_item.delete),
34 (path.as_str(), "options", &mut path_item.options),
35 (path.as_str(), "head", &mut path_item.head),
36 (path.as_str(), "patch", &mut path_item.patch),
37 (path.as_str(), "trace", &mut path_item.trace),
38 ]
39 .into_iter()
40 .filter_map(|(path, method, maybe_op)| {
41 maybe_op.as_mut().map(|op| (path, method, op))
42 })
43 })
44 }
45}
46
47#[test]
48fn test_add_operation_ids() {
49 const SCHEMA: &str = r#"
50{
51 "openapi": "3.0.0",
52 "info": {
53 "title": "Test API",
54 "version": "1.0.0"
55 },
56 "paths": {
57 "/foo": {
58 "get": {
59 "responses": {}
60 }
61 }
62 }
63}
64"#;
65
66 let mut openapi: OpenAPI = serde_json::from_str(SCHEMA).unwrap();
67 let mut oa_ext = OpenAPIExt::new(&mut openapi);
68 for (path, method, op) in oa_ext.operations_mut() {
69 op.operation_id = Some(format!("{}_{}", path, method));
70 }
71
72 assert_eq!(
73 openapi.paths.paths["/foo"]
74 .as_item()
75 .unwrap()
76 .get
77 .as_ref()
78 .unwrap()
79 .operation_id,
80 Some("/foo_get".to_string())
81 );
82}