///|
pub struct Ipv6NetworkSet {
networks : Array[Ipv6Network]
} derive(Debug)
///|
pub fn Ipv6NetworkSet::new() -> Ipv6NetworkSet {
{ networks: Array::new() }
}
///|
pub fn Ipv6NetworkSet::from_array(
networks : Array[Ipv6Network],
) -> Ipv6NetworkSet {
let mut set = Ipv6NetworkSet::new()
for network in networks {
set = set.insert(network)
}
set
}
///|
pub fn Ipv6NetworkSet::parse_all(
items : Array[String],
) -> Result[Ipv6NetworkSet, CidrError] {
let mut set = Ipv6NetworkSet::new()
for item in items {
match Ipv6Network::parse(item) {
Err(error) => return Err(error)
Ok(network) => set = set.insert(network)
}
}
Ok(set)
}
///|
pub fn Ipv6NetworkSet::insert(
self : Ipv6NetworkSet,
network : Ipv6Network,
) -> Ipv6NetworkSet {
if self.is_covered(network) {
self
} else {
let networks = Array::new()
for existing in self.networks {
if !network.contains_network(existing) {
networks.push(existing)
}
}
networks.push(network)
sort_ipv6_networks(networks)
{ networks, }
}
}
///|
pub fn Ipv6Network::contains_network(
self : Ipv6Network,
other : Ipv6Network,
) -> Bool {
self.prefix() <= other.prefix() && self.contains(other.address())
}
///|
pub fn Ipv6NetworkSet::len(self : Ipv6NetworkSet) -> Int {
self.networks.length()
}
///|
pub fn Ipv6NetworkSet::contains(
self : Ipv6NetworkSet,
address : Ipv6Address,
) -> Bool {
self.match_network(address) is Some(_)
}
///|
pub fn Ipv6NetworkSet::match_network(
self : Ipv6NetworkSet,
address : Ipv6Address,
) -> Ipv6Network? {
let mut best : Ipv6Network? = None
for network in self.networks {
if network.contains(address) {
match best {
None => best = Some(network)
Some(current) =>
if network.prefix() > current.prefix() {
best = Some(network)
}
}
}
}
best
}
///|
pub fn Ipv6NetworkSet::is_covered(
self : Ipv6NetworkSet,
network : Ipv6Network,
) -> Bool {
for existing in self.networks {
if existing.contains_network(network) {
return true
}
}
false
}
///|
pub fn Ipv6NetworkSet::to_array(self : Ipv6NetworkSet) -> Array[Ipv6Network] {
self.networks.copy()
}
///|
pub fn Ipv6NetworkSet::to_string(self : Ipv6NetworkSet) -> String {
let mut text = ""
let mut index = 0
for network in self.networks {
if index > 0 {
text = text + ", "
}
text = text + network.to_string()
index = index + 1
}
text
}
///|
fn sort_ipv6_networks(networks : Array[Ipv6Network]) -> Unit {
let mut i = 0
while i < networks.length() {
let mut j = i + 1
while j < networks.length() {
if ipv6_should_swap(networks[i], networks[j]) {
let tmp = networks[i]
networks[i] = networks[j]
networks[j] = tmp
}
j = j + 1
}
i = i + 1
}
}
///|
fn ipv6_should_swap(left : Ipv6Network, right : Ipv6Network) -> Bool {
let la = left.address()
let ra = right.address()
if la > ra {
true
} else if la == ra {
left.prefix() > right.prefix()
} else {
false
}
}