1use crate::bulletins::num::handle_num;
2use crate::bulletins::string::TomlString;
3use crate::bulletins::TomlValue;
4use crate::bulletins::{get_type, Types};
5use crate::lexer::Tokens;
6use crate::{assert_toml, comp_err};
7use std::iter::Peekable;
8
9pub struct Arr<'a, S: Iterator<Item = Tokens>> {
10 peekable: &'a mut Peekable<S>,
11 arr_type: Option<Types>,
12}
13
14#[derive(Debug)]
15struct TomlArray<T> {
16 array: Vec<T>,
17}
18
19#[macro_use]
20macro_rules! close_or_comma {
21 ( $arr : expr ) => {
22 if let Some(Tokens::Sbc) = $arr.peekable.peek() {
23 break;
24 } else {
25 assert_toml!($arr.peekable.next(), Tokens::Comma);
26 }
27 };
28}
29
30impl<'a, S: Iterator<Item = Tokens>> Arr<'a, S> {
31 pub fn handle(peekable: &mut Peekable<S>) -> TomlValue {
32 let mut arr = Arr {
35 peekable: peekable,
36 arr_type: None,
37 };
38 let mut vec = Vec::new();
39 while arr.peekable.peek().is_some() {
40 if let Some(x) = arr.peekable.next() {
41 match x {
42 Tokens::DoubleQuote | Tokens::SingleQuote => {
43 if !arr.has_type() {
44 arr.set_type(Types::String);
45 let mut string = TomlValue::String("".to_string());
46 if x == Tokens::DoubleQuote {
47 string = TomlString::handle(arr.peekable, 1);
48 } else {
49 string = TomlString::handle(arr.peekable, 3)
50 }
51 vec.push(string);
52 close_or_comma!(arr);
53 } else {
54 if arr.arr_type == Some(Types::String) {
55 let mut string = TomlValue::String("".to_string());
56 if x == Tokens::DoubleQuote {
57 string = TomlString::handle(arr.peekable, 1);
58 } else {
59 string = TomlString::handle(arr.peekable, 3)
60 }
61 vec.push(string);
62 close_or_comma!(arr);
63 } else {
64 if let Some(x) = arr.peekable.next() {
65 panic!(
66 "{:?} type found inside a {:?} type array",
67 get_type(&x.to_string()),
68 arr.arr_type
69 );
70 }
71 }
72 }
73 }
74 Tokens::Sbo => {
75 let something = Arr::handle(arr.peekable);
76 close_or_comma!(arr);
77 }
78 Tokens::LineBreak => (),
80 _ => {
81 let type_of_literal = get_type(&x.to_string());
82 if !arr.has_type() {
83 arr.set_type(type_of_literal);
84 match type_of_literal {
85 Types::String => {
86 comp_err!("Unexpected token, expected quotes or number")
87 }
88 Types::Int | Types::Floating => {
89 let final_num = handle_num(x.to_string());
90 vec.push(final_num);
91 close_or_comma!(arr);
92 }
93 Types::Boolean => {
94 vec.push(TomlValue::String(x.to_string()));
95 close_or_comma!(arr);
96 }
97 _ => (),
98 }
99 } else {
100 let arr_type = arr.arr_type.unwrap();
101 if type_of_literal == arr_type {
102 vec.push(TomlValue::String(x.to_string()));
103 close_or_comma!(arr);
104 } else {
105 comp_err!(format!(
106 "Found a {:?} type found in a {:?} type array",
107 type_of_literal, arr_type
108 ));
109 }
110 }
111 }
112 }
113 }
114 }
115 assert_toml!(arr.peekable.next(), Tokens::Sbc);
116 TomlValue::Array(vec)
117 }
118
119 pub fn has_type(&self) -> bool {
120 self.arr_type.is_some()
121 }
122 pub fn set_type(&mut self, ele_type: Types) {
123 self.arr_type = Some(ele_type);
124 }
125}