@@ -20,57 +20,45 @@ mod paths;
2020mod schemas;
2121mod utils;
2222
23- use std:: collections:: HashSet ;
24- use std:: io:: { BufWriter , Write } ;
25- use std:: path:: Path ;
2623use indexmap:: IndexMap ;
2724
28- use clients_schema:: { Availabilities , Endpoint , IndexedModel , Stability } ;
25+ use clients_schema:: { Availabilities , Flavor , IndexedModel , Stability , Visibility } ;
2926use openapiv3:: { Components , OpenAPI } ;
30- use tracing:: warn;
31-
27+ use clients_schema:: transform:: ExpandConfig ;
3228use crate :: components:: TypesAndComponents ;
3329
34- pub fn convert_schema_file (
35- path : impl AsRef < Path > ,
36- filter : Option < fn ( & Option < Availabilities > ) -> bool > ,
37- endpoint_filter : fn ( e : & Endpoint ) -> bool ,
38- out : impl Write ,
39- ) -> anyhow:: Result < ( ) > {
40- // Parsing from a string is faster than using a buffered reader when there is a need for look-ahead
41- // See https://github.com/serde-rs/json/issues/160
42- let json = & std:: fs:: read_to_string ( path) ?;
43- let json_deser = & mut serde_json:: Deserializer :: from_str ( json) ;
44-
45- let mut unused = HashSet :: new ( ) ;
46- let mut model: IndexedModel = serde_ignored:: deserialize ( json_deser, |path| {
47- if let serde_ignored:: Path :: Map { parent : _, key } = path {
48- unused. insert ( key) ;
49- }
50- } ) ?;
51- if !unused. is_empty ( ) {
52- let msg = unused. into_iter ( ) . collect :: < Vec < _ > > ( ) . join ( ", " ) ;
53- warn ! ( "Unknown fields found in schema.json: {}" , msg) ;
54- }
30+ /// Convert an API model into an OpenAPI v3 schema, optionally filtered for a given flavor
31+ pub fn convert_schema ( mut schema : IndexedModel , flavor : Option < Flavor > ) -> anyhow:: Result < OpenAPI > {
32+ // Expand generics
33+ schema = clients_schema:: transform:: expand_generics ( schema, ExpandConfig :: default ( ) ) ?;
34+
35+ // Filter flavor
36+ let filter: Option < fn ( & Option < Availabilities > ) -> bool > = match flavor {
37+ None => None ,
38+ Some ( Flavor :: Stack ) => Some ( |a| {
39+ // Generate only public items for Stack
40+ Flavor :: Stack . visibility ( a) == Some ( Visibility :: Public )
41+ } ) ,
42+ Some ( Flavor :: Serverless ) => Some ( |a| {
43+ // Generate only public items for Serverless
44+ Flavor :: Serverless . visibility ( a) == Some ( Visibility :: Public )
45+ } ) ,
46+ } ;
5547
5648 if let Some ( filter) = filter {
57- model = clients_schema:: transform:: filter_availability ( model , filter) ?;
49+ schema = clients_schema:: transform:: filter_availability ( schema , filter) ?;
5850 }
5951
60- model. endpoints . retain ( endpoint_filter) ;
61-
62- let openapi = convert_schema ( & model) ?;
63- serde_json:: to_writer_pretty ( BufWriter :: new ( out) , & openapi) ?;
64- Ok ( ( ) )
52+ convert_expanded_schema ( & schema)
6553}
6654
67- /// Convert an API model into an OpenAPI v3 schema. The input model must have all generics expanded, converstion
55+ /// Convert an API model into an OpenAPI v3 schema. The input model must have all generics expanded, conversion
6856/// will fail otherwise.
6957///
70- /// Note: there are ways to represent [generics in JSON Schema], but its unlikely that tooling will understood it.
58+ /// Note: there are ways to represent [generics in JSON Schema], but its unlikely that tooling will understand it.
7159///
7260/// [generics in JSON Schema]: https://json-schema.org/blog/posts/dynamicref-and-generics
73- pub fn convert_schema ( model : & IndexedModel ) -> anyhow:: Result < OpenAPI > {
61+ pub fn convert_expanded_schema ( model : & IndexedModel ) -> anyhow:: Result < OpenAPI > {
7462 let mut openapi = OpenAPI {
7563 openapi : "3.0.3" . into ( ) ,
7664 info : info ( model) ,
0 commit comments