Created accounting journal entry report.
This commit is contained in:
parent
55403fb4a9
commit
e0439325e2
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "cryptools"
|
name = "cryptools"
|
||||||
version = "0.8.1"
|
version = "0.8.2"
|
||||||
authors = ["scoobybejesus <scoobybejesus@users.noreply.github.com>"]
|
authors = ["scoobybejesus <scoobybejesus@users.noreply.github.com>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
description = "Command-line utility for processing cryptocurrency transactions into 'lots' and 'movements'."
|
description = "Command-line utility for processing cryptocurrency transactions into 'lots' and 'movements'."
|
||||||
|
|
|
@ -26,6 +26,14 @@ impl RawAccount {
|
||||||
pub fn is_home_currency(&self, compare: &String) -> bool {
|
pub fn is_home_currency(&self, compare: &String) -> bool {
|
||||||
&self.ticker == compare
|
&self.ticker == compare
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn margin_string(&self) -> String {
|
||||||
|
if self.is_margin {
|
||||||
|
"Margin".to_string()
|
||||||
|
} else {
|
||||||
|
"Non-margin".to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
|
|
|
@ -32,6 +32,7 @@ pub struct ImportProcessParameters {
|
||||||
pub input_file_has_iso_date_style: bool,
|
pub input_file_has_iso_date_style: bool,
|
||||||
pub should_export: bool,
|
pub should_export: bool,
|
||||||
pub print_menu: bool,
|
pub print_menu: bool,
|
||||||
|
pub journal_entry_export: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn import_and_process_final(
|
pub fn import_and_process_final(
|
||||||
|
|
|
@ -223,6 +223,8 @@ impl Transaction {
|
||||||
|
|
||||||
let auto_memo = if self.action_record_idx_vec.len() == 2 {
|
let auto_memo = if self.action_record_idx_vec.len() == 2 {
|
||||||
|
|
||||||
|
let tx_type = self.transaction_type(ars, raw_accts, acct_map)?;
|
||||||
|
|
||||||
let marginness = self.marginness(ars, raw_accts, acct_map);
|
let marginness = self.marginness(ars, raw_accts, acct_map);
|
||||||
|
|
||||||
if (marginness == TxHasMargin::NoARs) | (marginness == TxHasMargin::TwoARs) {
|
if (marginness == TxHasMargin::NoARs) | (marginness == TxHasMargin::TwoARs) {
|
||||||
|
@ -239,9 +241,13 @@ impl Transaction {
|
||||||
let ic_raw_acct = raw_accts.get(&ic_acct.raw_key).unwrap();
|
let ic_raw_acct = raw_accts.get(&ic_acct.raw_key).unwrap();
|
||||||
let ic_ticker = &ic_raw_acct.ticker;
|
let ic_ticker = &ic_raw_acct.ticker;
|
||||||
|
|
||||||
|
if tx_type == TxType::Exchange {
|
||||||
format!("Paid {} {} for {} {}, valued at {} {}.",
|
format!("Paid {} {} for {} {}, valued at {} {}.",
|
||||||
og_amt, og_ticker, ic_amt, ic_ticker, self.proceeds, home_currency)
|
og_amt, og_ticker, ic_amt, ic_ticker, self.proceeds, home_currency)
|
||||||
|
} else {
|
||||||
|
format!("Transferred {} {} to another account. Received {} {}, likely after a transaction fee.",
|
||||||
|
og_amt, og_ticker, ic_amt, ic_ticker)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
format!("Margin profit or loss valued at {} {}.", self.proceeds, home_currency)
|
format!("Margin profit or loss valued at {} {}.", self.proceeds, home_currency)
|
||||||
|
@ -286,6 +292,17 @@ impl ActionRecord {
|
||||||
else { Polarity::Incoming }
|
else { Polarity::Incoming }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn cost_basis_in_ar(&self) -> d128 {
|
||||||
|
|
||||||
|
let mut cb = d128!(0);
|
||||||
|
|
||||||
|
for mvmt in self.movements.borrow().iter() {
|
||||||
|
cb += mvmt.cost_basis.get()
|
||||||
|
}
|
||||||
|
|
||||||
|
cb.abs()
|
||||||
|
}
|
||||||
|
|
||||||
// pub fn is_quote_acct_for_margin_exch(
|
// pub fn is_quote_acct_for_margin_exch(
|
||||||
// &self,
|
// &self,
|
||||||
// raw_accts: &HashMap<u16, RawAccount>,
|
// raw_accts: &HashMap<u16, RawAccount>,
|
||||||
|
|
|
@ -9,6 +9,7 @@ use crptls::account::{Account, RawAccount};
|
||||||
use crptls::core_functions::{ImportProcessParameters};
|
use crptls::core_functions::{ImportProcessParameters};
|
||||||
use crate::export_csv;
|
use crate::export_csv;
|
||||||
use crate::export_txt;
|
use crate::export_txt;
|
||||||
|
use crate::export_je;
|
||||||
|
|
||||||
|
|
||||||
pub fn export(
|
pub fn export(
|
||||||
|
@ -85,5 +86,15 @@ pub fn export(
|
||||||
&account_map,
|
&account_map,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
if !settings.lk_treatment_enabled {
|
||||||
|
export_je::prepare_non_lk_journal_entries(
|
||||||
|
&settings,
|
||||||
|
&action_records_map,
|
||||||
|
&raw_acct_map,
|
||||||
|
&account_map,
|
||||||
|
&transactions_map,
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
|
@ -622,7 +622,6 @@ pub fn _6_transaction_mvmt_detail_to_csv_w_orig(
|
||||||
let mut orig_proc = mvmt.proceeds.get();
|
let mut orig_proc = mvmt.proceeds.get();
|
||||||
let mut orig_cost = mvmt.cost_basis.get();
|
let mut orig_cost = mvmt.cost_basis.get();
|
||||||
let mut orig_gain_loss = mvmt.get_orig_gain_or_loss();
|
let mut orig_gain_loss = mvmt.get_orig_gain_or_loss();
|
||||||
println!("{:?}", expense);
|
|
||||||
|
|
||||||
if tx_type == TxType::Flow && amount > d128!(0) {
|
if tx_type == TxType::Flow && amount > d128!(0) {
|
||||||
proceeds_lk = d128!(0);
|
proceeds_lk = d128!(0);
|
||||||
|
|
|
@ -0,0 +1,292 @@
|
||||||
|
// Copyright (c) 2017-2019, scoobybejesus
|
||||||
|
// Redistributions must include the license: https://github.com/scoobybejesus/cryptools/blob/master/LEGAL.txt
|
||||||
|
|
||||||
|
use std::fs::{OpenOptions};
|
||||||
|
use std::collections::{HashMap};
|
||||||
|
use std::path::PathBuf;
|
||||||
|
use std::error::Error;
|
||||||
|
use std::io::prelude::Write;
|
||||||
|
|
||||||
|
use decimal::d128;
|
||||||
|
|
||||||
|
use crptls::transaction::{Transaction, ActionRecord, Polarity, TxType};
|
||||||
|
use crptls::account::{Account, RawAccount, Term};
|
||||||
|
use crptls::core_functions::{ImportProcessParameters};
|
||||||
|
|
||||||
|
|
||||||
|
pub fn prepare_non_lk_journal_entries(
|
||||||
|
settings: &ImportProcessParameters,
|
||||||
|
ars: &HashMap<u32, ActionRecord>,
|
||||||
|
raw_acct_map: &HashMap<u16, RawAccount>,
|
||||||
|
acct_map: &HashMap<u16, Account>,
|
||||||
|
txns_map: &HashMap<u32, Transaction>,
|
||||||
|
) -> Result<(), Box<dyn Error>> {
|
||||||
|
|
||||||
|
let file_name = PathBuf::from("J1_Journal_Entries.txt");
|
||||||
|
let path = PathBuf::from(&settings.export_path.clone());
|
||||||
|
let full_path: PathBuf = [path, file_name].iter().collect();
|
||||||
|
|
||||||
|
let mut file = OpenOptions::new()
|
||||||
|
.write(true)
|
||||||
|
.create(true)
|
||||||
|
.truncate(true)
|
||||||
|
.open(full_path)?;
|
||||||
|
|
||||||
|
writeln!(file, "Journal Entries
|
||||||
|
\nCosting method used: {}.
|
||||||
|
Home currency: {}
|
||||||
|
Enable like-kind treatment: {}",
|
||||||
|
settings.costing_method,
|
||||||
|
settings.home_currency,
|
||||||
|
settings.lk_treatment_enabled
|
||||||
|
)?;
|
||||||
|
|
||||||
|
if settings.lk_treatment_enabled {
|
||||||
|
writeln!(file, "Like-kind cut-off date: {}.",
|
||||||
|
settings.lk_cutoff_date
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
let length = txns_map.len();
|
||||||
|
|
||||||
|
for txn_num in 1..=length {
|
||||||
|
|
||||||
|
let txn_num = txn_num as u32;
|
||||||
|
let txn = txns_map.get(&(txn_num)).unwrap();
|
||||||
|
let date = txn.date;
|
||||||
|
let user_memo = txn.user_memo.to_string();
|
||||||
|
let auto_memo = txn.get_auto_memo(ars, raw_acct_map,acct_map, &settings.home_currency)?;
|
||||||
|
let tx_type = txn.transaction_type(&ars, &raw_acct_map, &acct_map)?;
|
||||||
|
|
||||||
|
writeln!(file, "\n=====================================\n")?;
|
||||||
|
writeln!(file, "Txn {} on {}. {}. {}",
|
||||||
|
txn_num,
|
||||||
|
date,
|
||||||
|
user_memo,
|
||||||
|
auto_memo,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let mut cost_basis_ic: Option<d128> = None;
|
||||||
|
let mut cost_basis_og: Option<d128> = None;
|
||||||
|
|
||||||
|
let mut acct_string_ic = "".to_string();
|
||||||
|
let mut acct_string_og = "".to_string();
|
||||||
|
|
||||||
|
for ar_num in txn.action_record_idx_vec.iter() {
|
||||||
|
|
||||||
|
let ar = ars.get(ar_num).unwrap();
|
||||||
|
let acct = acct_map.get(&ar.account_key).unwrap();
|
||||||
|
let raw_acct = raw_acct_map.get(&acct.raw_key).unwrap();
|
||||||
|
|
||||||
|
if ar.direction() == Polarity::Incoming {
|
||||||
|
cost_basis_ic = Some(ar.cost_basis_in_ar());
|
||||||
|
acct_string_ic = format!("{} - {} ({}) (#{})",
|
||||||
|
raw_acct.name,
|
||||||
|
raw_acct.ticker,
|
||||||
|
raw_acct.margin_string(),
|
||||||
|
raw_acct.account_num,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
cost_basis_og = Some(ar.cost_basis_in_ar());
|
||||||
|
acct_string_og = format!("{} - {} ({}) (#{})",
|
||||||
|
raw_acct.name,
|
||||||
|
raw_acct.ticker,
|
||||||
|
raw_acct.margin_string(),
|
||||||
|
raw_acct.account_num,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut term_st: Option<Term> = None;
|
||||||
|
let mut term_lt: Option<Term> = None;
|
||||||
|
|
||||||
|
let mut polarity: Option<Polarity> = None;
|
||||||
|
|
||||||
|
let mut amount_st = d128!(0);
|
||||||
|
let mut proceeds_st = d128!(0);
|
||||||
|
let mut cost_basis_st = d128!(0);
|
||||||
|
|
||||||
|
let mut amount_lt = d128!(0);
|
||||||
|
let mut proceeds_lt = d128!(0);
|
||||||
|
let mut cost_basis_lt = d128!(0);
|
||||||
|
|
||||||
|
let mut income = d128!(0);
|
||||||
|
let mut expense = d128!(0);
|
||||||
|
|
||||||
|
let flow_or_outgoing_exchange_movements = txn.get_outgoing_exchange_and_flow_mvmts(
|
||||||
|
&settings.home_currency,
|
||||||
|
ars,
|
||||||
|
raw_acct_map,
|
||||||
|
acct_map,
|
||||||
|
txns_map
|
||||||
|
)?;
|
||||||
|
|
||||||
|
for mvmt in flow_or_outgoing_exchange_movements.iter() {
|
||||||
|
|
||||||
|
if let None = polarity {
|
||||||
|
polarity = if mvmt.amount > d128!(0) {
|
||||||
|
Some(Polarity::Incoming)
|
||||||
|
} else { Some(Polarity::Outgoing)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
let term = mvmt.get_term(acct_map, ars);
|
||||||
|
|
||||||
|
if term == Term::LT {
|
||||||
|
amount_lt += mvmt.amount;
|
||||||
|
proceeds_lt += mvmt.proceeds_lk.get();
|
||||||
|
cost_basis_lt += mvmt.cost_basis_lk.get();
|
||||||
|
match term_lt {
|
||||||
|
None => { term_lt = Some(term)}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
assert_eq!(term, Term::ST);
|
||||||
|
amount_st += mvmt.amount;
|
||||||
|
proceeds_st += mvmt.proceeds_lk.get();
|
||||||
|
cost_basis_st += mvmt.cost_basis_lk.get();
|
||||||
|
if term_st == None {
|
||||||
|
term_st = Some(term);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
income += mvmt.get_income(ars, &raw_acct_map, &acct_map, &txns_map)?;
|
||||||
|
expense += mvmt.get_expense(ars, &raw_acct_map, &acct_map, &txns_map)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (txn.transaction_type(
|
||||||
|
ars,
|
||||||
|
&raw_acct_map,
|
||||||
|
&acct_map)? == TxType::Flow
|
||||||
|
) & (polarity == Some(Polarity::Incoming)) {
|
||||||
|
|
||||||
|
proceeds_st = d128!(0);
|
||||||
|
cost_basis_st = d128!(0);
|
||||||
|
|
||||||
|
proceeds_lt = d128!(0);
|
||||||
|
cost_basis_lt = d128!(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
let lt_gain_loss = proceeds_lt + cost_basis_lt;
|
||||||
|
let st_gain_loss = proceeds_st + cost_basis_st;
|
||||||
|
|
||||||
|
let mut debits = d128!(0);
|
||||||
|
let mut credits = d128!(0);
|
||||||
|
|
||||||
|
if let Some(cb) = cost_basis_ic {
|
||||||
|
debits += cb;
|
||||||
|
writeln!(file, "{:50}{:5}{:>20}{:5}{:>20}",
|
||||||
|
acct_string_ic,
|
||||||
|
"",
|
||||||
|
cb.to_string(),
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(cb) = cost_basis_og {
|
||||||
|
credits += cb;
|
||||||
|
writeln!(file, "{:50}{:5}{:>20}{:5}{:>20}",
|
||||||
|
acct_string_og,
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
cb.to_string(),
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
if lt_gain_loss != d128!(0) {
|
||||||
|
|
||||||
|
if lt_gain_loss > d128!(0) {
|
||||||
|
credits += lt_gain_loss.abs();
|
||||||
|
let ltg_string = format!("Long-term gain disposing {}", amount_lt.abs());
|
||||||
|
writeln!(file, "{:50}{:5}{:>20}{:5}{:>20}",
|
||||||
|
ltg_string,
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
lt_gain_loss.to_string(),
|
||||||
|
)?;
|
||||||
|
} else {
|
||||||
|
debits += lt_gain_loss.abs();
|
||||||
|
let ltl_string = format!("Long-term loss disposing {}", amount_lt.abs());
|
||||||
|
writeln!(file, "{:50}{:5}{:>20}{:5}{:>20}",
|
||||||
|
ltl_string,
|
||||||
|
"",
|
||||||
|
lt_gain_loss.abs().to_string(),
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if st_gain_loss != d128!(0) {
|
||||||
|
|
||||||
|
if st_gain_loss > d128!(0) {
|
||||||
|
credits += st_gain_loss.abs();
|
||||||
|
let stg_string = format!("Short-term gain disposing {}", amount_st.abs());
|
||||||
|
writeln!(file, "{:50}{:5}{:>20}{:5}{:>20}",
|
||||||
|
stg_string,
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
st_gain_loss.to_string(),
|
||||||
|
)?;
|
||||||
|
} else {
|
||||||
|
debits += st_gain_loss.abs();
|
||||||
|
let stl_string = format!("Short-term loss disposing {}", amount_st.abs());
|
||||||
|
writeln!(file, "{:50}{:5}{:>20}{:5}{:>20}",
|
||||||
|
stl_string,
|
||||||
|
"",
|
||||||
|
st_gain_loss.abs().to_string(),
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if income != d128!(0) {
|
||||||
|
credits += income;
|
||||||
|
writeln!(file, "{:50}{:5}{:>20}{:5}{:>20}",
|
||||||
|
"Income",
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
income.to_string(),
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
if expense != d128!(0) {
|
||||||
|
debits += expense.abs();
|
||||||
|
writeln!(file, "{:50}{:5}{:>20}{:5}{:>20}",
|
||||||
|
"Expense",
|
||||||
|
"",
|
||||||
|
expense.abs().to_string(),
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
writeln!(file, "{:50}{:5}{:>20}{:5}{:>20}",
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
"--------------------",
|
||||||
|
"",
|
||||||
|
"--------------------",
|
||||||
|
)?;
|
||||||
|
|
||||||
|
writeln!(file, "{:50}{:5}{:>20}{:5}{:>20}",
|
||||||
|
" Totals",
|
||||||
|
"",
|
||||||
|
debits,
|
||||||
|
"",
|
||||||
|
credits,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
// if (debits - credits) != d128!(0) {
|
||||||
|
// println!("Rounding issue on transaction #{}", txn_num);
|
||||||
|
// }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
|
@ -379,3 +379,5 @@ Enable like-kind treatment: {}",
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
23
src/main.rs
23
src/main.rs
|
@ -21,6 +21,7 @@ mod skip_wizard;
|
||||||
mod mytui;
|
mod mytui;
|
||||||
mod export_csv;
|
mod export_csv;
|
||||||
mod export_txt;
|
mod export_txt;
|
||||||
|
mod export_je;
|
||||||
mod export_all;
|
mod export_all;
|
||||||
mod tests;
|
mod tests;
|
||||||
|
|
||||||
|
@ -48,6 +49,13 @@ pub struct Flags {
|
||||||
#[structopt(name = "accept args", short = "a", long = "accept")]
|
#[structopt(name = "accept args", short = "a", long = "accept")]
|
||||||
accept_args: bool,
|
accept_args: bool,
|
||||||
|
|
||||||
|
/// This flag will suppress the printing of "all" reports, except that it will trigger the
|
||||||
|
/// production of a txt file containing an accounting journal entry for every transaction.
|
||||||
|
/// Individual account and transaction reports may still be printed via the print_menu
|
||||||
|
/// with the -p flag. The journal entry report is only suitable for non-like-kind activity.
|
||||||
|
#[structopt(name = "journal entries", short, long = "journal-entries")]
|
||||||
|
journal_entries_only: bool,
|
||||||
|
|
||||||
/// This will cause the program to expect the txDate field in the file_to_import to use the format
|
/// This will cause the program to expect the txDate field in the file_to_import to use the format
|
||||||
/// YYYY-MM-dd or YY-MM-dd (or YYYY/MM/dd or YY/MM/dd, depending on the date-separator option)
|
/// YYYY-MM-dd or YY-MM-dd (or YYYY/MM/dd or YY/MM/dd, depending on the date-separator option)
|
||||||
/// instead of the default US-style MM-dd-YYYY or MM-dd-YY (or MM/dd/YYYY or MM/dd/YY, depending on the
|
/// instead of the default US-style MM-dd-YYYY or MM-dd-YY (or MM/dd/YYYY or MM/dd/YY, depending on the
|
||||||
|
@ -126,8 +134,10 @@ fn main() -> Result<(), Box<dyn Error>> {
|
||||||
|
|
||||||
let mut should_export_all = settings.should_export;
|
let mut should_export_all = settings.should_export;
|
||||||
let present_print_menu_tui = settings.print_menu;
|
let present_print_menu_tui = settings.print_menu;
|
||||||
|
let print_journal_entries_only = settings.journal_entry_export;
|
||||||
|
|
||||||
if present_print_menu_tui { should_export_all = false }
|
if present_print_menu_tui { should_export_all = false }
|
||||||
|
if print_journal_entries_only { should_export_all = false }
|
||||||
|
|
||||||
if should_export_all {
|
if should_export_all {
|
||||||
|
|
||||||
|
@ -140,6 +150,19 @@ fn main() -> Result<(), Box<dyn Error>> {
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if print_journal_entries_only {
|
||||||
|
|
||||||
|
if !settings.lk_treatment_enabled {
|
||||||
|
export_je::prepare_non_lk_journal_entries(
|
||||||
|
&settings,
|
||||||
|
&action_records_map,
|
||||||
|
&raw_acct_map,
|
||||||
|
&account_map,
|
||||||
|
&transactions_map,
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if present_print_menu_tui {
|
if present_print_menu_tui {
|
||||||
|
|
||||||
mytui::print_menu_tui::print_menu_tui(
|
mytui::print_menu_tui::print_menu_tui(
|
||||||
|
|
|
@ -73,6 +73,7 @@ pub (crate) fn run_setup(args: super::Cli) -> Result<(PathBuf, ImportProcessPara
|
||||||
should_export: should_export,
|
should_export: should_export,
|
||||||
export_path: output_dir_path,
|
export_path: output_dir_path,
|
||||||
print_menu: args.flags.print_menu,
|
print_menu: args.flags.print_menu,
|
||||||
|
journal_entry_export: args.flags.journal_entries_only,
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok((input_file_path, settings))
|
Ok((input_file_path, settings))
|
||||||
|
|
Loading…
Reference in New Issue