use std::collections::{HashMap, HashSet};
use std::fmt;
use std::ops::{Deref, DerefMut, Index, Range, RangeFrom, RangeFull, RangeTo};
#[derive(Debug, Clone, Copy)]
pub struct Span<T> {
data: *const T,
size: usize,
}
unsafe impl<T: Send> Send for Span<T> {}
unsafe impl<T: Sync> Sync for Span<T> {}
impl<T> Span<T> {
pub fn from_ptr_len(ptr: *const T, size: usize) -> Self {
Self { data: ptr, size }
}
pub fn from_slice(slice: &[T]) -> Self {
Self {
data: slice.as_ptr(),
size: slice.len(),
}
}
pub fn from_first_last(first: *const T, last: *const T) -> Self {
let size = unsafe { last.offset_from(first) } as usize;
Self { data: first, size }
}
pub fn size(&self) -> usize {
self.size
}
pub fn size_bytes(&self) -> usize {
self.size * std::mem::size_of::<T>()
}
pub fn empty(&self) -> bool {
self.size == 0
}
pub fn front(&self) -> Option<&T> {
if self.size > 0 {
unsafe { Some(&*self.data) }
} else {
None
}
}
pub fn back(&self) -> Option<&T> {
if self.size > 0 {
unsafe { Some(&*self.data.add(self.size - 1)) }
} else {
None
}
}
pub fn data_ptr(&self) -> *const T {
self.data
}
pub fn first(&self, count: usize) -> Self {
let n = count.min(self.size);
Self {
data: self.data,
size: n,
}
}
pub fn last(&self, count: usize) -> Self {
let n = count.min(self.size);
Self {
data: unsafe { self.data.add(self.size - n) },
size: n,
}
}
pub fn subspan(&self, offset: usize, count: usize) -> Self {
let off = offset.min(self.size);
let n = count.min(self.size - off);
Self {
data: unsafe { self.data.add(off) },
size: n,
}
}
pub fn iter(&self) -> SpanIter<T> {
SpanIter {
ptr: self.data,
remaining: self.size,
}
}
pub fn contains(&self, value: &T) -> bool
where
T: PartialEq,
{
self.iter().any(|x| x == value)
}
}
impl<T> Default for Span<T> {
fn default() -> Self {
Self {
data: std::ptr::null(),
size: 0,
}
}
}
impl<T> PartialEq for Span<T>
where
T: PartialEq,
{
fn eq(&self, other: &Self) -> bool {
if self.size != other.size {
return false;
}
for i in 0..self.size {
unsafe {
if *self.data.add(i) != *other.data.add(i) {
return false;
}
}
}
true
}
}
impl<T: fmt::Display> fmt::Display for Span<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "[")?;
for i in 0..self.size {
if i > 0 {
write!(f, ", ")?;
}
unsafe {
write!(f, "{}", *self.data.add(i))?;
}
}
write!(f, "]")
}
}
pub struct SpanIter<T> {
ptr: *const T,
remaining: usize,
}
impl<T> Iterator for SpanIter<T> {
type Item = T;
fn next(&mut self) -> Option<T>
where
T: Copy,
{
if self.remaining == 0 {
return None;
}
let val = unsafe { std::ptr::read(self.ptr) };
self.ptr = unsafe { self.ptr.add(1) };
self.remaining -= 1;
Some(val)
}
fn size_hint(&self) -> (usize, Option<usize>) {
(self.remaining, Some(self.remaining))
}
}
impl<T: Copy> ExactSizeIterator for SpanIter<T> {}
#[derive(Debug, Clone, Copy)]
pub struct StringView<'a> {
data: &'a [u8],
}
impl<'a> StringView<'a> {
pub fn new(s: &'a str) -> Self {
Self { data: s.as_bytes() }
}
pub fn from_bytes(data: &'a [u8]) -> Self {
Self { data }
}
pub fn size(&self) -> usize {
self.data.len()
}
pub fn length(&self) -> usize {
self.data.len()
}
pub fn empty(&self) -> bool {
self.data.is_empty()
}
pub fn front(&self) -> Option<u8> {
self.data.first().copied()
}
pub fn back(&self) -> Option<u8> {
self.data.last().copied()
}
pub fn data(&self) -> &[u8] {
self.data
}
pub fn as_str(&self) -> &str {
std::str::from_utf8(self.data).unwrap_or("")
}
pub fn substr(&self, pos: usize, count: usize) -> Self {
let start = pos.min(self.data.len());
let end = (pos + count).min(self.data.len());
Self {
data: &self.data[start..end],
}
}
pub fn remove_prefix(&mut self, n: usize) {
let n = n.min(self.data.len());
self.data = &self.data[n..];
}
pub fn remove_suffix(&mut self, n: usize) {
let n = n.min(self.data.len());
let end = self.data.len() - n;
self.data = &self.data[..end];
}
pub fn find(&self, needle: &str, pos: usize) -> Option<usize> {
let start = pos.min(self.data.len());
self.data[start..]
.windows(needle.len())
.position(|w| w == needle.as_bytes())
.map(|p| start + p)
}
pub fn rfind(&self, needle: &str) -> Option<usize> {
self.data
.windows(needle.len())
.rposition(|w| w == needle.as_bytes())
}
pub fn find_first_of(&self, chars: &str) -> Option<usize> {
let set: HashSet<u8> = chars.as_bytes().iter().copied().collect();
self.data.iter().position(|c| set.contains(c))
}
pub fn find_first_not_of(&self, chars: &str) -> Option<usize> {
let set: HashSet<u8> = chars.as_bytes().iter().copied().collect();
self.data.iter().position(|c| !set.contains(c))
}
pub fn compare(&self, other: &StringView) -> std::cmp::Ordering {
self.data.cmp(other.data)
}
pub fn starts_with(&self, prefix: &str) -> bool {
self.data.starts_with(prefix.as_bytes())
}
pub fn ends_with(&self, suffix: &str) -> bool {
self.data.ends_with(suffix.as_bytes())
}
pub fn contains(&self, substring: &str) -> bool {
self.find(substring, 0).is_some()
}
}
impl<'a> PartialEq for StringView<'a> {
fn eq(&self, other: &Self) -> bool {
self.data == other.data
}
}
impl<'a> Eq for StringView<'a> {}
impl<'a> PartialOrd for StringView<'a> {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
Some(self.data.cmp(other.data))
}
}
impl<'a> Ord for StringView<'a> {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.data.cmp(other.data)
}
}
impl<'a> fmt::Display for StringView<'a> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.as_str())
}
}
impl<'a> From<&'a str> for StringView<'a> {
fn from(s: &'a str) -> Self {
Self::new(s)
}
}
#[derive(Debug, Clone)]
pub struct Variant<T1, T2, T3> {
index: usize,
value: VariantValue<T1, T2, T3>,
}
#[derive(Debug, Clone)]
enum VariantValue<T1, T2, T3> {
First(T1),
Second(T2),
Third(T3),
}
impl<T1, T2, T3> Variant<T1, T2, T3> {
pub fn first(val: T1) -> Self {
Self {
index: 0,
value: VariantValue::First(val),
}
}
pub fn second(val: T2) -> Self {
Self {
index: 1,
value: VariantValue::Second(val),
}
}
pub fn third(val: T3) -> Self {
Self {
index: 2,
value: VariantValue::Third(val),
}
}
pub fn index(&self) -> usize {
self.index
}
pub fn holds_first(&self) -> bool {
self.index == 0
}
pub fn holds_second(&self) -> bool {
self.index == 1
}
pub fn holds_third(&self) -> bool {
self.index == 2
}
pub fn get_first(&self) -> Option<&T1> {
match &self.value {
VariantValue::First(v) => Some(v),
_ => None,
}
}
pub fn get_second(&self) -> Option<&T2> {
match &self.value {
VariantValue::Second(v) => Some(v),
_ => None,
}
}
pub fn get_third(&self) -> Option<&T3> {
match &self.value {
VariantValue::Third(v) => Some(v),
_ => None,
}
}
}
pub fn visit_variant<T1, T2, T3, R>(
variant: &Variant<T1, T2, T3>,
f1: impl FnOnce(&T1) -> R,
f2: impl FnOnce(&T2) -> R,
f3: impl FnOnce(&T3) -> R,
) -> R {
match &variant.value {
VariantValue::First(v) => f1(v),
VariantValue::Second(v) => f2(v),
VariantValue::Third(v) => f3(v),
}
}
#[derive(Debug)]
pub struct Any {
type_name: String,
has_value: bool,
serialized: String,
}
impl Any {
pub fn new() -> Self {
Self {
type_name: String::new(),
has_value: false,
serialized: String::new(),
}
}
pub fn emplace<T: fmt::Display>(&mut self, value: &T) {
self.type_name = std::any::type_name::<T>().to_string();
self.has_value = true;
self.serialized = format!("{}", value);
}
pub fn has_value(&self) -> bool {
self.has_value
}
pub fn type_name(&self) -> &str {
&self.type_name
}
pub fn any_cast<T: 'static + fmt::Display>(&self) -> Option<String> {
if self.type_name == std::any::type_name::<T>() && self.has_value {
Some(self.serialized.clone())
} else {
None
}
}
pub fn reset(&mut self) {
self.has_value = false;
self.type_name.clear();
self.serialized.clear();
}
}
impl Default for Any {
fn default() -> Self {
Self::new()
}
}
impl Clone for Any {
fn clone(&self) -> Self {
Self {
type_name: self.type_name.clone(),
has_value: self.has_value,
serialized: self.serialized.clone(),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct Optional<T> {
value: Option<T>,
}
impl<T> Optional<T> {
pub fn none() -> Self {
Self { value: None }
}
pub fn some(val: T) -> Self {
Self { value: Some(val) }
}
pub fn has_value(&self) -> bool {
self.value.is_some()
}
pub fn value(&self) -> &T {
self.value.as_ref().expect("optional has no value")
}
pub fn value_or(&self, default: T) -> T
where
T: Clone,
{
self.value.clone().unwrap_or(default)
}
pub fn value_or_else<F: FnOnce() -> T>(&self, f: F) -> T
where
T: Clone,
{
self.value.clone().unwrap_or_else(f)
}
pub fn emplace(&mut self, val: T) {
self.value = Some(val);
}
pub fn reset(&mut self) {
self.value = None;
}
pub fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Optional<U> {
Optional {
value: self.value.map(f),
}
}
pub fn and_then<U, F: FnOnce(T) -> Optional<U>>(self, f: F) -> Optional<U> {
match self.value {
Some(v) => f(v),
None => Optional::none(),
}
}
pub fn or_else<F: FnOnce() -> Optional<T>>(self, f: F) -> Optional<T> {
if self.value.is_some() {
self
} else {
f()
}
}
pub fn transform<U, F: FnOnce(&T) -> U>(&self, f: F) -> Optional<U> {
Optional {
value: self.value.as_ref().map(f),
}
}
pub fn into_option(self) -> Option<T> {
self.value
}
}
impl<T> Default for Optional<T> {
fn default() -> Self {
Self::none()
}
}
impl<T: fmt::Display> fmt::Display for Optional<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match &self.value {
Some(v) => write!(f, "Some({})", v),
None => write!(f, "None"),
}
}
}
impl<T> From<Option<T>> for Optional<T> {
fn from(opt: Option<T>) -> Self {
Self { value: opt }
}
}
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Tuple2<T1, T2> {
pub first: T1,
pub second: T2,
}
impl<T1, T2> Tuple2<T1, T2> {
pub fn new(first: T1, second: T2) -> Self {
Self { first, second }
}
}
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Tuple3<T1, T2, T3> {
pub first: T1,
pub second: T2,
pub third: T3,
}
impl<T1, T2, T3> Tuple3<T1, T2, T3> {
pub fn new(first: T1, second: T2, third: T3) -> Self {
Self {
first,
second,
third,
}
}
}
pub fn make_tuple<T1, T2>(a: T1, b: T2) -> Tuple2<T1, T2> {
Tuple2::new(a, b)
}
pub fn make_tuple3<T1, T2, T3>(a: T1, b: T2, c: T3) -> Tuple3<T1, T2, T3> {
Tuple3::new(a, b, c)
}
pub fn tie<'a, 'b, T1, T2>(a: &'a mut T1, b: &'b mut T2) -> (&'a mut T1, &'b mut T2) {
(a, b)
}
pub fn forward_as_tuple<T1, T2>(a: T1, b: T2) -> (T1, T2) {
(a, b)
}
pub fn tuple_cat<T1, T2, T3>(t1: (T1,), t2: (T2, T3)) -> (T1, T2, T3) {
(t1.0, t2.0, t2.1)
}
pub fn tuple_cat3<T1, T2, T3, T4, T5>(a: (T1, T2), b: (T3,), c: (T4, T5)) -> (T1, T2, T3, T4, T5) {
(a.0, a.1, b.0, c.0, c.1)
}
pub fn apply<F, T1, T2, R>(f: F, args: (T1, T2)) -> R
where
F: FnOnce(T1, T2) -> R,
{
f(args.0, args.1)
}
pub fn apply3<F, T1, T2, T3, R>(f: F, args: (T1, T2, T3)) -> R
where
F: FnOnce(T1, T2, T3) -> R,
{
f(args.0, args.1, args.2)
}
pub fn make_from_tuple<T, F, Args>(constructor: F, args: (Args,)) -> T
where
F: FnOnce(Args) -> T,
{
constructor(args.0)
}
pub struct StdFunction<R> {
target_name: String,
target_size: usize,
uses_small_buffer: bool,
result_type: String,
arg_types: Vec<String>,
_phantom: std::marker::PhantomData<R>,
}
impl<R> StdFunction<R> {
pub fn new(target_name: &str, arg_types: Vec<String>, target_size: usize) -> Self {
Self {
target_name: target_name.to_string(),
target_size,
uses_small_buffer: target_size <= 32,
result_type: std::any::type_name::<R>().to_string(),
arg_types,
_phantom: std::marker::PhantomData,
}
}
pub fn has_target(&self) -> bool {
!self.target_name.is_empty()
}
pub fn target_name(&self) -> &str {
&self.target_name
}
pub fn is_small(&self) -> bool {
self.uses_small_buffer
}
pub fn target_size(&self) -> usize {
self.target_size
}
pub fn arg_types(&self) -> &[String] {
&self.arg_types
}
}
impl<R> fmt::Debug for StdFunction<R> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("StdFunction")
.field("target", &self.target_name)
.field("result_type", &self.result_type)
.finish()
}
}
impl<R> Clone for StdFunction<R> {
fn clone(&self) -> Self {
Self {
target_name: self.target_name.clone(),
target_size: self.target_size,
uses_small_buffer: self.uses_small_buffer,
result_type: self.result_type.clone(),
arg_types: self.arg_types.clone(),
_phantom: std::marker::PhantomData,
}
}
}
impl<R> Default for StdFunction<R> {
fn default() -> Self {
Self::new("", Vec::new(), 0)
}
}
#[derive(Debug)]
pub struct ReferenceWrapper<T> {
ptr: *const T,
}
impl<T> ReferenceWrapper<T> {
pub fn new(val: &T) -> Self {
Self {
ptr: val as *const T,
}
}
pub fn get(&self) -> &T {
unsafe { &*self.ptr }
}
pub fn as_ref(&self) -> &T {
self.get()
}
}
impl<T> Clone for ReferenceWrapper<T> {
fn clone(&self) -> Self {
Self { ptr: self.ptr }
}
}
impl<T> Copy for ReferenceWrapper<T> {}
pub fn ref_wrap<T>(val: &T) -> ReferenceWrapper<T> {
ReferenceWrapper::new(val)
}
pub fn cref_wrap<T>(val: &T) -> ReferenceWrapper<T> {
ReferenceWrapper::new(val)
}
pub fn invoke<F, A, R>(f: F, arg: A) -> R
where
F: FnOnce(A) -> R,
{
f(arg)
}
pub fn invoke2<F, A1, A2, R>(f: F, a1: A1, a2: A2) -> R
where
F: FnOnce(A1, A2) -> R,
{
f(a1, a2)
}
pub struct MemFn<F> {
method_name: String,
_phantom: std::marker::PhantomData<F>,
}
impl<F> MemFn<F> {
pub fn new(method_name: &str) -> Self {
Self {
method_name: method_name.to_string(),
_phantom: std::marker::PhantomData,
}
}
pub fn method_name(&self) -> &str {
&self.method_name
}
}
impl<F> fmt::Debug for MemFn<F> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "MemFn({})", self.method_name)
}
}
pub fn bind_front<F, A>(f: F, arg: A) -> BoundFn<F, A> {
BoundFn {
func: f,
bound_arg: arg,
}
}
pub struct BoundFn<F, A> {
func: F,
bound_arg: A,
}
impl<F, A> BoundFn<F, A> {
pub fn bound(&self) -> &A {
&self.bound_arg
}
}
impl<F: Clone, A: Clone> Clone for BoundFn<F, A> {
fn clone(&self) -> Self {
Self {
func: self.func.clone(),
bound_arg: self.bound_arg.clone(),
}
}
}
pub fn not_fn<F, T>(f: F) -> impl Fn(T) -> bool
where
F: Fn(T) -> bool,
{
move |x: T| !f(x)
}
#[derive(Debug, Clone)]
pub struct Regex {
pattern: String,
flags: RegexFlags,
is_valid: bool,
}
#[derive(Debug, Clone, Copy, Default)]
pub struct RegexFlags {
pub icase: bool,
pub nosubs: bool,
pub optimize: bool,
pub collate: bool,
pub multiline: bool,
}
impl Regex {
pub fn new(pattern: &str) -> Self {
Self {
pattern: pattern.to_string(),
flags: RegexFlags::default(),
is_valid: true,
}
}
pub fn with_flags(pattern: &str, flags: RegexFlags) -> Self {
Self {
pattern: pattern.to_string(),
flags,
is_valid: true,
}
}
pub fn pattern(&self) -> &str {
&self.pattern
}
pub fn is_valid(&self) -> bool {
self.is_valid
}
}
#[derive(Debug, Clone)]
pub struct RegexMatchResult {
pub matched: bool,
pub position: usize,
pub length: usize,
pub groups: Vec<Option<String>>,
}
impl RegexMatchResult {
pub fn no_match() -> Self {
Self {
matched: false,
position: 0,
length: 0,
groups: Vec::new(),
}
}
pub fn matched_at(pos: usize, len: usize) -> Self {
Self {
matched: true,
position: pos,
length: len,
groups: Vec::new(),
}
}
}
pub fn regex_match(pattern: &str, input: &str) -> bool {
input.contains(pattern)
}
pub fn regex_search(pattern: &str, input: &str) -> RegexMatchResult {
if let Some(pos) = input.find(pattern) {
RegexMatchResult::matched_at(pos, pattern.len())
} else {
RegexMatchResult::no_match()
}
}
pub fn regex_replace(pattern: &str, input: &str, replacement: &str) -> String {
if pattern.is_empty() {
return input.to_string();
}
input.replace(pattern, replacement)
}
pub struct RegexIterator<'a> {
pattern: &'a str,
input: &'a str,
position: usize,
}
impl<'a> RegexIterator<'a> {
pub fn new(pattern: &'a str, input: &'a str) -> Self {
Self {
pattern,
input,
position: 0,
}
}
}
impl<'a> Iterator for RegexIterator<'a> {
type Item = RegexMatchResult;
fn next(&mut self) -> Option<Self::Item> {
if self.position >= self.input.len() {
return None;
}
if let Some(pos) = self.input[self.position..].find(self.pattern) {
let abs_pos = self.position + pos;
self.position = abs_pos + self.pattern.len();
Some(RegexMatchResult::matched_at(abs_pos, self.pattern.len()))
} else {
None
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum CharconvError {
Success,
Overflow,
Underflow,
InvalidArgument,
Range,
}
#[derive(Debug, Clone)]
pub struct ToCharsResult {
pub ptr: usize,
pub error: CharconvError,
}
#[derive(Debug, Clone)]
pub struct FromCharsResult<T> {
pub value: T,
pub ptr: usize,
pub error: CharconvError,
}
pub fn to_chars_int(value: i64, base: u32) -> ToCharsResult {
match base {
10 => {
let s = value.to_string();
ToCharsResult {
ptr: s.len(),
error: CharconvError::Success,
}
}
16 => {
let s = format!("{:x}", value);
ToCharsResult {
ptr: s.len(),
error: CharconvError::Success,
}
}
8 => {
let s = format!("{:o}", value);
ToCharsResult {
ptr: s.len(),
error: CharconvError::Success,
}
}
2 => {
let s = format!("{:b}", value);
ToCharsResult {
ptr: s.len(),
error: CharconvError::Success,
}
}
_ => ToCharsResult {
ptr: 0,
error: CharconvError::InvalidArgument,
},
}
}
pub fn from_chars_int(s: &str, base: u32) -> FromCharsResult<i64> {
let trimmed = s.trim();
match i64::from_str_radix(trimmed, base) {
Ok(val) => FromCharsResult {
value: val,
ptr: trimmed.len(),
error: CharconvError::Success,
},
Err(_) => FromCharsResult {
value: 0,
ptr: 0,
error: CharconvError::InvalidArgument,
},
}
}
pub fn to_chars_float(value: f64, precision: usize) -> ToCharsResult {
let s = format!("{:.prec$}", value, prec = precision);
ToCharsResult {
ptr: s.len(),
error: CharconvError::Success,
}
}
pub fn from_chars_float(s: &str) -> FromCharsResult<f64> {
match s.trim().parse::<f64>() {
Ok(val) => FromCharsResult {
value: val,
ptr: s.trim().len(),
error: CharconvError::Success,
},
Err(_) => FromCharsResult {
value: 0.0,
ptr: 0,
error: CharconvError::InvalidArgument,
},
}
}
#[derive(Debug, Clone)]
pub struct FormatSpec {
pub fill: char,
pub align: char,
pub sign: char,
pub alternate: bool,
pub zero_pad: bool,
pub width: Option<usize>,
pub precision: Option<usize>,
pub presentation: char,
}
impl Default for FormatSpec {
fn default() -> Self {
Self {
fill: ' ',
align: '<',
sign: '-',
alternate: false,
zero_pad: false,
width: None,
precision: None,
presentation: 's',
}
}
}
impl FormatSpec {
pub fn parse(spec: &str) -> Self {
let mut fs = FormatSpec::default();
if spec.is_empty() {
return fs;
}
let chars: Vec<char> = spec.chars().collect();
let mut i = 0;
if i + 1 < chars.len() && "<>^".contains(chars[i + 1]) {
fs.fill = chars[i];
fs.align = chars[i + 1];
i += 2;
} else if i < chars.len() && "<>^".contains(chars[i]) {
fs.align = chars[i];
i += 1;
}
if i < chars.len() && "+- ".contains(chars[i]) {
fs.sign = chars[i];
i += 1;
}
if i < chars.len() && chars[i] == '#' {
fs.alternate = true;
i += 1;
}
if i < chars.len() && chars[i] == '0' {
fs.zero_pad = true;
i += 1;
}
if i < chars.len() && chars[i].is_ascii_digit() {
let start = i;
while i < chars.len() && chars[i].is_ascii_digit() {
i += 1;
}
let width_str: String = chars[start..i].iter().collect();
fs.width = width_str.parse().ok();
}
if i < chars.len() && chars[i] == '.' {
i += 1;
let start = i;
while i < chars.len() && chars[i].is_ascii_digit() {
i += 1;
}
let prec_str: String = chars[start..i].iter().collect();
fs.precision = prec_str.parse().ok();
}
if i < chars.len() {
fs.presentation = chars[i];
}
fs
}
}
pub fn format_value<T: fmt::Display>(value: &T, spec: &FormatSpec) -> String {
let raw = format!("{}", value);
if spec.presentation == 's' && spec.width.is_none() {
return raw;
}
let formatted = match spec.presentation {
'd' => format!("{}", raw),
'x' => format!("{:x}", raw.parse::<i64>().unwrap_or(0)),
'X' => format!("{:X}", raw.parse::<i64>().unwrap_or(0)),
'o' => format!("{:o}", raw.parse::<i64>().unwrap_or(0)),
'b' => format!("{:b}", raw.parse::<i64>().unwrap_or(0)),
'f' => format!("{}", raw),
'e' => format!("{:e}", raw.parse::<f64>().unwrap_or(0.0)),
'E' => format!("{:E}", raw.parse::<f64>().unwrap_or(0.0)),
_ => raw.clone(),
};
if let Some(width) = spec.width {
let pad_char = if spec.zero_pad { '0' } else { spec.fill };
match spec.align {
'<' => format!("{:<width$}", formatted, width = width),
'>' => format!("{:>width$}", formatted, width = width),
'^' => format!("{:^width$}", formatted, width = width),
_ => formatted,
}
.replace(' ', &pad_char.to_string())
} else {
formatted
}
}
pub fn std_format(template: &str, args: &[String]) -> String {
let mut result = template.to_string();
for arg in args {
if let Some(pos) = result.find("{}") {
result.replace_range(pos..pos + 2, arg);
} else if let Some(start) = result.find("{:") {
if let Some(end) = result[start..].find('}') {
let spec_str = &result[start + 2..start + end];
let fs = FormatSpec::parse(spec_str);
let placeholder = &result[start..=start + end];
let formatted = format_value(&arg.as_str(), &fs);
result = result.replace(placeholder, &formatted);
}
}
}
result
}
#[derive(Debug, Clone)]
pub struct RangeView<T> {
data: Vec<T>,
}
impl<T> RangeView<T> {
pub fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
Self {
data: iter.into_iter().collect(),
}
}
pub fn from_vec(data: Vec<T>) -> Self {
Self { data }
}
pub fn len(&self) -> usize {
self.data.len()
}
pub fn is_empty(&self) -> bool {
self.data.is_empty()
}
pub fn filter<F: Fn(&T) -> bool>(self, f: F) -> RangeView<T>
where
T: Clone,
{
Self {
data: self.data.into_iter().filter(|x| f(x)).collect(),
}
}
pub fn transform<U, F: Fn(&T) -> U>(&self, f: F) -> RangeView<U> {
RangeView {
data: self.data.iter().map(f).collect(),
}
}
pub fn take(self, n: usize) -> RangeView<T> {
Self {
data: self.data.into_iter().take(n).collect(),
}
}
pub fn drop(self, n: usize) -> RangeView<T> {
Self {
data: self.data.into_iter().skip(n).collect(),
}
}
pub fn take_while<F: Fn(&T) -> bool>(self, f: F) -> RangeView<T>
where
T: Clone,
{
Self {
data: self.data.into_iter().take_while(|x| f(x)).collect(),
}
}
pub fn drop_while<F: Fn(&T) -> bool>(self, f: F) -> RangeView<T>
where
T: Clone,
{
let mut skip = true;
Self {
data: self
.data
.into_iter()
.filter(|x| {
if skip && f(x) {
false
} else {
skip = false;
true
}
})
.collect(),
}
}
pub fn reverse(self) -> RangeView<T> {
let mut data = self.data;
data.reverse();
Self { data }
}
pub fn collect(self) -> Vec<T> {
self.data
}
}
pub fn views_split<T: PartialEq + Clone>(data: &[T], delimiter: &T) -> Vec<Vec<T>> {
let mut result = Vec::new();
let mut current = Vec::new();
for item in data {
if item == delimiter {
result.push(std::mem::take(&mut current));
} else {
current.push(item.clone());
}
}
result.push(current);
result
}
pub fn views_join<T: Clone>(ranges: &[Vec<T>], delimiter: &T) -> Vec<T> {
let mut result = Vec::new();
for (i, range) in ranges.iter().enumerate() {
if i > 0 {
result.push(delimiter.clone());
}
result.extend(range.iter().cloned());
}
result
}
pub fn views_keys<K: Clone, V>(map: &HashMap<K, V>) -> Vec<K> {
map.keys().cloned().collect()
}
pub fn views_values<K, V: Clone>(map: &HashMap<K, V>) -> Vec<V> {
map.values().cloned().collect()
}
pub fn views_elements<T: Clone>(tuples: &[(T, T)], index: usize) -> Vec<T> {
tuples
.iter()
.map(|t| if index == 0 { t.0.clone() } else { t.1.clone() })
.collect()
}
pub fn views_common<T>(range: &RangeView<T>) -> RangeView<T>
where
T: Clone,
{
range.clone()
}
pub trait Emplacer<T> {
fn emplace_back(&mut self, val: T);
fn emplace_front(&mut self, val: T);
}
pub trait Reservable {
fn reserve(&mut self, additional: usize);
fn capacity(&self) -> usize;
fn shrink_to_fit(&mut self);
}
#[derive(Debug, Clone)]
pub struct StdVector<T> {
data: Vec<T>,
}
impl<T> StdVector<T> {
pub fn new() -> Self {
Self { data: Vec::new() }
}
pub fn with_capacity(cap: usize) -> Self {
Self {
data: Vec::with_capacity(cap),
}
}
pub fn push_back(&mut self, val: T) {
self.data.push(val);
}
pub fn pop_back(&mut self) -> Option<T> {
self.data.pop()
}
pub fn size(&self) -> usize {
self.data.len()
}
pub fn empty(&self) -> bool {
self.data.is_empty()
}
pub fn capacity(&self) -> usize {
self.data.capacity()
}
pub fn reserve(&mut self, additional: usize) {
self.data.reserve(additional);
}
pub fn shrink_to_fit(&mut self) {
self.data.shrink_to_fit();
}
pub fn clear(&mut self) {
self.data.clear();
}
pub fn front(&self) -> Option<&T> {
self.data.first()
}
pub fn back(&self) -> Option<&T> {
self.data.last()
}
pub fn front_mut(&mut self) -> Option<&mut T> {
self.data.first_mut()
}
pub fn back_mut(&mut self) -> Option<&mut T> {
self.data.last_mut()
}
pub fn get(&self, index: usize) -> Option<&T> {
self.data.get(index)
}
pub fn get_mut(&mut self, index: usize) -> Option<&mut T> {
self.data.get_mut(index)
}
pub fn data_ptr(&self) -> *const T {
self.data.as_ptr()
}
pub fn as_slice(&self) -> &[T] {
&self.data
}
pub fn iter(&self) -> std::slice::Iter<T> {
self.data.iter()
}
}
impl<T> Default for StdVector<T> {
fn default() -> Self {
Self::new()
}
}
impl<T> Index<usize> for StdVector<T> {
type Output = T;
fn index(&self, index: usize) -> &Self::Output {
&self.data[index]
}
}
impl<T> IntoIterator for StdVector<T> {
type Item = T;
type IntoIter = std::vec::IntoIter<T>;
fn into_iter(self) -> Self::IntoIter {
self.data.into_iter()
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::collections::HashMap;
#[test]
fn test_span_from_slice() {
let data = vec![1, 2, 3, 4, 5];
let span = Span::from_slice(&data);
assert_eq!(span.size(), 5);
assert!(!span.empty());
assert_eq!(span.front(), Some(&1));
assert_eq!(span.back(), Some(&5));
}
#[test]
fn test_span_first_last() {
let data = vec![10, 20, 30, 40, 50];
let span = Span::from_slice(&data);
let first3 = span.first(3);
assert_eq!(first3.size(), 3);
unsafe {
assert_eq!(*first3.data_ptr(), 10);
}
let last2 = span.last(2);
assert_eq!(last2.size(), 2);
assert_eq!(last2.back(), Some(&50));
}
#[test]
fn test_span_subspan() {
let data = vec![1, 2, 3, 4, 5];
let span = Span::from_slice(&data);
let sub = span.subspan(1, 3);
assert_eq!(sub.size(), 3);
}
#[test]
fn test_span_empty() {
let span: Span<i32> = Span::default();
assert!(span.empty());
assert_eq!(span.size(), 0);
}
#[test]
fn test_span_size_bytes() {
let data = vec![1i32, 2, 3];
let span = Span::from_slice(&data);
assert_eq!(span.size_bytes(), 12);
}
#[test]
fn test_string_view_new() {
let sv = StringView::new("hello world");
assert_eq!(sv.size(), 11);
assert!(!sv.empty());
assert_eq!(sv.front(), Some(b'h'));
assert_eq!(sv.back(), Some(b'd'));
}
#[test]
fn test_string_view_substr() {
let sv = StringView::new("hello world");
let sub = sv.substr(6, 5);
assert_eq!(sub.as_str(), "world");
}
#[test]
fn test_string_view_find() {
let sv = StringView::new("hello world");
assert_eq!(sv.find("world", 0), Some(6));
assert_eq!(sv.find("xyz", 0), None);
}
#[test]
fn test_string_view_starts_with() {
let sv = StringView::new("hello world");
assert!(sv.starts_with("hello"));
assert!(!sv.starts_with("world"));
}
#[test]
fn test_string_view_ends_with() {
let sv = StringView::new("hello world");
assert!(sv.ends_with("world"));
assert!(!sv.ends_with("hello"));
}
#[test]
fn test_string_view_contains() {
let sv = StringView::new("hello world");
assert!(sv.contains("lo wo"));
assert!(!sv.contains("xyz"));
}
#[test]
fn test_string_view_remove_prefix() {
let mut sv = StringView::new("hello world");
sv.remove_prefix(6);
assert_eq!(sv.as_str(), "world");
}
#[test]
fn test_string_view_remove_suffix() {
let mut sv = StringView::new("hello world");
sv.remove_suffix(6);
assert_eq!(sv.as_str(), "hello");
}
#[test]
fn test_string_view_compare() {
let a = StringView::new("abc");
let b = StringView::new("abd");
assert!(a < b);
assert_eq!(a.compare(&b), std::cmp::Ordering::Less);
}
#[test]
fn test_variant_first() {
let v: Variant<i32, String, f64> = Variant::first(42);
assert!(v.holds_first());
assert!(!v.holds_second());
assert_eq!(v.index(), 0);
assert_eq!(v.get_first(), Some(&42));
}
#[test]
fn test_variant_second() {
let v = Variant::second(String::from("hello"));
assert!(v.holds_second());
assert_eq!(v.index(), 1);
assert_eq!(v.get_second(), Some(&"hello".to_string()));
}
#[test]
fn test_visit_variant() {
let v = Variant::first(100i32);
let result = visit_variant(&v, |x| *x * 2, |_: &String| 0, |_: &f64| 0);
assert_eq!(result, 200);
}
#[test]
fn test_any_new_empty() {
let a = Any::new();
assert!(!a.has_value());
}
#[test]
fn test_any_emplace() {
let mut a = Any::new();
a.emplace(&42i32);
assert!(a.has_value());
assert!(!a.type_name().is_empty());
}
#[test]
fn test_any_reset() {
let mut a = Any::new();
a.emplace(&"test");
a.reset();
assert!(!a.has_value());
}
#[test]
fn test_optional_none() {
let opt: Optional<i32> = Optional::none();
assert!(!opt.has_value());
}
#[test]
fn test_optional_some() {
let opt = Optional::some(42);
assert!(opt.has_value());
assert_eq!(opt.value(), &42);
}
#[test]
fn test_optional_value_or() {
let opt: Optional<i32> = Optional::none();
assert_eq!(opt.value_or(10), 10);
let opt = Optional::some(42);
assert_eq!(opt.value_or(10), 42);
}
#[test]
fn test_optional_map() {
let opt = Optional::some(5);
let mapped = opt.map(|x| x * 2);
assert_eq!(*mapped.value(), 10);
}
#[test]
fn test_optional_and_then() {
let opt = Optional::some(5);
let result = opt.and_then(|x| {
if x > 0 {
Optional::some(x * 2)
} else {
Optional::none()
}
});
assert_eq!(*result.value(), 10);
}
#[test]
fn test_optional_reset() {
let mut opt = Optional::some(42);
opt.reset();
assert!(!opt.has_value());
}
#[test]
fn test_make_tuple() {
let t = make_tuple(1, "hello");
assert_eq!(t.first, 1);
assert_eq!(t.second, "hello");
}
#[test]
fn test_apply() {
let add = |a: i32, b: i32| a + b;
let result = apply(add, (3, 4));
assert_eq!(result, 7);
}
#[test]
fn test_std_function_new() {
let f: StdFunction<i32> = StdFunction::new("main", vec!["int".to_string()], 16);
assert!(f.has_target());
assert_eq!(f.target_name(), "main");
assert!(f.is_small());
}
#[test]
fn test_std_function_default() {
let f: StdFunction<i32> = StdFunction::default();
assert!(!f.has_target());
}
#[test]
fn test_reference_wrapper() {
let x = 42;
let rw = ref_wrap(&x);
assert_eq!(*rw.get(), 42);
}
#[test]
fn test_not_fn() {
let is_even = |x: i32| x % 2 == 0;
let is_odd = not_fn(is_even);
assert!(is_odd(3));
assert!(!is_odd(4));
}
#[test]
fn test_bind_front() {
let add = |a: i32, b: i32| a + b;
let add5 = bind_front(add, 5);
assert_eq!(*add5.bound(), 5);
}
#[test]
fn test_regex_new() {
let re = Regex::new("[a-z]+");
assert!(re.is_valid());
assert_eq!(re.pattern(), "[a-z]+");
}
#[test]
fn test_regex_match_basic() {
assert!(regex_match("hello", "hello world"));
}
#[test]
fn test_regex_search() {
let result = regex_search("world", "hello world");
assert!(result.matched);
assert_eq!(result.position, 6);
}
#[test]
fn test_regex_replace() {
let result = regex_replace("hello", "hello world hello", "hi");
assert_eq!(result, "hi world hi");
}
#[test]
fn test_regex_iterator() {
let iter = RegexIterator::new("ab", "ab ab ab");
let matches: Vec<_> = iter.collect();
assert_eq!(matches.len(), 3);
}
#[test]
fn test_to_chars_int_decimal() {
let result = to_chars_int(42, 10);
assert_eq!(result.error, CharconvError::Success);
assert!(result.ptr > 0);
}
#[test]
fn test_to_chars_int_hex() {
let result = to_chars_int(255, 16);
assert_eq!(result.error, CharconvError::Success);
}
#[test]
fn test_from_chars_int() {
let result = from_chars_int("42", 10);
assert_eq!(result.error, CharconvError::Success);
assert_eq!(result.value, 42);
}
#[test]
fn test_from_chars_int_hex() {
let result = from_chars_int("ff", 16);
assert_eq!(result.error, CharconvError::Success);
assert_eq!(result.value, 0xff);
}
#[test]
fn test_from_chars_float() {
let result = from_chars_float("3.14");
assert_eq!(result.error, CharconvError::Success);
assert!((result.value - 3.14).abs() < 0.001);
}
#[test]
fn test_format_spec_parse_empty() {
let spec = FormatSpec::parse("");
assert_eq!(spec.presentation, 's');
}
#[test]
fn test_format_spec_parse_decimal() {
let spec = FormatSpec::parse("d");
assert_eq!(spec.presentation, 'd');
}
#[test]
fn test_format_spec_parse_width() {
let spec = FormatSpec::parse(">10s");
assert_eq!(spec.align, '>');
assert_eq!(spec.width, Some(10));
assert_eq!(spec.presentation, 's');
}
#[test]
fn test_std_format_basic() {
let result = std_format("hello {} world", &["beautiful".to_string()]);
assert_eq!(result, "hello beautiful world");
}
#[test]
fn test_std_format_multiple() {
let result = std_format(
"{} + {} = {}",
&["1".to_string(), "2".to_string(), "3".to_string()],
);
assert_eq!(result, "1 + 2 = 3");
}
#[test]
fn test_range_view_filter() {
let data = RangeView::from_vec(vec![1, 2, 3, 4, 5, 6]);
let filtered = data.filter(|x| *x % 2 == 0);
assert_eq!(filtered.collect(), vec![2, 4, 6]);
}
#[test]
fn test_range_view_transform() {
let data = RangeView::from_vec(vec![1, 2, 3]);
let transformed = data.transform(|x| x * 2);
assert_eq!(transformed.collect(), vec![2, 4, 6]);
}
#[test]
fn test_range_view_take() {
let data = RangeView::from_vec(vec![1, 2, 3, 4, 5]);
let taken = data.take(3);
assert_eq!(taken.collect(), vec![1, 2, 3]);
}
#[test]
fn test_range_view_drop() {
let data = RangeView::from_vec(vec![1, 2, 3, 4, 5]);
let dropped = data.drop(2);
assert_eq!(dropped.collect(), vec![3, 4, 5]);
}
#[test]
fn test_range_view_reverse() {
let data = RangeView::from_vec(vec![1, 2, 3]);
let reversed = data.reverse();
assert_eq!(reversed.collect(), vec![3, 2, 1]);
}
#[test]
fn test_views_split() {
let data = vec![1, 2, 0, 3, 4, 0, 5];
let result = views_split(&data, &0);
assert_eq!(result, vec![vec![1, 2], vec![3, 4], vec![5]]);
}
#[test]
fn test_views_join() {
let data = vec![vec![1, 2], vec![3, 4], vec![5]];
let result = views_join(&data, &0);
assert_eq!(result, vec![1, 2, 0, 3, 4, 0, 5]);
}
#[test]
fn test_views_keys() {
let mut map = HashMap::new();
map.insert("a".to_string(), 1);
map.insert("b".to_string(), 2);
let mut keys = views_keys(&map);
keys.sort();
assert_eq!(keys, vec!["a", "b"]);
}
#[test]
fn test_std_vector_push_back() {
let mut v = StdVector::new();
v.push_back(1);
v.push_back(2);
assert_eq!(v.size(), 2);
assert_eq!(v.front(), Some(&1));
}
#[test]
fn test_std_vector_pop() {
let mut v = StdVector::new();
v.push_back(10);
assert_eq!(v.pop_back(), Some(10));
assert!(v.empty());
}
#[test]
fn test_std_vector_reserve() {
let mut v = StdVector::new();
v.reserve(100);
assert!(v.capacity() >= 100);
}
#[test]
fn test_span_contains() {
let data = vec![1, 2, 3, 4, 5];
let span = Span::from_slice(&data);
assert!(span.contains(&3));
assert!(!span.contains(&10));
}
#[test]
fn test_string_view_find_first_of() {
let sv = StringView::new("hello world");
let pos = sv.find_first_of("aeiou");
assert_eq!(pos, Some(1)); }
#[test]
fn test_string_view_find_first_not_of() {
let sv = StringView::new("hello");
let pos = sv.find_first_not_of("hel");
assert_eq!(pos, Some(3)); let sv2 = StringView::new("hello");
let pos2 = sv2.find_first_not_of("he");
assert_eq!(pos2, Some(2)); }
#[test]
fn test_format_spec_parse_precision() {
let spec = FormatSpec::parse(".4f");
assert_eq!(spec.precision, Some(4));
assert_eq!(spec.presentation, 'f');
}
#[test]
fn test_to_chars_int_binary() {
let result = to_chars_int(5, 2);
assert_eq!(result.error, CharconvError::Success);
}
#[test]
fn test_to_chars_int_invalid_base() {
let result = to_chars_int(5, 99);
assert_eq!(result.error, CharconvError::InvalidArgument);
}
}