use super::{FormatConfig, escape_string, format_amount, format_meta_value};
use crate::{
Balance, Close, Commodity, Custom, Document, Event, Metadata, Note, Open, Pad, Price, Query,
};
use std::fmt::Write;
pub(super) fn format_metadata(meta: &Metadata, indent: &str, out: &mut String) {
let mut keys: Vec<_> = meta.keys().collect();
keys.sort();
for key in keys {
let value = &meta[key];
writeln!(out, "{indent}{}: {}", key, format_meta_value(value))
.expect("write to String is infallible");
}
}
pub fn format_balance(bal: &Balance, config: &FormatConfig) -> String {
let mut out = format!(
"{} balance {} {}",
bal.date,
bal.account,
format_amount(&bal.amount)
);
if let Some(tol) = &bal.tolerance {
write!(out, " ~ {tol}").expect("write to String is infallible");
}
out.push('\n');
format_metadata(&bal.meta, &config.indent, &mut out);
out
}
pub fn format_open(open: &Open, config: &FormatConfig) -> String {
let mut out = format!("{} open {}", open.date, open.account);
if !open.currencies.is_empty() {
write!(out, " {}", open.currencies.join(",")).expect("write to String is infallible");
}
if let Some(booking) = &open.booking {
write!(out, " \"{booking}\"").expect("write to String is infallible");
}
out.push('\n');
format_metadata(&open.meta, &config.indent, &mut out);
out
}
pub fn format_close(close: &Close, config: &FormatConfig) -> String {
let mut out = format!("{} close {}\n", close.date, close.account);
format_metadata(&close.meta, &config.indent, &mut out);
out
}
pub fn format_commodity(comm: &Commodity, config: &FormatConfig) -> String {
let mut out = format!("{} commodity {}\n", comm.date, comm.currency);
format_metadata(&comm.meta, &config.indent, &mut out);
out
}
pub fn format_pad(pad: &Pad, config: &FormatConfig) -> String {
let mut out = format!("{} pad {} {}\n", pad.date, pad.account, pad.source_account);
format_metadata(&pad.meta, &config.indent, &mut out);
out
}
pub fn format_event(event: &Event, config: &FormatConfig) -> String {
let mut out = format!(
"{} event \"{}\" \"{}\"\n",
event.date,
escape_string(&event.event_type),
escape_string(&event.value)
);
format_metadata(&event.meta, &config.indent, &mut out);
out
}
pub fn format_query(query: &Query, config: &FormatConfig) -> String {
let mut out = format!(
"{} query \"{}\" \"{}\"\n",
query.date,
escape_string(&query.name),
escape_string(&query.query)
);
format_metadata(&query.meta, &config.indent, &mut out);
out
}
pub fn format_note(note: &Note, config: &FormatConfig) -> String {
let mut out = format!(
"{} note {} \"{}\"\n",
note.date,
note.account,
escape_string(¬e.comment)
);
format_metadata(¬e.meta, &config.indent, &mut out);
out
}
pub fn format_document(doc: &Document, config: &FormatConfig) -> String {
let mut out = format!(
"{} document {} \"{}\"\n",
doc.date,
doc.account,
escape_string(&doc.path)
);
format_metadata(&doc.meta, &config.indent, &mut out);
out
}
pub fn format_price(price: &Price, config: &FormatConfig) -> String {
let mut out = format!(
"{} price {} {}\n",
price.date,
price.currency,
format_amount(&price.amount)
);
format_metadata(&price.meta, &config.indent, &mut out);
out
}
pub fn format_custom(custom: &Custom, config: &FormatConfig) -> String {
let mut out = format!(
"{} custom \"{}\"",
custom.date,
escape_string(&custom.custom_type)
);
for value in &custom.values {
write!(out, " {}", format_meta_value(value)).expect("write to String is infallible");
}
out.push('\n');
format_metadata(&custom.meta, &config.indent, &mut out);
out
}