fn handle_status_change(
    service_handler: &ServiceHandler,
    next_status: ServiceStatus,
) -> (ServiceHandler, ServiceStatus) {
    let mut new_service_handler = service_handler.clone();
    if next_status == service_handler.status {
        return (new_service_handler, next_status);
    }
    //TODO: refactor + cleanup.
    // A -> [B,C] means that transition to A is allowed only if service is in state B or C.
    let allowed_transitions = hashmap! {
        ServiceStatus::Initial        => vec![ServiceStatus::Success, ServiceStatus::Failed,
                                              ServiceStatus::Started],
        ServiceStatus::Starting       => vec![ServiceStatus::Initial],
        ServiceStatus::Started        => vec![ServiceStatus::Starting],
        ServiceStatus::InKilling      => vec![ServiceStatus::Initial,
                                              ServiceStatus::Running,
                                              ServiceStatus::Starting,
                                              ServiceStatus::Started],
        ServiceStatus::Running        => vec![ServiceStatus::Started],
        ServiceStatus::FinishedFailed => vec![ServiceStatus::Starting,
                                              ServiceStatus::Started,
                                              ServiceStatus::Failed,
                                              ServiceStatus::InKilling],
        ServiceStatus::Success        => vec![ServiceStatus::Starting,
                                              ServiceStatus::Started,
                                              ServiceStatus::Running,
                                              ServiceStatus::InKilling],
        ServiceStatus::Failed         => vec![ServiceStatus::Starting,
                                              ServiceStatus::Started,
                                              ServiceStatus::Running,
                                              ServiceStatus::InKilling],
        ServiceStatus::Finished       => vec![ServiceStatus::Success,
                                             ServiceStatus::Initial],
    };
    let allowed = allowed_transitions
        .get(&next_status)
        .unwrap_or_else(|| panic!("New status: {} not found!", next_status));
    if allowed.contains(&service_handler.status) {
        match next_status {
            ServiceStatus::Started if allowed.contains(&service_handler.status) => {
                new_service_handler.status = ServiceStatus::Started;
                new_service_handler.restart_attempts = 0;
            }
            ServiceStatus::Running if allowed.contains(&service_handler.status) => {
                new_service_handler.status = ServiceStatus::Running;
            }
            ServiceStatus::InKilling if allowed.contains(&service_handler.status) => {
                debug!(
                    " service: {},  status: {}, new status: {}",
                    service_handler.name(),
                    service_handler.status,
                    next_status
                );
                new_service_handler.status = if service_handler.status == ServiceStatus::Initial {
                    ServiceStatus::Success
                } else {
                    ServiceStatus::InKilling
                };
            }
            new_status => {
                new_service_handler.status = new_status;
            }
        }
    } else {
        debug!(
            "Tried to make an illegal transition: (current) {} ⇾ {} (received) for service: {}",
            service_handler.status,
            next_status,
            service_handler.name()
        );
    }
    let new_status = new_service_handler.status.clone();
    (new_service_handler, new_status)
}
// TODO: test
/// Handles the service handler's status change
test
Handles the service handler's status change
test Handles the service handler ' s status change
fn handle_status_change(
    service_handler: &ServiceHandler,
    next_status: ServiceStatus,
) -> (ServiceHandler, ServiceStatus) {
    let mut new_service_handler = service_handler.clone();
    if next_status == service_handler.status {
        return (new_service_handler, next_status);
    }
    //TODO: refactor + cleanup.
    // A -> [B,C] means that transition to A is allowed only if service is in state B or C.
    let allowed_transitions = hashmap! {
        ServiceStatus::Initial        => vec![ServiceStatus::Success, ServiceStatus::Failed,
                                              ServiceStatus::Started],
        ServiceStatus::Starting       => vec![ServiceStatus::Initial],
        ServiceStatus::Started        => vec![ServiceStatus::Starting],
        ServiceStatus::InKilling      => vec![ServiceStatus::Initial,
                                              ServiceStatus::Running,
                                              ServiceStatus::Starting,
                                              ServiceStatus::Started],
        ServiceStatus::Running        => vec![ServiceStatus::Started],
        ServiceStatus::FinishedFailed => vec![ServiceStatus::Starting,
                                              ServiceStatus::Started,
                                              ServiceStatus::Failed,
                                              ServiceStatus::InKilling],
        ServiceStatus::Success        => vec![ServiceStatus::Starting,
                                              ServiceStatus::Started,
                                              ServiceStatus::Running,
                                              ServiceStatus::InKilling],
        ServiceStatus::Failed         => vec![ServiceStatus::Starting,
                                              ServiceStatus::Started,
                                              ServiceStatus::Running,
                                              ServiceStatus::InKilling],
        ServiceStatus::Finished       => vec![ServiceStatus::Success,
                                             ServiceStatus::Initial],
    };
    let allowed = allowed_transitions
        .get(&next_status)
        .unwrap_or_else(|| panic!("New status: {} not found!", next_status));
    if allowed.contains(&service_handler.status) {
        match next_status {
            ServiceStatus::Started if allowed.contains(&service_handler.status) => {
                new_service_handler.status = ServiceStatus::Started;
                new_service_handler.restart_attempts = 0;
            }
            ServiceStatus::Running if allowed.contains(&service_handler.status) => {
                new_service_handler.status = ServiceStatus::Running;
            }
            ServiceStatus::InKilling if allowed.contains(&service_handler.status) => {
                debug!(
                    " service: {},  status: {}, new status: {}",
                    service_handler.name(),
                    service_handler.status,
                    next_status
                );
                new_service_handler.status = if service_handler.status == ServiceStatus::Initial {
                    ServiceStatus::Success
                } else {
                    ServiceStatus::InKilling
                };
            }
            new_status => {
                new_service_handler.status = new_status;
            }
        }
    } else {
        debug!(
            "Tried to make an illegal transition: (current) {} ⇾ {} (received) for service: {}",
            service_handler.status,
            next_status,
            service_handler.name()
        );
    }
    let new_status = new_service_handler.status.clone();
    (new_service_handler, new_status)
}
fn handle_status_change ( service_handler : & ServiceHandler , next_status : ServiceStatus , ) -> ( ServiceHandler , ServiceStatus ) { let mut new_service_handler = service_handler . clone ( ) ; if next_status == service_handler . status { return ( new_service_handler , next_status ) ; } //TODO: refactor + cleanup. // A -> [B,C] means that transition to A is allowed only if service is in state B or C. let allowed_transitions = hashmap ! { ServiceStatus Initial vec [ ServiceStatus Success ServiceStatus Failed ServiceStatus Started ] ServiceStatus Starting vec [ ServiceStatus Initial ] ServiceStatus Started vec [ ServiceStatus Starting ] ServiceStatus InKilling vec [ ServiceStatus Initial ServiceStatus Running ServiceStatus Starting ServiceStatus Started ] ServiceStatus Running vec [ ServiceStatus Started ] ServiceStatus FinishedFailed vec [ ServiceStatus Starting ServiceStatus Started ServiceStatus Failed ServiceStatus InKilling ] ServiceStatus Success vec [ ServiceStatus Starting ServiceStatus Started ServiceStatus Running ServiceStatus InKilling ] ServiceStatus Failed vec [ ServiceStatus Starting ServiceStatus Started ServiceStatus Running ServiceStatus InKilling ] ServiceStatus Finished vec [ ServiceStatus Success ServiceStatus Initial ] } ; let allowed = allowed_transitions . get ( & next_status ) . unwrap_or_else ( | | panic ! ( " " next_status ) ) ; if allowed . contains ( & service_handler . status ) { match next_status { ServiceStatus :: Started if allowed . contains ( & service_handler . status ) => { new_service_handler . status = ServiceStatus :: Started ; new_service_handler . restart_attempts = 0 ; } ServiceStatus :: Running if allowed . contains ( & service_handler . status ) => { new_service_handler . status = ServiceStatus :: Running ; } ServiceStatus :: InKilling if allowed . contains ( & service_handler . status ) => { debug ! ( " " service_handler name ( ) service_handler status next_status ) ; new_service_handler . status = if service_handler . status == ServiceStatus :: Initial { ServiceStatus :: Success } else { ServiceStatus :: InKilling } ; } new_status => { new_service_handler . status = new_status ; } } } else { debug ! ( " service_handler status next_status service_handler name ( ) ) ; } let new_status = new_service_handler . status . clone ( ) ; ( new_service_handler , new_status ) }
TODO: test
Handles the service handler's status change
TODO : test Handles the service handler ' s status change
service_handler
&ServiceHandler
next_status
ServiceStatus
service_handler
&ServiceHandler
next_status
ServiceStatus