Functional Weave
Code in TypeScript

net.cidr@1.0.0

impl/rust/is_cidr.rs

1,435 bytes · the Rust implementation · view raw

Imports name this capability’s declared dependencies, which fune builds next to it in your project; each one links to its page.

use super::funejson::Value;  ← the fune runtime: the JSON value the test vectors use; fune build keeps it only where a signature takes one
use super::net_ipv4_parse_ipv4::ipv4_value;
use super::net_ipv6_parse_ipv6::ipv6_groups;

/// True for a well-formed IPv4 (prefix 0-32) or IPv6 (prefix 0-128) block; never panics.
pub fn is_cidr(text: &str) -> bool {
    cidr_block(text).is_some()
}

// Exported for the other functions of this group; not part of its contract.

/// The block as (version, bits, prefix): bits is [address] for version 4 and
/// the eight groups for version 6. None when the text is not address/prefix
/// with a strict decimal prefix.
pub fn cidr_block(text: &str) -> Option<(i64, Vec<i64>, i64)> {
    let mut halves = text.split('/');
    let address = halves.next()?;
    let digits = halves.next()?;
    if halves.next().is_some() {
        return None;
    }
    let bytes = digits.as_bytes();
    if bytes.is_empty() || bytes.len() > 3 || !bytes.iter().all(|b| b.is_ascii_digit()) {
        return None;
    }
    if bytes.len() > 1 && bytes[0] == b'0' {
        return None;
    }
    let prefix = bytes.iter().fold(0i64, |acc, b| acc * 10 + (b - b'0') as i64);
    if let Some(v4) = ipv4_value(address) {
        return if prefix <= 32 { Some((4, vec![v4], prefix)) } else { None };
    }
    if let Some(v6) = ipv6_groups(address) {
        return if prefix <= 128 { Some((6, v6, prefix)) } else { None };
    }
    None
}

pub fn fune_vector(args: &[Value]) -> Value {
    Value::Bool(is_cidr(args[0].as_str()))
}