use inquire::{Select, Text};
#[derive(Debug, Clone, interactive_clap::InteractiveClap)]
#[interactive_clap(input_context = crate::GlobalContext)]
#[interactive_clap(output_context = EditConnectionContext)]
pub struct EditConnection {
#[interactive_clap(skip_default_input_arg)]
connection_name: String,
#[interactive_clap(subargs)]
parameter: Parameter,
}
#[derive(Debug, Clone)]
pub struct EditConnectionContext {
global_context: crate::GlobalContext,
connection_name: String,
network_config: crate::config::NetworkConfig,
}
impl EditConnectionContext {
pub fn from_previous_context(
previous_context: crate::GlobalContext,
scope: &<EditConnection as interactive_clap::ToInteractiveClapContextScope>::InteractiveClapContextScope,
) -> color_eyre::eyre::Result<Self> {
let network_config = previous_context
.config
.network_connection
.get(&scope.connection_name)
.unwrap_or_else(|| {
panic!(
"Network connection \"{}\" not found",
&scope.connection_name
)
})
.clone();
Ok(Self {
global_context: previous_context,
connection_name: scope.connection_name.clone(),
network_config,
})
}
}
impl EditConnection {
fn input_connection_name(
context: &crate::GlobalContext,
) -> color_eyre::eyre::Result<Option<String>> {
crate::common::input_network_name(&context.config, &[])
}
}
#[derive(Debug, Clone, interactive_clap::InteractiveClap)]
#[interactive_clap(input_context = EditConnectionContext)]
#[interactive_clap(output_context = ParameterContext)]
pub struct Parameter {
#[interactive_clap(long)]
#[interactive_clap(skip_default_input_arg)]
key: String,
#[interactive_clap(long)]
#[interactive_clap(skip_default_input_arg)]
value: String,
}
#[derive(Debug, Clone)]
pub struct ParameterContext;
impl ParameterContext {
pub fn from_previous_context(
previous_context: EditConnectionContext,
scope: &<Parameter as interactive_clap::ToInteractiveClapContextScope>::InteractiveClapContextScope,
) -> color_eyre::eyre::Result<Self> {
let mut config = previous_context.global_context.config;
let Some(network_config) = config
.network_connection
.get_mut(&previous_context.connection_name)
else {
return color_eyre::eyre::Result::Err(color_eyre::eyre::eyre!(
"Network connection \"{}\" not found",
&previous_context.connection_name
));
};
match scope.key.as_str() {
"network_name" => network_config.network_name.clone_from(&scope.value),
"rpc_url" => network_config.rpc_url = scope.value.parse()?,
"rpc_api_key" => {
network_config.rpc_api_key = if scope.value == "null" {
None
} else {
Some(scope.value.parse()?)
};
}
"wallet_url" => {
network_config.wallet_url = scope.value.parse()?;
}
"explorer_transaction_url" => {
network_config.explorer_transaction_url = scope.value.parse()?;
}
"linkdrop_account_id" => {
network_config.linkdrop_account_id = if scope.value == "null" {
None
} else {
Some(scope.value.parse()?)
};
}
"near_social_db_contract_account_id" => {
network_config.near_social_db_contract_account_id = if &scope.value == "null" {
None
} else {
Some(scope.value.parse()?)
};
}
"faucet_url" => {
network_config.faucet_url = if scope.value == "null" {
None
} else {
Some(scope.value.parse()?)
};
}
"meta_transaction_relayer_url" => {
network_config.meta_transaction_relayer_url = if &scope.value == "null" {
None
} else {
Some(scope.value.parse()?)
};
}
"fastnear_url" => {
network_config.fastnear_url = if &scope.value == "null" {
None
} else {
Some(scope.value.parse()?)
};
}
"staking_pools_factory_account_id" => {
network_config.staking_pools_factory_account_id = if &scope.value == "null" {
None
} else {
Some(scope.value.parse()?)
};
}
"coingecko_url" => {
network_config.coingecko_url = if &scope.value == "null" {
None
} else {
Some(scope.value.parse()?)
};
}
_ => {
return color_eyre::eyre::Result::Err(color_eyre::eyre::eyre!(
"Configuration key <{}> not found",
&scope.key
));
}
}
eprintln!();
config.write_config_toml()?;
eprintln!(
"Network connection \"{}\" was successfully updated with the new value for <{}>",
&previous_context.connection_name, &scope.key
);
Ok(Self)
}
}
impl Parameter {
fn input_key(context: &EditConnectionContext) -> color_eyre::eyre::Result<Option<String>> {
let variants = context.network_config.get_fields()?;
let select_submit = Select::new("Which setting do you want to change?", variants).prompt();
match select_submit {
Ok(value) => Ok(Some(
value.split_once(':').expect("Internal error").0.to_string(),
)),
Err(
inquire::error::InquireError::OperationCanceled
| inquire::error::InquireError::OperationInterrupted,
) => Ok(None),
Err(err) => Err(err.into()),
}
}
pub fn input_value(
_context: &EditConnectionContext,
) -> color_eyre::eyre::Result<Option<String>> {
let value: String =
Text::new("Enter a new value for this parameter (if you want to remove an optional parameter, use \"null\"):")
.prompt()?;
Ok(Some(value))
}
}