use std::cmp::Ordering;
pub fn vec_char_to_clean_str(v: &mut Vec<char>) -> String {
v.drain(..).collect::<String>()
}
pub fn is_non_character(ch: &char) -> bool {
matches!(
ch,
'\u{FDD0}'
..='\u{FDEF}'
| '\u{FFFE}'
| '\u{FFFF}'
| '\u{1FFFE}'
| '\u{1FFFF}'
| '\u{2FFFE}'
| '\u{2FFFF}'
| '\u{3FFFE}'
| '\u{3FFFF}'
| '\u{4FFFE}'
| '\u{4FFFF}'
| '\u{5FFFE}'
| '\u{5FFFF}'
| '\u{6FFFE}'
| '\u{6FFFF}'
| '\u{7FFFE}'
| '\u{7FFFF}'
| '\u{8FFFE}'
| '\u{8FFFF}'
| '\u{9FFFE}'
| '\u{9FFFF}'
| '\u{AFFFE}'
| '\u{AFFFF}'
| '\u{BFFFE}'
| '\u{BFFFF}'
| '\u{CFFFE}'
| '\u{CFFFF}'
| '\u{DFFFE}'
| '\u{DFFFF}'
| '\u{EFFFE}'
| '\u{EFFFF}'
| '\u{FFFFE}'
| '\u{FFFFF}'
| '\u{10FFFE}'
| '\u{10FFFF}'
)
}
pub fn is_char_available_in_key(ch: &char) -> bool {
if ch.is_ascii_alphanumeric() || ['_', '-', '.', ':'].contains(ch) {
return true;
}
if ch.is_ascii_whitespace()
|| ch.is_ascii_control()
|| is_non_character(ch)
|| ch.is_ascii_punctuation()
|| *ch == '\u{0000}'
{
return false;
}
true
}
#[allow(dead_code)]
pub enum RoundType {
Floor,
Ceil,
Round,
}
pub fn divide_isize(a: isize, b: isize, round: RoundType) -> isize {
let mut res = a / b;
let remainder = a % b;
use RoundType::*;
match round {
Floor => {
if res < 0 && remainder != 0 {
res -= 1;
}
}
Ceil => {
if res > 0 && remainder != 0 {
res += 1;
}
}
Round => {
if res != 0 && remainder != 0 {
let symbol = if res < 0 { -1 } else { 1 };
let total = remainder * 2 - symbol * b;
if (total >= 0 && a > 0) || (total <= 0 && a < 0) {
res += symbol;
}
}
}
}
res
}
pub fn retain_by_index<T>(v: &mut Vec<T>, indexs: &[usize]) {
for (i, index) in indexs.iter().enumerate() {
v.remove(index - i);
}
}
pub fn get_class_list(attr_class: &str) -> Vec<Vec<char>> {
let mut class_list: Vec<Vec<char>> = Vec::with_capacity(2);
let mut class_name: Vec<char> = Vec::with_capacity(5);
let mut prev_is_whitespace = true;
for ch in attr_class.chars() {
if ch.is_ascii_whitespace() {
if prev_is_whitespace {
continue;
}
prev_is_whitespace = true;
class_list.push(class_name);
class_name = Vec::with_capacity(5);
} else {
prev_is_whitespace = false;
class_name.push(ch);
}
}
if !prev_is_whitespace {
class_list.push(class_name);
}
class_list
}
pub fn class_list_to_string(class_list: &[Vec<char>]) -> String {
let total = class_list.len();
match total.cmp(&1) {
Ordering::Equal => class_list[0].iter().collect::<String>(),
Ordering::Greater => {
let mut attr_class: Vec<char> = Vec::with_capacity(total * 5);
let last_index = total - 1;
for name in &class_list[..last_index] {
attr_class.extend_from_slice(name);
attr_class.push(' ');
}
attr_class.extend_from_slice(&class_list[last_index]);
attr_class.iter().collect::<String>()
}
Ordering::Less => String::new(),
}
}
pub fn is_equal_chars_ignore_case(target: &[char], cmp: &[char]) -> bool {
if target.len() != cmp.len() {
return false;
}
for (index, ch) in target.iter().enumerate() {
let cmp_ch = &cmp[index];
if cmp_ch == ch {
continue;
}
match cmp_ch {
'a'..='z' => {
if &cmp_ch.to_ascii_uppercase() != ch {
return false;
}
}
'A'..='Z' => {
if &cmp_ch.to_ascii_lowercase() != ch {
return false;
}
}
_ => {
return false;
}
}
}
true
}
pub fn is_equal_chars(target: &[char], cmp: &[char]) -> bool {
let t_len = target.len();
let s_len = cmp.len();
if t_len == s_len {
for (index, ch) in target.iter().enumerate() {
if ch != &cmp[index] {
return false;
}
}
return true;
}
false
}
fn contains_chars_nocheck(target: &[char], search: &[char], t_len: usize, s_len: usize) -> bool {
let max_start_index: usize = t_len - s_len;
let mut start_index: usize = 0;
while start_index <= max_start_index {
let mut move_one = false;
for (index, ch) in target[start_index..start_index + s_len].iter().enumerate() {
if ch == &search[index] {
continue;
}
move_one = true;
}
if !move_one {
return true;
}
start_index += 1;
}
false
}
pub fn contains_chars(target: &[char], search: &[char]) -> bool {
let t_len = target.len();
let s_len = search.len();
if t_len < s_len {
return false;
}
contains_chars_nocheck(target, search, t_len, s_len)
}
#[cfg(test)]
mod tests {
use super::{divide_isize, RoundType};
#[test]
fn test_divide_isize() {
assert_eq!(divide_isize(7, 4, RoundType::Round), 2);
assert_eq!(divide_isize(6, 4, RoundType::Round), 2);
assert_eq!(divide_isize(5, 4, RoundType::Round), 1);
assert_eq!(divide_isize(4, 4, RoundType::Round), 1);
assert_eq!(divide_isize(-7, -4, RoundType::Round), 2);
assert_eq!(divide_isize(-6, -4, RoundType::Round), 2);
assert_eq!(divide_isize(-5, -4, RoundType::Round), 1);
assert_eq!(divide_isize(-4, -4, RoundType::Round), 1);
assert_eq!(divide_isize(7, -4, RoundType::Round), -2);
assert_eq!(divide_isize(6, -4, RoundType::Round), -2);
assert_eq!(divide_isize(5, -4, RoundType::Round), -1);
assert_eq!(divide_isize(4, -4, RoundType::Round), -1);
assert_eq!(divide_isize(-7, 4, RoundType::Round), -2);
assert_eq!(divide_isize(-6, 4, RoundType::Round), -2);
assert_eq!(divide_isize(-5, 4, RoundType::Round), -1);
assert_eq!(divide_isize(-4, 4, RoundType::Round), -1);
assert_eq!(divide_isize(7, 4, RoundType::Floor), 1);
assert_eq!(divide_isize(6, 4, RoundType::Floor), 1);
assert_eq!(divide_isize(5, 4, RoundType::Floor), 1);
assert_eq!(divide_isize(4, 4, RoundType::Floor), 1);
assert_eq!(divide_isize(-7, -4, RoundType::Floor), 1);
assert_eq!(divide_isize(-6, -4, RoundType::Floor), 1);
assert_eq!(divide_isize(-5, -4, RoundType::Floor), 1);
assert_eq!(divide_isize(-4, -4, RoundType::Floor), 1);
assert_eq!(divide_isize(7, -4, RoundType::Floor), -2);
assert_eq!(divide_isize(6, -4, RoundType::Floor), -2);
assert_eq!(divide_isize(5, -4, RoundType::Floor), -2);
assert_eq!(divide_isize(4, -4, RoundType::Floor), -1);
assert_eq!(divide_isize(-7, 4, RoundType::Floor), -2);
assert_eq!(divide_isize(-6, 4, RoundType::Floor), -2);
assert_eq!(divide_isize(-5, 4, RoundType::Floor), -2);
assert_eq!(divide_isize(-4, 4, RoundType::Floor), -1);
assert_eq!(divide_isize(7, 4, RoundType::Ceil), 2);
assert_eq!(divide_isize(6, 4, RoundType::Ceil), 2);
assert_eq!(divide_isize(5, 4, RoundType::Ceil), 2);
assert_eq!(divide_isize(4, 4, RoundType::Ceil), 1);
assert_eq!(divide_isize(-7, -4, RoundType::Ceil), 2);
assert_eq!(divide_isize(-6, -4, RoundType::Ceil), 2);
assert_eq!(divide_isize(-5, -4, RoundType::Ceil), 2);
assert_eq!(divide_isize(-4, -4, RoundType::Ceil), 1);
assert_eq!(divide_isize(7, -4, RoundType::Ceil), -1);
assert_eq!(divide_isize(6, -4, RoundType::Ceil), -1);
assert_eq!(divide_isize(5, -4, RoundType::Ceil), -1);
assert_eq!(divide_isize(4, -4, RoundType::Ceil), -1);
assert_eq!(divide_isize(-7, 4, RoundType::Ceil), -1);
assert_eq!(divide_isize(-6, 4, RoundType::Ceil), -1);
assert_eq!(divide_isize(-5, 4, RoundType::Ceil), -1);
assert_eq!(divide_isize(-4, 4, RoundType::Ceil), -1);
}
}