use anyhow::Result;
use colored::Colorize;
use dialoguer::Confirm;
use enum_iterator::all;
use iceoryx2::config::Config;
use iceoryx2_bb_posix::directory::Directory;
use iceoryx2_bb_posix::file::Permission;
use iceoryx2_bb_posix::system_configuration::*;
use iceoryx2_bb_posix::*;
use iceoryx2_bb_system_types::file_path::FilePath;
use iceoryx2_bb_system_types::path::Path;
use std::panic::catch_unwind;
use iceoryx2_cli::config_descriptions::get_sections;
pub fn print_system_configuration() {
println!(
"{}",
"posix system configuration".underline().bright_green()
);
println!();
println!(" {}", "system info".underline().bright_green());
all::<SystemInfo>().for_each(|i| {
println!(
" {:<50} {}",
format!("{i:?}").white(),
format!("{}", i.value()).bright_blue(),
);
});
println!();
println!(" {}", "limit".underline().bright_green());
for i in all::<Limit>().collect::<Vec<_>>() {
let limit = i.value();
let limit = if limit == 0 {
"[ unlimited ]".to_string()
} else {
limit.to_string()
};
println!(" {:<50} {}", format!("{i:?}").white(), limit.bright_blue(),);
}
println!();
println!(" {}", "options".underline().bright_green());
for i in all::<SysOption>().collect::<Vec<_>>() {
if i.is_available() {
println!(
" {:<50} {}",
format!("{i:?}").white(),
format!("{}", i.is_available()).bright_blue()
);
} else {
println!(" {:<50} {}", format!("{:?}", i), i.is_available(),);
}
}
println!();
println!(" {}", "features".underline().bright_green());
for i in all::<Feature>().collect::<Vec<_>>() {
if i.is_available() {
println!(
" {:<50} {}",
format!("{i:?}").white(),
format!("{}", i.is_available()).bright_blue(),
);
} else {
println!(" {:<50} {}", format!("{:?}", i), i.is_available(),);
}
}
println!();
println!(" {}", "process resource limits".underline().bright_green());
for i in all::<ProcessResourceLimit>().collect::<Vec<_>>() {
let soft_limit_result = catch_unwind(|| i.soft_limit());
let hard_limit_result = catch_unwind(|| i.hard_limit());
match (soft_limit_result, hard_limit_result) {
(Ok(soft), Ok(hard)) => {
println!(
" {:<43} soft: {:<24} hard: {}",
format!("{i:?}").white(),
format!("{soft}").bright_blue(),
format!("{hard}").bright_blue()
);
}
(Err(e), _) | (_, Err(e)) => {
println!(
" {:<43} Error: {}",
format!("{i:?}").white(),
format!("Unable to acquire limit due to: {e:?}").red()
);
}
}
}
}
pub fn show_system_config() -> Result<()> {
print_system_configuration();
Ok(())
}
pub fn show_current_config() -> Result<()> {
let config = Config::global_config();
let toml_config = toml::to_string_pretty(&config)?;
println!("{toml_config}");
Ok(())
}
pub fn generate_global() -> Result<()> {
let mut global_config_path = GLOBAL_CONFIG_PATH;
global_config_path.add_path_entry(&iceoryx2::config::Config::relative_config_path())?;
let filepath = FilePath::from_path_and_file(
&global_config_path,
&iceoryx2::config::Config::default_config_file_name(),
)
.unwrap();
generate(global_config_path, filepath)
}
pub fn generate_local() -> Result<()> {
let user = iceoryx2_bb_posix::user::User::from_self().unwrap();
let mut user_config_path = match user.details() {
Some(details) => *details.config_dir(),
None => {
return Err(anyhow::anyhow!(
"User config directory not available on this platform!"
))
}
};
user_config_path.add_path_entry(&iceoryx2::config::Config::relative_config_path())?;
let filepath = FilePath::from_path_and_file(
&user_config_path,
&iceoryx2::config::Config::default_config_file_name(),
)
.unwrap();
generate(user_config_path, filepath)
}
fn generate(config_dir: Path, filepath: FilePath) -> Result<()> {
if let Ok(exists) = file::File::does_exist(&filepath) {
if exists {
let proceed = Confirm::new()
.with_prompt("Configuration file already exists. Do you want to overwrite it?")
.default(false)
.interact()?;
if !proceed {
println!("Operation cancelled. Configuration file was not overwritten.");
return Ok(());
}
} else if let Ok(false) = Directory::does_exist(&config_dir) {
Directory::create(
&config_dir,
file::Permission::OWNER_ALL
| Permission::GROUP_READ
| Permission::GROUP_EXEC
| Permission::OTHERS_READ
| Permission::OTHERS_EXEC,
)
.map_err(|e| anyhow::anyhow!("{:?}", e))?;
}
}
let toml_string = toml::to_string_pretty(&Config::default())?;
let mut file = file::FileBuilder::new(&filepath)
.creation_mode(file::CreationMode::PurgeAndCreate)
.permission(
file::Permission::OWNER_WRITE
| file::Permission::OWNER_READ
| file::Permission::GROUP_READ
| file::Permission::OTHERS_READ,
)
.create()
.map_err(|e| anyhow::anyhow!("{:?}", e))?;
file.write(toml_string.as_bytes())
.expect("Failed to write to file");
println!("Default configuration is generated at {filepath}");
Ok(())
}
pub fn print_config_description() -> Result<()> {
let sections = get_sections();
for section in sections {
println!("\n{}", format!("== {} ==", section.name).bright_green());
for entry in section.entries {
println!(
"-> {} [{}]",
entry.key.bright_blue(),
entry.value_type.bright_red()
);
println!(
" {}",
format!("(Default value: {})", entry.default_value.bright_white()).bright_yellow()
);
println!(" {}", entry.description.italic());
}
}
Ok(())
}