#![doc = include_str!("../README.md")]
#[doc = include_str!("../doc/export_info_v4.md")]
pub mod ipv4_source{}
#[doc = include_str!("../doc/export_info_v6.md")]
pub mod ipv6_source{}
use std::num::NonZeroU16;
macro_rules! align {
{
$($t:ident ($n:expr)),* $(,)?
} => {
$(
#[doc=concat!(stringify!($n), " bytes.")]
#[repr(align($n))]
struct $t<T>(T);
)*
}
}
align!{
Align2(2),
Align4(4),
Align16(16),
}
macro_rules! data {
{
$({$w:ident $v:ident from $path:expr})*
} => {
$(
static $v : $w<[u8; include_bytes!($path).len()]>
= $w(*include_bytes!($path));
)*
}
}
data! {
{ Align4 GEOIP_DATA_V4S from "../data/geoip_data_v4s" }
{ Align2 GEOIP_DATA_V4C from "../data/geoip_data_v4c" }
{ Align16 GEOIP_DATA_V6S from "../data/geoip_data_v6s" }
{ Align2 GEOIP_DATA_V6C from "../data/geoip_data_v6c" }
}
unsafe fn export<T>(a: &'static [u8]) -> &'static [T] {
let (pre, data, post) = unsafe { a.align_to::<T>() };
assert!(pre.is_empty(), "Data was not aligned!");
assert!(post.is_empty(), "Data had an invalid length!");
data
}
pub fn ipv4s() -> &'static [u32] {
unsafe { export(&GEOIP_DATA_V4S.0) }
}
pub fn ipv4c() -> &'static [Option<NonZeroU16>] {
unsafe { export(&GEOIP_DATA_V4C.0) }
}
pub fn ipv6s() -> &'static [u128] {
unsafe { export(&GEOIP_DATA_V6S.0) }
}
pub fn ipv6c() -> &'static [Option<NonZeroU16>] {
unsafe { export(&GEOIP_DATA_V6C.0) }
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn v4_looks_ok() {
let (v4s, v4c) = (ipv4s(), ipv4c());
assert!(v4s.is_sorted());
assert_eq!(v4s.len(), v4c.len());
}
#[test]
fn v6_looks_ok() {
let (v6s, v6c) = (ipv6s(), ipv6c());
assert!(v6s.is_sorted());
assert_eq!(v6s.len(), v6c.len());
}
}