tomcat/src/main.rs

134 lines
4.2 KiB
Rust

// Copyright (c) 2022 Emma Tebibyte
// SPDX-License-Identifier: AGPL-3.0-or-later
/* Tomcat is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* Tomcat is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
* details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see https://www.gnu.org/licenses/.
*/
use std::env;
use std::fs::File;
use std::io::Read;
use std::path::Path;
use exit_no_std::exit;
use std::str::FromStr;
use toml::Value;
fn main() {
let mut arguments: Vec<String> = env::args().collect();
let argv0 = arguments.remove(0);
if arguments[1].is_empty() {
eprintln!("Usage: {} [table...].[value[index]] [file...]", argv0);
exit(64); // sysexits(3) EX_USAGE
}
let input = &arguments[1];
let mut content = String::new();
let file = Path::new(&input);
if file.is_file() {
File::open(file).unwrap().read_to_string(&mut content).unwrap();
} else { content = input.to_string(); }
let mut tabkey: Vec<&str> = arguments[0].split(".").collect();
let mut indexvec = Vec::new();
let mut index: usize = 0;
match tabkey.iter().skip(1).peekable().peek() {
Some(_) => {
indexvec = tabkey[1].split(&['[', ']'][..]).collect();
tabkey[1] = indexvec.remove(0);
if ! indexvec.is_empty() {
let istr = indexvec.remove(0);
match usize::from_str(istr) {
Ok(i) => index = i,
Err(_) => {
eprintln!("{}: {}: Cannot index by given value.", argv0, istr);
exit(64); // sysexits(3) EX_USAGE
},
};
}
},
None => {},
};
let mut root = content.parse::<Value>().unwrap();
let mut out = String::new();
let mut valiter = tabkey.iter().peekable();
while let Some(item) = valiter.next() {
match root.get(item) {
Some(value) => {
match value {
// TODO: Implement other type parsing
Value::Array(array) => {
match valiter.peek() {
Some(_) => {
eprintln!("{}: {}: Not a table.", argv0, item);
exit(65); // sysexits(3) EX_DATAERR
},
None => {
match array.get(index) {
Some(element) => {
match element.as_str() {
Some(val) => out.push_str(val),
None => {
eprintln!(
"{}: {:?}: No value at given index.", argv0, index
);
exit(65); // sysexits(3) EX_DATAERR
},
};
},
None => {
eprintln!(
"{}: {:?}: No value at given index.", argv0, index
);
exit(65); // sysexits(3) EX_DATAERR
},
};
},
};
},
Value::Boolean(_boolean) => {},
Value::Datetime(_datetime) => {},
Value::Float(_float) => {},
Value::Integer(_int) => {},
Value::String(string) => {
match valiter.peek() {
Some(_) => {
eprintln!("{}: {}: Not a table.", argv0, item);
exit(65); // sysexits(3) EX_DATAERR
},
None => out.push_str(string.as_str()),
};
},
Value::Table(table) => {
match valiter.peek() {
Some(_) => {
root = toml::Value::Table(table.to_owned());
},
None => {}, // out.push_str(table.as_str()),
};
},
};
},
None => {
eprintln!("{}: {}: No such table or key.", argv0, item);
exit(65); // sysexits(3) EX_DATAERR
},
};
}
println!("{}", out);
}