Skip to content

Commit

Permalink
Release v0.2.0
Browse files Browse the repository at this point in the history
  • Loading branch information
Zachary Dziura committed Mar 16, 2018
1 parent 01e8097 commit 26aecf2
Show file tree
Hide file tree
Showing 6 changed files with 397 additions and 81 deletions.
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,12 @@ Cargo.lock
# These are backup files generated by rustfmt
**/*.rs.bk

### VisualStudioCode ###
.vscode/
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
.history

# End of https://www.gitignore.io/api/rust
8 changes: 6 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "sterling"
version = "0.1.0"
version = "0.2.0"
description = "Converts a given D&D 5e currency value to the Silver Standard."
authors = ["Zachary Dziura <zcdziura@gmail.com>"]
readme = "README.md"
Expand All @@ -12,6 +12,10 @@ keywords = ["dnd", "coins", "converter", "currency", "5e"]
clap = "2.31.1"
lazy_static = "1.0.0"
regex = "0.2"
serde = "1.0"
serde_derive = "1.0"
serde_yaml = "0.7"

[profile.release]
lto = true
lto = true
panic = "abort"
57 changes: 49 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,20 @@ and [I make Silver Standard for 5th Edition (Spreadsheets.)](https://www.reddit.
## Usage

```
sterling [VALUE]...
USAGE:
sterling.exe [FLAGS] [OPTIONS] [VALUE]...
FLAGS:
-f, --full Print currencies with full name, rather than with alias.
-h, --help Prints help information
-V, --version Prints version information
OPTIONS:
-c, --config <CONFIG> Specify location of config file; defaults to './sterling-conf.yml'.
ARGS:
<VALUE>... The value to be converted; should be suffixed with the coin's short-hand
abbreviation, i.e. p, g, e, s, or c. Defaults coin type to 'g'.
abbreviation, i.e. p, g, e, s, or c.
```

## Examples
Expand All @@ -25,16 +30,52 @@ ARGS:
sterling 100p // 10g
// Convert one hundred platinum, fifty gold coins:
sterling 100p 50g // 10g 5s
sterling 100p 50g // 10g, 5s
// Convert fifteen thousand copper coins, printing the full names of the coins:
sterling -f 15000c // 1 gold, 50 silver
// Convert fifteen thousand copper coins:
sterling 15000c // 1g 50s
// Convert one platinum, thirty-six gold, twelve electrum, eighty-two silver, and four hundred
// sixty-nine copper coins, printing the full names of the coins
sterling --full 1p 36g 12e 82s 469c // 64 silver, 89 copper
// Convert one platinum, thirty-six gold, twelve electrum, eighty-two silver, and four hundred
// sixty-nine copper coins
sterling 1p 36g 12e 82s 469c // 64s 89c
// sixty-nine copper coins, printing the full names of the coins, using the custom config file
// detailed below.
sterling --full -c "~/Documents/D&D/sterling-conf.yml" 1p 36g 12e 82s 469c // 27 sterling, 9 farthing
```

## Custom Currencies

`sterling` allows for user-defined currencies, with their own names and conversion rates. By
default, `sterling` will look at a file within the current directory called `sterling-conf.yml`, or
in whatever location as supplied by the `-c` flag. Below is an example `sterling-conf.yml` file,
showing the actual currencies that I use within my own campaign!

```
-
name: "florin"
rate: 8640
alias: "F"
-
name: "sterling"
rate: 240
alias: "s"
-
name: "penny"
rate: 12
alias: "p"
plural: "pence"
-
name: "farthing"
rate: 1
alias: "f"
```

Please note that the `rate` value is defined as the number of copper coins that goes into one of
that particular currency. In the example above, twelve copper coins goes into one "penny", and
two-hundred forty copper coins goes into one "sterling".

## Abstract

Items and expenses are, by default, assigned arbitrary currency values within the official D&D 5th
Expand All @@ -46,7 +87,7 @@ campaign aught to treat gold similarly!

## Explanation

The basis of the Silver Standard treats 1 gold coin from the official D&D 5e source books as 1
The basis of the Silver Standard treats one gold coin from the official D&D 5e source books as one
silver coin, and that there are one hundred of a given coin to every one of the next highest valued
coin. That's all. Thus, one hundred fifty copper coins equals one silver and fifty copper coins,
while a suit of heavy plate armor equals fifteen gold coins, rather than fifteen hundred.
Expand Down
62 changes: 62 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
use std::error::Error;
use std::fmt::{self, Display, Formatter};
use std::convert::From;
use std::fs::File;
use std::io::{self, BufReader, ErrorKind};

use serde_yaml;

use currency::Currency;

pub fn load_config(filename: &str) -> Result<Vec<Currency>, ConfigError> {
let config_file = File::open(filename)?;
let mut configs: Vec<Currency> = serde_yaml::from_reader(BufReader::new(config_file))?;
configs.sort_by(|a, b| b.cmp(a));

Ok(configs)
}

pub fn default_config() -> Vec<Currency> {
vec![
Currency::new("platinum", 1000000, "p", None),
Currency::new("gold", 10000, "g", None),
Currency::new("silver", 100, "s", None),
Currency::new("copper", 1, "c", None),
]
}

#[derive(Debug)]
pub struct ConfigError {
desc: String,
pub kind: ErrorKind,
}

impl Display for ConfigError {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
write!(f, "Sterling Error: {}", self.desc)
}
}

impl Error for ConfigError {
fn description(&self) -> &str {
&self.desc
}
}

impl From<io::Error> for ConfigError {
fn from(error: io::Error) -> Self {
ConfigError {
desc: error.description().to_owned(),
kind: error.kind(),
}
}
}

impl From<serde_yaml::Error> for ConfigError {
fn from(error: serde_yaml::Error) -> Self {
ConfigError {
desc: error.description().to_owned(),
kind: ErrorKind::Other,
}
}
}
73 changes: 73 additions & 0 deletions src/currency.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
use std::cmp::Ordering;

#[derive(Clone, Debug, Eq, Serialize, Deserialize)]
pub struct Currency {
pub name: String,
pub rate: usize,
pub value: Option<usize>,
pub alias: String,
pub plural: Option<String>,
}

impl Currency {
pub fn new(name: &str, rate: usize, alias: &str, plural: Option<String>) -> Currency {
Currency {
name: name.to_owned(),
rate,
value: None,
alias: alias.to_owned(),
plural,
}
}

pub fn with_value(&mut self, value: usize) -> Currency {
Currency {
name: self.name.clone(),
rate: self.rate,
value: Some(value),
alias: self.alias.clone(),
plural: self.plural.clone(),
}
}

pub fn alias_display(&self) -> String {
self.value.unwrap_or(0).to_string() + &self.alias
}

pub fn full_display(&self) -> String {
let mut display = self.value.unwrap_or(0).to_string() + " ";

if self.value.unwrap_or(0) > 1 {
match &self.plural {
&Some(ref plural) => display = display + &plural,
&None => display = display + &self.name,
}
} else {
display = display + &self.name;
}

display
}
}

// impl Display for Currency {
// fn
// }

impl Ord for Currency {
fn cmp(&self, other: &Currency) -> Ordering {
self.value.cmp(&other.value)
}
}

impl PartialOrd for Currency {
fn partial_cmp(&self, other: &Currency) -> Option<Ordering> {
Some(self.cmp(other))
}
}

impl PartialEq for Currency {
fn eq(&self, other: &Currency) -> bool {
self.value == other.value
}
}
Loading

0 comments on commit 26aecf2

Please sign in to comment.