use crate::num::conversion::string::options::{FromSciStringOptions, ToSciOptions};
use crate::num::conversion::string::to_sci::SciWrapper;
use crate::rounding_modes::RoundingMode;
use std::fmt::{Formatter, Result};
pub trait Digits<T>: Sized {
fn to_digits_asc(&self, base: &T) -> Vec<T>;
fn to_digits_desc(&self, base: &T) -> Vec<T>;
fn from_digits_asc<I: Iterator<Item = T>>(base: &T, digits: I) -> Option<Self>;
fn from_digits_desc<I: Iterator<Item = T>>(base: &T, digits: I) -> Option<Self>;
}
pub trait PowerOf2DigitIterator<T>: Iterator<Item = T> + DoubleEndedIterator<Item = T> {
fn get(&self, index: u64) -> T;
}
pub trait PowerOf2DigitIterable<T> {
type PowerOf2DigitIterator: PowerOf2DigitIterator<T>;
fn power_of_2_digits(self, log_base: u64) -> Self::PowerOf2DigitIterator;
}
pub trait PowerOf2Digits<T>: Sized {
fn to_power_of_2_digits_asc(&self, log_base: u64) -> Vec<T>;
fn to_power_of_2_digits_desc(&self, log_base: u64) -> Vec<T>;
fn from_power_of_2_digits_asc<I: Iterator<Item = T>>(log_base: u64, digits: I) -> Option<Self>;
fn from_power_of_2_digits_desc<I: Iterator<Item = T>>(log_base: u64, digits: I)
-> Option<Self>;
}
pub trait FromStringBase: Sized {
fn from_string_base(base: u8, s: &str) -> Option<Self>;
}
pub trait ToStringBase {
fn to_string_base(&self, base: u8) -> String;
fn to_string_base_upper(&self, base: u8) -> String;
}
pub trait ToSci: Sized {
fn fmt_sci(&self, f: &mut Formatter, options: ToSciOptions) -> Result;
fn fmt_sci_valid(&self, options: ToSciOptions) -> bool;
fn to_sci_with_options(&self, options: ToSciOptions) -> SciWrapper<Self> {
SciWrapper { x: self, options }
}
#[inline]
fn to_sci(&self) -> SciWrapper<Self> {
SciWrapper {
x: self,
options: ToSciOptions::default(),
}
}
}
pub trait FromSciString: Sized {
fn from_sci_string_with_options(s: &str, options: FromSciStringOptions) -> Option<Self>;
#[inline]
fn from_sci_string(s: &str) -> Option<Self> {
Self::from_sci_string_with_options(s, FromSciStringOptions::default())
}
}
pub trait ExactFrom<T>: Sized {
fn exact_from(value: T) -> Self;
}
pub trait ExactInto<T> {
fn exact_into(self) -> T;
}
impl<T, U: TryFrom<T>> ExactFrom<T> for U {
#[inline]
fn exact_from(value: T) -> U {
U::try_from(value).ok().unwrap()
}
}
impl<T, U: ExactFrom<T>> ExactInto<U> for T {
#[inline]
fn exact_into(self) -> U {
U::exact_from(self)
}
}
pub trait WrappingFrom<T>: Sized {
fn wrapping_from(value: T) -> Self;
}
pub trait WrappingInto<T>: Sized {
fn wrapping_into(self) -> T;
}
impl<T, U: WrappingFrom<T>> WrappingInto<U> for T {
#[inline]
fn wrapping_into(self) -> U {
U::wrapping_from(self)
}
}
pub trait SaturatingFrom<T>: Sized {
fn saturating_from(value: T) -> Self;
}
pub trait SaturatingInto<T>: Sized {
fn saturating_into(self) -> T;
}
impl<T, U: SaturatingFrom<T>> SaturatingInto<U> for T {
#[inline]
fn saturating_into(self) -> U {
U::saturating_from(self)
}
}
pub trait OverflowingFrom<T>: Sized {
fn overflowing_from(value: T) -> (Self, bool);
}
pub trait OverflowingInto<T>: Sized {
fn overflowing_into(self) -> (T, bool);
}
impl<T, U: OverflowingFrom<T>> OverflowingInto<U> for T {
#[inline]
fn overflowing_into(self) -> (U, bool) {
U::overflowing_from(self)
}
}
pub trait RoundingFrom<T>: Sized {
fn rounding_from(value: T, rm: RoundingMode) -> Self;
}
pub trait RoundingInto<T>: Sized {
fn rounding_into(self, rm: RoundingMode) -> T;
}
impl<T, U: RoundingFrom<T>> RoundingInto<U> for T {
#[inline]
fn rounding_into(self, rm: RoundingMode) -> U {
U::rounding_from(self, rm)
}
}
pub trait ConvertibleFrom<T> {
fn convertible_from(value: T) -> bool;
}
pub trait HasHalf {
type Half;
}
pub trait JoinHalves: HasHalf {
fn join_halves(upper: Self::Half, lower: Self::Half) -> Self;
}
pub trait SplitInHalf: HasHalf {
fn lower_half(&self) -> Self::Half;
fn upper_half(&self) -> Self::Half;
#[inline]
fn split_in_half(&self) -> (Self::Half, Self::Half) {
(self.upper_half(), self.lower_half())
}
}
pub trait IsInteger {
#[allow(clippy::wrong_self_convention)]
fn is_integer(self) -> bool;
}
pub trait RawMantissaAndExponent<M, E, T = Self>: Sized {
fn raw_mantissa_and_exponent(self) -> (M, E);
fn raw_mantissa(self) -> M {
self.raw_mantissa_and_exponent().0
}
fn raw_exponent(self) -> E {
self.raw_mantissa_and_exponent().1
}
fn from_raw_mantissa_and_exponent(raw_mantissa: M, raw_exponent: E) -> T;
}
pub trait IntegerMantissaAndExponent<M, E, T = Self>: Sized {
fn integer_mantissa_and_exponent(self) -> (M, E);
fn integer_mantissa(self) -> M {
self.integer_mantissa_and_exponent().0
}
fn integer_exponent(self) -> E {
self.integer_mantissa_and_exponent().1
}
fn from_integer_mantissa_and_exponent(integer_mantissa: M, integer_exponent: E) -> Option<T>;
}
pub trait SciMantissaAndExponent<M, E, T = Self>: Sized {
fn sci_mantissa_and_exponent(self) -> (M, E);
fn sci_mantissa(self) -> M {
self.sci_mantissa_and_exponent().0
}
fn sci_exponent(self) -> E {
self.sci_mantissa_and_exponent().1
}
fn from_sci_mantissa_and_exponent(sci_mantissa: M, sci_exponent: E) -> Option<T>;
}
pub trait FromOtherTypeSlice<T: Sized> {
fn from_other_type_slice(slice: &[T]) -> Self;
}
pub trait VecFromOtherTypeSlice<T: Sized>: Sized {
fn vec_from_other_type_slice(slice: &[T]) -> Vec<Self>;
}
pub trait VecFromOtherType<T>: Sized {
fn vec_from_other_type(value: T) -> Vec<Self>;
}