Initialize Twilight project, set up basic framework, initialize DB module
This commit is contained in:
@@ -0,0 +1,222 @@
|
||||
use std::{fmt, ops::{Deref, DerefMut}};
|
||||
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum ArgumentParsingError {
|
||||
#[error("This argument was missing in the arguments array")]
|
||||
MissingArgument,
|
||||
|
||||
#[error("An argument was there but it could not be parsed into the specified value")]
|
||||
InvalidArgument,
|
||||
}
|
||||
|
||||
pub trait FromArguments: Sized {
|
||||
fn from_args(args: &str) -> Result<(Self, &str), ArgumentParsingError>;
|
||||
}
|
||||
|
||||
impl FromArguments for String {
|
||||
fn from_args(args: &str) -> Result<(Self, &str), ArgumentParsingError> {
|
||||
if !args.is_empty() {
|
||||
match args.split_once(" ") {
|
||||
Some((arg, rest)) => Ok((arg.to_string(), rest)),
|
||||
None => Ok((args.to_string(), "")),
|
||||
}
|
||||
} else {
|
||||
Ok((args.to_string(), ""))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct GreedyString(pub String);
|
||||
|
||||
impl FromArguments for GreedyString {
|
||||
fn from_args<'a>(args: &str) -> Result<(Self, &str), ArgumentParsingError> {
|
||||
let value = GreedyString(args.to_string());
|
||||
|
||||
Ok((value, ""))
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for GreedyString {
|
||||
type Target = String;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl DerefMut for GreedyString {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
&mut self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for GreedyString {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
self.0.fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct NeedyString(pub String);
|
||||
|
||||
impl Deref for NeedyString {
|
||||
type Target = String;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl DerefMut for NeedyString {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
&mut self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for NeedyString {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
self.0.fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl FromArguments for NeedyString {
|
||||
fn from_args(args: &str) -> Result<(Self, &str), ArgumentParsingError> {
|
||||
if !args.is_empty() {
|
||||
match args.split_once(" ") {
|
||||
Some((arg, rest)) => Ok((Self(arg.to_string()), rest)),
|
||||
None => Ok((Self(args.to_string()), "")),
|
||||
}
|
||||
} else {
|
||||
Err(ArgumentParsingError::MissingArgument)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FromArguments for bool {
|
||||
fn from_args(args: &str) -> Result<(Self, &str), ArgumentParsingError> {
|
||||
let arg: &str;
|
||||
let rest: &str;
|
||||
|
||||
match args.split_once(" ") {
|
||||
Some((a, b)) => {
|
||||
arg = a;
|
||||
rest = b;
|
||||
}
|
||||
None => {
|
||||
arg = args;
|
||||
rest = "";
|
||||
}
|
||||
}
|
||||
|
||||
match arg {
|
||||
"y" | "yes" | "on" | "true" | "t" | "1" => Ok((true, rest)),
|
||||
"n" | "no" | "off" | "false" | "f" | "0" => Ok((false, rest)),
|
||||
_ => Err(ArgumentParsingError::InvalidArgument),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> FromArguments for Option<T>
|
||||
where
|
||||
T: FromArguments,
|
||||
{
|
||||
fn from_args(args: &str) -> Result<(Self, &str), ArgumentParsingError> {
|
||||
match T::from_args(args) {
|
||||
Ok((result, rest)) => Ok((Some(result), rest)),
|
||||
Err(_) => Ok((None, args)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait ParseArguments: Sized {
|
||||
fn parse(args: &str) -> Result<Self, ArgumentParsingError>;
|
||||
}
|
||||
|
||||
impl ParseArguments for () {
|
||||
fn parse(_: &str) -> Result<Self, ArgumentParsingError> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<A> ParseArguments for A
|
||||
where
|
||||
A: FromArguments,
|
||||
{
|
||||
fn parse(args: &str) -> Result<Self, ArgumentParsingError> {
|
||||
let (a, _) = A::from_args(args)?;
|
||||
|
||||
Ok(a)
|
||||
}
|
||||
}
|
||||
|
||||
impl<A> ParseArguments for (A,)
|
||||
where
|
||||
A: FromArguments,
|
||||
{
|
||||
fn parse(args: &str) -> Result<Self, ArgumentParsingError> {
|
||||
let (a, _) = A::from_args(args)?;
|
||||
|
||||
Ok((a,))
|
||||
}
|
||||
}
|
||||
|
||||
impl<A, B> ParseArguments for (A, B)
|
||||
where
|
||||
A: FromArguments,
|
||||
B: FromArguments,
|
||||
{
|
||||
fn parse(args: &str) -> Result<Self, ArgumentParsingError> {
|
||||
let (a, args) = A::from_args(args)?;
|
||||
let (b, _) = B::from_args(args)?;
|
||||
|
||||
Ok((a, b))
|
||||
}
|
||||
}
|
||||
|
||||
impl<A, B, C> ParseArguments for (A, B, C)
|
||||
where
|
||||
A: FromArguments,
|
||||
B: FromArguments,
|
||||
C: FromArguments,
|
||||
{
|
||||
fn parse(args: &str) -> Result<Self, ArgumentParsingError> {
|
||||
let (a, args) = A::from_args(args)?;
|
||||
let (b, args) = B::from_args(args)?;
|
||||
let (c, _) = C::from_args(args)?;
|
||||
|
||||
Ok((a, b, c))
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Argument {
|
||||
pub name: &'static str,
|
||||
pub is_optional: bool,
|
||||
pub is_greedy: bool,
|
||||
}
|
||||
|
||||
impl fmt::Display for Argument {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
let mut argument = String::new();
|
||||
|
||||
if self.is_optional {
|
||||
argument.push('[');
|
||||
} else {
|
||||
argument.push('<');
|
||||
}
|
||||
|
||||
argument.push_str(self.name);
|
||||
|
||||
if self.is_greedy {
|
||||
argument.push_str("...");
|
||||
}
|
||||
|
||||
if self.is_optional {
|
||||
argument.push(']');
|
||||
} else {
|
||||
argument.push('>');
|
||||
}
|
||||
|
||||
write!(f, "{argument}")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user