1pub const CURRENT_VERSION: u32 = 3;
16
17#[derive(PartialEq)]
18enum Modes {
19 Version,
20 Language,
21 Branch,
22 OS,
23 Other,
24}
25
26pub enum Tokens {
27 Language,
28 Branch,
29 OS,
30 Other,
31
32 Push,
33 Push5,
34 Push10,
35 Push50,
36 Push100,
37 Sub,
38
39 Print,
40}
41
42pub struct Identicode {
43 lang_list: Vec<String>,
44 branch_list: Vec<String>,
45 os_list: Vec<String>,
46 other_list: Vec<String>,
47
48 mode: Modes,
49
50 stack: u64,
51
52 pub version: u32,
53 pub languages: Vec<String>,
54 pub branches: Vec<String>,
55 pub oses: Vec<String>,
56 pub others: Vec<String>,
57}
58
59impl Tokens {
60 fn val(ch: char) -> Self {
61 use self::Tokens::*;
62
63 match ch {
64 '$' => Language,
65 '@' => Branch,
66 '?' => OS,
67 '&' => Other,
68
69 '+' => Push,
70 '*' => Push5,
71 '/' => Push10,
72 '%' => Push50,
73 '=' => Push100,
74 '-' => Sub,
75
76 ';' => Print,
77 _ => {
78 println!("\x1b[1;31merror:\x1b[0m unknown character '{}'", ch);
79 std::process::exit(1);
80 }
81 }
82 }
83}
84
85impl Default for Identicode {
86 fn default() -> Self {
87 let langs = String::from_utf8_lossy(include_bytes!("data/langs.txt"))
88 .lines()
89 .map(str::to_string)
90 .collect();
91 let branches = String::from_utf8_lossy(include_bytes!("data/branches.txt"))
92 .lines()
93 .map(str::to_string)
94 .collect();
95 let oses = String::from_utf8_lossy(include_bytes!("data/oses.txt"))
96 .lines()
97 .map(str::to_string)
98 .collect();
99 let others = String::from_utf8_lossy(include_bytes!("data/others.txt"))
100 .lines()
101 .map(str::to_string)
102 .collect();
103
104 Identicode {
105 version: 0,
106 mode: Modes::Version,
107 stack: 0,
108 languages: vec![],
109 branches: vec![],
110 oses: vec![],
111 others: vec![],
112 lang_list: langs,
113 branch_list: branches,
114 other_list: others,
115 os_list: oses,
116 }
117 }
118}
119
120impl Identicode {
121 pub fn init(&mut self, file_data: String) {
122 use Tokens::*;
123
124 for ch in file_data.chars() {
125 match Tokens::val(ch) {
126 Language => {
127 self.mode = Modes::Language;
128 }
129 Branch => {
130 self.mode = Modes::Branch;
131 }
132 OS => {
133 self.mode = Modes::OS;
134 }
135 Other => {
136 self.mode = Modes::Other;
137 }
138
139 Push => {
140 self.stack += 1;
141 }
142 Push5 => {
143 self.stack += 5;
144 }
145 Push10 => {
146 self.stack += 10;
147 }
148 Push50 => {
149 self.stack += 50;
150 }
151 Push100 => {
152 self.stack += 100;
153 }
154 Sub => {
155 self.stack -= 1;
156 }
157
158 Print => {
159 fn push_item(vect: &mut Vec<String>, list: &mut Vec<String>, stack: u64) {
160 if list[stack as usize] != "" {
161 vect.push(list[stack as usize].clone());
162 list[stack as usize] = "".to_string();
163 }
164 }
165
166 if self.mode == Modes::Language && self.stack < self.lang_list.len() as u64 {
167 push_item(&mut self.languages, &mut self.lang_list, self.stack);
168 } else if self.mode == Modes::Branch
169 && self.stack < self.branch_list.len() as u64
170 {
171 push_item(&mut self.branches, &mut self.branch_list, self.stack);
172 } else if self.mode == Modes::OS && self.stack < self.os_list.len() as u64 {
173 push_item(&mut self.oses, &mut self.os_list, self.stack);
174 } else if self.mode == Modes::Other && self.stack < self.other_list.len() as u64
175 {
176 push_item(&mut self.others, &mut self.other_list, self.stack);
177 } else if self.mode == Modes::Version {
178 self.version = self.stack as u32;
179 self.stack = 0;
180 }
181
182 self.stack = 0;
183 }
184 }
185 }
186 }
187}