// 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 = 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::().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); }