use std::path::MAIN_SEPARATOR;
use idpath::{DEPTH1, DEPTH2, DEPTH3, decode, encode};
#[test]
fn test_encode_decode() {
for id in 0..100000 {
let path = encode("/test", id);
let decoded = decode(&path).unwrap();
assert_eq!(id, decoded, "id={id} path={path}");
}
for id in [u64::MAX, u64::MAX - 1, u64::MAX / 2, 1 << 32, 1 << 48] {
let path = encode("/test", id);
let decoded = decode(&path).unwrap();
assert_eq!(id, decoded, "id={id} path={path}");
}
}
#[test]
fn test_encode_lengths() {
let cases: &[(u64, usize, &str)] = &[
(0, 0, "len=0"),
(1, 1, "len=1"),
(31, 1, "len=1"),
(32, 2, "len=2"),
(1023, 2, "len=2"),
(1024, 3, "len=3"),
(32767, 3, "len=3"),
(32768, 4, "len=4"),
(1048575, 4, "len=4"),
(1048576, 5, "len=5"),
(33554431, 5, "len=5"),
(33554432, 6, "len>=6"),
(1073741823, 6, "len>=6"),
(1073741824, 7, "len>=7"),
(u64::MAX, 13, "len>=7"),
];
for &(id, expected_len, desc) in cases {
let path = encode("/test", id);
let parts: Vec<&str> = path.as_str().split(MAIN_SEPARATOR).collect();
println!("{desc}: id={id} -> {path}");
let last = parts.last().unwrap();
let last_char = last.chars().last().unwrap();
match expected_len {
0..=2 => assert_eq!(last_char, DEPTH1 as char, "len 0-2 should end with DEPTH1"),
3 => assert_eq!(last_char, DEPTH2 as char, "len 3 should end with DEPTH2"),
4 => assert_eq!(last_char, DEPTH3 as char, "len 4 should end with DEPTH3"),
_ => assert!(
last_char != DEPTH1 as char && last_char != DEPTH2 as char && last_char != DEPTH3 as char,
"len>=5 should have no suffix"
),
}
let decoded = decode(&path).unwrap();
assert_eq!(id, decoded);
}
}
#[test]
fn test_path_format() {
let path = encode("/test", 0x12345);
let parts: Vec<&str> = path.as_str().split(MAIN_SEPARATOR).collect();
assert_eq!(parts[0], "");
assert_eq!(parts[1], "test");
assert_eq!(parts[2], "t5");
assert!(parts[3].ends_with(DEPTH3 as char));
}