Skip to content

Commit

Permalink
refactor: Refactor parse_conf_command function and improve code reada…
Browse files Browse the repository at this point in the history
…bility
  • Loading branch information
LeChatP committed Oct 15, 2024
1 parent 810ee3f commit beb6622
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 76 deletions.
89 changes: 42 additions & 47 deletions rar-common/src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -190,47 +190,48 @@ fn remove_outer_quotes(input: &str) -> String {

pub fn parse_conf_command(command: &SCommand) -> Result<Vec<String>, Box<dyn Error>> {
match command {
SCommand::Simple(command) => Ok(shell_words::split(command)?),
SCommand::Complex(command) => {
if let Some(array) = command.as_array() {
let mut result = Vec::new();
if !array.iter().all(|item| {
// if it is a string
item.is_string() && {
//add to result
result.push(item.as_str().unwrap().to_string());
true // continue
}
}) {
// if any of the items is not a string
return Err("Invalid command".into());
}
Ok(result)
} else {
// call PluginManager
#[cfg(feature = "finder")]
{
let res = PluginManager::notify_complex_command_parser(command);
debug!("Parsed command {:?}", res);
res
}
#[cfg(not(feature = "finder"))]
{
Err("Invalid command".into())
}
}
}
SCommand::Simple(command) => parse_simple_command(command),
SCommand::Complex(command) => parse_complex_command(command),
}
}

pub fn find_from_envpath<P>(exe_name: &P) -> Option<PathBuf>
where
P: AsRef<Path>,
{
fn parse_simple_command(command: &str) -> Result<Vec<String>, Box<dyn Error>> {
shell_words::split(command).map_err(Into::into)
}

fn parse_complex_command(command: &serde_json::Value) -> Result<Vec<String>, Box<dyn Error>> {
if let Some(array) = command.as_array() {
let result: Result<Vec<String>, _> = array
.iter()
.map(|item| {
item.as_str()
.map(|s| s.to_string())
.ok_or_else(|| "Invalid command".into())
})
.collect();
result
} else {
parse_complex_command_with_finder(command)
}
}

#[cfg(feature = "finder")]
fn parse_complex_command_with_finder(command: &serde_json::Value) -> Result<Vec<String>, Box<dyn Error>> {
let res = PluginManager::notify_complex_command_parser(command);
debug!("Parsed command {:?}", res);
res
}

#[cfg(not(feature = "finder"))]
fn parse_complex_command_with_finder(_command: &serde_json::Value) -> Result<Vec<String>, Box<dyn Error>> {
Err("Invalid command".into())
}

pub fn find_from_envpath<P: AsRef<Path>>(exe_name: P) -> Option<PathBuf> {
env::var_os("PATH").and_then(|paths| {
env::split_paths(&paths)
.filter_map(|dir| {
let full_path = dir.join(exe_name);
let full_path = dir.join(&exe_name);
if full_path.is_file() {
Some(full_path)
} else {
Expand All @@ -241,20 +242,14 @@ where
})
}

pub fn final_path(path: &String) -> PathBuf {
let result;
if let Some(env_path) = find_from_envpath(&path) {
result = env_path
} else if let Ok(cannon_path) = std::fs::canonicalize(path) {
result = cannon_path;
pub fn final_path(path: &str) -> PathBuf {
if let Some(env_path) = find_from_envpath(path) {
env_path
} else if let Ok(canon_path) = std::fs::canonicalize(path) {
canon_path
} else {
result = path.parse().expect("The path is not valid");
PathBuf::from(path)
}
result
.to_str()
.expect("The path is not valid")
.parse()
.expect("The path is not valid")
}

#[cfg(debug_assertions)]
Expand Down
60 changes: 31 additions & 29 deletions src/chsr/cli/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -392,41 +392,43 @@ pub fn process_input(storage: &Storage, inputs: Inputs) -> Result<bool, Box<dyn
_ => Err("Unknown Input".into()),
}
}

pub fn perform_on_target_opt(
rconfig: &Rc<RefCell<rar_common::database::structs::SConfig>>,
role_id: Option<String>,
task_id: Option<IdTask>,
exec_on_opt: impl Fn(Rc<RefCell<Opt>>) -> Result<(), Box<dyn Error>>,
) -> Result<(), Box<dyn Error>> {
let config = rconfig.as_ref().borrow_mut();
if let Some(role_id) = role_id {
if let Some(role) = config.role(&role_id) {
if let Some(task_id) = task_id {
if let Some(task) = role.as_ref().borrow().task(&task_id) {
if let Some(options) = &task.as_ref().borrow_mut().options {
exec_on_opt(options.clone())
} else {
let options = Rc::new(RefCell::new(Opt::default()));
let ret = exec_on_opt(options.clone());
task.as_ref().borrow_mut().options = Some(options);
ret
}
} else {
Err("Task not found".into())
}
} else if let Some(options) = &role.as_ref().borrow_mut().options {
exec_on_opt(options.clone())
} else {
let options = Rc::new(RefCell::new(Opt::default()));
let ret = exec_on_opt(options.clone());
role.as_ref().borrow_mut().options = Some(options);
ret
}
let mut config = rconfig.as_ref().borrow_mut();

// Helper function to execute on option or create a new one
fn execute_or_create_option(
exec_on_opt: impl Fn(Rc<RefCell<Opt>>) -> Result<(), Box<dyn Error>>,
options: &mut Option<Rc<RefCell<Opt>>>,
) -> Result<(), Box<dyn Error>> {
if let Some(opt) = options {
exec_on_opt(opt.clone())
} else {
Err("Role not found".into())
let new_opt = Rc::new(RefCell::new(Opt::default()));
let result = exec_on_opt(new_opt.clone());
*options = Some(new_opt);
result
}
} else {
return exec_on_opt(config.options.as_ref().unwrap().clone());
}
}

// If role_id is provided, find the role
if let Some(role_id) = role_id {
let role = config.role(&role_id).ok_or("Role not found")?;
let mut role_borrowed = role.as_ref().borrow_mut();

// If task_id is provided, find the task
if let Some(task_id) = task_id {
let task = role_borrowed.task(&task_id).ok_or("Task not found")?;
return execute_or_create_option(exec_on_opt, &mut task.as_ref().borrow_mut().options);
}
// No task_id, use role options
return execute_or_create_option(exec_on_opt, &mut role_borrowed.options);
}

// No role_id, use global config options
execute_or_create_option(exec_on_opt, &mut config.options)
}

0 comments on commit beb6622

Please sign in to comment.