#![no_std]
#![forbid(unsafe_code)]
extern crate alloc;
use alloc::string::String;
use alloc::vec::Vec;
pub mod ini;
pub mod encoding;
pub mod xml;
pub mod num;
pub mod settings;
pub mod rng;
pub mod metrics;
pub mod cmdtree;
pub mod hashring;
pub mod lru;
pub mod pattern;
pub use ini::Ini;
pub use settings::{Key, Schema, Settings};
pub use num::{f64_format, f64_parse, parse_i64};
pub use rng::{Pcg32, SplitMix64};
pub fn utf8_decode(s: &[u8], i: usize) -> (u32, usize) {
const BAD: u32 = 0xFFFD;
let Some(&b0) = s.get(i) else { return (BAD, i.saturating_add(1)) };
let b0 = b0 as u32;
if b0 < 0x80 {
return (b0, i + 1);
}
let (n, init, min) = match b0 {
0xC2..=0xDF => (1, b0 & 0x1F, 0x80),
0xE0..=0xEF => (2, b0 & 0x0F, 0x800),
0xF0..=0xF4 => (3, b0 & 7, 0x10000),
_ => return (BAD, i + 1), };
let mut cp = init;
let mut j = i + 1;
for _ in 0..n {
if j >= s.len() || s[j] & 0xC0 != 0x80 {
return (BAD, i + 1);
}
cp = cp << 6 | (s[j] & 0x3F) as u32;
j += 1;
}
if cp < min || cp > 0x10FFFF || cp & 0xFFFF_F800 == 0xD800 {
return (BAD, i + 1); }
(cp, j)
}
pub struct Args(pub Vec<String>);
impl Args {
pub fn value(&self, name: &str) -> Option<&str> {
let i = self.0.iter().skip(1).position(|a| a == name)? + 1;
self.0.get(i + 1).map(|s| s.as_str())
}
pub fn flag(&self, name: &str) -> bool {
self.0.iter().skip(1).any(|a| a == name)
}
pub fn int(&self, name: &str, def: i32) -> i32 {
self.value(name).map_or(def, |v| v.parse().unwrap_or(def))
}
}