made the code so much more readable
This commit is contained in:
parent
35401c4bbc
commit
7157c70b1f
@ -1,10 +0,0 @@
|
||||
[unstable]
|
||||
build-std = [ "std", "panic_abort" ]
|
||||
build-std-features = [ "panic_immediate_abort" ]
|
||||
|
||||
[profile.release]
|
||||
strip = true # strip symbols from the binary
|
||||
opt-level = "z" # optimize for size
|
||||
lto = true # link time optimization
|
||||
codegen-units = 1 # decrease parallelization
|
||||
panic = "abort"
|
217
Cargo.lock
generated
217
Cargo.lock
generated
@ -3,16 +3,83 @@
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "exit-no-std"
|
||||
version = "0.1.3"
|
||||
name = "bindgen"
|
||||
version = "0.63.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4a608ccc67fac78c1916aa88ad75d6f6a3e353521844abce906c22a45d161d99"
|
||||
checksum = "36d860121800b2a9a94f9b5604b332d5cffb234ce17609ea479d723dbc9d3885"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"pc-ints",
|
||||
"winapi",
|
||||
"bitflags",
|
||||
"cexpr",
|
||||
"clang-sys",
|
||||
"lazy_static",
|
||||
"lazycell",
|
||||
"log",
|
||||
"peeking_take_while",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"regex",
|
||||
"rustc-hash",
|
||||
"shlex",
|
||||
"syn",
|
||||
"which",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "cexpr"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766"
|
||||
dependencies = [
|
||||
"nom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "clang-sys"
|
||||
version = "1.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "77ed9a53e5d4d9c573ae844bfac6872b159cb1d1585a83b29e7a64b7eef7332a"
|
||||
dependencies = [
|
||||
"glob",
|
||||
"libc",
|
||||
"libloading",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91"
|
||||
|
||||
[[package]]
|
||||
name = "glob"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "lazycell"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.138"
|
||||
@ -20,10 +87,96 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "db6d7e329c562c5dfab7a46a2afabc8b987ab9a4834c9d1ca04dc54c1546cef8"
|
||||
|
||||
[[package]]
|
||||
name = "pc-ints"
|
||||
version = "0.1.4"
|
||||
name = "libloading"
|
||||
version = "0.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "422b0cc3a966f6e0987d2f948c234585bd917a1f16df1470e60c56ad6de2c085"
|
||||
checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
|
||||
|
||||
[[package]]
|
||||
name = "minimal-lexical"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
||||
|
||||
[[package]]
|
||||
name = "nom"
|
||||
version = "7.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
"minimal-lexical",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.17.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3"
|
||||
|
||||
[[package]]
|
||||
name = "peeking_take_while"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.51"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5d727cae5b39d21da60fa540906919ad737832fe0b1c165da3a34d6548c849d6"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "48aaa5748ba571fb95cd2c85c09f629215d3a6ece942baa100950af03a34f733"
|
||||
dependencies = [
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.6.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-hash"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
@ -31,12 +184,29 @@ version = "1.0.148"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e53f64bb4ba0191d6d0676e1b141ca55047d83b74f5607e6d8eb88126c52c2dc"
|
||||
|
||||
[[package]]
|
||||
name = "shlex"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.109"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tomcat"
|
||||
version = "0.0.1"
|
||||
dependencies = [
|
||||
"exit-no-std",
|
||||
"toml",
|
||||
"yacexits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -48,6 +218,23 @@ dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc"
|
||||
|
||||
[[package]]
|
||||
name = "which"
|
||||
version = "4.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2441c784c52b289a054b7201fc93253e288f094e2f4be9058343127c4226a269"
|
||||
dependencies = [
|
||||
"either",
|
||||
"libc",
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
@ -69,3 +256,13 @@ name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
[[package]]
|
||||
name = "yacexits"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b3afbe270dff95fe94b3a55c7e2dce91457a89b2b0dc6013814bba9806d099be"
|
||||
dependencies = [
|
||||
"bindgen",
|
||||
"libc",
|
||||
]
|
||||
|
@ -6,5 +6,5 @@ license = "AGPL-3.0-or-later"
|
||||
authors = [ "Emma Tebibyte <emma@tebibyte.media>" ]
|
||||
|
||||
[dependencies]
|
||||
exit-no-std = "0.1.3"
|
||||
toml = "0.5.9"
|
||||
yacexits = "0.1.2"
|
||||
|
@ -1,2 +0,0 @@
|
||||
[toolchain]
|
||||
channel = "nightly"
|
257
src/main.rs
257
src/main.rs
@ -1,12 +1,13 @@
|
||||
// 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.
|
||||
/*
|
||||
* Copyright (c) 2022 Emma Tebibyte
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*
|
||||
* This program 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
|
||||
* This program 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.
|
||||
@ -15,119 +16,173 @@
|
||||
* 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 std::{
|
||||
env,
|
||||
fs::File,
|
||||
io::{
|
||||
Read,
|
||||
stdin,
|
||||
},
|
||||
iter::Peekable,
|
||||
path::Path,
|
||||
str::FromStr,
|
||||
};
|
||||
|
||||
use toml::Value;
|
||||
use yacexits::*;
|
||||
|
||||
fn parse_toml(
|
||||
mut root: Value,
|
||||
mut tabkey: Peekable<std::slice::Iter<'_, &str>>,
|
||||
index: Option<usize>,
|
||||
) -> Result<String, (String, u32)> {
|
||||
let mut out = String::new();
|
||||
|
||||
while let Some(item) = tabkey.next() {
|
||||
let value = match root.get(item) {
|
||||
Some(val) => val,
|
||||
None => {
|
||||
return Err((format!("{}: No such table or key.", item), EX_DATAERR));
|
||||
},
|
||||
};
|
||||
|
||||
match value {
|
||||
Value::Table(table) => {
|
||||
match tabkey.peek() {
|
||||
Some(_) => {
|
||||
root = toml::Value::Table(table.to_owned());
|
||||
continue;
|
||||
},
|
||||
None => {}, // out.push_str(table.as_str()),
|
||||
};
|
||||
},
|
||||
_ => {
|
||||
match tabkey.peek() {
|
||||
Some(_) => {
|
||||
return Err((format!("{}: Not a table.", item), EX_DATAERR));
|
||||
},
|
||||
None => {},
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
match value {
|
||||
// TODO: Implement other type parsing
|
||||
Value::Array(array) => {
|
||||
let element: String;
|
||||
match index {
|
||||
Some(i) => {
|
||||
element = match array.get(i) {
|
||||
Some(element) => {
|
||||
match element.as_str() {
|
||||
Some(val) => val.to_owned(),
|
||||
None => {
|
||||
return Err((
|
||||
format!("{:?}: No value at given key.", index),
|
||||
EX_DATAERR
|
||||
));
|
||||
},
|
||||
}
|
||||
},
|
||||
None => {
|
||||
return Err(
|
||||
(format!("{:?}: No value at given index.", i), EX_DATAERR)
|
||||
);
|
||||
},
|
||||
};
|
||||
},
|
||||
None => element = format!("{:?}", array),
|
||||
};
|
||||
out.push_str(&element);
|
||||
},
|
||||
Value::Boolean(_boolean) => {},
|
||||
Value::Datetime(_datetime) => {},
|
||||
Value::Float(_float) => {},
|
||||
Value::Integer(_int) => {},
|
||||
Value::String(string) => out.push_str(string.as_str()),
|
||||
_ => return Err((format!("{:?}: No such key.", item), EX_DATAERR)),
|
||||
};
|
||||
}
|
||||
Ok(out)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut arguments: Vec<String> = env::args().collect();
|
||||
let argv0 = arguments.remove(0);
|
||||
if arguments.is_empty() {
|
||||
eprintln!("Usage: {} [table...].[value[index]] [file...]", argv0);
|
||||
let argv: Vec<String> = env::args().collect();
|
||||
|
||||
if argv.len() <= 1 {
|
||||
eprintln!("Usage: {} [table...].[value[index]] [file...]", argv[0]);
|
||||
exit(64); // sysexits(3) EX_USAGE
|
||||
}
|
||||
let input = &arguments[1];
|
||||
let mut content = String::new();
|
||||
|
||||
let input = match argv.get(2) {
|
||||
Some(val) => val,
|
||||
None => {
|
||||
eprintln!("Usage: {} [table...].[value[index]] [file...]", argv[0]);
|
||||
exit(EX_USAGE);
|
||||
},
|
||||
};
|
||||
let mut content = Vec::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();
|
||||
if input == &"-" {
|
||||
match stdin().lock().read_to_end(&mut content) {
|
||||
Ok(_) => {},
|
||||
Err(_) => {
|
||||
eprintln!("{}: Could not read from standard input.", argv[0]);
|
||||
exit(EX_OSERR);
|
||||
},
|
||||
};
|
||||
} else {
|
||||
match File::open(file).unwrap().read_to_end(&mut content) {
|
||||
Ok(_) => {},
|
||||
Err(_) => {
|
||||
eprintln!("{}: {:?}: No such file or directory.", argv[0], file);
|
||||
exit(EX_UNAVAILABLE);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
let mut tabkey: Vec<&str> = argv[1].split(".").collect();
|
||||
let mut indexvec = Vec::new();
|
||||
let mut index: usize = 0;
|
||||
let mut index: Option<usize> = None;
|
||||
|
||||
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
|
||||
if ! indexvec.is_empty() {
|
||||
let istr = indexvec.remove(0);
|
||||
match usize::from_str(istr) {
|
||||
Ok(i) => index = Some(i),
|
||||
Err(_) => {
|
||||
eprintln!("{}: {}: Cannot index by given value.", argv[0], istr);
|
||||
exit(EX_USAGE);
|
||||
},
|
||||
};
|
||||
}
|
||||
println!("{}", out);
|
||||
|
||||
let root = match String::from_utf8(content).unwrap().parse::<Value>() {
|
||||
Ok(toml) => toml,
|
||||
Err(_) => {
|
||||
eprintln!("{}: Unable to parse TOML.", argv[0]);
|
||||
exit(EX_DATAERR);
|
||||
},
|
||||
};
|
||||
|
||||
let valiter = tabkey.iter().peekable();
|
||||
println!(
|
||||
"{}",
|
||||
match parse_toml(root, valiter, index) {
|
||||
Ok(val) => val,
|
||||
Err((err, code)) => {
|
||||
eprintln!("{}: {}", argv[0], err);
|
||||
exit(code);
|
||||
},
|
||||
},
|
||||
);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user