1212//!
1313//! Docs: <https://forge.rust-lang.org/infra/channel-layout.html>
1414
15- use std:: collections:: HashMap ;
16- use std:: collections:: hash_map:: Entry ;
17- use std:: fmt;
18- use std:: hash:: { Hash , Hasher } ;
19- use std:: str:: FromStr ;
15+ use std:: {
16+ collections:: { BTreeMap , btree_map:: Entry } ,
17+ fmt,
18+ hash:: { Hash , Hasher } ,
19+ str:: FromStr ,
20+ } ;
2021
2122use anyhow:: { Context , Result , anyhow, bail} ;
2223use serde:: { Deserialize , Serialize } ;
@@ -41,13 +42,13 @@ pub struct Manifest {
4142 pub ( crate ) manifest_version : ManifestVersion ,
4243 pub date : String ,
4344 #[ serde( default , rename = "pkg" ) ]
44- pub packages : HashMap < String , Package > ,
45+ pub packages : BTreeMap < String , Package > ,
4546 #[ serde( default ) ]
46- pub renames : HashMap < String , Renamed > ,
47+ pub renames : BTreeMap < String , Renamed > ,
4748 #[ serde( default , skip_serializing) ]
48- pub reverse_renames : HashMap < String , String > ,
49+ pub reverse_renames : BTreeMap < String , String > ,
4950 #[ serde( default ) ]
50- pub profiles : HashMap < Profile , Vec < String > > ,
51+ pub profiles : BTreeMap < Profile , Vec < String > > ,
5152}
5253
5354impl Manifest {
@@ -94,12 +95,12 @@ pub struct Package {
9495#[ serde( from = "TargetsMap" , into = "TargetsMap" ) ]
9596pub enum PackageTargets {
9697 Wildcard ( TargetedPackage ) ,
97- Targeted ( HashMap < TargetTriple , TargetedPackage > ) ,
98+ Targeted ( BTreeMap < TargetTriple , TargetedPackage > ) ,
9899}
99100
100101#[ derive( Deserialize , Serialize ) ]
101102#[ serde( transparent) ]
102- struct TargetsMap ( HashMap < TargetTriple , TargetedPackage > ) ;
103+ struct TargetsMap ( BTreeMap < TargetTriple , TargetedPackage > ) ;
103104
104105impl From < TargetsMap > for PackageTargets {
105106 fn from ( mut map : TargetsMap ) -> Self {
@@ -115,7 +116,7 @@ impl From<PackageTargets> for TargetsMap {
115116 fn from ( targets : PackageTargets ) -> Self {
116117 match targets {
117118 PackageTargets :: Wildcard ( tpkg) => {
118- let mut map = HashMap :: new ( ) ;
119+ let mut map = BTreeMap :: new ( ) ;
119120 map. insert ( TargetTriple :: new ( "*" ) , tpkg) ;
120121 Self ( map)
121122 }
@@ -639,6 +640,9 @@ mod tests {
639640
640641 // Example manifest from https://public.etherpad-mozilla.org/p/Rust-infra-work-week
641642 static EXAMPLE : & str = include_str ! ( "manifest/tests/channel-rust-nightly-example.toml" ) ;
643+ // Same manifest as above, but with the packages in a different order.
644+ static EXAMPLE_REORDERED : & str =
645+ include_str ! ( "manifest/tests/channel-rust-nightly-example.toml" ) ;
642646 // From brson's live build-rust-manifest.py script
643647 static EXAMPLE2 : & str = include_str ! ( "manifest/tests/channel-rust-nightly-example2.toml" ) ;
644648
@@ -742,4 +746,13 @@ date = "2015-10-10"
742746
743747 assert ! ( Manifest :: parse( & manifest) . is_ok( ) ) ;
744748 }
749+
750+ // #4715
751+ #[ test]
752+ fn manifest_serialized_with_sorted_keys ( ) -> anyhow:: Result < ( ) > {
753+ let manifest = Manifest :: parse ( EXAMPLE ) ?;
754+ let manifest_reordered = Manifest :: parse ( EXAMPLE_REORDERED ) ?;
755+ assert_eq ! ( manifest. stringify( ) ?, manifest_reordered. stringify( ) ?) ;
756+ Ok ( ( ) )
757+ }
745758}
0 commit comments