initial commit

master
Avril 3 years ago
commit f16bf876e2
Signed by: flanchan
GPG Key ID: 284488987C31F630

2
.gitignore vendored

@ -0,0 +1,2 @@
/target
*~

14
Cargo.lock generated

@ -0,0 +1,14 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "units"
version = "0.1.0"
dependencies = [
"lazy_static",
]

@ -0,0 +1,10 @@
[package]
name = "units"
version = "0.1.0"
authors = ["Avril <flanchan@cumallover.me>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
lazy_static = "1.4.0"

@ -0,0 +1,62 @@
use std::{fmt, error};
pub fn prog_name() -> &'static str
{
lazy_static! {
static ref NAME: String = std::env::args().next().unwrap();
}
&NAME[..]
}
/// Print usage then exit with error code `0`.
pub fn usage() -> !
{
println!("Unit conversion v{}", env!("CARGO_PKG_VERSION"));
println!(" by {} with <3 (license GPL3+)", env!("CARGO_PKG_AUTHORS"));
println!();
println!("usage: {} <unit> <value>", prog_name());
println!("usage: {} --help", prog_name());
println!();
//TODO: generalise units
println!(r#"Units:
BYTES\t\tConvert byte unit into single bytes"#);
std::process::exit(0)
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum Operation
{
Help,
Convert(String, String),
}
#[inline] pub fn parse_args() -> Result<Operation, ArgParseError>
{
parse(std::env::args().skip(1))
}
fn parse<T: Into<String>>(from: impl IntoIterator<Item = T>) -> Result<Operation, ArgParseError>
{
let mut from = from.into_iter().map(Into::into);
let first = from.next().ok_or(ArgParseError)?;
match first.to_lowercase().trim() {
"--help" => Ok(Operation::Help),
_ => {
Ok(Operation::Convert(first, from.next().ok_or(ArgParseError)?))
},
}
}
#[derive(Debug)]
pub struct ArgParseError;
impl error::Error for ArgParseError{}
impl fmt::Display for ArgParseError
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
{
write!(f, "Failed to parse args. Try passing `--help`.")
}
}

@ -0,0 +1,16 @@
use super::*;
#[derive(Debug)]
pub struct Bytes;
impl Conversion for Bytes
{
const UNIT: &'static str = "bytes";
type Output = u64;
fn convert(&self, input: &str) -> Result<Self::Output, Self::Error>
{
}
}

@ -0,0 +1,46 @@
use std::error;
use std::fmt;
use std::convert::Infallible;
pub mod bytes;
pub trait Conversion
{
const UNIT: &'static str;
type Output: fmt::Display;
type Error: Into<ConversionError> = ConversionError;
fn convert(&self, input: &str) -> Result<Self::Output, Self::Error>;
}
#[derive(Debug)]
pub struct ConversionError(String);
impl error::Error for ConversionError{}
impl fmt::Display for ConversionError
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
{
write!(f, "conversion failed: {}", self.0)
}
}
impl From<Infallible> for ConversionError
{
fn from(from: Infallible) -> Self
{
match from {}
}
}
/// Dispatch a conversion of `value` for type `unit` and print the result to stdout.
pub fn dispatch_out(unit: impl AsRef<str>, value: impl AsRef<str>) -> Result<(), ConversionError>
{
match unit.as_ref() {
bytes::Bytes::UNIT => println!("{}", bytes::Bytes.convert(value.as_ref())?),
name => return Err(ConversionError(format!("Unknown unit {}", name))),
}
Ok(())
}

@ -0,0 +1,29 @@
#![feature(associated_type_defaults)]
#[macro_use] extern crate lazy_static;
#[macro_export] macro_rules! unwrap {
($err:expr) => {
match $err {
Ok(v) => v,
Err(e) => {
eprintln!("Error: {}", e);
std::process::exit(1);
}
}
};
}
mod arg;
mod conv;
fn main() {
use arg::Operation;
match unwrap!(arg::parse_args()) {
Operation::Help => arg::usage(),
Operation::Convert(unit, from) => {
unwrap!(conv::dispatch(unit, from));
},
}
}
Loading…
Cancel
Save