#![deny(
missing_docs,
trivial_casts,
trivial_numeric_casts,
unstable_features,
unused_import_braces,
unused_qualifications
)]
#[cfg(feature = "parsing")]
extern crate regex;
#[cfg(feature = "serialization")]
extern crate serde;
#[cfg(feature = "serialization")]
extern crate serde_json;
#[cfg(feature = "serialization")]
#[macro_use]
extern crate serde_derive;
use std::default::Default;
pub type Symbol = char;
pub mod display;
pub mod math;
#[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Eq)]
#[cfg_attr(feature = "serialization", derive(Serialize))]
pub struct Currency {
pub symbol: Option<Symbol>,
pub value: i64,
}
impl Currency {
#[inline]
pub fn new() -> Currency {
Currency {
symbol: None,
value: 0,
}
}
pub fn from_value(value: i64) -> Currency {
Currency {
symbol: None,
value,
}
}
#[cfg(feature = "parsing")]
pub fn from_string(s: &str) -> Option<Currency> {
use regex::Regex;
let s = s.trim();
let re =
Regex::new(r"^(?:\b|(-)?)(\p{Currency_Symbol})?((?:(?:\d{1,3}[\.,])+\d{3})|\d+)(?:[\.,](\d{2}))?\b$")
.unwrap();
let mut multiplier = 1;
let mut sign: Option<Symbol> = None;
let coin_str: String;
match re.captures(s) {
None => return None,
Some(caps) => {
if caps.get(1).is_some() {
multiplier = -1;
}
if caps.get(2).is_some() {
if multiplier < 0 {
sign = Some(s.chars().skip(1).next().unwrap());
} else {
sign = Some(s.chars().next().unwrap());
}
}
coin_str = caps
.get(3)
.map(|m| m.as_str())
.unwrap()
.replace(".", "")
.replace(",", "")
+ caps.get(4).map(|m| m.as_str()).unwrap_or("00");
}
}
if let Ok(coin) = coin_str.parse::<i64>() {
return Some(Currency {
symbol: sign,
value: multiplier * coin,
});
}
None
}
pub fn postfix(&self) -> Postfix<'_> {
Postfix { money: self }
}
pub fn prefix(&self) -> Prefix<'_> {
Prefix { money: self }
}
pub fn as_float(&self) -> f64 {
self.value as f64 / 100.0
}
pub fn value(&self) -> i64 {
self.value
}
pub fn symbol(&self) -> Option<Symbol> {
self.symbol
}
}
use std::ops::Deref;
impl Deref for Currency {
type Target = i64;
fn deref(&self) -> &i64 {
&self.value
}
}
impl From<i64> for Currency {
fn from(value: i64) -> Currency {
Currency::from_value(value)
}
}
impl From<(Symbol, i64)> for Currency {
fn from(tpl: (Symbol, i64)) -> Currency {
let (symbol, cents) = tpl;
Currency {
symbol: Some(symbol),
value: cents,
}
}
}
impl From<(i64, Symbol)> for Currency {
fn from(tpl: (i64, Symbol)) -> Currency {
let (cents, symbol) = tpl;
Currency {
symbol: Some(symbol),
value: cents,
}
}
}
impl Default for Currency {
fn default() -> Self {
Currency {
symbol: None,
value: 0,
}
}
}
pub struct Postfix<'a> {
money: &'a Currency,
}
pub struct Prefix<'a> {
money: &'a Currency,
}