diff options
| author | 魏曹先生 <1992414357@qq.com> | 2026-04-17 00:00:04 +0800 |
|---|---|---|
| committer | 魏曹先生 <1992414357@qq.com> | 2026-04-17 00:00:04 +0800 |
| commit | 0816230e8712948df451fee7aee48537efe043cb (patch) | |
| tree | 749d581dfd8f3e6c7e535108eb16803102466774 /src/bill.rs | |
| parent | 6e36fc3707e791c3c748133d648957706b54fd3a (diff) | |
Add edit command with table serialization support
Diffstat (limited to 'src/bill.rs')
| -rw-r--r-- | src/bill.rs | 69 |
1 files changed, 68 insertions, 1 deletions
diff --git a/src/bill.rs b/src/bill.rs index e03cd22..4b66554 100644 --- a/src/bill.rs +++ b/src/bill.rs @@ -3,7 +3,7 @@ use std::collections::BTreeMap; use serde::{Deserialize, Serialize}; use uuid::Uuid; -use crate::who::Who; +use crate::{display::SimpleTable, string_vec, who::Who}; #[derive(Debug, Default, Serialize, Deserialize)] pub struct Bills { @@ -169,3 +169,70 @@ impl SplitResult { self.final_result.get(&(payer, payee)).copied() } } + +impl Bills { + pub fn table(self) -> String { + let mut table = SimpleTable::new(string_vec![ + "#", "Who", "|", "Paid", "|", "Split", "|", "Reason" + ]); + let mut items: Vec<_> = self.items.into_iter().collect(); + items.sort_by(|a, b| { + b.1.paid + .partial_cmp(&a.1.paid) + .unwrap_or(std::cmp::Ordering::Equal) + }); + for (_, items) in items { + let split = items + .split + .iter() + .map(|i| i.to_string()) + .collect::<Vec<String>>() + .join(", "); + table.push_item(string_vec![ + "", + items.who_paid, + "|", + items.paid, + "|", + split, + "|", + items.reason + ]); + } + table.to_string() + } + + pub fn from_table_str(table_str: impl Into<String>) -> Bills { + let mut bills = Bills::default(); + let table_str = table_str.into(); + + for line in table_str.lines() { + let line = line.trim(); + if line.is_empty() || line.starts_with('#') { + continue; + } + + let parts: Vec<&str> = line.split('|').map(|s| s.trim()).collect(); + if parts.len() != 4 { + continue; + } + + let who_paid = parts[0]; + let paid_str = parts[1]; + let split_str = parts[2]; + let reason = parts[3]; + + let paid = paid_str.parse::<f64>().unwrap_or(0.0); + + let split: Vec<&str> = split_str + .split(',') + .map(|s| s.trim()) + .filter(|s| !s.is_empty()) + .collect(); + + bills.add_bill(who_paid, reason, paid, split); + } + + bills + } +} |
