mod ui;
use std::sync::mpsc::{Receiver, RecvTimeoutError};
use crate::{
buildkit::container_info::SCellContainerInfo,
cli::{
MIN_FPS,
ls::app::{AppInner, AppItemSuperTrait, error_window::ErrorWindowState, ls::LsState},
},
};
pub struct StoppingState<Item> {
pub for_stop: Item,
pub ls_state: LsState<Item>,
pub rx: Receiver<color_eyre::Result<Vec<Item>>>,
}
impl StoppingState<SCellContainerInfo> {
pub fn stop(
ls_state: LsState<SCellContainerInfo>,
for_stop: SCellContainerInfo,
) -> AppInner<SCellContainerInfo> {
let buildkit = ls_state.buildkit.clone();
let (tx, rx) = std::sync::mpsc::channel();
tokio::spawn({
let container = for_stop.clone();
async move {
let res = buildkit.stop_container(&container).await;
let res = match res {
Ok(()) => buildkit.list_containers().await,
Err(e) => Err(e),
};
drop(tx.send(res));
}
});
AppInner::Stopping(Self {
for_stop,
ls_state,
rx,
})
}
}
impl<Item: Clone + AppItemSuperTrait> StoppingState<Item> {
pub fn try_recv(self) -> color_eyre::Result<AppInner<Item>> {
match self.rx.recv_timeout(MIN_FPS) {
Ok(Ok(items)) => Ok(LsState::ls(items, self.ls_state.buildkit)),
Ok(Err(e)) => {
Ok(AppInner::ErrorWindow(ErrorWindowState {
ls_state: self.ls_state,
message: e.to_string(),
}))
},
Err(RecvTimeoutError::Timeout) => Ok(AppInner::Stopping(self)),
Err(RecvTimeoutError::Disconnected) => {
color_eyre::eyre::bail!(
"StoppingState channel cannot be disconnected without returning a result"
)
},
}
}
}