solana_cli_config/
config_input.rs1use {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}