# 使用场景

完整可执行代码在 [独立消费模块](../examples/consumer/main.mbt)。运行 `moon -C examples/consumer run . --target wasm-gc`，对应测试同时检查以下结果。

## 1. 校验和归一化地址清单

输入设备登记值 `192.168.1.7`、`100.64.0.1`、`2001:0DB8::1`，通过 `ip_address` 解析，输出规范文本、`is_private` 和 `is_global`。结果分别为 `(true,false)`、`(false,false)`、`(true,false)`，IPv6 规范文本为 `2001:db8::1`。调用者可据此检查配置类型；这些属性不替代网络访问策略。

## 2. 给站点划分四个 VLAN 网段

将 `192.168.10.0/24` 通过 `subnets(new_prefix=26)` 划分成四个 `/26`，用 `hosts().next()` 取得首个可用主机作为网关候选：

| 网段 | 首个主机 | 掩码 |
| --- | --- | --- |
| 192.168.10.0/26 | 192.168.10.1 | 255.255.255.192 |
| 192.168.10.64/26 | 192.168.10.65 | 255.255.255.192 |
| 192.168.10.128/26 | 192.168.10.129 | 255.255.255.192 |
| 192.168.10.192/26 | 192.168.10.193 | 255.255.255.192 |

四个子网不重叠，合并后精确还原原站点范围。库不实际分配地址或修改设备。

## 3. 检查双栈接口配置

解析 `192.168.10.7/255.255.255.192` 和 `2001:db8:10::7/64`。`IpInterface` 保留两个主机地址，同时得到 `192.168.10.0/26` 和 `2001:db8:10::/64`；`network().contains(ip())` 均为真。

IPv6 `/64` 的地址数量为 `18446744073709551616`。`hosts().take(3)` 仅生成 `2001:db8:10::1`、`::2`、`::3`，无需分配整个地址空间。

## 4. 从已分配范围中排除保留地址

将 `192.0.2.0/24` 与 `2001:db8::/126` 放入 `IpSet`，减去 `192.0.2.64/26` 和 `2001:db8::2/127`，得到：

```text
192.0.2.0/26
192.0.2.128/25
2001:db8::/127
```

同一集合内允许两个地址族；数值网段归并函数 `collapse_addresses` 要求输入同族。与带顺序或动作的防火墙规则不同，这些操作只处理成员关系。

## 文件清单变更

```bash
node bin/ipset.mjs diff examples/policies/old.txt examples/policies/new.txt --json
```

返回退出码 `1` 并输出：

```json
{"added":["10.0.1.10/32","2001:db8:1::/126"],"removed":["10.0.0.128/25","2001:db8::/127"]}
```
