aboutsummaryrefslogtreecommitdiff
path: root/src/bill.rs
diff options
context:
space:
mode:
author魏曹先生 <1992414357@qq.com>2026-04-17 00:00:04 +0800
committer魏曹先生 <1992414357@qq.com>2026-04-17 00:00:04 +0800
commit0816230e8712948df451fee7aee48537efe043cb (patch)
tree749d581dfd8f3e6c7e535108eb16803102466774 /src/bill.rs
parent6e36fc3707e791c3c748133d648957706b54fd3a (diff)
Add edit command with table serialization support
Diffstat (limited to 'src/bill.rs')
-rw-r--r--src/bill.rs69
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
+ }
+}