Browse Source

rustfmt pass.

Kestrel 2 tuần trước cách đây
mục cha
commit
9c4736b61d
6 tập tin đã thay đổi với 107 bổ sung59 xóa
  1. 10 7
      src/cmd.rs
  2. 4 1
      src/data.rs
  3. 2 2
      src/data/spec.rs
  4. 59 29
      src/import.rs
  5. 1 1
      src/main.rs
  6. 31 19
      src/show.rs

+ 10 - 7
src/cmd.rs

@@ -1,12 +1,11 @@
 use itertools::Itertools;
 
-use crate::{data,show,import::import_from};
-
+use crate::{data, import::import_from, show};
 
 #[derive(clap::Parser)]
 pub struct Invocation {
     /// path to treasure file
-    #[clap(long, short, env = "TREASURE_FILE")]
+    #[clap(long, short, env = "HOARD_ROOT")]
     pub file: std::path::PathBuf,
 
     /// verbosity of output messages
@@ -35,9 +34,14 @@ fn load_data(
 #[derive(clap::Subcommand)]
 pub enum Command {
     Summarize,
-    Ledger { account: String },
+    Ledger {
+        account: String,
+    },
     Reformat,
-    Import { account: String, from: std::path::PathBuf },
+    Import {
+        account: String,
+        from: std::path::PathBuf,
+    },
 }
 
 fn summarize(data: &data::Root) {
@@ -46,7 +50,7 @@ fn summarize(data: &data::Root) {
     let neutral = console::Style::new();
 
     let Some(maxlen) = data.account_names().map(|v| v.len()).max() else {
-        return 
+        return;
     };
 
     for shortname in data.account_names().sorted_by_key(|an| an.as_str()) {
@@ -77,7 +81,6 @@ fn summarize(data: &data::Root) {
             );
         }
     }
-    
 }
 
 impl Command {

+ 4 - 1
src/data.rs

@@ -103,7 +103,10 @@ pub struct Span {
 
 impl Default for Span {
     fn default() -> Self {
-        Self { range: (0,0), context: None }
+        Self {
+            range: (0, 0),
+            context: None,
+        }
     }
 }
 

+ 2 - 2
src/data/spec.rs

@@ -3,7 +3,7 @@ use std::collections::HashMap;
 use super::{AccountName, UnitName};
 
 #[derive(Debug, serde::Deserialize, PartialEq)]
-#[serde(deny_unknown_fields,rename_all="snake_case")]
+#[serde(deny_unknown_fields, rename_all = "snake_case")]
 pub enum CSVColumnSpec {
     Ignore,
     Datestamp,
@@ -27,7 +27,7 @@ pub struct CSVImportSpec {
 #[derive(Debug, serde::Deserialize)]
 #[serde(deny_unknown_fields, tag = "format")]
 pub enum ImportFileFormat {
-    CSV(CSVImportSpec)
+    CSV(CSVImportSpec),
 }
 
 #[derive(Debug, serde::Deserialize)]

+ 59 - 29
src/import.rs

@@ -1,4 +1,8 @@
-use crate::data::{AccountName, Datestamp, Decimal, spec::{AccountSpec, ImportFileFormat, CSVImportSpec, CSVColumnSpec}, ledger::{Change, Transaction}, Span, Spanned, UnitName};
+use crate::data::{
+    AccountName, Datestamp, Decimal, Span, Spanned, UnitName,
+    ledger::{Change, Transaction},
+    spec::{AccountSpec, CSVColumnSpec, CSVImportSpec, ImportFileFormat},
+};
 
 #[derive(Debug)]
 pub enum ImportError {
@@ -34,22 +38,37 @@ impl From<rust_decimal::Error> for ImportError {
 
 fn try_parse_decimal(from: &str) -> Result<Decimal, ImportError> {
     // remove any '$' or units from the string
-    let filtered = from.chars().filter(|f| char::is_digit(*f, 10) || *f == '.' || *f == '-').collect::<String>();
+    let filtered = from
+        .chars()
+        .filter(|f| char::is_digit(*f, 10) || *f == '.' || *f == '-')
+        .collect::<String>();
 
     Decimal::from_str_radix(filtered.as_str(), 10).map_err(Into::into)
 }
 
-fn import_from_csv(csv_spec: &CSVImportSpec, aspec: &AccountSpec, target: AccountName, mut reader: impl std::io::Read) -> Result<Vec<Transaction>, ImportError> {
+fn import_from_csv(
+    csv_spec: &CSVImportSpec,
+    aspec: &AccountSpec,
+    target: AccountName,
+    mut reader: impl std::io::Read,
+) -> Result<Vec<Transaction>, ImportError> {
     let mut csv_reader = csv::Reader::from_reader(reader);
 
     // validate CSV spec
     if !csv_spec.cols.contains(&CSVColumnSpec::Datestamp) {
-        return Err(ImportError::ConfigError("CSV config does not have a datestamp column".into()))
+        return Err(ImportError::ConfigError(
+            "CSV config does not have a datestamp column".into(),
+        ));
     }
 
     if !csv_spec.cols.contains(&CSVColumnSpec::Change) {
-        if !csv_spec.cols.contains(&CSVColumnSpec::Withdraw) || !csv_spec.cols.contains(&CSVColumnSpec::Deposit) {
-            return Err(ImportError::ConfigError("CSV config needs either a change column or both withdraw and deposit columns!".into()))
+        if !csv_spec.cols.contains(&CSVColumnSpec::Withdraw)
+            || !csv_spec.cols.contains(&CSVColumnSpec::Deposit)
+        {
+            return Err(ImportError::ConfigError(
+                "CSV config needs either a change column or both withdraw and deposit columns!"
+                    .into(),
+            ));
         }
     }
 
@@ -64,54 +83,58 @@ fn import_from_csv(csv_spec: &CSVImportSpec, aspec: &AccountSpec, target: Accoun
     for record in csv_reader.records() {
         let record = record?;
 
-        let mut txn_datestamp : Option<Datestamp> = None;
-        let mut txn_title : Option<String> = None;
-        let mut txn_change : Option<Decimal> = None;
-        let mut txn_balance : Option<Decimal> = None;
-        let mut txn_unit : Option<UnitName> = None;
+        let mut txn_datestamp: Option<Datestamp> = None;
+        let mut txn_title: Option<String> = None;
+        let mut txn_change: Option<Decimal> = None;
+        let mut txn_balance: Option<Decimal> = None;
+        let mut txn_unit: Option<UnitName> = None;
 
         for (record, spec) in record.iter().zip(csv_spec.cols.iter()) {
             match spec {
                 CSVColumnSpec::Ignore => (),
                 CSVColumnSpec::Datestamp => {
                     let date = date_parser.parse(record)?.date()?;
-                    txn_datestamp = Some(Datestamp { year: date.year() as u16, month: date.month(), day: date.day() });
-                },
+                    txn_datestamp = Some(Datestamp {
+                        year: date.year() as u16,
+                        month: date.month(),
+                        day: date.day(),
+                    });
+                }
                 CSVColumnSpec::Title => {
                     txn_title = Some(record.into());
-                },
+                }
                 CSVColumnSpec::Deposit => {
                     if record.trim().is_empty() {
-                        continue
+                        continue;
                     }
 
                     txn_change = Some(try_parse_decimal(record)?);
-                },
+                }
                 CSVColumnSpec::Withdraw => {
                     if record.trim().is_empty() {
-                        continue
+                        continue;
                     }
                     let mut dec = try_parse_decimal(record)?;
                     dec.set_sign_negative(true);
                     txn_change = Some(dec);
-                },
+                }
                 CSVColumnSpec::Change => {
                     if record.trim().is_empty() {
-                        continue
+                        continue;
                     }
 
                     txn_change = Some(try_parse_decimal(record)?);
-                },
+                }
                 CSVColumnSpec::Balance => {
                     if record.trim().is_empty() {
-                        continue
+                        continue;
                     }
 
                     txn_balance = Some(try_parse_decimal(record)?);
-                },
+                }
                 CSVColumnSpec::Unit => {
                     txn_unit = Some(UnitName::new(record));
-                },
+                }
             }
         }
 
@@ -125,15 +148,16 @@ fn import_from_csv(csv_spec: &CSVImportSpec, aspec: &AccountSpec, target: Accoun
                     amount: txn_change.unwrap().into(),
                     balance: txn_balance.map(Into::into),
                     unit: txn_unit.or(aspec.unit).map(Into::into).unwrap(),
-                }.into(),
-
+                }
+                .into(),
                 Change {
                     account: unbalanced.into(),
                     amount: txn_change.unwrap().into(),
                     balance: txn_balance.map(Into::into),
                     unit: txn_unit.or(aspec.unit).map(Into::into).unwrap(),
-                }.into(),
-            ]
+                }
+                .into(),
+            ],
         });
 
         // println!("{txn_datestamp:?}: {txn_title:?}");
@@ -143,11 +167,17 @@ fn import_from_csv(csv_spec: &CSVImportSpec, aspec: &AccountSpec, target: Accoun
     Ok(txns)
 }
 
-pub fn import_from(aspec: &AccountSpec, target: AccountName, path: &std::path::Path) -> Result<Vec<Transaction>, ImportError> {
+pub fn import_from(
+    aspec: &AccountSpec,
+    target: AccountName,
+    path: &std::path::Path,
+) -> Result<Vec<Transaction>, ImportError> {
     let reader = std::fs::File::open(path)?;
 
     match &aspec.import {
         Some(ImportFileFormat::CSV(csv)) => import_from_csv(csv, aspec, target, reader),
-        None => Err(ImportError::ConfigError(format!("no import configuration for {target}"))),
+        None => Err(ImportError::ConfigError(format!(
+            "no import configuration for {target}"
+        ))),
     }
 }

+ 1 - 1
src/main.rs

@@ -1,8 +1,8 @@
 mod check;
 mod cmd;
 mod data;
-mod show;
 mod import;
+mod show;
 
 fn main() -> anyhow::Result<()> {
     use clap::Parser;

+ 31 - 19
src/show.rs

@@ -3,8 +3,7 @@ use std::fmt::Display;
 use console::Style;
 
 use crate::data::{
-    Root,
-    AccountName, Decimal,
+    AccountName, Decimal, Root,
     ledger::{Change, Transaction},
     spec::AccountSpec,
 };
@@ -81,8 +80,12 @@ fn show_table<'d>(cols: Vec<Column>, rows: impl Iterator<Item = Row>) {
 pub struct TransactionTable {}
 
 impl TransactionTable {
-    pub fn show<'d>(self, root: &Root, account: AccountName, txns: impl Iterator<Item = &'d Transaction>) {
-
+    pub fn show<'d>(
+        self,
+        root: &Root,
+        account: AccountName,
+        txns: impl Iterator<Item = &'d Transaction>,
+    ) {
         show_table(
             vec![
                 // datestamp
@@ -109,22 +112,31 @@ impl TransactionTable {
                 },
             ],
             vec![
-                Row::Data(vec!["Date".into(), "Memo".into(), "Amount".into(), "Balance".into()]),
+                Row::Data(vec![
+                    "Date".into(),
+                    "Memo".into(),
+                    "Amount".into(),
+                    "Balance".into(),
+                ]),
                 Row::Line,
-            ].into_iter().chain(
-            txns.filter_map(|txn| txn.change_for(account).map(|chg| (txn, chg)))
-                .map(|(txn, chg)| {
-                    let precision = root.unit_spec(*chg.unit).unwrap().precision.unwrap_or(2) as usize;
-                    Row::Data(vec![
-                        txn.datestamp.to_string(),
-                        txn.title.clone().unwrap_or_else(String::new),
-                        format!("{:.precision$}", chg.amount),
-                        chg.balance
-                            .as_deref()
-                            .map(|b| format!("{:.precision$}", b))
-                            .unwrap_or(String::new()),
-                    ])
-                })),
+            ]
+            .into_iter()
+            .chain(
+                txns.filter_map(|txn| txn.change_for(account).map(|chg| (txn, chg)))
+                    .map(|(txn, chg)| {
+                        let precision =
+                            root.unit_spec(*chg.unit).unwrap().precision.unwrap_or(2) as usize;
+                        Row::Data(vec![
+                            txn.datestamp.to_string(),
+                            txn.title.clone().unwrap_or_else(String::new),
+                            format!("{:.precision$}", chg.amount),
+                            chg.balance
+                                .as_deref()
+                                .map(|b| format!("{:.precision$}", b))
+                                .unwrap_or(String::new()),
+                        ])
+                    }),
+            ),
         )
     }
 }