2JBFREZGJ2PST2DE3ZVDQADXAOFXBYPMSFTG7C65GDKLOZGETTGAC
Q54Z5TPAAXPT4KB3UHSBEXEHW57AT2GKM7SQW4PHES5J7WZQO4YQC
UESS5YZE6ZHPMVUL2P2OACW2Y2QLFLLLLC3F3JAENVH6A7REKLBAC
5PYSO4HI4ATDTZ3CWI7HGGPZDEG52YELOOGXCSU6Q4KPFMFR5KHAC
I2P2FTLEKLICJKHQ3FHOLRQRQYGZCJTCTU2MWXU2TMIRIKG6YFCQC
YDK6X6PPD42DMLFGF6OO2O3G7GA4Z2PCIDJIREHX6XNX2NYEBJSQC
D6UTHZA4XNAR2PTG4YEZFNNH3OTSNOWGDSVBYDRE5R2YSV7MPN6AC
MG46NYACGKHTJ5V6NLPDGKQSETQQNCOGP7TDS4KPJDJFNPKWEFJAC
ONRIF4V72HMVLO4BWDHI7ZOWYWTLTVYNH5TXUN5HB7BQUMV22NVAC
SJ6AFVZL5HEXG5ZUV5STIGGIGLU56WGAQCSZBFFHQOVHAILBOS2QC
NSWL54NMMYELYDQNRFAO7S6GBFDW6MDJ5TM2EYMK2VX336DGACHQC
QRIJE4AQWN7A7O2CO7FXRV4FXZ5RHONQKRGHYXAD7WSECJYK2MFAC
5S4MZHL5SO3D3M2CNQESORNJ47QCX7X7SPTO3K63VDXMITYMRZBQC
ND7GASJ45SLCZWNTZVAEQOWRF4HQ4GQ7TQLQZ4CUTW2IW3JN776QC
M7VINXOFAKFTEKQZR3RFO3WJQ3RXE2TWD4YAVKTPLMJWC4LISTIQC
# This template contains all of the possible sections and their default values
# Note that all fields that take a lint level have these possible values:
# * deny - An error will be produced and the check will fail
# * warn - A warning will be produced, but the check will not fail
# * allow - No warning or error will be produced, though in some cases a note
# will be
# This section is considered when running `cargo deny check licenses`
# More documentation for the licenses section can be found here:
# https://embarkstudios.github.io/cargo-deny/checks/licenses/cfg.html
[licenses]
# Blanket approval or denial for OSI-approved or FSF Free/Libre licenses
# * both - The license will be approved if it is both OSI-approved *AND* FSF
# * either - The license will be approved if it is either OSI-approved *OR* FSF
# * osi-only - The license will be approved if is OSI-approved *AND NOT* FSF
# * fsf-only - The license will be approved if is FSF *AND NOT* OSI-approved
# * neither - This predicate is ignored and the default lint level is used
allow-osi-fsf-free = "either"
[licenses.private]
# If true, ignores workspace crates that aren't published, or are only
# published to private registries.
# To see how to mark a crate as unpublished (to the official registry),
# visit https://doc.rust-lang.org/cargo/reference/manifest.html#the-publish-field.
ignore = true
# This section is considered when running `cargo deny check bans`.
# More documentation about the 'bans' section can be found here:
# https://embarkstudios.github.io/cargo-deny/checks/bans/cfg.html
[bans]
# Lint level for when a crate version requirement is `*`
wildcards = "deny"
# The graph highlighting used when creating dotgraphs for crates
# with multiple versions
# * lowest-version - The path to the lowest versioned duplicate is highlighted
# * simplest-path - The path to the version with the fewest edges is highlighted
# * all - Both lowest-version and simplest-path are used
highlight = "all"
warn = [
# rustc-lints
"explicit_outlives_requirements",
"macro_use_extern_crate",
"meta_variable_misuse",
"missing_copy_implementations",
"missing_debug_implementations",
"noop_method_call",
"trivial_casts",
"trivial_numeric_casts",
"unreachable_pub",
"unsafe_code",
"unsafe_op_in_unsafe_fn",
"unused_import_braces",
"unused_lifetimes",
"unused_macro_rules",
"unused_qualifications",
"unused_tuple_struct_fields",
"variant_size_differences",
# clippy lints
"clippy::alloc_instead_of_core",
"clippy::cargo",
"clippy::case_sensitive_file_extension_comparisons",
"clippy::std_instead_of_alloc",
"clippy::std_instead_of_core",
"clippy::unnecessary_self_imports",
]
/// * SAW_DECIMAL_SEPARATOR - a decimal point has been seen
/// * NEGATIVE - we've encountered a `-` and the number is negative
/// * SAW_DIGIT - a digit has been encountered (when HAS is false it's invalid)
/// * BIG - a number that uses 96 bits instead of only 64 bits
/// * FIRST - true if it is the first byte in the string
/// * `SAW_DECIMAL_SEPARATOR` - a decimal point has been seen
/// * `NEGATIVE` - we've encountered a `-` and the number is negative
/// * `SAW_DIGIT` - a digit has been encountered (when HAS is false it's invalid)
/// * `BIG` - a number that uses 96 bits instead of only 64 bits
/// * `FIRST` - true if it is the first byte in the string
use std::fmt::Display;
pub use crate::account::Acc;
pub use crate::account::Account;
pub use crate::amount::Amount;
pub use crate::balance::Balance;
pub use crate::commodity::Commodity;
pub use crate::cost::CostBasis;
pub use crate::transaction::Flag;
pub use crate::transaction::Posting;
pub use crate::transaction::Transaction;
use core::fmt;
use core::fmt::Display;
use core::fmt::Formatter;
pub use crate::account::Acc;
pub use crate::account::Account;
pub use crate::amount::Amount;
pub use crate::balance::Balance;
pub use crate::commodity::Commodity;
pub use crate::cost::CostBasis;
pub use crate::transaction::Posting;
pub use crate::transaction::Transaction;
pub use crate::transaction::TransactionFlag;
}
}
impl PartialEq<Commodity> for str {
fn eq(&self, other: &Commodity) -> bool {
other.eq(self)
}
}
impl PartialEq<str> for Commodity {
fn eq(&self, other: &str) -> bool {
self.partial_cmp(other)
.map(Ordering::is_eq)
.unwrap_or_default()
}
}
impl PartialOrd<Commodity> for str {
fn partial_cmp(&self, other: &Commodity) -> Option<Ordering> {
other.partial_cmp(self)
use crate::Commodity;
use core::fmt;
use core::fmt::Display;
use core::fmt::Formatter;
use core::hash::Hash;
use core::hash::Hasher;
use core::ops::Add;
use core::ops::AddAssign;
use core::ops::Div;
use core::ops::DivAssign;
use core::ops::Mul;
use core::ops::MulAssign;
use core::ops::Neg;
use core::ops::Sub;
use core::ops::SubAssign;
use core::str::FromStr;
use std::fmt::Display;
use std::ops::Neg;
use std::str::FromStr;
use crate::Commodity;
macro_rules! forward_commutative_binop {
(impl $trait:ident<$ltype:ty> for $rtype:ty { $fn:ident }) => {
forward_commutative_binop!(@single<'l> $trait, $fn, &'l $ltype, &$rtype);
forward_commutative_binop!(@single<'l> $trait, $fn, &'l $ltype, $rtype);
forward_commutative_binop!(@single $trait, $fn, $ltype, &$rtype);
forward_commutative_binop!(@single $trait, $fn, $ltype, $rtype);
};
(@single$(<$lt:lifetime>)? $trait:ident, $fn:ident, $ltype:ty, $rtype:ty) => {
impl$(<$lt>)? $trait<$ltype> for $rtype {
type Output = <$ltype as $trait<Self>>::Output;
#[inline]
fn $fn(self, rhs: $ltype) -> Self::Output {
rhs.$fn(self)
}
}
};
}
macro_rules! implement_binop {
(impl $trait:ident<$rtype:ty> for $ltype:ty { fn $method:ident($self:ident, $rhs:ident) $body:block }) => {
implement_binop! {@single
impl $trait<&'_ $rtype> for &'_ $ltype {
fn $method($self, $rhs) -> $ltype {
(*$self).$method($rhs)
}
}
}
implement_binop! {@single
impl $trait<&'_ $rtype> for $ltype {
fn $method($self, $rhs) -> $ltype $body
}
}
implement_binop! {@single
impl $trait<$rtype> for &'_ $ltype {
fn $method($self, $rhs) -> $ltype {
$self.$method(&$rhs)
}
}
}
implement_binop! {@single
impl $trait<$rtype> for $ltype {
fn $method($self, $rhs) -> $ltype {
$self.$method(&$rhs)
}
}
}
};
(@single impl $trait:ident<$rtype:ty> for $ltype:ty { fn $method:ident($self:ident, $rhs:ident) -> $output:ty $body:block }) => {
impl $trait<$rtype> for $ltype {
type Output = $output;
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
#[inline]
fn $method($self, $rhs: $rtype) -> Self::Output $body
}
};
}
macro_rules! implement_binop_assign {
(impl $trait:ident<$rtype:ty> for $ltype:ty { fn $method:ident($self:ident, $rhs:ident) $body:block }) => {
implement_binop_assign! {@single
impl $trait<&'_ $rtype> for $ltype {
fn $method($self, $rhs) $body
}
}
implement_binop_assign!(@single impl $trait<$rtype> for $ltype { fn $method($self, $rhs) { $self.$method(&$rhs)} });
};
(@single impl $trait:ident<$rtype:ty> for $ltype:ty { fn $method:ident($self:ident, $rhs:ident) $body:block }) => {
impl $trait<$rtype> for $ltype {
#[inline]
fn $method(&mut $self, $rhs: $rtype) $body
}
};
}
macro_rules! implement_binop_complete {
(@com impl $assign_trait:ident<$rtype:ty> for $ltype:ty { fn $assign_method:ident($self:ident, $rhs:ident) $body:block } .. $op_trait:ident { $op_method:ident }) => {
forward_commutative_binop! {
impl $op_trait<$ltype> for $rtype { $op_method }
}
implement_binop_complete!(impl $assign_trait<$rtype> for $ltype { fn $assign_method($self, $rhs) $body } .. $op_trait { $op_method });
};
(impl $assign_trait:ident<$rtype:ty> for $ltype:ty { fn $assign_method:ident($self:ident, $rhs:ident) $body:block } .. $op_trait:ident { $op_method:ident }) => {
implement_binop! {
impl $op_trait<$rtype> for $ltype {
fn $op_method($self, $rhs) {
let mut this = $self;
this.$assign_method($rhs);
this
}
}
}
implement_binop_assign! {
impl $assign_trait<$rtype> for $ltype {
fn $assign_method($self, $rhs) $body
}
}
};
}
#[derive(Clone, Copy, Debug)]
}
impl Amount {
#[inline]
pub fn checked_add(self, rhs: Self) -> Option<Self> {
self.try_reduce(rhs, Decimal::checked_add)
}
#[inline]
pub fn checked_div(self, rhs: Self) -> Option<Self> {
self.try_reduce(rhs, Decimal::checked_div)
}
#[inline]
pub fn checked_mul(self, rhs: Self) -> Option<Self> {
self.try_reduce(rhs, Decimal::checked_mul)
}
#[inline]
pub fn checked_sub(self, rhs: Self) -> Option<Self> {
self.try_reduce(rhs, Decimal::checked_sub)
}
#[inline]
pub fn saturating_add(self, rhs: Self) -> Option<Self> {
self.reduce(rhs, Decimal::saturating_add)
}
#[inline]
pub fn saturating_mul(self, rhs: Self) -> Option<Self> {
self.reduce(rhs, Decimal::saturating_mul)
}
#[inline]
pub fn saturating_sub(self, rhs: Self) -> Option<Self> {
self.reduce(rhs, Decimal::saturating_sub)
}
}
impl Amount {
#[inline]
fn reduce(self, rhs: Self, f: impl FnOnce(Decimal, Decimal) -> Decimal) -> Option<Self> {
self.try_reduce(rhs, |lhs, rhs| Some(f(lhs, rhs)))
}
#[inline]
fn try_reduce(
self,
rhs: Self,
f: impl FnOnce(Decimal, Decimal) -> Option<Decimal>,
) -> Option<Self> {
(self.commodity == rhs.commodity)
.then_some((self.amount, rhs.amount))
.and_then(|(lhs, rhs)| f(lhs, rhs))
.map(|amount| Self { amount, ..self })
}
}
implement_binop_complete! {
impl AddAssign<Amount> for Amount {
fn add_assign(self, rhs) {
assert!(self.commodity == rhs.commodity);
self.amount.add_assign(rhs.amount);
}
}
.. Add { add }
}
}
impl Hash for Amount {
fn hash<H: Hasher>(&self, state: &mut H) {
self.commodity.hash(state);
self.amount.hash(state);
}
}
implement_binop_complete! {
@com
impl MulAssign<Decimal> for Amount {
fn mul_assign(self, rhs) {
self.amount.mul_assign(rhs);
}
}
.. Mul { mul }
}
impl Neg for &Amount {
type Output = Amount;
#[inline]
fn neg(self) -> Self::Output {
(*self).neg()
extern crate alloc;
use core::borrow::Borrow;
use core::cmp::Ordering;
use core::fmt;
use core::fmt::Display;
use core::fmt::Formatter;
use core::hash::Hash;
use core::hash::Hasher;
use core::iter::FusedIterator;
use core::ops::Deref;
use core::str::FromStr;
use core::str::Split;
use alloc::borrow::Cow;
/// A borrowed account name (akin to [`str`])
///
/// This type supports a number of operations for inspecting an account name, including breaking the account name into its segments.
///
/// This is an _unsized_ type, meaning that it must always be used behind a pointer like `&` or [`Box`].
/// For an owned version of this type see, see [`Account`].
/// Produces an iterator over `Acc` and its ancestors.
///
/// The iterator will yield all `Acc`s that are returned if the [`parent`](Self::parent) method is used zero or more times.
/// The iterator will always yield at least one value, namely `&self`.
self.name
.split_once(':')
.map(|(parent, _)| unsafe { Self::from_unchecked(parent) })
self.name.split_once(':').map(|(parent, _)| {
#[allow(unsafe_code)]
unsafe {
// SAFETY: By construction, if `self` is a valid account name, `self.parent` is also a valid account name.
Self::from_unchecked(parent)
}
})
/// Create a new `Acc` from a `str` without validating the name before.
///
/// # Safety
///
/// Other functions on this type assume that `name` is a valid account name, as defined by beancount.
/// You must ensure that this is the case.
/// See [`is_valid_account_name`] for a function providing that guarantee.
#[allow(unsafe_code)]
use camino::Utf8PathBuf;
use core::fmt;
use core::fmt::Formatter;
use core::marker::PhantomData;
use serde::Deserialize;
use serde::Deserializer;
#[derive(Clone, Debug)]
pub struct Config {
pub output_path: Utf8PathBuf,
pub pretty_printer: PrettyPrinterConfig,
}
impl<'de> Deserialize<'de> for Config {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
enum Field {
OutputPath,
PrettyPrinter,
Ignored,
}
struct FieldVisitor;
impl<'de> serde::de::Visitor<'de> for FieldVisitor {
type Value = Field;
fn expecting(&self, formatter: &mut Formatter) -> fmt::Result {
formatter.write_str("field identifier")
}
fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
match value {
0u64 => Ok(Field::OutputPath),
1u64 => Ok(Field::PrettyPrinter),
_ => Ok(Field::Ignored),
}
}
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
match value {
"output_path" => Ok(Field::OutputPath),
"pretty_printer" => Ok(Field::PrettyPrinter),
_ => Ok(Field::Ignored),
}
}
fn visit_bytes<E>(self, value: &[u8]) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
match value {
b"output_path" => Ok(Field::OutputPath),
b"pretty_printer" => Ok(Field::PrettyPrinter),
_ => Ok(Field::Ignored),
}
}
}
impl<'de> Deserialize<'de> for Field {
#[inline]
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_identifier(FieldVisitor)
}
}
struct Visitor<'de> {
lifetime: PhantomData<&'de ()>,
}
impl<'de> serde::de::Visitor<'de> for Visitor<'de> {
type Value = Config;
fn expecting(&self, formatter: &mut Formatter) -> fmt::Result {
formatter.write_str("struct Config")
}
#[inline]
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: serde::de::SeqAccess<'de>,
{
let output_path = seq
.next_element::<Utf8PathBuf>()?
.ok_or_else(|| {
serde::de::Error::invalid_length(0, &"struct Config with 2 elements")
})
.and_then(|path| path.canonicalize_utf8().map_err(serde::de::Error::custom))?;
let pretty_printer = seq
.next_element::<PrettyPrinterConfig>()?
.unwrap_or_default();
Ok(Config {
output_path,
pretty_printer,
})
}
#[inline]
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
where
A: serde::de::MapAccess<'de>,
{
let mut output_path: Option<Utf8PathBuf> = None;
let mut pretty_printer: Option<PrettyPrinterConfig> = None;
while let Some(key) = map.next_key::<Field>()? {
match key {
Field::OutputPath if output_path.is_some() => {
return Err(serde::de::Error::duplicate_field("output_path"));
}
Field::OutputPath => {
output_path = Some(map.next_value::<Utf8PathBuf>()?);
}
Field::PrettyPrinter if pretty_printer.is_some() => {
return Err(serde::de::Error::duplicate_field("pretty_printer"));
}
Field::PrettyPrinter => {
pretty_printer = Some(map.next_value::<PrettyPrinterConfig>()?);
}
_ => {
map.next_value::<serde::de::IgnoredAny>()?;
}
}
}
let output_path = output_path
.ok_or_else(|| serde::de::Error::missing_field("output_path"))
.and_then(|path| path.canonicalize_utf8().map_err(serde::de::Error::custom))?;
let pretty_printer = pretty_printer.unwrap_or_default();
Ok(Config {
output_path,
pretty_printer,
})
}
}
const FIELDS: &[&str] = &["output_path", "pretty_printer"];
deserializer.deserialize_struct(
"Config",
FIELDS,
Visitor {
lifetime: PhantomData,
},
)
}
}
#[derive(Clone, Copy, Debug, Default, Deserialize)]
pub enum PrettyPrinterConfig {
#[default]
GloballyDerived,
LocallyDerived,
Static(beancount_pretty_printer::Config),
}
icu_provider.workspace = true
[profile.release-lto]
codegen-units = 1
inherits = "release"
lto = "thin"
[[package]]
name = "beancount-importers-framework"
version = "0.0.0-dev.0"
dependencies = [
"beancount-pretty-printer",
"beancount-tree-writer",
"camino",
"clap",
"clap-verbosity-flag",
"color-eyre",
"inventory",
"ron",
"serde",
"tracing",
"tracing-error",
"tracing-log",
"tracing-subscriber",
"uniondepot",
]
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223"
dependencies = [
"lazy_static",
"memchr",
"regex-automata 0.1.10",
"serde",
]
[[package]]
name = "bstr"
name = "clap"
version = "4.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5840cd9093aabeabf7fd932754c435b7674520fc3ddc935c397837050f0f1e4b"
dependencies = [
"atty",
"bitflags",
"clap_derive",
"clap_lex",
"once_cell",
"strsim",
"termcolor",
]
[[package]]
name = "clap-verbosity-flag"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23e2b6c3dcdb73299f48ae05b294da14e2f560b3ed2c09e742269eb1b22af231"
dependencies = [
"clap",
"log",
]
[[package]]
name = "clap_derive"
version = "4.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "92289ffc6fb4a85d85c246ddb874c05a87a2e540fb6ad52f7ca07c8c1e1840b1"
dependencies = [
"heck",
"proc-macro-error",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "clap_lex"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d4198f73e42b4936b35b5bb248d81d2b595ecb170da0bac7655c54eedfa8da8"
dependencies = [
"os_str_bytes",
]
[[package]]
name = "csv"
version = "1.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22813a6dc45b335f9bade10bf7271dc477e81113e89eb251a0bc2a8a81c536e1"
dependencies = [
"bstr 0.2.17",
"csv-core",
"itoa 0.4.8",
"ryu",
"serde",
]
[[package]]
name = "csv-core"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b2466559f260f48ad25fe6317b3c8dac77b5bdb5763ac7d9d6103530663bc90"
dependencies = [
"memchr",
]
[[package]]
name = "ctor"
version = "0.1.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdffe87e1d521a10f9696f833fe502293ea446d7f256c06128293a4119bdf4cb"
dependencies = [
"quote",
"syn",
]
[[package]]
]
[[package]]
name = "inventory"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "30a61b8101d87996f82d725ba701b1987b7afc72f481c13513a30b855b9c9133"
dependencies = [
"ctor",
"ghost",
name = "ron"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "300a51053b1cb55c80b7a9fde4120726ddf25ca241a1cbb926626f62fb136bff"
dependencies = [
"base64",
"bitflags",
"serde",
]
[[package]]
name = "termcolor"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755"
dependencies = [
"winapi-util",
]
[[package]]
name = "tracing-log"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922"
dependencies = [
"lazy_static",
"log",
"tracing-core",
]
[[package]]