use crate::stringifier::Stringifier;
use crate::toml::auto_correct::AutoCorrect;
use crate::{ArrayOfTable, Level, Log, Opt, Table, NEW_LINE};
#[derive(Clone)]
pub enum KindOfTable {
Table(Table),
ArrayOfTable(ArrayOfTable),
}
#[derive(Clone)]
pub struct InternalTable {
pub base_name: String,
pub table: KindOfTable,
}
impl InternalTable {
pub fn from_table(table: &Table) -> Self {
InternalTable {
base_name: table.base_name.to_string(),
table: KindOfTable::Table(table.clone()),
}
}
pub fn from_sub_table(name: &str, sub_table: &Table) -> Self {
InternalTable {
base_name: name.to_string(),
table: KindOfTable::Table(sub_table.clone()),
}
}
pub fn from_aot(name: &str, aot: &ArrayOfTable) -> Self {
InternalTable {
base_name: name.to_string(),
table: KindOfTable::ArrayOfTable(aot.clone()),
}
}
pub fn create_log_level_kv_pair(table: &Table) -> String {
let message = if table.message_trailing_newline {
format!("{}{}", table.message, NEW_LINE)
} else {
table.message.to_string()
};
format!(
"{} = {}
",
table.level,
Stringifier::format_str_value(&message)
)
}
pub fn stringify(&self) -> String {
let toml = &mut String::new();
let indent_spaces = &mut String::new();
InternalTable::stringify_sub_table(
toml,
indent_spaces,
None,
match &self.table {
KindOfTable::Table(table) => Some(InternalTable::create_log_level_kv_pair(&table)),
KindOfTable::ArrayOfTable(_) => None,
},
&self,
);
toml.push_str(
"
",
);
toml.to_string()
}
pub fn stringify_sub_table(
toml: &mut String,
indent_spaces: &mut String,
parent: Option<&str>,
log_level_kv_pair: Option<String>,
i_table: &InternalTable,
) {
let path = &format!(
"{}{}",
if let Some(parent) = parent {
format!("{}.", parent).to_string()
} else {
"".to_string()
},
i_table.base_name
);
match &i_table.table {
KindOfTable::Table(k_table) => {
toml.push_str(&indent_spaces);
toml.push_str(&format!(
"[{}]
",
path
));
if let Some(log_level_kv_pair) = log_level_kv_pair {
toml.push_str(&log_level_kv_pair);
}
if let Some(sorted_map) = &k_table.sorted_map {
for (k2, formatted_v) in sorted_map {
toml.push_str(&indent_spaces);
toml.push_str(&format!(
"{} = {}
",
k2, formatted_v
));
}
}
if let Some(sub_tables) = &k_table.sub_tables {
indent_spaces.push_str(" ");
for (_k1, sub_i_table) in sub_tables {
InternalTable::stringify_sub_table(
toml,
indent_spaces,
Some(path),
None,
sub_i_table,
);
}
indent_spaces.pop();
indent_spaces.pop();
}
}
KindOfTable::ArrayOfTable(k_aot) => {
for (i, sibling_table) in k_aot.tables.iter().enumerate() {
toml.push_str(&indent_spaces);
toml.push_str(&format!(
"[[{}]]
",
path
));
if let Some(sorted_map) = &sibling_table.sorted_map {
for (k2, formatted_v) in sorted_map {
toml.push_str(&indent_spaces);
toml.push_str(&format!(
"{} = {}
",
k2, formatted_v
));
}
}
if let Some(sub_tables) = &sibling_table.sub_tables {
indent_spaces.push_str(" ");
for (_k1, sub_i_table) in sub_tables {
InternalTable::stringify_sub_table(
toml,
indent_spaces,
Some(&format!("{}.{}", path, i)),
None,
sub_i_table,
);
}
indent_spaces.pop();
indent_spaces.pop();
}
}
}
}
}
}
impl Default for ArrayOfTable {
fn default() -> Self {
ArrayOfTable { tables: Vec::new() }
}
}
impl ArrayOfTable {
pub fn table(&mut self, table: &Table) -> &mut Self {
self.tables.push(table.clone());
self
}
}
impl Default for Table {
fn default() -> Self {
Table {
base_name: "".to_string(),
level: Level::Trace,
message: "".to_string(),
message_trailing_newline: false,
sorted_map: None,
sub_tables: None,
}
}
}
impl Table {
pub fn bool<'a>(&'a mut self, key: &'a str, value: bool) -> &'a mut Self {
let mut old = None;
self.get_sorted_map(|sorted_map| {
old = sorted_map.insert(
AutoCorrect::correct_key(key),
value.to_string(),
);
});
if let Some(old) = old {
Table::print_already_use(key, &old, &value.to_string());
}
self
}
pub fn char<'a>(&'a mut self, key: &'a str, value: char) -> &'a mut Self {
let mut old = None;
self.get_sorted_map(|sorted_map| {
old = sorted_map.insert(
AutoCorrect::correct_key(key),
Stringifier::format_str_value(&value.to_string()).to_string(),
);
});
if let Some(old) = old {
Table::print_already_use(key, &old, &value.to_string());
}
self
}
pub fn float<'a>(&'a mut self, key: &'a str, value: f64) -> &'a mut Self {
let mut old = None;
self.get_sorted_map(|sorted_map| {
old = sorted_map.insert(
AutoCorrect::correct_key(key),
value.to_string(),
);
});
if let Some(old) = old {
Table::print_already_use(key, &old, &value.to_string());
}
self
}
pub fn int<'a>(&'a mut self, key: &'a str, value: i128) -> &'a mut Self {
let mut old = None;
self.get_sorted_map(|sorted_map| {
old = sorted_map.insert(
AutoCorrect::correct_key(key),
value.to_string(),
);
});
if let Some(old) = old {
Table::print_already_use(key, &old, &value.to_string());
}
self
}
pub fn isize<'a>(&'a mut self, key: &'a str, value: isize) -> &'a mut Self {
let mut old = None;
self.get_sorted_map(|sorted_map| {
old = sorted_map.insert(
AutoCorrect::correct_key(key),
value.to_string(),
);
});
if let Some(old) = old {
Table::print_already_use(key, &old, &value.to_string());
}
self
}
pub fn literal<'a>(&'a mut self, key: &'a str, value: &str) -> &'a mut Self {
let mut old = None;
self.get_sorted_map(|sorted_map| {
old = sorted_map.insert(
AutoCorrect::correct_key(key),
value.to_string(),
);
});
if let Some(old) = old {
Table::print_already_use(key, &old, &value.to_string());
}
self
}
pub fn str<'a>(&'a mut self, key: &'a str, value: &str) -> &'a mut Self {
let mut old = None;
self.get_sorted_map(|sorted_map| {
old = sorted_map.insert(
AutoCorrect::correct_key(key),
Stringifier::format_str_value(value).to_string(),
);
});
if let Some(old) = old {
Table::print_already_use(key, &old, &value.to_string());
}
self
}
pub fn sub_t<'a>(&'a mut self, base_name: &str, sub_table: &Table) -> &'a mut Self {
let mut old = None;
self.get_sub_tables(|sub_i_tables| {
old = sub_i_tables.insert(
AutoCorrect::correct_key(base_name),
InternalTable::from_sub_table(&AutoCorrect::correct_key(base_name), &sub_table),
);
});
if let Some(_) = old {
Table::print_already_use(
&AutoCorrect::correct_key(base_name),
&"...Omitted...",
&"...Omitted...",
);
}
self
}
pub fn sub_aot<'a>(&'a mut self, base_name: &str, aot: &ArrayOfTable) -> &'a mut Self {
let mut old = None;
self.get_sub_tables(|sub_i_tables| {
old = sub_i_tables.insert(
AutoCorrect::correct_key(base_name),
InternalTable::from_aot(&AutoCorrect::correct_key(base_name), &aot),
);
});
if let Some(_) = old {
Table::print_already_use(
&AutoCorrect::correct_key(base_name),
&"...Omitted...",
&"...Omitted...",
);
}
self
}
pub fn uint<'a>(&'a mut self, key: &'a str, value: u128) -> &'a mut Self {
let mut old = None;
self.get_sorted_map(|sorted_map| {
old = sorted_map.insert(
AutoCorrect::correct_key(key),
value.to_string(),
);
});
if let Some(old) = old {
Table::print_already_use(key, &old, &value.to_string());
}
self
}
pub fn usize<'a>(&'a mut self, key: &'a str, value: usize) -> &'a mut Self {
let mut old = None;
self.get_sorted_map(|sorted_map| {
old = sorted_map.insert(
AutoCorrect::correct_key(key),
value.to_string(),
);
});
if let Some(old) = old {
Table::print_already_use(key, &old, &value.to_string());
}
self
}
fn print_already_use(key: &str, old: &str, value: &str) {
if let Ok(opt) = Log::get_opt() {
match opt {
Opt::BeginnersSupport | Opt::Development => {
println!(
"casual_logger | |{}| is already use. |{}| is is overwritten by |{}|.",
key, old, value
);
}
_ => {}
}
}
}
}