make stuff more portable and improve the cli #4

Merged
mossfet merged 7 commits from portability into main 2023-07-02 10:39:30 +00:00
14 changed files with 464 additions and 76 deletions

24
.vscode/launch.json vendored
View file

@ -4,13 +4,17 @@
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "lldb",
"request": "launch",
"name": "Debug",
"program": "${workspaceFolder}/<executable file>",
"args": [],
"cwd": "${workspaceFolder}"
}
]
}
{
"type": "lldb",
"request": "launch",
"name": "run meowy-cli",
"program": "${workspaceFolder}/target/debug/meowy-cli",
"args": ["print"],
"cwd": "${workspaceFolder}",
"sourceMap": {},
"sourceLanguages": [
"rust"
],
}
]
}

176
Cargo.lock generated
View file

@ -53,7 +53,7 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b"
dependencies = [
"windows-sys",
"windows-sys 0.48.0",
]
[[package]]
@ -63,7 +63,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "180abfa45703aebe0093f79badacc01b8fd4ea2e35118747e5811127f926e188"
dependencies = [
"anstyle",
"windows-sys",
"windows-sys 0.48.0",
]
[[package]]
@ -253,9 +253,11 @@ name = "cli"
version = "0.1.0"
dependencies = [
"clap",
"log",
"serde",
"serde_json",
"shared",
"simple_logger",
]
[[package]]
@ -337,6 +339,27 @@ dependencies = [
"crypto-common",
]
[[package]]
name = "directories"
version = "5.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a49173b84e034382284f27f1af4dcbbd231ffa358c0fe316541a7337f376a35"
dependencies = [
"dirs-sys",
]
[[package]]
name = "dirs-sys"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c"
dependencies = [
"libc",
"option-ext",
"redox_users",
"windows-sys 0.48.0",
]
[[package]]
name = "either"
version = "1.8.1"
@ -366,7 +389,7 @@ checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a"
dependencies = [
"errno-dragonfly",
"libc",
"windows-sys",
"windows-sys 0.48.0",
]
[[package]]
@ -653,7 +676,7 @@ checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2"
dependencies = [
"hermit-abi 0.3.1",
"libc",
"windows-sys",
"windows-sys 0.48.0",
]
[[package]]
@ -665,7 +688,7 @@ dependencies = [
"hermit-abi 0.3.1",
"io-lifetimes",
"rustix",
"windows-sys",
"windows-sys 0.48.0",
]
[[package]]
@ -744,11 +767,13 @@ version = "0.1.0"
dependencies = [
"askama",
"askama_rocket",
"log",
"rocket",
"rust-embed",
"serde",
"serde_json",
"shared",
"simple_logger",
]
[[package]]
@ -790,7 +815,7 @@ checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2"
dependencies = [
"libc",
"wasi",
"windows-sys",
"windows-sys 0.48.0",
]
[[package]]
@ -858,6 +883,12 @@ version = "1.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
[[package]]
name = "option-ext"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d"
[[package]]
name = "overload"
version = "0.1.1"
@ -882,7 +913,7 @@ checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447"
dependencies = [
"cfg-if",
"libc",
"redox_syscall",
"redox_syscall 0.3.5",
"smallvec",
"windows-targets",
]
@ -995,6 +1026,15 @@ dependencies = [
"getrandom",
]
[[package]]
name = "redox_syscall"
version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
dependencies = [
"bitflags 1.3.2",
]
[[package]]
name = "redox_syscall"
version = "0.3.5"
@ -1004,6 +1044,17 @@ dependencies = [
"bitflags 1.3.2",
]
[[package]]
name = "redox_users"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b"
dependencies = [
"getrandom",
"redox_syscall 0.2.16",
"thiserror",
]
[[package]]
name = "ref-cast"
version = "1.0.16"
@ -1187,7 +1238,7 @@ dependencies = [
"io-lifetimes",
"libc",
"linux-raw-sys",
"windows-sys",
"windows-sys 0.48.0",
]
[[package]]
@ -1287,6 +1338,8 @@ dependencies = [
name = "shared"
version = "0.1.0"
dependencies = [
"directories",
"log",
"serde",
"serde_json",
]
@ -1300,6 +1353,16 @@ dependencies = [
"libc",
]
[[package]]
name = "simple_logger"
version = "4.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2230cd5c29b815c9b699fb610b49a5ed65588f3509d9f0108be3a885da629333"
dependencies = [
"log",
"windows-sys 0.42.0",
]
[[package]]
name = "slab"
version = "0.4.8"
@ -1375,9 +1438,29 @@ dependencies = [
"autocfg",
"cfg-if",
"fastrand",
"redox_syscall",
"redox_syscall 0.3.5",
"rustix",
"windows-sys",
"windows-sys 0.48.0",
]
[[package]]
name = "thiserror"
version = "1.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
@ -1432,7 +1515,7 @@ dependencies = [
"signal-hook-registry",
"socket2",
"tokio-macros",
"windows-sys",
"windows-sys 0.48.0",
]
[[package]]
@ -1707,6 +1790,21 @@ dependencies = [
"windows-targets",
]
[[package]]
name = "windows-sys"
version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7"
dependencies = [
"windows_aarch64_gnullvm 0.42.2",
"windows_aarch64_msvc 0.42.2",
"windows_i686_gnu 0.42.2",
"windows_i686_msvc 0.42.2",
"windows_x86_64_gnu 0.42.2",
"windows_x86_64_gnullvm 0.42.2",
"windows_x86_64_msvc 0.42.2",
]
[[package]]
name = "windows-sys"
version = "0.48.0"
@ -1722,51 +1820,93 @@ version = "0.48.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
"windows_aarch64_gnullvm 0.48.0",
"windows_aarch64_msvc 0.48.0",
"windows_i686_gnu 0.48.0",
"windows_i686_msvc 0.48.0",
"windows_x86_64_gnu 0.48.0",
"windows_x86_64_gnullvm 0.48.0",
"windows_x86_64_msvc 0.48.0",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc"
[[package]]
name = "windows_aarch64_msvc"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
[[package]]
name = "windows_aarch64_msvc"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3"
[[package]]
name = "windows_i686_gnu"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
[[package]]
name = "windows_i686_gnu"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241"
[[package]]
name = "windows_i686_msvc"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
[[package]]
name = "windows_i686_msvc"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00"
[[package]]
name = "windows_x86_64_gnu"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
[[package]]
name = "windows_x86_64_gnu"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953"
[[package]]
name = "windows_x86_64_msvc"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
[[package]]
name = "windows_x86_64_msvc"
version = "0.48.0"

View file

@ -8,6 +8,9 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
log = "0.4"
[dependencies.rocket]
version = "=0.5.0-rc.3"
default_features = false
@ -38,3 +41,7 @@ default-features = false
[dependencies.shared]
path = "./shared"
[dependencies.simple_logger]
version = "4"
default-features = false

View file

@ -6,6 +6,7 @@ edition = "2021"
[dependencies]
serde = "1.0"
serde_json = "1.0"
log = "0.4"
[dependencies.clap]
version = "4"
@ -14,6 +15,10 @@ features = ["derive"]
[dependencies.shared]
path = "../shared"
[dependencies.simple_logger]
version = "4"
default-features = false
[[bin]]
name = "meowy-cli"
path = "src/main.rs"

View file

@ -3,8 +3,8 @@ use clap::{arg, command, Args, Parser, Subcommand};
#[derive(Parser, Debug)]
#[command(author, version, about, long_about = None)]
pub(crate) struct Arguments {
#[arg(help = "the path to the names.json file")]
pub(crate) path: String,
#[arg(help = "the path to the names.json file", long, short)]
pub(crate) path: Option<String>,
#[command(subcommand)]
pub(crate) command: Commands,
}
@ -13,8 +13,27 @@ pub(crate) struct Arguments {
pub(crate) enum Commands {
#[command(about = "print the current webring sites and their names")]
Print {
#[arg(help = "url you want to filter to")]
filter: Option<String>,
#[command(flatten)]
group: PrintGroup,
#[arg(
long,
short,
help = "a seperator character to seperate the url from the name. defaults to ,",
requires = "url",
requires = "name"
)]
seperator: Option<char>,
#[arg(
long,
short,
conflicts_with = "url",
conflicts_with = "name",
conflicts_with = "seperator",
help = "print the data out as a json string"
)]
json: bool,
},
#[command(about = "add a site to the webring")]
Add {
@ -48,8 +67,8 @@ pub(crate) enum Commands {
#[derive(Args, Debug)]
#[group(required = false)]
pub struct PrintGroup {
#[arg(long, short, action = clap::ArgAction::SetTrue, conflicts_with = "name", help = "print the url only")]
#[arg(long, short, action = clap::ArgAction::SetTrue, help = "print the url only")]
pub(crate) url: bool,
#[arg(long, short, action = clap::ArgAction::SetTrue, conflicts_with = "url", help = "print the name only")]
#[arg(long, short, action = clap::ArgAction::SetTrue, help = "print the name only")]
pub(crate) name: bool,
}

View file

@ -1,54 +1,141 @@
use shared::{
errors::{Error, ErrorStatus},
names::Site,
};
use std::path::Path;
use shared::errors::ErrorStatus;
use shared::names;
use shared::{errors::Error, names::Site};
use crate::arguments::PrintGroup;
fn read_names(path: &String) -> Result<Vec<Site>, Error> {
match std::fs::read_to_string(path) {
Ok(names) => {
return shared::names::load_names(names);
fn group_printing(seperator: &Option<char>, site: &Site, group: &PrintGroup) {
let mut string = String::new();
let delimiter = seperator.unwrap_or(',');
if group.url {
string += &site.url;
}
if group.name {
if !string.is_empty() {
string += &format!(
"{}{}",
delimiter,
site.name.as_ref().unwrap_or(&"None".into())
)
} else {
string += &site.name.as_ref().unwrap_or(&"None".into());
}
}
log::info!("{}", string);
}
fn json_printing(site: &Site) -> Result<(), Error> {
match serde_json::to_string(&site) {
Ok(json) => {
log::info!("{}", json);
Ok(())
}
Err(err) => Err(Error {
status: ErrorStatus::IOError,
status: ErrorStatus::ParsingError,
data: err.to_string(),
}),
}
}
pub(crate) fn print(path: &String, group: &PrintGroup) -> Result<(), Error> {
let names = read_names(path)?;
fn filter_site(
site: &Site,
json: bool,
seperator: &Option<char>,
group: &PrintGroup,
) -> Result<(), Error> {
if json {
json_printing(site)?;
return Ok(());
}
Ok(for site in names {
if group.name {
println!("{}", site.name.unwrap_or_default());
continue;
}
if group.url {
println!("{}", site.url);
continue;
}
println!("{:?}", site);
})
if !group.url && !group.name {
log::info!("{:?}", site);
return Ok(());
}
return Ok(group_printing(seperator, site, group));
}
pub(crate) fn add(path: &String, url: &String, name: &Option<String>) -> Result<(), Error> {
let mut names = read_names(path)?;
pub(crate) fn print(
path: &Path,
filter: &Option<String>,
group: &PrintGroup,
seperator: &Option<char>,
json: bool,
) -> Result<(), Error> {
let names_file = names::read_names_file(path)?;
let mut names = names::load_names(names_file)?;
if let Some(filter) = filter {
names.retain(|f| &f.url == filter);
if names.len() == 0 {
return Err(Error {
status: ErrorStatus::NotFoundError,
data: "this url was not found in names.json".into(),
});
}
return filter_site(&names[0], json, seperator, group);
}
for site in names {
if json {
json_printing(&site)?;
continue;
}
if !group.url && !group.name {
log::info!("{:?}", site);
continue;
}
group_printing(seperator, &site, group);
}
Ok(())
}
pub(crate) fn add(path: &Path, url: &String, name: &Option<String>) -> Result<(), Error> {
let names_file = names::read_names_file(path)?;
let mut names = names::load_names(names_file)?;
if names.iter().any(|site| site.url.contains(url)) {
return Err(Error {
status: ErrorStatus::AlreadyExistsError,
data:
"this url already exists in names.json. you can't have more then 1 of the same url."
.into(),
});
}
let site = Site {
url: url.to_string(),
name: name.to_owned(),
};
names.push(site);
log::debug!("adding {:?} to {}", site, path.display());
names.push(site.clone());
let json = serde_json::to_string(&names).unwrap();
std::fs::write(path, json).unwrap();
log::info!("added {:?} to names.json", site);
Ok(())
}
pub(crate) fn remove(path: &String, url: &String) -> Result<(), Error> {
let mut names = read_names(path)?;
names.retain(|site| &site.url != url);
pub(crate) fn remove(path: &Path, url: &String) -> Result<(), Error> {
let names_file = names::read_names_file(path)?;
let mut names = names::load_names(names_file)?;
names.retain(|site| {
if &site.url == url {
log::info!("removing {:?} from names.json", site);
}
&site.url != url
});
let json = serde_json::to_string(&names).unwrap();
std::fs::write(path, json).unwrap();
Ok(())
}

18
cli/src/logging.rs Normal file
View file

@ -0,0 +1,18 @@
use log::LevelFilter;
use shared::errors::{Error, ErrorStatus};
use simple_logger::SimpleLogger;
pub fn initialize_logger() -> Result<(), Error> {
if let Err(err) = SimpleLogger::new()
.with_level(LevelFilter::Info)
.env()
.init()
{
return Err(Error {
status: ErrorStatus::LoggerInitializationError,
data: err.to_string(),
});
}
Ok(())
}

View file

@ -1,18 +1,28 @@
use std::path::Path;
use arguments::{Arguments, Commands};
use clap::Parser;
use commands::{add, print, remove};
use shared::errors::Error;
use shared::{directories, errors::Error};
mod arguments;
mod commands;
mod logging;
fn main() -> Result<(), Error> {
fn main() -> Result<(), Error> {
logging::initialize_logger()?;
let default_path = directories::get_names_path()?;
let args = Arguments::parse();
let path = match &args.path {
Some(path) => Path::new(path),
None => &default_path,
};
match &args.command {
Commands::Print { group } => print(&args.path, &group)?,
Commands::Add { url, name } => add(&args.path, url, name)?,
Commands::Remove { url } => remove(&args.path, url)?,
Commands::Print { filter, group, seperator, json, } => print(path, filter, group, seperator, *json)?,
Commands::Add { url, name } => add(path, url, name)?,
Commands::Remove { url } => remove(path, url)?,
};
Ok(())

View file

@ -5,6 +5,8 @@ edition = "2021"
[dependencies]
serde_json = "1.0"
directories = "5.0"
log = "0.4"
[dependencies.serde]
version = "1.0"

40
shared/src/directories.rs Normal file
View file

@ -0,0 +1,40 @@
use std::path::{Path, PathBuf};
use directories::ProjectDirs;
use crate::errors::{Error, ErrorStatus, DIRECTORIES_ERROR_MESSAGE};
pub fn get_project_dir() -> Result<ProjectDirs, Error> {
match ProjectDirs::from("moe", "solarpunk", "meowy-webring") {
Some(project) => Ok(project),
None => Err(Error {
status: ErrorStatus::DirectoriesError,
data: DIRECTORIES_ERROR_MESSAGE.into(),
}),
}
}
pub fn get_file_from_directory(path: &Path, filename: &str) -> Result<PathBuf, Error> {
if !path.exists() {
create_directory(path)?;
}
Ok(path.join(filename))
}
pub fn get_names_path() -> Result<PathBuf, Error> {
let directory = get_project_dir()?;
return get_file_from_directory(directory.data_dir(), "names.json");
}
fn create_directory(path: &Path) -> Result<(), Error> {
match std::fs::create_dir_all(path) {
Ok(_) => {
log::debug!("created the directory {}", path.display());
Ok(())
}
Err(err) => Err(Error {
status: ErrorStatus::IOError,
data: err.to_string(),
}),
}
}

View file

@ -1,16 +1,26 @@
#[derive(Debug)]
pub enum ErrorStatus {
IOError,
ParsingError
ParsingError,
DirectoriesError,
LoggerInitializationError,
NotFoundError,
AlreadyExistsError
}
pub struct Error {
pub status: ErrorStatus,
pub data: String
pub data: String,
}
pub(crate) static DIRECTORIES_ERROR_MESSAGE: &str = "could not retreive a valid home path from the operating system. maybe try to define the HOME enviroment variable if you\'re on a unix or unix like operating system.";
impl core::fmt::Debug for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "A {:?} error has occured.\nDetails: {}", self.status, self.data)
}
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"A {:?} error has occured.\nDetails: {}",
self.status, self.data
)
}
}

View file

@ -1,2 +1,3 @@
pub mod names;
pub mod errors;
pub mod directories;

View file

@ -1,8 +1,8 @@
use serde::{Deserialize, Serialize};
use crate::errors::{Error, ErrorStatus};
use serde::{Deserialize, Serialize};
use std::path::Path;
#[derive(Serialize, Deserialize, Debug)]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Site {
pub url: String,
pub name: Option<String>,
@ -10,10 +10,50 @@ pub struct Site {
pub fn load_names(names: String) -> Result<Vec<Site>, Error> {
match serde_json::from_str::<Vec<Site>>(&names) {
Ok(content) => Ok(content),
Ok(content) => {
log::debug!("successfully parsed names.json.");
Ok(content)
}
Err(err) => Err(Error {
status: ErrorStatus::ParsingError,
data: err.to_string(),
}),
}
}
pub fn read_names_file(path: &Path) -> Result<String, Error> {
if !path.exists() {
log::debug!(
"the names.json file does not exist at {}. creating names.json",
path.display()
);
create_names_file(path)?
}
match std::fs::read_to_string(path) {
Ok(data) => {
log::debug!(
"successfully read the names.json file at {}",
path.display()
);
Ok(data)
}
Err(err) => Err(Error {
status: ErrorStatus::IOError,
data: err.to_string(),
}),
}
}
fn create_names_file(path: &Path) -> Result<(), Error> {
match std::fs::write(path, "[]") {
Ok(_) => {
log::debug!("created a names.json file at {}", path.display());
Ok(())
}
Err(err) => Err(Error {
status: ErrorStatus::IOError,
data: err.to_string(),
}),
}
}

View file

@ -1,3 +1,5 @@
use shared::{directories, names};
#[macro_use]
extern crate rocket;
@ -7,8 +9,11 @@ mod routes;
#[launch]
fn rocket() -> _ {
let names_file = std::fs::read_to_string("names.json").unwrap();
let names = shared::names::load_names(names_file).unwrap();
let names_path = directories::get_names_path().unwrap();
println!("names.json path: {}", names_path.display());
let names_file = names::read_names_file(&names_path).unwrap();
let names = names::load_names(names_file).unwrap();
rocket::build()
.manage(names)
.mount(