canic-host 0.70.7

Host-side build, install, deployment, and fleet-template library for Canic workspaces
Documentation
use super::super::*;
use std::collections::BTreeSet;

pub(super) const AUTHORITY_UNSAFE_BLOCKED_CODE: &str = "authority_unsafe_blocked";
pub(super) fn difference(left: &[String], right: &[String]) -> Vec<String> {
    left.iter()
        .filter(|value| !right.iter().any(|candidate| candidate == *value))
        .cloned()
        .collect()
}

pub(super) fn controller_delta(missing: &[String], extra: &[String]) -> AuthorityControllerDeltaV1 {
    AuthorityControllerDeltaV1 {
        add_controllers: missing.to_vec(),
        remove_controllers: extra.to_vec(),
    }
}

pub(super) fn sorted_unique(values: Vec<String>) -> Vec<String> {
    values
        .into_iter()
        .collect::<BTreeSet<_>>()
        .into_iter()
        .collect()
}

pub(super) fn controller_delta_reason(missing: &[String], extra: &[String]) -> String {
    match (missing.is_empty(), extra.is_empty()) {
        (false, true) => format!("missing desired controllers: {}", missing.join(",")),
        (true, false) => format!("extra observed controllers: {}", extra.join(",")),
        (false, false) => format!(
            "controller set differs: missing {}; extra {}",
            missing.join(","),
            extra.join(",")
        ),
        (true, true) => "observed controller set already matches desired authority".to_string(),
    }
}

pub(super) fn action_subject(action: &CanisterAuthorityActionV1) -> Option<String> {
    action
        .canister_id
        .clone()
        .or_else(|| action.role.as_ref().map(|role| format!("role:{role}")))
}