Skip to content

Commit 135d7e0

Browse files
cli: Fix custom provider.cluster (solana-foundation#3428)
1 parent 2ae3774 commit 135d7e0

File tree

2 files changed

+46
-7
lines changed

2 files changed

+46
-7
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ The minor version will be incremented upon a breaking change and the patch versi
102102
- cli: Avoid extra IDL generation during `verify` ([#3398](https://github.com/coral-xyz/anchor/pull/3398)).
103103
- lang: Require `zero` accounts to be unique ([#3409](https://github.com/coral-xyz/anchor/pull/3409)).
104104
- lang: Deduplicate `zero` accounts against `init` accounts ([#3422](https://github.com/coral-xyz/anchor/pull/3422)).
105+
- cli: Fix custom `provider.cluster` ([#3428](https://github.com/coral-xyz/anchor/pull/3428)).
105106

106107
### Breaking
107108

cli/src/config.rs

+45-7
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ use dirs::home_dir;
77
use heck::ToSnakeCase;
88
use reqwest::Url;
99
use serde::de::{self, MapAccess, Visitor};
10-
use serde::{Deserialize, Deserializer, Serialize};
10+
use serde::ser::SerializeMap;
11+
use serde::{Deserialize, Deserializer, Serialize, Serializer};
1112
use solana_cli_config::{Config as SolanaConfig, CONFIG_FILE};
1213
use solana_sdk::clock::Slot;
1314
use solana_sdk::pubkey::Pubkey;
@@ -590,11 +591,29 @@ struct _Config {
590591

591592
#[derive(Debug, Serialize, Deserialize)]
592593
struct Provider {
593-
#[serde(deserialize_with = "des_cluster")]
594+
#[serde(serialize_with = "ser_cluster", deserialize_with = "des_cluster")]
594595
cluster: Cluster,
595596
wallet: String,
596597
}
597598

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+
598617
fn des_cluster<'de, D>(deserializer: D) -> Result<Cluster, D::Error>
599618
where
600619
D: Deserializer<'de>,
@@ -1465,15 +1484,34 @@ mod tests {
14651484
wallet = \"id.json\"
14661485
";
14671486

1468-
const CUSTOM_CONFIG: &str = "
1487+
#[test]
1488+
fn parse_custom_cluster_str() {
1489+
let config = Config::from_str(
1490+
"
14691491
[provider]
1470-
cluster = { http = \"http://my-url.com\", ws = \"ws://my-url.com\" }
1492+
cluster = \"http://my-url.com\"
14711493
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+
}
14731504

14741505
#[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();
14771515
assert!(!config.features.skip_lint);
14781516
}
14791517

0 commit comments

Comments
 (0)