@@ -42,7 +42,9 @@ use void::Void;
4242pub mod code_gen;
4343pub mod output;
4444
45+ use itertools:: Itertools ;
4546use output:: { merge_file, write_file} ;
47+ use std:: cmp:: Ordering ;
4648
4749lazy_static ! {
4850 static ref VERSION : Version = semver:: Version :: parse( env!( "CARGO_PKG_VERSION" ) ) . unwrap( ) ;
@@ -205,6 +207,37 @@ pub struct Deprecated {
205207 pub description : String ,
206208}
207209
210+ impl PartialOrd for Deprecated {
211+ fn partial_cmp ( & self , other : & Self ) -> Option < Ordering > {
212+ match (
213+ Version :: parse ( & self . version ) ,
214+ Version :: parse ( & other. version ) ,
215+ ) {
216+ ( Err ( _) , _) => None ,
217+ ( _, Err ( _) ) => None ,
218+ ( Ok ( self_version) , Ok ( other_version) ) => self_version. partial_cmp ( & other_version) ,
219+ }
220+ }
221+ }
222+
223+ impl Deprecated {
224+ /// Combine optional deprecations, keeping either lack of deprecation or the highest version
225+ pub fn combine < ' a > (
226+ left : & ' a Option < Deprecated > ,
227+ right : & ' a Option < Deprecated > ,
228+ ) -> & ' a Option < Deprecated > {
229+ if let ( Some ( leftd) , Some ( rightd) ) = ( left, right) {
230+ if leftd > rightd {
231+ left
232+ } else {
233+ right
234+ }
235+ } else {
236+ & None
237+ }
238+ }
239+ }
240+
208241/// An API url path
209242#[ derive( Debug , PartialEq , Deserialize , Clone ) ]
210243pub struct Path {
@@ -392,6 +425,7 @@ pub struct ApiEndpoint {
392425 documentation : Documentation ,
393426 pub stability : Stability ,
394427 pub url : Url ,
428+ pub deprecated : Option < Deprecated > ,
395429 #[ serde( default = "BTreeMap::new" ) ]
396430 pub params : BTreeMap < String , Type > ,
397431 pub body : Option < Body > ,
@@ -583,6 +617,11 @@ pub fn read_api(branch: &str, download_dir: &PathBuf) -> Result<Api, failure::Er
583617 let mut file = File :: open ( & path) ?;
584618 let ( name, api_endpoint) = endpoint_from_file ( display, & mut file) ?;
585619
620+ if api_endpoint. stability != Stability :: Stable && api_endpoint. deprecated . is_some ( ) {
621+ // Do not generate deprecated unstable endpoints
622+ continue ;
623+ }
624+
586625 let name_parts: Vec < & str > = name. splitn ( 2 , '.' ) . collect ( ) ;
587626 let ( namespace, method_name) = match name_parts. len ( ) {
588627 len if len > 1 => ( name_parts[ 0 ] . to_string ( ) , name_parts[ 1 ] . to_string ( ) ) ,
@@ -655,21 +694,37 @@ where
655694 R : Read ,
656695{
657696 // deserialize the map from the reader
658- let endpoint : BTreeMap < String , ApiEndpoint > =
697+ let endpoints : BTreeMap < String , ApiEndpoint > =
659698 serde_json:: from_reader ( reader) . map_err ( |e| super :: error:: ParseError {
660699 message : format ! ( "Failed to parse {} because: {}" , name, e) ,
661700 } ) ?;
662701
663702 // get the first (and only) endpoint name and endpoint body
664- let mut first_endpoint = endpoint . into_iter ( ) . next ( ) . unwrap ( ) ;
665- first_endpoint . 1 . full_name = Some ( first_endpoint . 0 . clone ( ) ) ;
703+ let ( name , mut endpoint ) = endpoints . into_iter ( ) . next ( ) . unwrap ( ) ;
704+ endpoint . full_name = Some ( name . clone ( ) ) ;
666705
667706 // sort the HTTP methods so that we can easily pattern match on them later
668- for path in first_endpoint . 1 . url . paths . iter_mut ( ) {
707+ for path in endpoint . url . paths . iter_mut ( ) {
669708 path. methods . sort ( ) ;
670709 }
671710
672- Ok ( first_endpoint)
711+ // endpoint deprecation is the "least deprecated" of its paths
712+ let deprecation = endpoint
713+ . url
714+ . paths
715+ . iter ( )
716+ . map ( |p| & p. deprecated )
717+ . fold1 ( |d1, d2| Deprecated :: combine ( d1, d2) )
718+ . unwrap_or ( & None ) ;
719+
720+ if let Some ( deprecated) = deprecation {
721+ endpoint. deprecated = Some ( Deprecated {
722+ version : deprecated. version . clone ( ) ,
723+ description : "Deprecated via one of the child items" . to_string ( ) ,
724+ } )
725+ }
726+
727+ Ok ( ( name, endpoint) )
673728}
674729
675730/// deserializes Common from a file
@@ -699,4 +754,20 @@ mod tests {
699754 assert ! ( Stability :: Beta > Stability :: Experimental ) ;
700755 assert ! ( Stability :: Stable > Stability :: Beta ) ;
701756 }
757+
758+ #[ test]
759+ fn combine_deprecations ( ) {
760+ let d1 = Some ( Deprecated {
761+ version : "7.5.0" . to_string ( ) ,
762+ description : "foo" . to_string ( ) ,
763+ } ) ;
764+
765+ let d2 = Some ( Deprecated {
766+ version : "7.6.0" . to_string ( ) ,
767+ description : "foo" . to_string ( ) ,
768+ } ) ;
769+
770+ assert_eq ! ( & d2, Deprecated :: combine( & d1, & d2) ) ;
771+ assert_eq ! ( & None , Deprecated :: combine( & d1, & None ) ) ;
772+ }
702773}
0 commit comments