use rustledger_core::{
Amount, Balance, Close, Commodity, CostSpec, Custom, Document, Event, IncompleteAmount,
MetaValue, Note, Open, Pad, Posting, Price, PriceAnnotation, Query, Transaction,
};
use crate::types::{
AmountData, BalanceData, CloseData, CommodityData, CostData, CustomData, DocumentData,
EventData, MetaValueData, NoteData, OpenData, PadData, PostingData, PriceAnnotationData,
PriceData, QueryData, TransactionData,
};
pub(super) fn transaction_to_data(txn: &Transaction) -> TransactionData {
TransactionData {
flag: txn.flag.to_string(),
payee: txn.payee.as_ref().map(ToString::to_string),
narration: txn.narration.to_string(),
tags: txn.tags.iter().map(ToString::to_string).collect(),
links: txn.links.iter().map(ToString::to_string).collect(),
metadata: txn
.meta
.iter()
.map(|(k, v)| (k.clone(), meta_value_to_data(v)))
.collect(),
postings: txn.postings.iter().map(posting_to_data).collect(),
}
}
pub(super) fn posting_to_data(posting: &Posting) -> PostingData {
PostingData {
account: posting.account.to_string(),
units: posting.units.as_ref().and_then(incomplete_amount_to_data),
cost: posting.cost.as_ref().map(cost_to_data),
price: posting.price.as_ref().map(price_annotation_to_data),
flag: posting.flag.map(|c| c.to_string()),
metadata: posting
.meta
.iter()
.map(|(k, v)| (k.clone(), meta_value_to_data(v)))
.collect(),
}
}
pub(super) fn incomplete_amount_to_data(incomplete: &IncompleteAmount) -> Option<AmountData> {
match incomplete {
IncompleteAmount::Complete(amount) => Some(amount_to_data(amount)),
IncompleteAmount::CurrencyOnly(currency) => Some(AmountData {
number: String::new(), currency: currency.to_string(),
}),
IncompleteAmount::NumberOnly(number) => Some(AmountData {
number: number.to_string(),
currency: String::new(), }),
}
}
pub(super) fn amount_to_data(amount: &Amount) -> AmountData {
AmountData {
number: amount.number.to_string(),
currency: amount.currency.to_string(),
}
}
pub(super) fn cost_to_data(cost: &CostSpec) -> CostData {
CostData {
number_per: cost.number_per.map(|n| n.to_string()),
number_total: cost.number_total.map(|n| n.to_string()),
currency: cost.currency.as_ref().map(ToString::to_string),
date: cost.date.map(|d| d.to_string()),
label: cost.label.clone(),
merge: cost.merge,
}
}
pub(super) fn price_annotation_to_data(price: &PriceAnnotation) -> PriceAnnotationData {
match price {
PriceAnnotation::Unit(amount) => PriceAnnotationData {
is_total: false,
amount: Some(amount_to_data(amount)),
number: None,
currency: None,
},
PriceAnnotation::Total(amount) => PriceAnnotationData {
is_total: true,
amount: Some(amount_to_data(amount)),
number: None,
currency: None,
},
PriceAnnotation::UnitIncomplete(inc) => PriceAnnotationData {
is_total: false,
amount: inc.as_amount().map(amount_to_data),
number: inc.number().map(|n| n.to_string()),
currency: inc.currency().map(String::from),
},
PriceAnnotation::TotalIncomplete(inc) => PriceAnnotationData {
is_total: true,
amount: inc.as_amount().map(amount_to_data),
number: inc.number().map(|n| n.to_string()),
currency: inc.currency().map(String::from),
},
PriceAnnotation::UnitEmpty => PriceAnnotationData {
is_total: false,
amount: None,
number: None,
currency: None,
},
PriceAnnotation::TotalEmpty => PriceAnnotationData {
is_total: true,
amount: None,
number: None,
currency: None,
},
}
}
pub(super) fn meta_value_to_data(value: &MetaValue) -> MetaValueData {
match value {
MetaValue::String(s) => MetaValueData::String(s.clone()),
MetaValue::Number(n) => MetaValueData::Number(n.to_string()),
MetaValue::Date(d) => MetaValueData::Date(d.to_string()),
MetaValue::Account(a) => MetaValueData::Account(a.clone()),
MetaValue::Currency(c) => MetaValueData::Currency(c.clone()),
MetaValue::Tag(t) => MetaValueData::Tag(t.clone()),
MetaValue::Link(l) => MetaValueData::Link(l.clone()),
MetaValue::Amount(a) => MetaValueData::Amount(amount_to_data(a)),
MetaValue::Bool(b) => MetaValueData::Bool(*b),
MetaValue::None => MetaValueData::String(String::new()),
}
}
pub(super) fn balance_to_data(bal: &Balance) -> BalanceData {
BalanceData {
account: bal.account.to_string(),
amount: amount_to_data(&bal.amount),
tolerance: bal.tolerance.map(|t| t.to_string()),
metadata: bal
.meta
.iter()
.map(|(k, v)| (k.clone(), meta_value_to_data(v)))
.collect(),
}
}
pub(super) fn open_to_data(open: &Open) -> OpenData {
OpenData {
account: open.account.to_string(),
currencies: open.currencies.iter().map(ToString::to_string).collect(),
booking: open.booking.clone(),
metadata: open
.meta
.iter()
.map(|(k, v)| (k.clone(), meta_value_to_data(v)))
.collect(),
}
}
pub(super) fn close_to_data(close: &Close) -> CloseData {
CloseData {
account: close.account.to_string(),
metadata: close
.meta
.iter()
.map(|(k, v)| (k.clone(), meta_value_to_data(v)))
.collect(),
}
}
pub(super) fn commodity_to_data(comm: &Commodity) -> CommodityData {
CommodityData {
currency: comm.currency.to_string(),
metadata: comm
.meta
.iter()
.map(|(k, v)| (k.clone(), meta_value_to_data(v)))
.collect(),
}
}
pub(super) fn pad_to_data(pad: &Pad) -> PadData {
PadData {
account: pad.account.to_string(),
source_account: pad.source_account.to_string(),
metadata: pad
.meta
.iter()
.map(|(k, v)| (k.clone(), meta_value_to_data(v)))
.collect(),
}
}
pub(super) fn event_to_data(event: &Event) -> EventData {
EventData {
event_type: event.event_type.clone(),
value: event.value.clone(),
metadata: event
.meta
.iter()
.map(|(k, v)| (k.clone(), meta_value_to_data(v)))
.collect(),
}
}
pub(super) fn note_to_data(note: &Note) -> NoteData {
NoteData {
account: note.account.to_string(),
comment: note.comment.clone(),
metadata: note
.meta
.iter()
.map(|(k, v)| (k.clone(), meta_value_to_data(v)))
.collect(),
}
}
pub(super) fn document_to_data(doc: &Document) -> DocumentData {
DocumentData {
account: doc.account.to_string(),
path: doc.path.clone(),
metadata: doc
.meta
.iter()
.map(|(k, v)| (k.clone(), meta_value_to_data(v)))
.collect(),
}
}
pub(super) fn price_to_data(price: &Price) -> PriceData {
PriceData {
currency: price.currency.to_string(),
amount: amount_to_data(&price.amount),
metadata: price
.meta
.iter()
.map(|(k, v)| (k.clone(), meta_value_to_data(v)))
.collect(),
}
}
pub(super) fn query_to_data(query: &Query) -> QueryData {
QueryData {
name: query.name.clone(),
query: query.query.clone(),
metadata: query
.meta
.iter()
.map(|(k, v)| (k.clone(), meta_value_to_data(v)))
.collect(),
}
}
pub(super) fn custom_to_data(custom: &Custom) -> CustomData {
CustomData {
custom_type: custom.custom_type.clone(),
values: custom.values.iter().map(meta_value_to_data).collect(),
metadata: custom
.meta
.iter()
.map(|(k, v)| (k.clone(), meta_value_to_data(v)))
.collect(),
}
}