#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
mod cmds;
use std::path::{Path, PathBuf};
use anyhow::Error;
use cmds::{channel, log};
use slint::SharedString;
slint::include_modules!();
fn main() -> Result<(), Error> {
let cli_args: CLIArgs = argh::from_env();
let ui = AppWindow::new()?;
ui.set_exe_path(cli_args.exe_path.into());
ui.set_repo_path(match cli_args.repo_path {
Some(path_str) => path_str.into(),
None => path_to_uistr(std::env::current_dir()?),
});
ui.on_request_channel_list({
let ui_handle = ui.as_weak();
move || {
let ui = ui_handle.unwrap();
let exe_path_string = ui.get_exe_path();
let exe_path = Path::new(exe_path_string.as_str());
let repo_path_string = ui.get_repo_path();
let repo_path = Path::new(repo_path_string.as_str());
let channel_output = channel(exe_path, repo_path);
let channel_list = match channel_output {
Ok(channel_list) => channel_list,
Err(e) => {
println!("{:?}", e);
return;
}
};
let channel_strs = channel_list
.entries
.into_iter()
.map(SharedString::from)
.collect::<Vec<_>>();
ui.set_channels((&channel_strs[..]).into());
ui.set_active_channel(i32::try_from(channel_list.active).unwrap_or(-1));
let channel_strs = channel_list
.entries
.into_iter()
.map(SharedString::from)
.collect::<Vec<_>>();
ui.set_channels(ChannelsData {
names: (&channel_strs[..]).into(),
active: i32::try_from(channel_list.active).unwrap_or(-1),
});
}
});
ui.on_request_changes_log({
let ui_handle = ui.as_weak();
move |ch_name: SharedString| {
let ch_name = ch_name.as_str();
let ui = ui_handle.unwrap();
let exe_path_string = ui.get_exe_path();
let exe_path = Path::new(exe_path_string.as_str());
let repo_path_string = ui.get_repo_path();
let repo_path = Path::new(repo_path_string.as_str());
let log_output = log(
exe_path,
repo_path,
Some(ch_name).filter(|cn| !cn.is_empty()),
);
let log = match log_output {
Ok(log) => log,
Err(e) => {
println!("{:?}", e);
return;
}
};
let log_strs: Vec<ChangeData> = log
.into_iter()
.map(|change| ChangeData {
hash: change.hash.into(),
author: change
.authors
.first()
.unwrap_or(&String::new())
.clone()
.into(),
timestamp: change.timestamp.into(),
message: change.message.into(),
})
.collect();
ui.set_changes_log((&log_strs[..]).into());
}
});
ui.on_request_change_delta({
let ui_handle = ui.as_weak();
move |change_hash: SharedString| {
let change_hash = change_hash.as_str();
let ui = ui_handle.unwrap();
let exe_path_string = ui.get_exe_path();
let exe_path = Path::new(exe_path_string.as_str());
let repo_path_string = ui.get_repo_path();
let repo_path = Path::new(repo_path_string.as_str());
let change_output = cmds::change(exe_path, repo_path, change_hash);
let delta = match change_output {
Ok(delta) => delta,
Err(e) => {
println!("{:?}", e);
return;
}
};
ui.set_delta((&String::from(delta)[..]).into());
}
});
ui.on_request_diff_summary({
let ui_handle = ui.as_weak();
move |ch_name: SharedString| {
let ch_name = ch_name.as_str();
let ui = ui_handle.unwrap();
let exe_path_string = ui.get_exe_path();
let exe_path = Path::new(exe_path_string.as_str());
let repo_path_string = ui.get_repo_path();
let repo_path = Path::new(repo_path_string.as_str());
let diff_output = cmds::diff_short(
exe_path,
repo_path,
Some(ch_name).filter(|cn| !cn.is_empty()),
);
let file_changes = match diff_output {
Ok(changes) => changes,
Err(e) => {
println!("{:?}", e);
return;
}
};
ui.set_count_files_changed(i32::try_from(file_changes.len()).unwrap_or(-1));
}
});
ui.on_request_diff_delta({
let ui_handle = ui.as_weak();
move |ch_name: SharedString| {
let ch_name = ch_name.as_str();
let ui = ui_handle.unwrap();
let exe_path_string = ui.get_exe_path();
let exe_path = Path::new(exe_path_string.as_str());
let repo_path_string = ui.get_repo_path();
let repo_path = Path::new(repo_path_string.as_str());
let diff_output = cmds::diff(
exe_path,
repo_path,
Some(ch_name).filter(|cn| !cn.is_empty()),
);
let delta = match diff_output {
Ok(delta) => delta,
Err(e) => {
println!("{:?}", e);
return;
}
};
ui.set_delta((&String::from(delta)[..]).into());
}
});
ui.run()?;
Ok(())
}
#[derive(argh::FromArgs)]
struct CLIArgs {
#[argh(option, default = "\"pijul\".into()")]
exe_path: String,
#[argh(option)]
repo_path: Option<String>,
}
fn path_to_uistr(path: PathBuf) -> SharedString {
format!("{:?}", path).into()
}