pub(crate) trait StringErr<T> {
fn str_err(self) -> Result<T, String>;
}
impl<T, E: std::fmt::Display> StringErr<T> for Result<T, E> {
fn str_err(self) -> Result<T, String> {
self.map_err(|e| e.to_string())
}
}
macro_rules! git_task {
($msg:expr, $body:expr) => {
Task::perform(
async move {
let (tx, rx) = futures::channel::oneshot::channel();
std::thread::spawn(move || {
let _ = tx.send($body);
});
rx.await.map_err(|_| "Task cancelled".to_string())?
},
$msg,
)
};
}
macro_rules! with_repo {
($state:expr, dismiss, $status:expr, |$rp:ident| $cmd:expr) => {{
$state.active_tab_mut().context_menu = None;
with_repo!($state, $status, |$rp| $cmd)
}};
($state:expr, dismiss, loading, $status:expr, |$rp:ident| $cmd:expr) => {{
$state.active_tab_mut().context_menu = None;
with_repo!($state, loading, $status, |$rp| $cmd)
}};
($state:expr, $status:expr, |$rp:ident| $cmd:expr) => {{
let $rp = $state.active_tab().repo_path.clone();
if let Some($rp) = $rp {
$state.active_tab_mut().status_message = Some($status);
$cmd
} else {
Task::none()
}
}};
($state:expr, loading, $status:expr, |$rp:ident| $cmd:expr) => {{
let $rp = $state.active_tab().repo_path.clone();
if let Some($rp) = $rp {
{
let tab = $state.active_tab_mut();
tab.is_loading = true;
tab.status_message = Some($status);
}
$cmd
} else {
Task::none()
}
}};
}
macro_rules! icon {
($char:expr, $size:expr, $color:expr) => {
text($char)
.font(iced::Font::with_name("bootstrap-icons"))
.size($size)
.color($color)
};
($char:expr, $size:expr) => {
text($char)
.font(iced::Font::with_name("bootstrap-icons"))
.size($size)
};
}
macro_rules! set_field {
($state:expr, $field:ident, $value:expr) => {{
$state.active_tab_mut().$field = $value;
Task::none()
}};
}
macro_rules! clear_preview {
($state:expr) => {
$state.preview_editor = None;
$state.preview_path = None;
};
}
macro_rules! open_repo {
($path:expr) => {
gitkraft_core::features::repo::open_repo($path).str_err()?
};
}
macro_rules! git_repo_then_reload {
($path:expr, |$repo:ident| $op:expr) => {
git_task!(
Message::GitOperationResult,
(|| {
let $repo = open_repo!(&$path);
{ $op }.str_err()?;
crate::features::repo::commands::load_repo_blocking(&$path)
})()
)
};
}
macro_rules! git_wd_then_reload {
($path:expr, |$wd:ident| $op:expr) => {
git_task!(
Message::GitOperationResult,
(|| {
let $wd = crate::features::repo::commands::workdir(&$path)?;
{ $op }.str_err()?;
crate::features::repo::commands::load_repo_blocking(&$path)
})()
)
};
}
macro_rules! staging_op {
($path:expr, |$repo:ident| $op:expr) => {
git_task!(
Message::StagingUpdated,
(|| {
let $repo = open_repo!(&$path);
{ $op }.str_err()?;
crate::features::staging::commands::refresh_staging_state(&$path)
})()
)
};
}
macro_rules! row_style {
($($cond:expr => $style:expr),+ $(,)?) => {{
type RowStyleFn = fn(&iced::Theme) -> iced::widget::container::Style;
if false {
unreachable!()
}
$(else if $cond { $style as RowStyleFn })+
else { crate::theme::surface_style as RowStyleFn }
}};
}