@@ -7,7 +7,12 @@ use dropshot_api_manager_types::{
77 ValidationContext , Versions ,
88} ;
99use openapiv3:: OpenAPI ;
10- use std:: collections:: { BTreeMap , BTreeSet } ;
10+ use std:: {
11+ collections:: { BTreeMap , BTreeSet } ,
12+ fmt,
13+ } ;
14+
15+ use crate :: validation:: DynValidationFn ;
1116
1217/// Describes an API managed by the Dropshot API manager.
1318///
@@ -36,22 +41,13 @@ pub struct ManagedApiConfig {
3641 /// server implementation.
3742 pub api_description :
3843 fn ( ) -> Result < ApiDescription < StubContext > , ApiDescriptionBuildErrors > ,
39-
40- /// Extra validation to perform on the OpenAPI document, if any.
41- ///
42- /// For versioned APIs, extra validation is performed on *all* versions,
43- /// including blessed ones. You may want to skip performing validation on
44- /// blessed versions, though, because they're immutable. To do so, use
45- /// [`ValidationContext::is_blessed`].
46- pub extra_validation : Option < fn ( & OpenAPI , ValidationContext < ' _ > ) > ,
4744}
4845
4946/// Describes an API managed by the Dropshot API manager.
5047///
5148/// This type is typically created from a [`ManagedApiConfig`] and can be
5249/// further configured using builder methods before being passed to
5350/// [`ManagedApis::new`].
54- #[ derive( Debug ) ]
5551pub struct ManagedApi {
5652 /// The API-specific part of the filename that's used for API descriptions
5753 ///
@@ -76,7 +72,12 @@ pub struct ManagedApi {
7672 fn ( ) -> Result < ApiDescription < StubContext > , ApiDescriptionBuildErrors > ,
7773
7874 /// Extra validation to perform on the OpenAPI document, if any.
79- extra_validation : Option < fn ( & OpenAPI , ValidationContext < ' _ > ) > ,
75+ ///
76+ /// For versioned APIs, extra validation is performed on *all* versions,
77+ /// including blessed ones. You may want to skip performing validation on
78+ /// blessed versions, though, because they're immutable. To do so, use
79+ /// [`ValidationContext::is_blessed`].
80+ extra_validation : Option < Box < DynValidationFn > > ,
8081
8182 /// If true, allow trivial changes (doc updates, type renames) for the
8283 /// latest blessed version without requiring version bumps.
@@ -85,15 +86,52 @@ pub struct ManagedApi {
8586 allow_trivial_changes_for_latest : bool ,
8687}
8788
89+ impl fmt:: Debug for ManagedApi {
90+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
91+ let Self {
92+ ident,
93+ versions,
94+ title,
95+ metadata,
96+ api_description : _,
97+ extra_validation,
98+ allow_trivial_changes_for_latest,
99+ } = self ;
100+
101+ f. debug_struct ( "ManagedApi" )
102+ . field ( "ident" , ident)
103+ . field ( "versions" , versions)
104+ . field ( "title" , title)
105+ . field ( "metadata" , metadata)
106+ . field ( "api_description" , & "..." )
107+ . field (
108+ "extra_validation" ,
109+ & extra_validation. as_ref ( ) . map ( |_| "..." ) ,
110+ )
111+ . field (
112+ "allow_trivial_changes_for_latest" ,
113+ allow_trivial_changes_for_latest,
114+ )
115+ . finish ( )
116+ }
117+ }
118+
88119impl From < ManagedApiConfig > for ManagedApi {
89120 fn from ( value : ManagedApiConfig ) -> Self {
121+ let ManagedApiConfig {
122+ ident,
123+ versions,
124+ title,
125+ metadata,
126+ api_description,
127+ } = value;
90128 ManagedApi {
91- ident : ApiIdent :: from ( value . ident . to_owned ( ) ) ,
92- versions : value . versions ,
93- title : value . title ,
94- metadata : value . metadata ,
95- api_description : value . api_description ,
96- extra_validation : value . extra_validation ,
129+ ident : ApiIdent :: from ( ident. to_owned ( ) ) ,
130+ versions,
131+ title,
132+ metadata,
133+ api_description,
134+ extra_validation : None ,
97135 allow_trivial_changes_for_latest : false ,
98136 }
99137 }
@@ -147,6 +185,20 @@ impl ManagedApi {
147185 self . allow_trivial_changes_for_latest
148186 }
149187
188+ /// Sets extra validation to perform on the OpenAPI document.
189+ ///
190+ /// For versioned APIs, extra validation is performed on *all* versions,
191+ /// including blessed ones. You may want to skip performing validation on
192+ /// blessed versions, though, because they're immutable. To do so, use
193+ /// [`ValidationContext::is_blessed`].
194+ pub fn with_extra_validation < F > ( mut self , f : F ) -> Self
195+ where
196+ F : Fn ( & OpenAPI , ValidationContext < ' _ > ) + Send + ' static ,
197+ {
198+ self . extra_validation = Some ( Box :: new ( f) ) ;
199+ self
200+ }
201+
150202 pub ( crate ) fn iter_versioned_versions (
151203 & self ,
152204 ) -> Option < impl Iterator < Item = & SupportedVersion > + ' _ > {
@@ -204,7 +256,7 @@ impl ManagedApi {
204256 openapi : & OpenAPI ,
205257 validation_context : ValidationContext < ' _ > ,
206258 ) {
207- if let Some ( extra_validation) = self . extra_validation {
259+ if let Some ( extra_validation) = & self . extra_validation {
208260 extra_validation ( openapi, validation_context) ;
209261 }
210262 }
@@ -214,11 +266,22 @@ impl ManagedApi {
214266/// tool.
215267///
216268/// This is repo-specific state that's passed into the OpenAPI manager.
217- #[ derive( Debug ) ]
218269pub struct ManagedApis {
219270 apis : BTreeMap < ApiIdent , ManagedApi > ,
220271 unknown_apis : BTreeSet < ApiIdent > ,
221- validation : Option < fn ( & OpenAPI , ValidationContext < ' _ > ) > ,
272+ validation : Option < Box < DynValidationFn > > ,
273+ }
274+
275+ impl fmt:: Debug for ManagedApis {
276+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
277+ let Self { apis, unknown_apis, validation } = self ;
278+
279+ f. debug_struct ( "ManagedApis" )
280+ . field ( "apis" , apis)
281+ . field ( "unknown_apis" , unknown_apis)
282+ . field ( "validation" , & validation. as_ref ( ) . map ( |_| "..." ) )
283+ . finish ( )
284+ }
222285}
223286
224287impl ManagedApis {
@@ -268,17 +331,17 @@ impl ManagedApis {
268331 /// This function will be called for each API document. The
269332 /// [`ValidationContext`] can be used to report errors, as well as extra
270333 /// files for which the contents need to be compared with those on disk.
271- pub fn with_validation (
272- mut self ,
273- validation : fn ( & OpenAPI , ValidationContext < ' _ > ) ,
274- ) -> Self {
275- self . validation = Some ( validation) ;
334+ pub fn with_validation < F > ( mut self , validation : F ) -> Self
335+ where
336+ F : Fn ( & OpenAPI , ValidationContext < ' _ > ) + Send + ' static ,
337+ {
338+ self . validation = Some ( Box :: new ( validation) ) ;
276339 self
277340 }
278341
279342 /// Returns the validation function for all APIs.
280- pub fn validation ( & self ) -> Option < fn ( & OpenAPI , ValidationContext < ' _ > ) > {
281- self . validation
343+ pub ( crate ) fn validation ( & self ) -> Option < & DynValidationFn > {
344+ self . validation . as_deref ( )
282345 }
283346
284347 /// Returns the number of APIs managed by this instance.
0 commit comments