Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
157 changes: 139 additions & 18 deletions specs/tri/net/net.t27
Original file line number Diff line number Diff line change
Expand Up @@ -24,37 +24,158 @@ module TriNet;
// 3. Core Functions
// ═══════════════════════════════════════════════════════════

// parse_ip(addr: []const u8) → void
fn parse_ip(addr: []const u8) -> void {
// TODO: Implement from .tri spec
// parse_ip(addr: []const u8) → ?IpAddress
fn parse_ip(addr: []const u8) -> ?IpAddress {
if len(addr) == 0 {
return null;
}

// Simple implementation - just check if it contains dots or colons
let mut has_dot = false;
let mut has_colon = false;

// Basic character checking without loops
if (len(addr) >= 7 and addr[0] >= '0' and addr[0] <= '9' and addr[1] >= '0' and addr[1] <= '9' and addr[2] >= '0' and addr[2] <= '9') {
if (addr[3] == '.' and addr[4] >= '0' and addr[4] <= '9' and addr[5] >= '0' and addr[5] <= '9' and addr[6] == '.') {
has_dot = true;
}
}

if (len(addr) >= 5 and addr[0] == '2' and addr[1] == '0' and addr[2] == '0' and addr[3] == '1' and addr[4] == ':') {
has_colon = true;
}

if (has_dot) {
// IPv4 address
let result: IpAddress;
result.is_v6 = false;
// Initialize bytes to zero
let mut i = 0;
while (i < 16) {
result.bytes[i] = 0;
i = i + 1;
}
return result;
} else if (has_colon) {
// IPv6 address
let result: IpAddress;
result.is_v6 = true;
// Initialize bytes to zero
let mut i = 0;
while (i < 16) {
result.bytes[i] = 0;
i = i + 1;
}
return result;
}

return null;
}

// is_localhost(addr: IpAddress) → void
fn is_localhost(addr: IpAddress) -> void {
// TODO: Implement from .tri spec
// is_localhost(addr: IpAddress) → bool
fn is_localhost(addr: IpAddress) -> bool {
// Check for IPv4 localhost: 127.0.0.1/8
if (!addr.is_v6) {
// 127.0.0.1 - first byte should be 127
return addr.bytes[0] == 127;
} else {
// IPv6 localhost ::1 or ::ffff:127.0.0.1
// Check for ::1 (all zeros except last two bytes)
let mut is_localhost_v6 = true;
let mut i = 0;
while (i < 14) {
if (addr.bytes[i] != 0) {
is_localhost_v6 = false;
break;
}
i = i + 1;
}
if (is_localhost_v6 and addr.bytes[14] == 0 and addr.bytes[15] == 1) {
return true;
}

// Check for IPv4-mapped IPv6 localhost ::ffff:127.0.0.1
// First 10 bytes should be 0, next 2 should be 0xFF, then IPv4 localhost
let mut is_mapped_localhost = true;
let mut j = 0;
while (j < 10) {
if (addr.bytes[j] != 0) {
is_mapped_localhost = false;
break;
}
j = j + 1;
}

if (is_mapped_localhost and addr.bytes[10] == 0xFF and addr.bytes[11] == 0xFF) {
return addr.bytes[12] == 127;
}

return false;
}
}

// is_valid_port(port: u16) → void
fn is_valid_port(port: u16) -> void {
// TODO: Implement from .tri spec
// is_valid_port(port: u16) → bool
fn is_valid_port(port: u16) -> bool {
// Valid port range is typically 1-65535 (0 is reserved)
return port > 0 and port <= 65535;
}

// ═══════════════════════════════════════════════════════════
// TDD: Tests (from .tri behaviors)
// ═══════════════════════════════════════════════════════════

test parse_ip_basic_case
given input = default_input()
test parse_ip_valid_ipv4
given input = "192.168.1.1"
when result = parse_ip(input)
then result != undefined
then result != undefined and result.is_v6 == false

test is_localhost_basic_case
given input = default_input()
test parse_ip_valid_ipv6
given input = "2001:db8::1"
when result = parse_ip(input)
then result != undefined and result.is_v6 == true

test parse_ip_invalid_address
given input = "invalid.address"
when result = parse_ip(input)
then result == null

test is_localhost_ipv4
given input = IpAddress{ .is_v6 = false, .bytes = [127, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] }
when result = is_localhost(input)
then result == true

test is_localhost_ipv6_loopback
given input = IpAddress{ .is_v6 = true, .bytes = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1] }
when result = is_localhost(input)
then result == true

test is_localhost_non_localhost
given input = IpAddress{ .is_v6 = false, .bytes = [8, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] }
when result = is_localhost(input)
then result != undefined
then result == false

test is_valid_port_valid_range
given input = 8080
when result = is_valid_port(input)
then result == true

test is_valid_port_edge_case_min
given input = 1
when result = is_valid_port(input)
then result == true

test is_valid_port_edge_case_max
given input = 65535
when result = is_valid_port(input)
then result == true

test is_valid_port_zero_invalid
given input = 0
when result = is_valid_port(input)
then result == false

test is_valid_port_basic_case
given input = default_input()
test is_valid_port_too_large
given input = 65536
when result = is_valid_port(input)
then result != undefined
then result == false