#[cfg(all(
feature = "package",
not(any(target_os = "ios", target_os = "android"))
))]
use corundum_framework_package::{After, Updater};
use corundum_framework_update::PackageStatus;
use super::panel::UpdateTarget;
#[allow(clippy::large_enum_variant)]
pub enum Target {
Binary(UpdateTarget),
#[cfg(all(
feature = "package",
not(any(target_os = "ios", target_os = "android"))
))]
Package(PackageTarget),
Delegated(Box<dyn DelegatedTarget>),
}
impl From<UpdateTarget> for Target {
fn from(target: UpdateTarget) -> Target {
Target::Binary(target)
}
}
#[cfg(all(
feature = "package",
not(any(target_os = "ios", target_os = "android"))
))]
pub struct PackageTarget {
pub label: String,
pub updater: Updater,
}
#[cfg(all(
feature = "package",
not(any(target_os = "ios", target_os = "android"))
))]
impl Target {
pub fn this_app(label: String, updater: Option<Updater>, binary: UpdateTarget) -> Target {
match updater {
Some(updater) if corundum_framework_platform::package::current().is_some() => {
Target::Package(PackageTarget { label, updater })
}
_ => Target::Binary(binary),
}
}
}
pub trait DelegatedTarget: Send + Sync + 'static {
fn label(&self) -> String;
fn status(&self) -> Result<PackageStatus, String>;
fn check(&self) -> Result<(), String>;
fn apply(&self) -> Result<(), String>;
}
#[cfg(all(
feature = "package",
not(any(target_os = "ios", target_os = "android"))
))]
impl DelegatedTarget for PackageTarget {
fn label(&self) -> String {
self.label.clone()
}
fn status(&self) -> Result<PackageStatus, String> {
Ok(self.updater.status())
}
fn check(&self) -> Result<(), String> {
self.updater.check_now();
Ok(())
}
fn apply(&self) -> Result<(), String> {
self.updater
.apply(After::RestartApp)
.map_err(|e| e.to_string())
}
}
impl Target {
pub(crate) fn label(&self) -> String {
match self {
Target::Binary(target) => target.label.clone(),
#[cfg(all(
feature = "package",
not(any(target_os = "ios", target_os = "android"))
))]
Target::Package(target) => target.label.clone(),
Target::Delegated(target) => target.label(),
}
}
pub(crate) fn binary(&self) -> Option<&UpdateTarget> {
match self {
Target::Binary(target) => Some(target),
_ => None,
}
}
pub(crate) fn package(&self) -> Option<&dyn DelegatedTarget> {
match self {
Target::Binary(_) => None,
#[cfg(all(
feature = "package",
not(any(target_os = "ios", target_os = "android"))
))]
Target::Package(target) => Some(target),
Target::Delegated(target) => Some(&**target),
}
}
pub(crate) fn live_status(&self) -> Option<PackageStatus> {
match self {
#[cfg(all(
feature = "package",
not(any(target_os = "ios", target_os = "android"))
))]
Target::Package(target) => Some(target.updater.status()),
_ => None,
}
}
pub(crate) fn closes_on_apply(&self) -> bool {
match self {
#[cfg(all(
feature = "package",
not(any(target_os = "ios", target_os = "android"))
))]
Target::Package(_) => true,
_ => false,
}
}
pub(crate) fn is_polled(&self) -> bool {
matches!(self, Target::Delegated(_))
}
pub(crate) fn repaint_on_change(&self, _ctx: &egui::Context) {
#[cfg(all(
feature = "package",
not(any(target_os = "ios", target_os = "android"))
))]
if let Target::Package(target) = self {
let ctx = _ctx.clone();
target.updater.on_change(move || ctx.request_repaint());
}
}
}