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
111
112
113
114
115
116
117
118
119
120
121
extern crate base_custom;
use base_custom::BaseCustom;
#[derive(Debug,Clone)]
pub struct Digits<'a> {
mapping: &'a BaseCustom<char>,
digit: u64,
left: Option<Box<Digits<'a>>>,
}
impl<'a> Digits<'a> {
pub fn new<S>(mapping: &'a BaseCustom<char>, number: S) -> Digits<'a>
where S: Into<String> {
let number = number.into();
if number.is_empty() { return Digits { mapping: mapping, digit: 0, left: None }; };
let (last, rest) = Digits::last_rest(number);
let continuation = {
if rest.is_empty() {
None
} else {
Some(Box::new(Digits::new(&mapping, rest)))
}
};
Digits {
mapping: mapping,
digit: mapping.decimal(last.to_string()),
left: continuation,
}
}
pub fn to_s(&self) -> String {
let num = self.mapping.gen(self.digit);
match &self.left {
&None => format!("{}", num),
&Some(ref bx) => format!("{}{}", bx.to_s(), num),
}
}
pub fn to_string(&self) -> String {
self.to_s()
}
fn last_rest(s: String) -> (char, String) {
let mut n = s.chars().rev();
let last = n.next().unwrap();
let rest = n.rev().collect::<String>();
(last, rest)
}
fn set_left(&mut self, d: Digits<'a>) {
if d.is_end() {
self.left = None;
} else {
self.left = Some(Box::new(d));
}
}
pub fn zero(&self) -> Self {
Digits { mapping: self.mapping, digit: 0, left: None }
}
fn is_end(&self) -> bool {
self.digit == 0 && match self.left { None => true, _ => false }
}
pub fn add(&mut self, other: Self) -> Self {
if other.is_end() { return self.clone(); };
let (last, rest) = Digits::last_rest(other.to_s());
let added = self.mapping.gen(self.mapping.decimal(last.to_string()) + self.digit);
let (l, r) = Digits::last_rest(added);
self.digit = self.mapping.decimal(l.to_string());
let mut intermediate = Digits::new(self.mapping, r);
intermediate.add(Digits::new(self.mapping, rest));
let current_left = match self.left.clone() {
None => { Box::new(self.zero()) },
Some(bx) => { bx },
}.as_ref().clone();
self.set_left( intermediate.add(current_left).clone() );
self.clone()
}
}
pub trait Into<String> {
fn into(self) -> String;
}
impl<'a> From<Digits<'a>> for String {
fn from(d: Digits) -> String {
d.to_s()
}
}
impl<'a> Into<String> for Digits<'a> {
fn into(self) -> String {
self.to_s()
}
}
impl Into<String> for String {
fn into(self) -> String {
self.clone()
}
}