use std::sync::atomic::{AtomicBool, Ordering};
use crate::application::OutputToken;
use crate::application::cache::{CachePort, DisplayAction};
use crate::application::errors::{ErrorLogger, ErrorPresenter, ErrorToken};
use crate::domain::{
branch_sync::BranchSyncRepository, ci_checks::CiChecksRepository,
merge_ready::MergeReadinessRepository, pr_state::PrStateRepository, review::ReviewRepository,
};
pub trait RepoIdPort {
fn get(&self) -> Option<String>;
}
pub enum PromptEffect {
Show(String),
ShowAndRefresh { output: String, repo_id: String },
ShowLoadingAndRefresh { repo_id: String },
NoOutput,
}
pub fn resolve_cached(repo_id: &impl RepoIdPort, cache: &impl CachePort) -> PromptEffect {
let Some(id) = repo_id.get() else {
return PromptEffect::NoOutput;
};
match crate::application::cache::resolve(&id, cache) {
DisplayAction::Display(s) => PromptEffect::Show(s),
DisplayAction::DisplayAndRefresh(s) => PromptEffect::ShowAndRefresh {
output: s,
repo_id: id,
},
DisplayAction::LoadingWithRefresh => PromptEffect::ShowLoadingAndRefresh { repo_id: id },
}
}
pub fn fetch_output<C, L>(client: &C, logger: &L) -> Option<Vec<OutputToken>>
where
C: PrStateRepository
+ BranchSyncRepository
+ CiChecksRepository
+ ReviewRepository
+ MergeReadinessRepository
+ Sync,
L: ErrorLogger + Sync,
{
struct TrackingPresenter(AtomicBool);
impl ErrorPresenter for TrackingPresenter {
fn show_error(&self, _token: ErrorToken) {
self.0.store(true, Ordering::Relaxed);
}
}
let presenter = TrackingPresenter(AtomicBool::new(false));
let tokens = crate::application::run(client, logger, &presenter);
if presenter.0.load(Ordering::Relaxed) {
None
} else {
Some(tokens)
}
}