use std::collections::HashMap;
use std::fmt;
use std::fmt::Write;
use std::hash::Hash;
use std::str::FromStr;
use std::string::String;
mod fmtstr;
mod formatter;
#[cfg(test)]
mod tests;
mod types;
#[macro_use]
mod fmtnum;
mod macros;
pub use fmtstr::strfmt_map;
pub use formatter::Formatter;
pub use types::{Alignment, FmtError, Result, Sign};
fmtint!(u8 i8 u16 i16 u32 i32 u64 i64 usize isize);
fmtfloat!(f32 f64);
pub fn strfmt<'a, K, T: DisplayStr>(fmtstr: &str, vars: &HashMap<K, T>) -> Result<String>
where
K: Hash + Eq + FromStr,
{
let formatter = |mut fmt: Formatter| {
let k: K = match fmt.key.parse() {
Ok(k) => k,
Err(_) => {
return Err(new_key_error(fmt.key));
}
};
let v = match vars.get(&k) {
Some(v) => v,
None => {
return Err(new_key_error(fmt.key));
}
};
v.display_str(&mut fmt)
};
strfmt_map(fmtstr, &formatter)
}
#[deprecated(
since = "0.2.0",
note = "This function contains a bug when formatting numbers. Use strfmt instead"
)]
pub fn strfmt_display<'a, K, T: fmt::Display>(fmtstr: &str, vars: &HashMap<K, T>) -> Result<String>
where
K: Hash + Eq + FromStr,
{
let formatter = |mut fmt: Formatter| {
let k: K = match fmt.key.parse() {
Ok(k) => k,
Err(_) => {
return Err(new_key_error(fmt.key));
}
};
let v = match vars.get(&k) {
Some(v) => v,
None => {
return Err(new_key_error(fmt.key));
}
};
fmt.str(v.to_string().as_str())
};
strfmt_map(fmtstr, &formatter)
}
macro_rules! display_str_impl {
($($t:ident)*) => ($(
impl DisplayStr for $t {
fn display_str(&self,f:&mut Formatter) -> Result<()> {
f.$t(*self)
}
}
)*)
}
display_str_impl!(u8 i8 u16 i16 u32 i32 u64 i64 usize isize);
display_str_impl!(f32 f64);
impl DisplayStr for String {
fn display_str(&self, f: &mut Formatter) -> Result<()> {
f.str(self.as_str())
}
}
impl DisplayStr for &str {
fn display_str(&self, f: &mut Formatter) -> Result<()> {
f.str(self)
}
}
impl DisplayStr for &dyn DisplayStr {
fn display_str(&self, f: &mut Formatter) -> Result<()> {
(*self).display_str(f)
}
}
impl DisplayStr for Box<dyn DisplayStr> {
fn display_str(&self, f: &mut Formatter) -> Result<()> {
self.as_ref().display_str(f)
}
}
pub trait DisplayStr {
fn display_str(&self, f: &mut Formatter) -> Result<()>;
}
pub trait Format {
fn format<K, D: DisplayStr>(&self, vars: &HashMap<K, D>) -> Result<String>
where
K: Hash + Eq + FromStr;
#[deprecated(
since = "0.2.0",
note = "This function contains a bug when formatting numbers. Use format instead"
)]
fn format_display<K, D: fmt::Display>(&self, vars: &HashMap<K, D>) -> Result<String>
where
K: Hash + Eq + FromStr;
}
impl Format for String {
fn format<'a, K, D: DisplayStr>(&self, vars: &HashMap<K, D>) -> Result<String>
where
K: Hash + Eq + FromStr,
{
strfmt(self.as_str(), vars)
}
fn format_display<'a, K, D: fmt::Display>(&self, vars: &HashMap<K, D>) -> Result<String>
where
K: Hash + Eq + FromStr,
{
#[allow(deprecated)]
strfmt_display(self.as_str(), vars)
}
}
impl Format for str {
fn format<K, D: DisplayStr>(&self, vars: &HashMap<K, D>) -> Result<String>
where
K: Hash + Eq + FromStr,
{
strfmt(self, vars)
}
fn format_display<'a, K, D: fmt::Display>(&self, vars: &HashMap<K, D>) -> Result<String>
where
K: Hash + Eq + FromStr,
{
#[allow(deprecated)]
strfmt_display(self, vars)
}
}
fn new_key_error(key: &str) -> FmtError {
let mut msg = String::new();
write!(msg, "Invalid key: {}", key).unwrap();
FmtError::KeyError(msg)
}