@@ -7,7 +7,8 @@ use dirs::home_dir;
7
7
use heck:: ToSnakeCase ;
8
8
use reqwest:: Url ;
9
9
use serde:: de:: { self , MapAccess , Visitor } ;
10
- use serde:: { Deserialize , Deserializer , Serialize } ;
10
+ use serde:: ser:: SerializeMap ;
11
+ use serde:: { Deserialize , Deserializer , Serialize , Serializer } ;
11
12
use solana_cli_config:: { Config as SolanaConfig , CONFIG_FILE } ;
12
13
use solana_sdk:: clock:: Slot ;
13
14
use solana_sdk:: pubkey:: Pubkey ;
@@ -590,11 +591,29 @@ struct _Config {
590
591
591
592
#[ derive( Debug , Serialize , Deserialize ) ]
592
593
struct Provider {
593
- #[ serde( deserialize_with = "des_cluster" ) ]
594
+ #[ serde( serialize_with = "ser_cluster" , deserialize_with = "des_cluster" ) ]
594
595
cluster : Cluster ,
595
596
wallet : String ,
596
597
}
597
598
599
+ fn ser_cluster < S : Serializer > ( cluster : & Cluster , s : S ) -> Result < S :: Ok , S :: Error > {
600
+ match cluster {
601
+ Cluster :: Custom ( http, ws) => {
602
+ match ( Url :: parse ( http) , Url :: parse ( ws) ) {
603
+ // If `ws` was derived from `http`, serialize `http` as string
604
+ ( Ok ( h) , Ok ( w) ) if h. domain ( ) == w. domain ( ) => s. serialize_str ( http) ,
605
+ _ => {
606
+ let mut map = s. serialize_map ( Some ( 2 ) ) ?;
607
+ map. serialize_entry ( "http" , http) ?;
608
+ map. serialize_entry ( "ws" , ws) ?;
609
+ map. end ( )
610
+ }
611
+ }
612
+ }
613
+ _ => s. serialize_str ( & cluster. to_string ( ) ) ,
614
+ }
615
+ }
616
+
598
617
fn des_cluster < ' de , D > ( deserializer : D ) -> Result < Cluster , D :: Error >
599
618
where
600
619
D : Deserializer < ' de > ,
@@ -1465,15 +1484,34 @@ mod tests {
1465
1484
wallet = \" id.json\"
1466
1485
" ;
1467
1486
1468
- const CUSTOM_CONFIG : & str = "
1487
+ #[ test]
1488
+ fn parse_custom_cluster_str ( ) {
1489
+ let config = Config :: from_str (
1490
+ "
1469
1491
[provider]
1470
- cluster = { http = \" http://my-url.com\" , ws = \" ws://my-url.com \" }
1492
+ cluster = \" http://my-url.com\"
1471
1493
wallet = \" id.json\"
1472
- " ;
1494
+ " ,
1495
+ )
1496
+ . unwrap ( ) ;
1497
+ assert ! ( !config. features. skip_lint) ;
1498
+
1499
+ // Make sure the layout of `provider.cluster` stays the same after serialization
1500
+ assert ! ( config
1501
+ . to_string( )
1502
+ . contains( r#"cluster = "http://my-url.com""# ) ) ;
1503
+ }
1473
1504
1474
1505
#[ test]
1475
- fn parse_custom_cluster ( ) {
1476
- let config = Config :: from_str ( CUSTOM_CONFIG ) . unwrap ( ) ;
1506
+ fn parse_custom_cluster_map ( ) {
1507
+ let config = Config :: from_str (
1508
+ "
1509
+ [provider]
1510
+ cluster = { http = \" http://my-url.com\" , ws = \" ws://my-url.com\" }
1511
+ wallet = \" id.json\"
1512
+ " ,
1513
+ )
1514
+ . unwrap ( ) ;
1477
1515
assert ! ( !config. features. skip_lint) ;
1478
1516
}
1479
1517
0 commit comments