use std::borrow::Cow; use tracing::warn; #[repr(u8)] pub(crate) enum Activity { Root(ActivityRoot), Unknown(ActivityUnknown), CopyPath(ActivityCopyPath), FileTransfer(ActivityFileTransfer), Realize(ActivityRealize), CopyPaths(ActivityCopyPaths), Builds(ActivityBuilds), Build(ActivityBuild), OptimizeStore(ActivityOptimizeStore), VerifyPaths(ActivityVerifyPaths), Substitute(ActivitySubstitute), QueryPathInfo(ActivityQueryPathInfo), PostBuildHook(ActivityPostBuildHook), BuildWaiting(ActivityBuildWaiting), FetchTree(ActivityFetchTree), } impl Activity { pub(crate) fn stop(&mut self) -> () { match self { Activity::Root(_activity_root) => { panic!("Attempted to start root activity."); } Activity::Unknown(activity_unknown) => { activity_unknown.state = ActivityState::Stopped; } Activity::CopyPath(activity_copy_path) => { activity_copy_path.state = ActivityState::Stopped; } Activity::FileTransfer(activity_file_transfer) => { activity_file_transfer.state = ActivityState::Stopped; } Activity::Realize(activity_realize) => { activity_realize.state = ActivityState::Stopped; } Activity::CopyPaths(activity_copy_paths) => { activity_copy_paths.state = ActivityState::Stopped; } Activity::Builds(activity_builds) => { activity_builds.state = ActivityState::Stopped; } Activity::Build(activity_build) => { activity_build.state = ActivityState::Stopped; } Activity::OptimizeStore(activity_optimize_store) => { activity_optimize_store.state = ActivityState::Stopped; } Activity::VerifyPaths(activity_verify_paths) => { activity_verify_paths.state = ActivityState::Stopped; } Activity::Substitute(activity_substitute) => { activity_substitute.state = ActivityState::Stopped; } Activity::QueryPathInfo(activity_query_path_info) => { activity_query_path_info.state = ActivityState::Stopped; } Activity::PostBuildHook(activity_post_build_hook) => { activity_post_build_hook.state = ActivityState::Stopped; } Activity::BuildWaiting(activity_build_waiting) => { activity_build_waiting.state = ActivityState::Stopped; } Activity::FetchTree(activity_fetch_tree) => { activity_fetch_tree.state = ActivityState::Stopped; } } } pub(crate) fn is_active(&self) -> bool { match self { Activity::Root(_activity_root) => true, Activity::Unknown(activity_unknown) => { matches!(activity_unknown.state, ActivityState::Started { .. }) } Activity::CopyPath(activity_copy_path) => { matches!(activity_copy_path.state, ActivityState::Started { .. }) } Activity::FileTransfer(activity_file_transfer) => { matches!(activity_file_transfer.state, ActivityState::Started { .. }) } Activity::Realize(activity_realize) => { matches!(activity_realize.state, ActivityState::Started { .. }) } Activity::CopyPaths(activity_copy_paths) => { matches!(activity_copy_paths.state, ActivityState::Started { .. }) } Activity::Builds(activity_builds) => { matches!(activity_builds.state, ActivityState::Started { .. }) } Activity::Build(activity_build) => { matches!(activity_build.state, ActivityState::Started { .. }) } Activity::OptimizeStore(activity_optimize_store) => { matches!(activity_optimize_store.state, ActivityState::Started { .. }) } Activity::VerifyPaths(activity_verify_paths) => { matches!(activity_verify_paths.state, ActivityState::Started { .. }) } Activity::Substitute(activity_substitute) => { matches!(activity_substitute.state, ActivityState::Started { .. }) } Activity::QueryPathInfo(activity_query_path_info) => { matches!( activity_query_path_info.state, ActivityState::Started { .. } ) } Activity::PostBuildHook(activity_post_build_hook) => { matches!( activity_post_build_hook.state, ActivityState::Started { .. } ) } Activity::BuildWaiting(activity_build_waiting) => { matches!(activity_build_waiting.state, ActivityState::Started { .. }) } Activity::FetchTree(activity_fetch_tree) => { matches!(activity_fetch_tree.state, ActivityState::Started { .. }) } } } pub(crate) fn is_transparent(&self) -> bool { match self { Activity::Root(_activity_root) => true, Activity::Unknown(_activity_unknown) => false, Activity::CopyPath(_activity_copy_path) => false, Activity::FileTransfer(_activity_file_transfer) => false, Activity::Realize(_activity_realize) => true, Activity::CopyPaths(_activity_copy_paths) => true, Activity::Builds(_activity_builds) => true, Activity::Build(_activity_build) => false, Activity::OptimizeStore(_activity_optimize_store) => false, Activity::VerifyPaths(_activity_verify_paths) => false, Activity::Substitute(_activity_substitute) => false, Activity::QueryPathInfo(_activity_query_path_info) => false, Activity::PostBuildHook(_activity_post_build_hook) => false, Activity::BuildWaiting(_activity_build_waiting) => true, Activity::FetchTree(_activity_fetch_tree) => false, } } pub(crate) fn display_name(&self) -> Option> { match self { Activity::Root(_activity_root) => { warn!("Unexpected display of root activity."); Some(Cow::Borrowed("Root")) } Activity::Unknown(activity_unknown) => { Some(Cow::Owned(format!("Unknown({})", activity_unknown.text))) } Activity::CopyPath(activity_copy_path) => Some(Cow::Owned(format!( "CopyPath({} | {} -> {})", activity_copy_path.missing_path, activity_copy_path.source, activity_copy_path.destination ))), Activity::FileTransfer(activity_file_transfer) => Some(Cow::Owned(format!( "FileTransfer({})", activity_file_transfer.url ))), Activity::Realize(_activity_realize) => Some(Cow::Borrowed("Realize")), Activity::CopyPaths(activity_copy_paths) => Some(Cow::Owned(format!( "CopyPaths({})", activity_copy_paths.text ))), Activity::Builds(_activity_builds) => Some(Cow::Borrowed("Builds")), Activity::Build(activity_build) => { if let Some(machine_name) = &activity_build.machine_name { Some(Cow::Owned(format!( "Build({}@{machine_name})", activity_build.drv_path ))) } else { Some(Cow::Owned(format!("Build({})", activity_build.drv_path))) } } Activity::OptimizeStore(_activity_optimize_store) => { Some(Cow::Borrowed("OptimizeStore")) } Activity::VerifyPaths(_activity_verify_paths) => Some(Cow::Borrowed("VerifyPaths")), Activity::Substitute(_activity_substitute) => Some(Cow::Borrowed("Substitute")), Activity::QueryPathInfo(_activity_query_path_info) => { Some(Cow::Borrowed("QueryPathInfo")) } Activity::PostBuildHook(_activity_post_build_hook) => { Some(Cow::Borrowed("PostBuildHook")) } Activity::BuildWaiting(activity_build_waiting) => Some(Cow::Owned(format!( "BuildWaiting({:?} | {:?} | {})", activity_build_waiting.drv_path, activity_build_waiting.path_resolved, activity_build_waiting.text ))), Activity::FetchTree(_activity_fetch_tree) => Some(Cow::Borrowed("FetchTree")), } } } pub(crate) struct ActivityRoot {} pub(crate) struct ActivityUnknown { pub(crate) state: ActivityState, pub(crate) text: String, } pub(crate) struct ActivityCopyPath { pub(crate) state: ActivityState, pub(crate) missing_path: String, /// The machine with the file(s) pub(crate) source: String, /// The machine that is receiving the file(s) pub(crate) destination: String, } pub(crate) struct ActivityFileTransfer { pub(crate) state: ActivityState, pub(crate) url: String, } pub(crate) struct ActivityRealize { pub(crate) state: ActivityState, } pub(crate) struct ActivityCopyPaths { pub(crate) state: ActivityState, pub(crate) text: String, } pub(crate) struct ActivityBuilds { pub(crate) state: ActivityState, } pub(crate) struct ActivityBuild { pub(crate) state: ActivityState, pub(crate) drv_path: String, pub(crate) machine_name: Option, } pub(crate) struct ActivityOptimizeStore { pub(crate) state: ActivityState, } pub(crate) struct ActivityVerifyPaths { pub(crate) state: ActivityState, } pub(crate) struct ActivitySubstitute { pub(crate) state: ActivityState, } pub(crate) struct ActivityQueryPathInfo { pub(crate) state: ActivityState, } pub(crate) struct ActivityPostBuildHook { pub(crate) state: ActivityState, } pub(crate) struct ActivityBuildWaiting { pub(crate) state: ActivityState, pub(crate) text: String, pub(crate) drv_path: Option, pub(crate) path_resolved: Option, } pub(crate) struct ActivityFetchTree { pub(crate) state: ActivityState, } pub(crate) enum ActivityState { Started { progress_numerator: u64, progress_denominator: u64, progress_running: u64, progress_failed: u64, }, Stopped, } impl Default for ActivityState { fn default() -> Self { ActivityState::Started { progress_numerator: 0, progress_denominator: 0, progress_running: 0, progress_failed: 0, } } }