#[allow(warnings)]
pub mod traits {
use std::thread::JoinHandle;
use std::{
any::Any,
fmt::{Debug, Display},
path::{Path, PathBuf},
ptr::null,
str::FromStr,
};
pub trait Spawn<T: Debug> {
fn spawn(self) -> JoinHandle<T>;
}
impl<T: 'static + Send + Debug, F: FnOnce() -> T + Send + 'static> Spawn<T> for F {
fn spawn(self) -> JoinHandle<T> {
std::thread::spawn(self)
}
}
pub trait Decimal {
fn round_to(&self, by: usize) -> Self
where
Self: Sized + Copy,
{
*self
}
fn random() -> Self;
fn random_in_range<R: std::ops::RangeBounds<Self>>(range: R) -> Self;
fn num_to_xl_col(&self) -> String;
}
impl Decimal for i32 {
fn num_to_xl_col(&self) -> String{
let index = *self as usize + 1;
let mut result = String::new();
let mut index = index;
while index > 0 {
let remainder = (index - 1) % 26;
result.push((b'A' + remainder as u8) as char);
index = (index - 1) / 26;
}
result.chars().rev().collect()
}
fn random() -> Self {
(LCG::new().random() * 10.0) as i32
}
fn random_in_range<R: std::ops::RangeBounds<Self>>(range: R) -> Self {
let min = match range.start_bound() {
std::ops::Bound::Included(v) => *v,
std::ops::Bound::Excluded(v) => *v,
std::ops::Bound::Unbounded => 0,
};
let max = match range.end_bound() {
std::ops::Bound::Included(v) => *v,
std::ops::Bound::Excluded(v) => *v,
std::ops::Bound::Unbounded => i32::MAX,
};
let random = LCG::new().random();
let sub = max - min;
(random * sub as f64) as i32 + min
}
}
impl Decimal for i64 {
fn num_to_xl_col(&self) -> String{
let index = *self as usize + 1;
let mut result = String::new();
let mut index = index;
while index > 0 {
let remainder = (index - 1) % 26;
result.push((b'A' + remainder as u8) as char);
index = (index - 1) / 26;
}
result.chars().rev().collect()
}
fn random() -> Self {
(LCG::new().random() * 10.0) as i64
}
fn random_in_range<R: std::ops::RangeBounds<Self>>(range: R) -> Self {
let min = match range.start_bound() {
std::ops::Bound::Included(v) => *v,
std::ops::Bound::Excluded(v) => *v,
std::ops::Bound::Unbounded => 0,
};
let max = match range.end_bound() {
std::ops::Bound::Included(v) => *v,
std::ops::Bound::Excluded(v) => *v,
std::ops::Bound::Unbounded => i64::MAX,
};
let random = LCG::new().random();
let sub = max - min;
(random * sub as f64) as i64 + min
}
}
impl Decimal for i128 {
fn num_to_xl_col(&self) -> String{
let index = *self as usize + 1;
let mut result = String::new();
let mut index = index;
while index > 0 {
let remainder = (index - 1) % 26;
result.push((b'A' + remainder as u8) as char);
index = (index - 1) / 26;
}
result.chars().rev().collect()
}
fn random() -> Self {
(LCG::new().random() * 10.0) as i128
}
fn random_in_range<R: std::ops::RangeBounds<Self>>(range: R) -> Self {
let min = match range.start_bound() {
std::ops::Bound::Included(v) => *v,
std::ops::Bound::Excluded(v) => *v,
std::ops::Bound::Unbounded => 0,
};
let max = match range.end_bound() {
std::ops::Bound::Included(v) => *v,
std::ops::Bound::Excluded(v) => *v,
std::ops::Bound::Unbounded => i128::MAX,
};
let random = LCG::new().random();
let sub = max - min;
(random * sub as f64) as i128 + min
}
}
impl Decimal for u32 {
fn num_to_xl_col(&self) -> String{
let index = *self as usize + 1;
let mut result = String::new();
let mut index = index;
while index > 0 {
let remainder = (index - 1) % 26;
result.push((b'A' + remainder as u8) as char);
index = (index - 1) / 26;
}
result.chars().rev().collect()
}
fn random() -> Self {
(LCG::new().random() * 10.0) as u32
}
fn random_in_range<R: std::ops::RangeBounds<Self>>(range: R) -> Self {
let min = match range.start_bound() {
std::ops::Bound::Included(v) => *v,
std::ops::Bound::Excluded(v) => *v,
std::ops::Bound::Unbounded => 0,
};
let max = match range.end_bound() {
std::ops::Bound::Included(v) => *v,
std::ops::Bound::Excluded(v) => *v,
std::ops::Bound::Unbounded => u32::MAX,
};
let random = LCG::new().random();
let sub = max - min;
(random * sub as f64) as u32 + min
}
}
impl Decimal for u64 {
fn num_to_xl_col(&self) -> String{
let index = *self as usize + 1;
let mut result = String::new();
let mut index = index;
while index > 0 {
let remainder = (index - 1) % 26;
result.push((b'A' + remainder as u8) as char);
index = (index - 1) / 26;
}
result.chars().rev().collect()
}
fn random() -> Self {
(LCG::new().random() * 10.0) as u64
}
fn random_in_range<R: std::ops::RangeBounds<Self>>(range: R) -> Self {
let min = match range.start_bound() {
std::ops::Bound::Included(v) => *v,
std::ops::Bound::Excluded(v) => *v,
std::ops::Bound::Unbounded => 0,
};
let max = match range.end_bound() {
std::ops::Bound::Included(v) => *v,
std::ops::Bound::Excluded(v) => *v,
std::ops::Bound::Unbounded => u64::MAX,
};
let random = LCG::new().random();
let sub = max - min;
(random * sub as f64) as u64 + min
}
}
impl Decimal for u128 {
fn num_to_xl_col(&self) -> String{
let index = *self as usize + 1;
let mut result = String::new();
let mut index = index;
while index > 0 {
let remainder = (index - 1) % 26;
result.push((b'A' + remainder as u8) as char);
index = (index - 1) / 26;
}
result.chars().rev().collect()
}
fn random() -> Self {
(LCG::new().random() * 10.0) as u128
}
fn random_in_range<R: std::ops::RangeBounds<Self>>(range: R) -> Self {
let min = match range.start_bound() {
std::ops::Bound::Included(v) => *v,
std::ops::Bound::Excluded(v) => *v,
std::ops::Bound::Unbounded => 0,
};
let max = match range.end_bound() {
std::ops::Bound::Included(v) => *v,
std::ops::Bound::Excluded(v) => *v,
std::ops::Bound::Unbounded => u128::MAX,
};
let random = LCG::new().random();
let sub = max - min;
(random * sub as f64) as u128 + min
}
}
impl Decimal for f64 {
fn num_to_xl_col(&self) -> String{
let index = *self as usize + 1;
let mut result = String::new();
let mut index = index;
while index > 0 {
let remainder = (index - 1) % 26;
result.push((b'A' + remainder as u8) as char);
index = (index - 1) / 26;
}
result.chars().rev().collect()
}
fn round_to(&self, by: usize) -> f64 {
let factor = 10.0_f64.powi(by as i32);
(self * factor).round() / factor
}
fn random() -> Self {
LCG::new().random()
}
fn random_in_range<R: std::ops::RangeBounds<Self>>(range: R) -> Self {
let min = match range.start_bound() {
std::ops::Bound::Included(v) => *v,
std::ops::Bound::Excluded(v) => *v,
std::ops::Bound::Unbounded => 0.0,
};
let max = match range.end_bound() {
std::ops::Bound::Included(v) => *v,
std::ops::Bound::Excluded(v) => *v,
std::ops::Bound::Unbounded => f64::MAX,
};
let random = LCG::new().random();
let sub = max - min;
(random * sub) + min
}
}
impl Decimal for f32 {
fn num_to_xl_col(&self) -> String{
let index = *self as usize + 1;
let mut result = String::new();
let mut index = index;
while index > 0 {
let remainder = (index - 1) % 26;
result.push((b'A' + remainder as u8) as char);
index = (index - 1) / 26;
}
result.chars().rev().collect()
}
fn round_to(&self, by: usize) -> f32 {
let factor = 10.0_f32.powi(by as i32);
(self * factor).round() / factor
}
fn random() -> Self {
LCG::new().random_f32()
}
fn random_in_range<R: std::ops::RangeBounds<Self>>(range: R) -> Self {
let min = match range.start_bound() {
std::ops::Bound::Included(v) => *v,
std::ops::Bound::Excluded(v) => *v,
std::ops::Bound::Unbounded => 0.0,
};
let max = match range.end_bound() {
std::ops::Bound::Included(v) => *v,
std::ops::Bound::Excluded(v) => *v,
std::ops::Bound::Unbounded => f32::MAX,
};
let random = LCG::new().random_f32();
let sub = max - min;
(random * sub) + min
}
}
pub trait DynType: ToString {}
impl<T: ToString> DynType for T {}
#[derive(Debug, Clone)]
pub struct ToDynType<T: ToString>(pub T);
impl<T: ToString> Into<Box<dyn DynType>> for ToDynType<T> {
fn into(self) -> Box<dyn DynType> {
Box::new(self.0.to_string())
}
}
use std::ops::Deref;
use crate::LCG;
pub trait Join {
fn join(&self, by: &str) -> String;
}
impl<T: ToString> Join for [T] {
fn join(&self, by: &str) -> String {
self.iter()
.map(|item| item.to_string())
.collect::<Vec<String>>()
.join(by)
}
}
pub trait Vector<T> {
fn element_to_string(&self) -> Vec<String>;
fn to_string_lossy(&self) -> String;
fn split_by_slice(&self, slice: &[T]) -> Vec<Vec<T>>;
fn random_choose(&self) -> T;
}
impl<T: ToString + PartialEq + Clone> Vector<T> for [T] {
fn element_to_string(&self) -> Vec<String> {
self.iter().map(|x| x.to_string()).collect::<Vec<String>>()
}
fn to_string_lossy(&self) -> String {
let vec = self
.iter()
.map(|x| x.to_string().parse::<u8>().unwrap())
.collect::<Vec<u8>>();
String::from_utf8_lossy(&vec).to_string()
}
fn split_by_slice(&self, slice: &[T]) -> Vec<Vec<T>> {
let mut result = Vec::new();
let mut start = 0;
while let Some(index) = self[start..]
.windows(slice.len())
.position(|window| window == slice)
{
let end = start + index;
result.push(self[start..end].to_vec());
start = end + slice.len();
}
result.push(self[start..].to_vec());
result
}
fn random_choose(&self) -> T {
use crate::LCG;
let lcg = LCG::new();
let random_index = lcg.random_in_range(0..self.len() as i128);
self.clone().get(random_index as usize).unwrap().to_owned()
}
}
pub trait Str {
fn cut(&self, start: i32, end: i32, step: usize) -> String;
fn format(&self, targets: Vec<(Box<dyn ToString>, Box<dyn ToString>)>) -> String;
fn to_path(&self) -> Box<Path>;
fn to_path_buf(&self) -> PathBuf;
fn split_to_vec(&self, delimiter: &str) -> Vec<String>;
fn to_box(&self) -> Box<str>;
fn push_back(&self, item: impl ToString) -> String;
fn push_front(&self, item: impl ToString) -> String;
fn is_equal(&self, other: &Self) -> bool;
fn add(&self, other: &Self) -> String;
fn reverse(&self) -> String;
fn capitalize(&self) -> String;
fn trim_lines(&self) -> String;
fn xl_col_to_num(&self) -> usize;
fn coordinate_to_position(&self) -> (usize, usize);
}
impl<S: ToString> Str for S {
fn coordinate_to_position(&self) -> (usize, usize){
let coord_str = self.to_string();
let mut col_str = String::new();
let mut row_str = String::new();
for c in coord_str.chars() {
if c.is_digit(10) {
row_str.push(c);
} else {
col_str.push(c);
}
}
let col_num = col_str.xl_col_to_num();
let row_num = row_str.parse::<usize>().unwrap();
(col_num, row_num)
}
fn xl_col_to_num(&self) -> usize{
let col_str = self.to_string().to_uppercase();
let mut col_num = 0;
for (i, c) in col_str.chars().enumerate() {
if (c as u8 as i8 - 'A' as u8 as i8) >= 0 {
let offset = (c as u8 - b'A') as usize + 1;
col_num = col_num * 26 + offset;
}
}
col_num -1
}
fn add(&self, other: &Self) -> String {
format!("{}{}", self.to_string(), other.to_string())
}
fn is_equal(&self, other: &Self) -> bool {
self.to_string() == other.to_string()
}
fn push_back(&self, item: impl ToString) -> String {
format!("{}{}", self.to_string(), item.to_string())
}
fn push_front(&self, item: impl ToString) -> String {
format!("{}{}", item.to_string(), self.to_string().to_string())
}
fn cut(&self, start: i32, end: i32, step: usize) -> String {
let mut res = String::new();
if start >= 0 && end >= 0 && start <= end {
let start = start as usize;
let end = end as usize;
for (i, c) in self.to_string().chars().enumerate().step_by(step) {
if i >= start && i <= end {
res.push(c);
}
}
} else if start < 0 && end < 0 {
if start > end {
let start = self.to_string().len() as i32 + end;
let end = self.to_string().len() as i32 + start;
let start = start as usize;
let end = end as usize;
for (i, c) in self.to_string().chars().enumerate().step_by(step) {
if i >= start && i <= end {
res.push(c);
}
}
} else {
let start = self.to_string().len() as i32 + start;
let end = self.to_string().len() as i32 + end;
let start = start as usize;
let end = end as usize;
for (i, c) in self.to_string().chars().enumerate().step_by(step) {
if i >= start && i <= end {
res.push(c);
}
}
}
} else if start > 0 && end < 0 {
let start = start as usize;
let end = self.to_string().len() as i32 + end;
let end = end as usize;
for (i, c) in self.to_string().chars().enumerate().step_by(step) {
if i >= start && i <= end {
res.push(c);
}
}
}
res
}
fn format(&self, targets: Vec<(Box<dyn ToString>, Box<dyn ToString>)>) -> String {
let mut s_mut = self.to_string().to_string();
for t in targets {
s_mut = s_mut.replace(&t.0.deref().to_string(), &t.1.deref().to_string());
}
s_mut
}
fn to_path(&self) -> Box<Path> {
Path::new(&self.to_string()).to_owned().into()
}
fn to_path_buf(&self) -> PathBuf {
PathBuf::from_str(&self.to_string()).unwrap()
}
fn split_to_vec(&self, delimiter: &str) -> Vec<String> {
crate::split_to_vec!(self.to_string(), delimiter)
}
fn to_box(&self) -> Box<str> {
Box::from(self.to_string())
}
fn reverse(&self) -> String {
let mut s = self.to_string().chars().rev().collect::<Vec<_>>();
s.join("")
}
fn capitalize(&self) -> String {
if let Some(c) = self.to_string().chars().next() {
let first_letter_capitalized = c.to_uppercase().collect::<String>();
let rest_of_string = &self.to_string()[1..];
return format!("{}{}", first_letter_capitalized, rest_of_string);
}
self.to_string()
}
fn trim_lines(&self) -> String {
self.split_to_vec("\n")
.iter()
.map(|s| s.trim().to_string())
.collect::<Vec<_>>()
.join("\n")
}
}
pub trait Then {
fn then(&self, run: impl Fn()) -> &Self;
}
impl<T> Then for T {
fn then(&self, run: impl Fn()) -> &Self {
run();
self
}
}
pub trait Sleep {
fn sleep(&self, secs: f64);
}
impl<T> Sleep for T {
fn sleep(&self, secs: f64) {
use std::thread::sleep;
use std::time::Duration;
sleep(Duration::from_secs_f64(secs));
}
}
pub trait DebugPrint {
fn dprint(&self);
fn deprint(&self);
fn dprintln(&self);
fn deprintln(&self);
fn dbg(&self);
}
impl<T> DebugPrint for T
where
T: Debug,
{
fn dprint(&self) {
print!("{:?}", self);
}
fn deprint(&self) {
eprint!("{:?}", self);
}
fn dprintln(&self) {
println!("{:?}", self);
}
fn deprintln(&self) {
eprintln!("{:?}", self);
}
fn dbg(&self) {
dbg!(self);
}
}
pub trait Print {
fn print(&self);
fn eprint(&self);
fn println(&self);
fn eprintln(&self);
}
impl<T> Print for T
where
T: Display,
{
fn print(&self) {
print!("{}", self);
}
fn eprint(&self) {
eprint!("{}", self);
}
fn println(&self) {
println!("{}", self);
}
fn eprintln(&self) {
eprintln!("{}", self);
}
}
pub trait IsThen<T> {
fn is_some_then(self, f: impl FnOnce(T) -> T) -> Option<T>;
fn is_none_then(self, f: impl FnOnce());
fn is_ok_then(self, f: impl FnOnce(T)) -> Option<T>;
fn is_err_then(self, f: impl FnOnce());
}
impl<T: Clone, U> IsThen<T> for Result<T, U> {
fn is_some_then(self, f: impl FnOnce(T) -> T) -> Option<T> {
match self {
Ok(value) => Some(f(value)),
Err(_) => None,
}
}
fn is_none_then(self, f: impl FnOnce()) {
if self.is_err() {
f();
}
}
fn is_ok_then(self, f: impl FnOnce(T)) -> Option<T> {
match self {
Ok(value) => {
f(value.clone());
Some(value)
}
Err(_) => None,
}
}
fn is_err_then(self, f: impl FnOnce()) {
if self.is_err() {
f();
}
}
}
impl<T: Clone> IsThen<T> for Option<T> {
fn is_some_then(self, f: impl FnOnce(T) -> T) -> Option<T> {
match self {
Some(value) => Some(f(value)),
None => None,
}
}
fn is_none_then(self, f: impl FnOnce()) {
if self.is_none() {
f();
}
}
fn is_ok_then(self, f: impl FnOnce(T)) -> Option<T> {
match self {
Some(value) => {
f(value.clone());
Some(value)
}
None => None,
}
}
fn is_err_then(self, f: impl FnOnce()) {
if self.is_none() {
f();
}
}
}
}