canic-host 0.82.26

Host-side build, install, deployment, and fleet-template library for Canic workspaces
Documentation
#[cfg(test)]
mod tests;

#[must_use]
pub fn find_field<'a>(value: &'a serde_json::Value, field: &str) -> Option<&'a serde_json::Value> {
    match value {
        serde_json::Value::Object(map) => map
            .get(field)
            .or_else(|| map.values().find_map(|value| find_field(value, field))),
        serde_json::Value::Array(values) => {
            values.iter().find_map(|value| find_field(value, field))
        }
        _ => None,
    }
}

#[must_use]
pub(crate) fn find_string_field(value: &serde_json::Value, field: &str) -> Option<String> {
    match value {
        serde_json::Value::Object(map) => map
            .get(field)
            .and_then(|value| value.as_str().map(ToString::to_string))
            .or_else(|| {
                map.values()
                    .find_map(|value| find_string_field(value, field))
            }),
        serde_json::Value::Array(values) => values
            .iter()
            .find_map(|value| find_string_field(value, field)),
        _ => None,
    }
}

#[must_use]
pub(crate) fn parse_cycle_balance_response(output: &str) -> Option<u128> {
    serde_json::from_str::<serde_json::Value>(output)
        .ok()
        .and_then(|value| find_field(&value, "Ok").and_then(parse_json_u128))
}

#[must_use]
pub fn parse_json_u64(value: &serde_json::Value) -> Option<u64> {
    value
        .as_u64()
        .or_else(|| value.as_str().and_then(parse_u64_digits))
}

#[must_use]
pub fn parse_json_u128(value: &serde_json::Value) -> Option<u128> {
    value
        .as_u64()
        .map(u128::from)
        .or_else(|| value.as_str().and_then(parse_u128_digits))
}

#[must_use]
pub fn parse_u64_digits(text: &str) -> Option<u64> {
    number_digits(text).parse().ok()
}

#[must_use]
pub fn parse_u128_digits(text: &str) -> Option<u128> {
    number_digits(text).parse().ok()
}

fn number_digits(text: &str) -> String {
    text.chars()
        .skip_while(|ch| !ch.is_ascii_digit())
        .take_while(|ch| ch.is_ascii_digit() || *ch == '_' || *ch == ',')
        .filter(char::is_ascii_digit)
        .collect()
}