Skip to main content

solana_cli_config/
config_input.rs

1use {crate::Config, solana_commitment_config::CommitmentConfig, std::str::FromStr};
2
3pub enum SettingType {
4    Explicit,
5    Computed,
6    SystemDefault,
7}
8
9pub struct ConfigInput {
10    pub json_rpc_url: String,
11    pub websocket_url: String,
12    pub keypair_path: String,
13    pub commitment: CommitmentConfig,
14}
15
16impl ConfigInput {
17    fn default_keypair_path() -> String {
18        Config::default().keypair_path
19    }
20
21    fn default_json_rpc_url() -> String {
22        Config::default().json_rpc_url
23    }
24
25    fn default_websocket_url() -> String {
26        Config::default().websocket_url
27    }
28
29    fn default_commitment() -> CommitmentConfig {
30        CommitmentConfig::confirmed()
31    }
32
33    fn first_nonempty_setting(
34        settings: std::vec::Vec<(SettingType, String)>,
35    ) -> (SettingType, String) {
36        settings
37            .into_iter()
38            .find(|(_, value)| !value.is_empty())
39            .expect("no nonempty setting")
40    }
41
42    fn first_setting_is_some<T>(
43        settings: std::vec::Vec<(SettingType, Option<T>)>,
44    ) -> (SettingType, T) {
45        let (setting_type, setting_option) = settings
46            .into_iter()
47            .find(|(_, value)| value.is_some())
48            .expect("all settings none");
49        (setting_type, setting_option.unwrap())
50    }
51
52    pub fn compute_websocket_url_setting(
53        websocket_cmd_url: &str,
54        websocket_cfg_url: &str,
55        json_rpc_cmd_url: &str,
56        json_rpc_cfg_url: &str,
57    ) -> (SettingType, String) {
58        Self::first_nonempty_setting(vec![
59            (SettingType::Explicit, websocket_cmd_url.to_string()),
60            (SettingType::Explicit, websocket_cfg_url.to_string()),
61            (
62                SettingType::Computed,
63                Config::compute_websocket_url(&normalize_to_url_if_moniker(json_rpc_cmd_url)),
64            ),
65            (
66                SettingType::Computed,
67                Config::compute_websocket_url(&normalize_to_url_if_moniker(json_rpc_cfg_url)),
68            ),
69            (SettingType::SystemDefault, Self::default_websocket_url()),
70        ])
71    }
72
73    pub fn compute_json_rpc_url_setting(
74        json_rpc_cmd_url: &str,
75        json_rpc_cfg_url: &str,
76    ) -> (SettingType, String) {
77        let (setting_type, url_or_moniker) = Self::first_nonempty_setting(vec![
78            (SettingType::Explicit, json_rpc_cmd_url.to_string()),
79            (SettingType::Explicit, json_rpc_cfg_url.to_string()),
80            (SettingType::SystemDefault, Self::default_json_rpc_url()),
81        ]);
82        (setting_type, normalize_to_url_if_moniker(url_or_moniker))
83    }
84
85    pub fn compute_keypair_path_setting(
86        keypair_cmd_path: &str,
87        keypair_cfg_path: &str,
88    ) -> (SettingType, String) {
89        Self::first_nonempty_setting(vec![
90            (SettingType::Explicit, keypair_cmd_path.to_string()),
91            (SettingType::Explicit, keypair_cfg_path.to_string()),
92            (SettingType::SystemDefault, Self::default_keypair_path()),
93        ])
94    }
95
96    pub fn compute_commitment_config(
97        commitment_cmd: &str,
98        commitment_cfg: &str,
99    ) -> (SettingType, CommitmentConfig) {
100        Self::first_setting_is_some(vec![
101            (
102                SettingType::Explicit,
103                CommitmentConfig::from_str(commitment_cmd).ok(),
104            ),
105            (
106                SettingType::Explicit,
107                CommitmentConfig::from_str(commitment_cfg).ok(),
108            ),
109            (SettingType::SystemDefault, Some(Self::default_commitment())),
110        ])
111    }
112}
113
114impl Default for ConfigInput {
115    fn default() -> ConfigInput {
116        ConfigInput {
117            json_rpc_url: Self::default_json_rpc_url(),
118            websocket_url: Self::default_websocket_url(),
119            keypair_path: Self::default_keypair_path(),
120            commitment: CommitmentConfig::confirmed(),
121        }
122    }
123}
124
125pub fn normalize_to_url_if_moniker<T: AsRef<str>>(url_or_moniker: T) -> String {
126    match url_or_moniker.as_ref() {
127        "m" | "mainnet-beta" => "https://api.mainnet-beta.solana.com",
128        "t" | "testnet" => "https://api.testnet.solana.com",
129        "d" | "devnet" => "https://api.devnet.solana.com",
130        "l" | "localhost" => "http://localhost:8899",
131        url => url,
132    }
133    .to_string()
134}