1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
//! # Overview
//!
//! Converting a uBase/iBase instance
//! ```rust
//! // converting down
//!
//! // create uBase instance
//! let mut number = uBase::from_string(7863, "NUMBERBASED");
//!
//! // convert number to base 10
//! number.convert(10);
//!
//! assert_eq!(number.display(), String::from("20781774882369576414324066149192513674771"));
//! // Do aslso note that number.conver(10).display() is equivalent to number.as_decimal() with the
//! // important distinction that as_decimal() returns a u128 and not a string
//!
//!
//!
//!
//!
//! // converting up
//!
//! // create uBase instance
//! let mut other_number = uBase::from_string(10, "120387517860123746975");
//!
//! // convert number to base 10000
//! other_number.convert(10000);
//!
//! assert_eq!(other_number.display(), String::from("1ࡒᶹ⇵ঢᮛ"));
//! ```
//!
//! Performing operations with uBase/iBase instances
//!
//! ```rust
//! // create the iBase instances
//! let number1 = iBase::from_string(30000, "-ð䧈炙㞈榻");
//! assert_eq!(number1.as_decimal(), -120387517860123746975);
//!
//! let number2 = iBase::from_string(30000, "20");
//! assert_eq!(number2.as_decimal(), 60000);
//!
//! // divide the numbers
//! let quotient = number1 / number2;
//! // other operations such as addition, subtraction, and multiplication are also available with
//! // the operators "+", "-", and "*" respectively
//!
//! assert_eq!(quotient.display(), String::from("-¦┒㡺嚊"));
//! assert_eq!(quotient.as_decimal(), -120387517860123746975 / 60000);
//! ```

use std::{
    fmt::Display,
    ops::{Add, Div, Mul, Sub},
};

mod unsigned_integer;
use crate::unsigned_integer::ubase;

mod signed_integer;
use crate::signed_integer::ibase;

mod utils;

mod graphemes;

#[allow(dead_code, non_camel_case_types)]
pub type uBase = ubase::uBase;

#[allow(dead_code, non_camel_case_types)]
pub type iBase = ibase::iBase;

pub trait NumberBase: Add + Sub + Div + Mul + Display + Sized + Clone {
    /// The type being returned when a decimal is to be returned
    /// For instance, the as_octal() function returns either an integer or float depending on
    /// whether the struct implementing NumberBase only accepts integers
    type DecimalType;

    /// returns the base of the number
    fn base(&self) -> u16;

    /// returns true if the number is greater than the input for this funciton
    fn greater_than(&self, number: Self) -> bool;

    /// returns the vector containg the digits in base 10
    fn digits(&self) -> &Vec<u16>;

    /// creates an instance of Self from a string
    fn from_string(base: u16, number: &str) -> Self;

    /// creates and instance of Self from a vector
    fn from_vec(base: u16, number: Vec<u16>) -> Self;

    /// converts the number to the inputted number base
    fn convert(&mut self, base: u16) -> Self;

    /// returns the value of the number as a string
    fn display(&self) -> String;

    /// returns an instance of self but in binary
    fn as_binary(&self) -> Self::DecimalType;

    /// returns an instance of self but in octal
    fn as_octal(&self) -> Self::DecimalType;

    /// returns an instance of self but in decimal
    fn as_decimal(&self) -> Self::DecimalType;

    /// returns an instance of self but in hex
    fn as_hex(&self) -> String;
}