add a library of important types for beancount

korrat
Sep 9, 2022, 7:29 PM
YDK6X6PPD42DMLFGF6OO2O3G7GA4Z2PCIDJIREHX6XNX2NYEBJSQC

Dependencies

  • [2] I2P2FTLE add basic parser for german decimals

Change contents

  • file addition: beancount-types (d--r------)
    [2.18]
  • file addition: src (d--r------)
    [0.27]
  • file addition: transaction.rs (---r------)
    [0.44]
    use crate::Account;
    use crate::Amount;
    use crate::CostBasis;
    use std::fmt::Display;
    use std::fmt::Write as _;
    use std::hash::Hash;
    use time::Date;
    #[derive(Clone, Debug, Eq, Hash, PartialEq)]
    pub struct Posting {
    pub flag: Option<TransactionFlag>,
    pub account: Account,
    pub amount: Option<Amount>,
    pub cost: Option<CostBasis>,
    pub price: Option<Amount>,
    }
    impl Display for Posting {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
    let Posting {
    flag,
    account,
    amount,
    cost,
    price,
    } = self;
    if let Some(flag) = flag {
    write!(f, "{flag} ")?;
    }
    write!(f, "{account}")?;
    if let Some(amount) = amount {
    write!(f, " {amount}")?;
    if let Some(cost) = cost {
    write!(f, " {cost}")?;
    }
    if let Some(price) = price {
    write!(f, " @ {price}")?;
    }
    }
    Ok(())
    }
    }
    #[derive(Clone, Debug, Eq, Hash, PartialEq)]
    pub struct Transaction {
    pub date: Date,
    pub flag: TransactionFlag,
    pub payee: Option<String>,
    pub narration: Option<String>,
    pub postings: Vec<Posting>,
    }
    impl Display for Transaction {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
    let Self {
    date,
    flag,
    payee,
    narration,
    postings,
    } = self;
    write!(f, "{date} {flag}")?;
    match (payee, narration) {
    (None, None) => {}
    (None, Some(narration)) => write!(f, r#" "{narration}""#)?,
    (Some(payee), None) => write!(f, r#" "{payee}" """#)?,
    (Some(payee), Some(narration)) => write!(f, r#" "{payee}" "{narration}""#)?,
    }
    for posting in postings {
    write!(f, "\n {posting}")?;
    }
    Ok(())
    }
    }
    #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
    pub enum TransactionFlag {
    Complete,
    Incomplete,
    }
    impl Display for TransactionFlag {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
    f.write_char(match self {
    TransactionFlag::Complete => '*',
    TransactionFlag::Incomplete => '!',
    })
    }
    }
  • file addition: that.rs (---r------)
    [0.44]
    mod account {
    use crate::account::Acc;
    use crate::account::Account;
    use static_assertions::assert_impl_all;
    use std::fmt::Debug;
    use std::hash::Hash;
    use std::str::FromStr;
    use test_case::test_case;
    assert_impl_all!(
    Account: Clone,
    Debug,
    FromStr,
    Hash,
    Ord,
    TryFrom<&'static str>
    );
    #[test_case("Assets"; "only top-level")]
    #[test_case("Equity:OpeningBalances"; "subaccount")]
    #[test_case("Expenses:Banking-Fees"; "subaccount with dash")]
    #[test_case("Income:Sales:2022"; "subaccount starting with number")]
    #[test_case("Liabilities:Credit-Cards:VISA"; "multiple levels")]
    fn parse_when_valid(name: &str) {
    let acc = <&Acc>::try_from(name).unwrap();
    let account = Account::try_from(name).unwrap();
    assert_eq!(account, name);
    assert_eq!(acc, name);
    }
    #[test_case("Cash"; "invalid account type")]
    #[test_case("Assets:Accounts_Receivable"; "invalid characters")]
    #[test_case("Assets:-Test"; "subaccount starting with dash")]
    #[test_case("Income::Sales"; "empty segment")]
    fn do_not_parse_when_invalid(name: &str) {
    <&Acc>::try_from(name).unwrap_err();
    }
    }
    mod amount {
    use {
    crate::Amount,
    static_assertions::assert_impl_all,
    std::{fmt::Debug, hash::Hash, str::FromStr},
    test_case::test_case,
    };
    assert_impl_all!(
    Amount: Copy,
    Debug,
    FromStr,
    Hash,
    PartialOrd,
    TryFrom<&'static str>
    );
    #[test_case("0 EUR"; "zero")]
    #[test_case("15 USD"; "integer amount")]
    #[test_case("0.30 CAD"; "fractional amount")]
    #[test_case("0.0000067 ETH"; "arbitrary precision")]
    #[test_case("-16.93 USD"; "negative amount")]
    fn parse_when_valid(amount: &str) {
    let account = Amount::try_from(amount).unwrap();
    assert_eq!(account.to_string(), amount);
    }
    #[test_case(" EUR"; "missing units")]
    #[test_case("15 "; "missing commodity")]
    #[test_case("15,000.00 USD"; "thousands separator")]
    #[test_case("15000,00 USD"; "invalid decimal separator")]
    fn do_not_parse_when_invalid(amount: &str) {
    Amount::try_from(amount).unwrap_err();
    }
    }
    mod commodities {
    use {
    crate::Commodity,
    static_assertions::assert_impl_all,
    std::{fmt::Debug, hash::Hash, str::FromStr},
    test_case::test_case,
    };
    assert_impl_all!(
    Commodity: Copy,
    Debug,
    FromStr,
    Hash,
    Ord,
    TryFrom<&'static str>
    );
    #[test_case("A"; "single letter")]
    #[test_case("USD"; "dollar")]
    #[test_case("EUR"; "euro")]
    #[test_case("MSFT"; "stock")]
    #[test_case("AIRMILE"; "creative")]
    #[test_case("DE.-_3"; "with special characters")]
    fn parse_when_valid(name: &str) {
    let commodity = Commodity::try_from(name).unwrap();
    assert_eq!(commodity.to_string(), name);
    }
    #[test_case("0"; "starting with number")]
    #[test_case("D-"; "ending with dash")]
    #[test_case("E_"; "ending with underscore")]
    #[test_case("X."; "ending with dot")]
    #[test_case("X 3"; "containing space")]
    #[test_case("X\\0"; "containing backslash")]
    fn do_not_parse_when_invalid(name: &str) {
    Commodity::try_from(name).unwrap_err();
    }
    // TODO proptest?
    }
  • file addition: lib.rs (---r------)
    [0.44]
    use std::fmt::Display;
    use time::Date;
    mod account;
    mod amount;
    mod balance;
    mod commodity;
    mod cost;
    mod transaction;
    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;
    #[derive(Clone, Debug)]
    pub enum Directive {
    Balance(balance::Balance),
    Transaction(transaction::Transaction),
    }
    impl Directive {
    pub fn date(&self) -> Date {
    match self {
    Self::Balance(balance) => balance.date,
    Self::Transaction(transaction) => transaction.date,
    }
    }
    pub fn main_account(&self) -> Option<&Acc> {
    match self {
    Directive::Balance(balance) => Some(&balance.account),
    Directive::Transaction(transaction) => transaction
    .postings
    .get(0)
    .map(|posting| posting.account.as_ref()),
    }
    }
    }
    impl Display for Directive {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
    match self {
    Self::Balance(balance) => balance.fmt(f),
    Self::Transaction(transaction) => transaction.fmt(f),
    }
    }
    }
    impl From<balance::Balance> for Directive {
    fn from(balance: balance::Balance) -> Self {
    Self::Balance(balance)
    }
    }
    impl From<transaction::Transaction> for Directive {
    fn from(transaction: transaction::Transaction) -> Self {
    Self::Transaction(transaction)
    }
    }
    #[cfg(test)]
    mod that;
  • file addition: cost.rs (---r------)
    [0.44]
    use crate::amount::Amount;
    use std::fmt::Display;
    use std::hash::Hash;
    #[derive(Clone, Debug, Eq, Hash, PartialEq)]
    pub enum CostBasis {
    Empty,
    PerUnit(Amount),
    Total(Amount),
    }
    impl Display for CostBasis {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
    match self {
    Self::Empty => write!(f, "{{}}"),
    Self::PerUnit(amount) => write!(f, "{{{amount}}}"),
    Self::Total(amount) => write!(f, "{{{{{amount}}}}}"),
    }
    }
    }
  • file addition: commodity.rs (---r------)
    [0.44]
    use arrayvec::ArrayString;
    use snafu::ensure;
    use snafu::Backtrace;
    use snafu::Snafu;
    use std::fmt::Display;
    use std::str::FromStr;
    #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
    pub struct Commodity {
    pub(crate) name: ArrayString<24>,
    }
    impl Display for Commodity {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
    f.pad(&self.name)
    }
    }
    impl FromStr for Commodity {
    type Err = <Self as TryFrom<&'static str>>::Error;
    fn from_str(name: &str) -> Result<Self, Self::Err> {
    Self::try_from(name)
    }
    }
    impl TryFrom<&str> for Commodity {
    type Error = CommodityError;
    fn try_from(name: &str) -> Result<Self, Self::Error> {
    ensure!(
    lazy_regex::regex_is_match!("^[A-Z](?:[-A-Z0-9._]{0,22}[A-Z0-9])?$", name),
    CommoditySnafu { name }
    );
    let name = name.try_into().expect("length should fit");
    Ok(Self { name })
    }
    }
    #[derive(Debug, Snafu)]
    #[snafu(display("invalid commodity: {name:?}"))]
    pub struct CommodityError {
    pub(crate) name: String,
    pub(crate) backtrace: Backtrace,
    }
  • file addition: balance.rs (---r------)
    [0.44]
    use crate::Account;
    use crate::Amount;
    use std::fmt::Display;
    use std::hash::Hash;
    use time::Date;
    #[derive(Clone, Debug, Eq, Hash, PartialEq)]
    pub struct Balance {
    pub date: Date,
    pub account: Account,
    pub amount: Amount,
    }
    impl Display for Balance {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
    let Balance {
    date,
    account,
    amount,
    } = self;
    write!(f, "{date} balance {account} {amount}")
    }
    }
  • file addition: amount.rs (---r------)
    [0.44]
    use crate::Commodity;
    use rust_decimal::Decimal;
    use snafu::Backtrace;
    use snafu::OptionExt as _;
    use snafu::Snafu;
    use std::fmt::Display;
    use std::ops::Neg;
    use std::str::FromStr;
    #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
    pub struct Amount {
    pub amount: Decimal,
    pub commodity: Commodity,
    }
    impl Display for Amount {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
    let Self { amount, commodity } = self;
    write!(f, "{amount} {commodity}")
    }
    }
    impl FromStr for Amount {
    type Err = <Self as TryFrom<&'static str>>::Error;
    fn from_str(amount: &str) -> Result<Self, Self::Err> {
    Self::try_from(amount)
    }
    }
    impl Neg for Amount {
    type Output = Self;
    fn neg(self) -> Self::Output {
    Self {
    amount: -self.amount,
    ..self
    }
    }
    }
    impl PartialOrd for Amount {
    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
    (self.commodity == other.commodity).then(|| self.amount.cmp(&other.amount))
    }
    }
    impl TryFrom<&str> for Amount {
    type Error = AmountError;
    fn try_from(amount: &str) -> Result<Self, Self::Error> {
    let context = AmountSnafu { value: amount };
    let (amount, commodity) = amount.split_once(' ').context(context)?;
    let amount = amount.parse().map_err(|_| context.build())?;
    let commodity = commodity.parse().map_err(|_| context.build())?;
    Ok(Self { amount, commodity })
    }
    }
    #[derive(Debug, Snafu)]
    pub struct AmountError {
    value: String,
    backtrace: Backtrace,
    }
  • file addition: account.rs (---r------)
    [0.44]
    use delegate::delegate;
    use snafu::ensure;
    use snafu::Backtrace;
    use snafu::Snafu;
    use std::borrow::Borrow;
    use std::borrow::Cow;
    use std::cmp::Ordering;
    use std::fmt::Display;
    use std::hash::Hash;
    use std::iter::FusedIterator;
    use std::ops::Deref;
    use std::str::FromStr;
    use std::str::Split;
    #[derive(Debug)]
    #[repr(transparent)]
    pub struct Acc {
    name: str,
    }
    impl Acc {
    pub fn ancestors(&self) -> impl Iterator<Item = &Self> + '_ {
    Ancestors { next: Some(self) }
    }
    pub fn segments(&self) -> Segments<'_> {
    Segments {
    inner: self.name.split(':'),
    }
    }
    pub fn parent(&self) -> Option<&Self> {
    self.name
    .split_once(':')
    .map(|(parent, _)| unsafe { Self::from_unchecked(parent) })
    }
    const unsafe fn from_unchecked(name: &str) -> &Self {
    &*(name as *const _ as *const _)
    }
    }
    impl AsRef<str> for Acc {
    #[inline]
    fn as_ref(&self) -> &str {
    self.borrow()
    }
    }
    impl Borrow<str> for Acc {
    #[inline]
    fn borrow(&self) -> &str {
    &self.name
    }
    }
    impl Display for Acc {
    #[inline]
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
    f.pad(&self.name)
    }
    }
    impl Eq for Acc {}
    impl Hash for Acc {
    #[inline]
    fn hash<H>(&self, state: &mut H)
    where
    H: std::hash::Hasher,
    {
    self.name.hash(state);
    }
    }
    impl Ord for Acc {
    #[inline]
    fn cmp(&self, other: &Self) -> Ordering {
    self.segments().cmp(other.segments())
    }
    }
    impl PartialEq for Acc {
    #[inline]
    fn eq(&self, other: &Self) -> bool {
    self.cmp(other).is_eq()
    }
    }
    impl PartialEq<&str> for Acc {
    #[inline]
    fn eq(&self, other: &&str) -> bool {
    self.partial_cmp(other).map_or(false, Ordering::is_eq)
    }
    }
    impl PartialEq<Acc> for &str {
    #[inline]
    fn eq(&self, other: &Acc) -> bool {
    self.partial_cmp(other).map_or(false, Ordering::is_eq)
    }
    }
    impl PartialEq<Acc> for Cow<'_, Acc> {
    #[inline]
    fn eq(&self, other: &Acc) -> bool {
    self.partial_cmp(other).map_or(false, Ordering::is_eq)
    }
    }
    impl PartialEq<Acc> for Cow<'_, str> {
    #[inline]
    fn eq(&self, other: &Acc) -> bool {
    self.partial_cmp(other).map_or(false, Ordering::is_eq)
    }
    }
    impl PartialEq<Acc> for String {
    #[inline]
    fn eq(&self, other: &Acc) -> bool {
    self.partial_cmp(other).map_or(false, Ordering::is_eq)
    }
    }
    impl PartialEq<Acc> for str {
    #[inline]
    fn eq(&self, other: &Acc) -> bool {
    self.partial_cmp(other).map_or(false, Ordering::is_eq)
    }
    }
    impl PartialEq<Cow<'_, Self>> for Acc {
    #[inline]
    fn eq(&self, other: &Cow<'_, Self>) -> bool {
    self.partial_cmp(other).map_or(false, Ordering::is_eq)
    }
    }
    impl PartialEq<Cow<'_, str>> for Acc {
    #[inline]
    fn eq(&self, other: &Cow<'_, str>) -> bool {
    self.partial_cmp(other).map_or(false, Ordering::is_eq)
    }
    }
    impl PartialEq<String> for Acc {
    #[inline]
    fn eq(&self, other: &String) -> bool {
    self.partial_cmp(other).map_or(false, Ordering::is_eq)
    }
    }
    impl PartialEq<str> for Acc {
    #[inline]
    fn eq(&self, other: &str) -> bool {
    self.partial_cmp(other).map_or(false, Ordering::is_eq)
    }
    }
    impl PartialOrd for Acc {
    #[inline]
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
    Some(self.cmp(other))
    }
    }
    impl PartialOrd<&str> for Acc {
    #[inline]
    fn partial_cmp(&self, other: &&str) -> Option<Ordering> {
    self.partial_cmp(*other)
    }
    }
    impl PartialOrd<Acc> for &str {
    #[inline]
    fn partial_cmp(&self, other: &Acc) -> Option<Ordering> {
    other.partial_cmp(self).map(Ordering::reverse)
    }
    }
    impl PartialOrd<Acc> for Cow<'_, Acc> {
    #[inline]
    fn partial_cmp(&self, other: &Acc) -> Option<Ordering> {
    other.partial_cmp(self).map(Ordering::reverse)
    }
    }
    impl PartialOrd<Acc> for Cow<'_, str> {
    #[inline]
    fn partial_cmp(&self, other: &Acc) -> Option<Ordering> {
    other.partial_cmp(self).map(Ordering::reverse)
    }
    }
    impl PartialOrd<Acc> for String {
    #[inline]
    fn partial_cmp(&self, other: &Acc) -> Option<Ordering> {
    other.partial_cmp(self).map(Ordering::reverse)
    }
    }
    impl PartialOrd<Acc> for str {
    #[inline]
    fn partial_cmp(&self, other: &Acc) -> Option<Ordering> {
    other.partial_cmp(self).map(Ordering::reverse)
    }
    }
    impl PartialOrd<Cow<'_, Acc>> for Acc {
    fn partial_cmp(&self, other: &Cow<'_, Acc>) -> Option<Ordering> {
    self.partial_cmp(&**other)
    }
    }
    impl PartialOrd<Cow<'_, str>> for Acc {
    fn partial_cmp(&self, other: &Cow<'_, str>) -> Option<Ordering> {
    self.partial_cmp(&**other)
    }
    }
    impl PartialOrd<String> for Acc {
    #[inline]
    fn partial_cmp(&self, other: &String) -> Option<Ordering> {
    self.partial_cmp(&**other)
    }
    }
    impl PartialOrd<str> for Acc {
    #[inline]
    fn partial_cmp(&self, other: &str) -> Option<Ordering> {
    other.try_into().ok().map(|other| self.cmp(other))
    }
    }
    impl ToOwned for Acc {
    type Owned = Account;
    fn to_owned(&self) -> Self::Owned {
    Account {
    name: self.name.to_owned(),
    }
    }
    }
    impl<'a> TryFrom<&'a str> for &'a Acc {
    type Error = AccountError;
    fn try_from(name: &'a str) -> Result<Self, Self::Error> {
    ensure!(is_valid_account_name(name), AccountSnafu { name });
    Ok(unsafe { Acc::from_unchecked(name) })
    }
    }
    #[derive(Clone, Debug)]
    #[repr(transparent)]
    pub struct Account {
    name: String,
    }
    impl Account {
    pub fn join(self, segment: impl AsRef<str>) -> Result<Self, AccountError> {
    fn join_inner(mut this: Account, segment: &str) -> Result<Account, AccountError> {
    ensure!(
    is_valid_account_segment(segment),
    AccountSnafu { name: segment }
    );
    this.name.push(':');
    this.name.push_str(segment);
    Ok(this)
    }
    join_inner(self, segment.as_ref())
    }
    }
    impl AsRef<Acc> for Account {
    #[inline]
    fn as_ref(&self) -> &Acc {
    self
    }
    }
    impl AsRef<String> for Account {
    #[inline]
    fn as_ref(&self) -> &String {
    self.borrow()
    }
    }
    impl AsRef<str> for Account {
    #[inline]
    fn as_ref(&self) -> &str {
    self.borrow()
    }
    }
    impl Borrow<Acc> for Account {
    #[inline]
    fn borrow(&self) -> &Acc {
    self
    }
    }
    impl Borrow<String> for Account {
    #[inline]
    fn borrow(&self) -> &String {
    &self.name
    }
    }
    impl Borrow<str> for Account {
    #[inline]
    fn borrow(&self) -> &str {
    &self.name
    }
    }
    impl Deref for Account {
    type Target = Acc;
    #[inline]
    fn deref(&self) -> &Self::Target {
    unsafe { Acc::from_unchecked(&self.name) }
    }
    }
    impl Display for Account {
    #[inline]
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
    (**self).fmt(f)
    }
    }
    impl Eq for Account {}
    impl From<&Acc> for Account {
    #[inline]
    fn from(acc: &Acc) -> Self {
    acc.to_owned()
    }
    }
    impl FromStr for Account {
    type Err = <Self as TryFrom<&'static str>>::Error;
    #[inline]
    fn from_str(name: &str) -> Result<Self, Self::Err> {
    Self::try_from(name)
    }
    }
    impl Hash for Account {
    #[inline]
    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
    (**self).hash(state)
    }
    }
    impl Ord for Account {
    #[inline]
    fn cmp(&self, other: &Self) -> Ordering {
    (**self).cmp(&**other)
    }
    }
    impl PartialEq for Account {
    #[inline]
    fn eq(&self, other: &Self) -> bool {
    self.cmp(other).is_eq()
    }
    }
    impl PartialEq<&Acc> for Account {
    #[inline]
    fn eq(&self, other: &&Acc) -> bool {
    self.partial_cmp(other).map_or(false, Ordering::is_eq)
    }
    }
    impl PartialEq<&str> for Account {
    #[inline]
    fn eq(&self, other: &&str) -> bool {
    self.partial_cmp(other).map_or(false, Ordering::is_eq)
    }
    }
    impl PartialEq<Acc> for Account {
    #[inline]
    fn eq(&self, other: &Acc) -> bool {
    self.partial_cmp(other).map_or(false, Ordering::is_eq)
    }
    }
    impl PartialEq<Account> for &Acc {
    #[inline]
    fn eq(&self, other: &Account) -> bool {
    self.partial_cmp(other).map_or(false, Ordering::is_eq)
    }
    }
    impl PartialEq<Account> for &str {
    #[inline]
    fn eq(&self, other: &Account) -> bool {
    self.partial_cmp(other).map_or(false, Ordering::is_eq)
    }
    }
    impl PartialEq<Account> for Acc {
    #[inline]
    fn eq(&self, other: &Account) -> bool {
    self.partial_cmp(other).map_or(false, Ordering::is_eq)
    }
    }
    impl PartialEq<Account> for Cow<'_, Acc> {
    #[inline]
    fn eq(&self, other: &Account) -> bool {
    self.partial_cmp(other).map_or(false, Ordering::is_eq)
    }
    }
    impl PartialEq<Account> for Cow<'_, str> {
    #[inline]
    fn eq(&self, other: &Account) -> bool {
    self.partial_cmp(other).map_or(false, Ordering::is_eq)
    }
    }
    impl PartialEq<Account> for String {
    #[inline]
    fn eq(&self, other: &Account) -> bool {
    self.partial_cmp(other).map_or(false, Ordering::is_eq)
    }
    }
    impl PartialEq<Account> for str {
    #[inline]
    fn eq(&self, other: &Account) -> bool {
    self.partial_cmp(other).map_or(false, Ordering::is_eq)
    }
    }
    impl PartialEq<Cow<'_, Acc>> for Account {
    #[inline]
    fn eq(&self, other: &Cow<'_, Acc>) -> bool {
    self.partial_cmp(other).map_or(false, Ordering::is_eq)
    }
    }
    impl PartialEq<Cow<'_, str>> for Account {
    #[inline]
    fn eq(&self, other: &Cow<'_, str>) -> bool {
    self.partial_cmp(other).map_or(false, Ordering::is_eq)
    }
    }
    impl PartialEq<String> for Account {
    #[inline]
    fn eq(&self, other: &String) -> bool {
    self.partial_cmp(other).map_or(false, Ordering::is_eq)
    }
    }
    impl PartialEq<str> for Account {
    #[inline]
    fn eq(&self, other: &str) -> bool {
    self.partial_cmp(other).map_or(false, Ordering::is_eq)
    }
    }
    impl PartialOrd for Account {
    #[inline]
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
    Some(self.cmp(other))
    }
    }
    impl PartialOrd<&Acc> for Account {
    #[inline]
    fn partial_cmp(&self, other: &&Acc) -> Option<Ordering> {
    self.partial_cmp(*other)
    }
    }
    impl PartialOrd<&str> for Account {
    #[inline]
    fn partial_cmp(&self, other: &&str) -> Option<Ordering> {
    self.partial_cmp(*other)
    }
    }
    impl PartialOrd<Acc> for Account {
    #[inline]
    fn partial_cmp(&self, other: &Acc) -> Option<Ordering> {
    (**self).partial_cmp(other)
    }
    }
    impl PartialOrd<Account> for &Acc {
    #[inline]
    fn partial_cmp(&self, other: &Account) -> Option<Ordering> {
    other.partial_cmp(self).map(Ordering::reverse)
    }
    }
    impl PartialOrd<Account> for &str {
    #[inline]
    fn partial_cmp(&self, other: &Account) -> Option<Ordering> {
    other.partial_cmp(self).map(Ordering::reverse)
    }
    }
    impl PartialOrd<Account> for Acc {
    #[inline]
    fn partial_cmp(&self, other: &Account) -> Option<Ordering> {
    other.partial_cmp(self).map(Ordering::reverse)
    }
    }
    impl PartialOrd<Account> for Cow<'_, Acc> {
    #[inline]
    fn partial_cmp(&self, other: &Account) -> Option<Ordering> {
    other.partial_cmp(self).map(Ordering::reverse)
    }
    }
    impl PartialOrd<Account> for Cow<'_, str> {
    #[inline]
    fn partial_cmp(&self, other: &Account) -> Option<Ordering> {
    other.partial_cmp(self).map(Ordering::reverse)
    }
    }
    impl PartialOrd<Account> for String {
    #[inline]
    fn partial_cmp(&self, other: &Account) -> Option<Ordering> {
    other.partial_cmp(self).map(Ordering::reverse)
    }
    }
    impl PartialOrd<Account> for str {
    #[inline]
    fn partial_cmp(&self, other: &Account) -> Option<Ordering> {
    other.partial_cmp(self).map(Ordering::reverse)
    }
    }
    impl PartialOrd<Cow<'_, Acc>> for Account {
    fn partial_cmp(&self, other: &Cow<'_, Acc>) -> Option<Ordering> {
    self.partial_cmp(&**other)
    }
    }
    impl PartialOrd<Cow<'_, str>> for Account {
    fn partial_cmp(&self, other: &Cow<'_, str>) -> Option<Ordering> {
    self.partial_cmp(&**other)
    }
    }
    impl PartialOrd<String> for Account {
    #[inline]
    fn partial_cmp(&self, other: &String) -> Option<Ordering> {
    self.partial_cmp(&**other)
    }
    }
    impl PartialOrd<str> for Account {
    #[inline]
    fn partial_cmp(&self, other: &str) -> Option<Ordering> {
    (**self).partial_cmp(other)
    }
    }
    impl TryFrom<&str> for Account {
    type Error = AccountError;
    #[inline]
    fn try_from(name: &str) -> Result<Self, Self::Error> {
    <&Acc>::try_from(name).map(Self::from)
    }
    }
    impl TryFrom<String> for Account {
    type Error = <Self as TryFrom<&'static str>>::Error;
    #[inline]
    fn try_from(name: String) -> Result<Self, Self::Error> {
    ensure!(is_valid_account_name(&name), AccountSnafu { name });
    Ok(Self { name })
    }
    }
    #[derive(Debug, Snafu)]
    #[snafu(display("invalid account: {name:?}"))]
    pub struct AccountError {
    name: String,
    backtrace: Backtrace,
    }
    struct Ancestors<'a> {
    next: Option<&'a Acc>,
    }
    impl FusedIterator for Ancestors<'_> {}
    impl<'a> Iterator for Ancestors<'a> {
    type Item = &'a Acc;
    fn next(&mut self) -> Option<Self::Item> {
    let next = self.next?;
    self.next = next.parent();
    Some(next)
    }
    }
    #[derive(Clone, Debug)]
    pub struct Segments<'a> {
    inner: Split<'a, char>,
    }
    impl DoubleEndedIterator for Segments<'_> {
    delegate! {
    to self.inner {
    fn next_back(&mut self) -> Option<Self::Item>;
    }
    }
    }
    impl FusedIterator for Segments<'_> {}
    impl<'a> Iterator for Segments<'a> {
    type Item = &'a str;
    delegate! {
    to self.inner {
    fn next(&mut self) -> Option<Self::Item>;
    }
    }
    }
    fn is_valid_account_name(name: &str) -> bool {
    lazy_regex::regex_is_match!(
    r#"^(?:Assets|Equity|Expenses|Income|Liabilities)(?::[\p{Lu}\p{Nd}][-\p{L}\p{Nd}]*)*$"#,
    name
    )
    }
    fn is_valid_account_segment(name: &str) -> bool {
    lazy_regex::regex_is_match!(r#"^(?:[\p{Lu}\p{Nd}][-\p{L}\p{Nd}]*)$"#, name)
    }
  • file addition: Cargo.toml (---r------)
    [0.27]
    [package]
    name = "beancount-types"
    version = "0.0.0-dev.0"
    edition = "2021"
    # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
    [dependencies]
    arrayvec = "0.7.2"
    delegate = "0.8.0"
    lazy-regex = "2.2.2"
    once_cell = "1.9.0"
    regex = "1.5.4"
    rust_decimal = "1.21.0"
    snafu = "0.7.0"
    time = "0.3.7"
    [dev-dependencies]
    insta = "1.12.0"
    proptest = "1.0.0"
    static_assertions = "1.1.0"
    test-case = "2.2.1"
    [features]
  • replacement in Cargo.toml at line 2
    [2.9844][2.9844:9880]()
    members = ["common/german-decimal"]
    [2.9844]
    members = ["common/beancount-types", "common/german-decimal"]
  • edit in Cargo.lock at line 6
    [2.10033]
    [2.10033]
    name = "aho-corasick"
    version = "0.7.19"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "b4f55bd91a0978cbfd91c457a164bab8b4001c833b7f323132c0a4e1922dd44e"
    dependencies = [
    "memchr",
    ]
    [[package]]
  • edit in Cargo.lock at line 27
    [2.10416]
    [2.10416]
    name = "beancount-types"
    version = "0.0.0-dev.0"
    dependencies = [
    "arrayvec",
    "delegate",
    "insta",
    "lazy-regex",
    "once_cell",
    "proptest",
    "regex",
    "rust_decimal",
    "snafu",
    "static_assertions",
    "test-case",
    "time",
    ]
    [[package]]
    name = "bit-set"
    version = "0.5.3"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1"
    dependencies = [
    "bit-vec",
    ]
    [[package]]
    name = "bit-vec"
    version = "0.6.3"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb"
    [[package]]
    name = "bitflags"
    version = "1.3.2"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
    [[package]]
    name = "byteorder"
    version = "1.4.3"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
    [[package]]
    name = "cfg-if"
    version = "1.0.0"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
    [[package]]
    name = "console"
    version = "0.15.1"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "89eab4d20ce20cea182308bca13088fecea9c05f6776cf287205d41a0ed3c847"
    dependencies = [
    "encode_unicode",
    "libc",
    "once_cell",
    "terminal_size",
    "winapi",
    ]
    [[package]]
    name = "delegate"
    version = "0.8.0"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "082a24a9967533dc5d743c602157637116fc1b52806d694a5a45e6f32567fcdd"
    dependencies = [
    "proc-macro2",
    "quote",
    "syn",
    ]
    [[package]]
    name = "doc-comment"
    version = "0.3.3"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10"
    [[package]]
    name = "encode_unicode"
    version = "0.3.6"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f"
    [[package]]
    name = "fastrand"
    version = "1.8.0"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499"
    dependencies = [
    "instant",
    ]
    [[package]]
    name = "fnv"
    version = "1.0.7"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
    [[package]]
  • edit in Cargo.lock at line 134
    [2.10522]
    [2.10522]
    ]
    [[package]]
    name = "getrandom"
    version = "0.2.7"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6"
    dependencies = [
    "cfg-if",
    "libc",
    "wasi",
  • edit in Cargo.lock at line 146
    [2.10524]
    [2.10524]
    [[package]]
    name = "heck"
    version = "0.4.0"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9"
  • edit in Cargo.lock at line 154
    [2.10537]
    [2.10537]
    name = "insta"
    version = "1.19.1"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "fc61e98be01e89296f3343a878e9f8ca75a494cb5aaf29df65ef55734aeb85f5"
    dependencies = [
    "console",
    "linked-hash-map",
    "once_cell",
    "similar",
    "yaml-rust",
    ]
    [[package]]
    name = "instant"
    version = "0.1.12"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
    dependencies = [
    "cfg-if",
    ]
    [[package]]
    name = "lazy-regex"
    version = "2.3.0"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "b6b12f2eb6ed7d39405c5eb25a034b4c106a9ad87a6d9be3298de6c5f32fd57d"
    dependencies = [
    "lazy-regex-proc_macros",
    "once_cell",
    "regex",
    ]
    [[package]]
    name = "lazy-regex-proc_macros"
    version = "2.3.0"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "f2496e5264069bc726ccf37eb76b9cd89406ae110d836c3f76729f99c8a23293"
    dependencies = [
    "proc-macro2",
    "quote",
    "regex",
    "syn",
    ]
    [[package]]
    name = "lazy_static"
    version = "1.4.0"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
    [[package]]
    name = "libc"
    version = "0.2.132"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "8371e4e5341c3a96db127eb2465ac681ced4c433e01dd0e938adbef26ba93ba5"
    [[package]]
    name = "linked-hash-map"
    version = "0.5.6"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"
    [[package]]
    name = "memchr"
    version = "2.5.0"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
    [[package]]
  • edit in Cargo.lock at line 229
    [2.10748]
    [2.10748]
    ]
    [[package]]
    name = "num_threads"
    version = "0.1.6"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44"
    dependencies = [
    "libc",
    ]
    [[package]]
    name = "once_cell"
    version = "1.14.0"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "2f7254b99e31cad77da24b08ebf628882739a608578bb1bcdfc1f9c21260d7c0"
    [[package]]
    name = "ppv-lite86"
    version = "0.2.16"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872"
    [[package]]
    name = "proc-macro-error"
    version = "1.0.4"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
    dependencies = [
    "proc-macro-error-attr",
    "proc-macro2",
    "quote",
    "syn",
    "version_check",
    ]
    [[package]]
    name = "proc-macro-error-attr"
    version = "1.0.4"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
    dependencies = [
    "proc-macro2",
    "quote",
    "version_check",
  • edit in Cargo.lock at line 286
    [2.10996]
    [2.10996]
    name = "proptest"
    version = "1.0.0"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "1e0d9cc07f18492d879586c92b485def06bc850da3118075cd45d50e9c95b0e5"
    dependencies = [
    "bit-set",
    "bitflags",
    "byteorder",
    "lazy_static",
    "num-traits",
    "quick-error 2.0.1",
    "rand",
    "rand_chacha",
    "rand_xorshift",
    "regex-syntax",
    "rusty-fork",
    "tempfile",
    ]
    [[package]]
    name = "quick-error"
    version = "1.2.3"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
    [[package]]
    name = "quick-error"
    version = "2.0.1"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3"
    [[package]]
  • edit in Cargo.lock at line 324
    [2.11206]
    [2.11206]
    ]
    [[package]]
    name = "rand"
    version = "0.8.5"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
    dependencies = [
    "libc",
    "rand_chacha",
    "rand_core",
    ]
    [[package]]
    name = "rand_chacha"
    version = "0.3.1"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
    dependencies = [
    "ppv-lite86",
    "rand_core",
    ]
    [[package]]
    name = "rand_core"
    version = "0.6.3"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7"
    dependencies = [
    "getrandom",
    ]
    [[package]]
    name = "rand_xorshift"
    version = "0.3.0"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "d25bf25ec5ae4a3f1b92f929810509a2f53d7dca2f50b794ff57e3face536c8f"
    dependencies = [
    "rand_core",
    ]
    [[package]]
    name = "redox_syscall"
    version = "0.2.16"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
    dependencies = [
    "bitflags",
    ]
    [[package]]
    name = "regex"
    version = "1.6.0"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b"
    dependencies = [
    "aho-corasick",
    "memchr",
    "regex-syntax",
    ]
    [[package]]
    name = "regex-syntax"
    version = "0.6.27"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244"
    [[package]]
    name = "remove_dir_all"
    version = "0.5.3"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7"
    dependencies = [
    "winapi",
  • edit in Cargo.lock at line 419
    [2.11710]
    [2.11710]
    ]
    [[package]]
    name = "rusty-fork"
    version = "0.3.0"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "cb3dcc6e454c328bb824492db107ab7c0ae8fcffe4ad210136ef014458c1bc4f"
    dependencies = [
    "fnv",
    "quick-error 1.2.3",
    "tempfile",
    "wait-timeout",
  • edit in Cargo.lock at line 438
    [2.11903]
    [2.11903]
    [[package]]
    name = "similar"
    version = "2.2.0"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "62ac7f900db32bf3fd12e0117dd3dc4da74bc52ebaac97f39668446d89694803"
    [[package]]
    name = "snafu"
    version = "0.7.1"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "5177903bf45656592d9eb5c0e22f408fc023aae51dbe2088889b71633ba451f2"
    dependencies = [
    "doc-comment",
    "snafu-derive",
    ]
    [[package]]
    name = "snafu-derive"
    version = "0.7.1"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "410b26ed97440d90ced3e2488c868d56a86e2064f5d7d6f417909b286afe25e5"
    dependencies = [
    "heck",
    "proc-macro2",
    "quote",
    "syn",
    ]
    [[package]]
    name = "static_assertions"
    version = "1.1.0"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
    [[package]]
    name = "syn"
    version = "1.0.99"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "58dbef6ec655055e20b86b15a8cc6d439cca19b667537ac6a1369572d151ab13"
    dependencies = [
    "proc-macro2",
    "quote",
    "unicode-ident",
    ]
    [[package]]
    name = "tempfile"
    version = "3.3.0"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4"
    dependencies = [
    "cfg-if",
    "fastrand",
    "libc",
    "redox_syscall",
    "remove_dir_all",
    "winapi",
    ]
    [[package]]
    name = "terminal_size"
    version = "0.1.17"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "633c1a546cee861a1a6d0dc69ebeca693bf4296661ba7852b9d21d159e0506df"
    dependencies = [
    "libc",
    "winapi",
    ]
    [[package]]
    name = "test-case"
    version = "2.2.1"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "07aea929e9488998b64adc414c29fe5620398f01c2e3f58164122b17e567a6d5"
    dependencies = [
    "test-case-macros",
    ]
    [[package]]
    name = "test-case-macros"
    version = "2.2.1"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "c95968eedc6fc4f5c21920e0f4264f78ec5e4c56bb394f319becc1a5830b3e54"
    dependencies = [
    "cfg-if",
    "proc-macro-error",
    "proc-macro2",
    "quote",
    "syn",
    ]
    [[package]]
    name = "time"
    version = "0.3.14"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "3c3f9a28b618c3a6b9251b6908e9c99e04b9e5c02e6581ccbb67d59c34ef7f9b"
    dependencies = [
    "libc",
    "num_threads",
    ]
  • edit in Cargo.lock at line 545
    [2.12100]
    [[package]]
    name = "version_check"
    version = "0.9.4"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
    [[package]]
    name = "wait-timeout"
    version = "0.2.0"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6"
    dependencies = [
    "libc",
    ]
    [[package]]
    name = "wasi"
    version = "0.11.0+wasi-snapshot-preview1"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
    [[package]]
    name = "winapi"
    version = "0.3.9"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
    dependencies = [
    "winapi-i686-pc-windows-gnu",
    "winapi-x86_64-pc-windows-gnu",
    ]
    [[package]]
    name = "winapi-i686-pc-windows-gnu"
    version = "0.4.0"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
    [[package]]
    name = "winapi-x86_64-pc-windows-gnu"
    version = "0.4.0"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
    [[package]]
    name = "yaml-rust"
    version = "0.4.5"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85"
    dependencies = [
    "linked-hash-map",
    ]