@@ -34,7 +34,8 @@ use std::{
34
34
} ;
35
35
36
36
#[ cfg( test) ]
37
- use quote:: { ToTokens , Tokens } ;
37
+ use quote:: ToTokens ;
38
+ use quote:: Tokens ;
38
39
use semver:: Version ;
39
40
use void:: Void ;
40
41
@@ -63,9 +64,9 @@ pub struct Api {
63
64
/// parameters that are common to all API methods
64
65
pub common_params : BTreeMap < String , Type > ,
65
66
/// root API methods e.g. Search, Index
66
- pub root : BTreeMap < String , ApiEndpoint > ,
67
+ pub root : ApiNamespace ,
67
68
/// namespace client methods e.g. Indices.Create, Ml.PutJob
68
- pub namespaces : BTreeMap < String , BTreeMap < String , ApiEndpoint > > ,
69
+ pub namespaces : BTreeMap < String , ApiNamespace > ,
69
70
/// enums in parameters
70
71
pub enums : Vec < ApiEnum > ,
71
72
}
@@ -79,9 +80,9 @@ impl Api {
79
80
pub fn endpoint_for_api_call ( & self , api_call : & str ) -> Option < & ApiEndpoint > {
80
81
let api_call_path: Vec < & str > = api_call. split ( '.' ) . collect ( ) ;
81
82
match api_call_path. len ( ) {
82
- 1 => self . root . get ( api_call_path[ 0 ] ) ,
83
+ 1 => self . root . endpoints ( ) . get ( api_call_path[ 0 ] ) ,
83
84
_ => match self . namespaces . get ( api_call_path[ 0 ] ) {
84
- Some ( namespace) => namespace. get ( api_call_path[ 1 ] ) ,
85
+ Some ( namespace) => namespace. endpoints ( ) . get ( api_call_path[ 1 ] ) ,
85
86
None => None ,
86
87
} ,
87
88
}
@@ -347,13 +348,49 @@ where
347
348
deserializer. deserialize_any ( StringOrStruct ( PhantomData ) )
348
349
}
349
350
351
+ /// Stability level of an API endpoint. Ordering defines increasing stability level, i.e.
352
+ /// `beta` is "more stable" than `experimental`.
353
+ #[ derive( Debug , Eq , PartialEq , Deserialize , Clone , Copy , Ord , PartialOrd ) ]
354
+ pub enum Stability {
355
+ #[ serde( rename = "experimental" ) ]
356
+ Experimental ,
357
+ #[ serde( rename = "beta" ) ]
358
+ Beta ,
359
+ #[ serde( rename = "stable" ) ]
360
+ Stable ,
361
+ }
362
+
363
+ impl Stability {
364
+ pub fn feature_name ( self ) -> Option < & ' static str > {
365
+ match self {
366
+ Stability :: Experimental => Some ( "experimental-apis" ) ,
367
+ Stability :: Beta => Some ( "beta-apis" ) ,
368
+ Stability :: Stable => None ,
369
+ }
370
+ }
371
+
372
+ /// Returns the (optional) feature configuration for this stability level as an outer
373
+ /// attribute, for use e.g. on function definitions.
374
+ pub fn outer_cfg_attr ( self ) -> Option < Tokens > {
375
+ let feature_name = self . feature_name ( ) ;
376
+ feature_name. map ( |name| quote ! ( #[ cfg( feature = #name) ] ) )
377
+ }
378
+
379
+ /// Returns the (optional) feature configuration for this stability level as an inner
380
+ /// attribute, for use e.g. at the top of a module source file
381
+ pub fn inner_cfg_attr ( self ) -> Option < Tokens > {
382
+ let feature_name = self . feature_name ( ) ;
383
+ feature_name. map ( |name| quote ! ( #![ cfg( feature = #name) ] ) )
384
+ }
385
+ }
386
+
350
387
/// An API endpoint defined in the REST API specs
351
388
#[ derive( Debug , PartialEq , Deserialize , Clone ) ]
352
389
pub struct ApiEndpoint {
353
390
pub full_name : Option < String > ,
354
391
#[ serde( deserialize_with = "string_or_struct" ) ]
355
392
documentation : Documentation ,
356
- pub stability : String ,
393
+ pub stability : Stability ,
357
394
pub url : Url ,
358
395
#[ serde( default = "BTreeMap::new" ) ]
359
396
pub params : BTreeMap < String , Type > ,
@@ -382,6 +419,34 @@ impl ApiEndpoint {
382
419
}
383
420
}
384
421
422
+ pub struct ApiNamespace {
423
+ stability : Stability ,
424
+ endpoints : BTreeMap < String , ApiEndpoint > ,
425
+ }
426
+
427
+ impl ApiNamespace {
428
+ pub fn new ( ) -> Self {
429
+ ApiNamespace {
430
+ stability : Stability :: Experimental , // will grow in stability as we add endpoints
431
+ endpoints : BTreeMap :: new ( ) ,
432
+ }
433
+ }
434
+
435
+ pub fn add ( & mut self , name : String , endpoint : ApiEndpoint ) {
436
+ // Stability of a namespace is that of the most stable of its endpoints
437
+ self . stability = Stability :: max ( self . stability , endpoint. stability ) ;
438
+ self . endpoints . insert ( name, endpoint) ;
439
+ }
440
+
441
+ pub fn stability ( & self ) -> Stability {
442
+ self . stability
443
+ }
444
+
445
+ pub fn endpoints ( & self ) -> & BTreeMap < String , ApiEndpoint > {
446
+ & self . endpoints
447
+ }
448
+ }
449
+
385
450
/// Common parameters accepted by all API endpoints
386
451
#[ derive( Debug , PartialEq , Deserialize , Clone ) ]
387
452
pub struct Common {
@@ -396,6 +461,7 @@ pub struct ApiEnum {
396
461
pub name : String ,
397
462
pub description : Option < String > ,
398
463
pub values : Vec < String > ,
464
+ pub stability : Stability , // inherited from the declaring API
399
465
}
400
466
401
467
impl Hash for ApiEnum {
@@ -499,7 +565,7 @@ pub use bulk::*;
499
565
/// Reads Api from a directory of REST Api specs
500
566
pub fn read_api ( branch : & str , download_dir : & PathBuf ) -> Result < Api , failure:: Error > {
501
567
let paths = fs:: read_dir ( download_dir) ?;
502
- let mut namespaces = BTreeMap :: new ( ) ;
568
+ let mut namespaces = BTreeMap :: < String , ApiNamespace > :: new ( ) ;
503
569
let mut enums: HashSet < ApiEnum > = HashSet :: new ( ) ;
504
570
let mut common_params = BTreeMap :: new ( ) ;
505
571
let root_key = "root" ;
@@ -517,11 +583,6 @@ pub fn read_api(branch: &str, download_dir: &PathBuf) -> Result<Api, failure::Er
517
583
let mut file = File :: open ( & path) ?;
518
584
let ( name, api_endpoint) = endpoint_from_file ( display, & mut file) ?;
519
585
520
- // Only generate builders and methods for stable APIs, not experimental or beta
521
- if & api_endpoint. stability != "stable" {
522
- continue ;
523
- }
524
-
525
586
let name_parts: Vec < & str > = name. splitn ( 2 , '.' ) . collect ( ) ;
526
587
let ( namespace, method_name) = match name_parts. len ( ) {
527
588
len if len > 1 => ( name_parts[ 0 ] . to_string ( ) , name_parts[ 1 ] . to_string ( ) ) ,
@@ -545,19 +606,20 @@ pub fn read_api(branch: &str, download_dir: &PathBuf) -> Result<Api, failure::Er
545
606
name : param. 0 . to_string ( ) ,
546
607
description : param. 1 . description . clone ( ) ,
547
608
values : options,
609
+ stability : api_endpoint. stability ,
548
610
} ) ;
549
611
}
550
612
551
613
// collect api endpoints into namespaces
552
614
if !namespaces. contains_key ( & namespace) {
553
- let mut api_endpoints = BTreeMap :: new ( ) ;
554
- api_endpoints . insert ( method_name, api_endpoint) ;
555
- namespaces. insert ( namespace. to_string ( ) , api_endpoints ) ;
615
+ let mut api_namespace = ApiNamespace :: new ( ) ;
616
+ api_namespace . add ( method_name, api_endpoint) ;
617
+ namespaces. insert ( namespace. to_string ( ) , api_namespace ) ;
556
618
} else {
557
619
namespaces
558
620
. get_mut ( & namespace)
559
621
. unwrap ( )
560
- . insert ( method_name, api_endpoint) ;
622
+ . add ( method_name, api_endpoint) ;
561
623
}
562
624
} else if name
563
625
. map ( |name| name == Some ( "_common.json" ) )
@@ -627,3 +689,14 @@ where
627
689
pub fn ast_eq < T : ToTokens > ( expected : Tokens , actual : T ) {
628
690
assert_eq ! ( expected, quote!( #actual) ) ;
629
691
}
692
+
693
+ #[ cfg( test) ]
694
+ mod tests {
695
+ use super :: * ;
696
+
697
+ #[ test]
698
+ fn stability_ordering ( ) {
699
+ assert ! ( Stability :: Beta > Stability :: Experimental ) ;
700
+ assert ! ( Stability :: Stable > Stability :: Beta ) ;
701
+ }
702
+ }
0 commit comments