edit in beancount/types/src/metadata/link.rs at line 25
+ }
+
+ #[cfg(feature = "arbitrary")]
+ impl<'a> arbitrary::Arbitrary<'a> for Link {
+ fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
+ use core::ops::ControlFlow;
+
+ const VALID_CHARS: &[u8] =
+ b"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_/.";
+
+ let mut inner = String::from("^");
+
+ u.arbitrary_loop(Some(1), Some(30), |u| {
+ inner.push(char::from(*u.choose(VALID_CHARS)?));
+
+ Ok(ControlFlow::Continue(()))
+ })?;
+
+ Self::try_from(inner).map_err(|_| arbitrary::Error::IncorrectFormat)
+ }
edit in beancount/types/src/metadata/kv.rs at line 41
+
+ #[cfg(feature = "arbitrary")]
+ impl<'a> arbitrary::Arbitrary<'a> for Key {
+ fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
+ use core::ops::ControlFlow;
edit in beancount/types/src/metadata/kv.rs at line 47
+ const VALID_CHARS: &[u8] =
+ b"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_";
+
+ let mut inner = String::new();
+ inner.push(char::from(*u.choose(&VALID_CHARS[..26])?));
+
+ u.arbitrary_loop(Some(1), Some(29), |u| {
+ inner.push(char::from(*u.choose(VALID_CHARS)?));
+
+ Ok(ControlFlow::Continue(()))
+ })?;
+
+ Self::try_from(dbg!(inner)).map_err(|_| arbitrary::Error::IncorrectFormat)
+ }
+ }
+
edit in beancount/types/src/metadata/kv.rs at line 213
+ }
+ }
+ }
+
+ #[cfg(feature = "arbitrary")]
+ impl<'a> arbitrary::Arbitrary<'a> for Value {
+ fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
+ match u.int_in_range(0..=2u8)? {
+ 0 => crate::core::ArbitraryDate::arbitrary(u)
+ .map(Date::from)
+ .map(Self::Date),
+ 1 => Decimal::arbitrary(u).map(Self::Number),
+ 2 => String::arbitrary(u).map(Self::String),
+ _ => unreachable!(),
edit in beancount/types/src/directive.rs at line 34
+ #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
edit in beancount/types/src/directive/transaction.rs at line 25
+ #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
edit in beancount/types/src/directive/transaction.rs at line 42
+ #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
edit in beancount/types/src/directive/transaction.rs at line 336
+
+ #[cfg(feature = "arbitrary")]
+ impl<'a> arbitrary::Arbitrary<'a> for Transaction {
+ fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
+ let date = crate::core::ArbitraryDate::arbitrary(u)?.into();
+ let flag = <_>::arbitrary(u)?;
+ let payee = <_>::arbitrary(u)?;
+ let narration = <_>::arbitrary(u)?;
+ let links = <_>::arbitrary(u)?;
+ let meta = dbg!(<_>::arbitrary(u))?;
+ let postings = <_>::arbitrary(u)?;
edit in beancount/types/src/directive/transaction.rs at line 348
+ Ok(Self {
+ date,
+ flag,
+ payee,
+ narration,
+ links,
+ meta,
+ postings,
+ })
+ }
+ }
+
edit in beancount/types/src/directive/price.rs at line 81
+ #[cfg(feature = "arbitrary")]
+ impl<'a> arbitrary::Arbitrary<'a> for Price {
+ fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
+ let date = crate::core::ArbitraryDate::arbitrary(u)?.into();
+ let quote = <_>::arbitrary(u)?;
+ let price = <_>::arbitrary(u)?;
+ let meta = <_>::arbitrary(u)?;
+
+ Ok(Self {
+ date,
+ quote,
+ price,
+ meta,
+ })
+ }
+ }
+
edit in beancount/types/src/directive/open.rs at line 114
+
+ #[cfg(feature = "arbitrary")]
+ impl<'a> arbitrary::Arbitrary<'a> for Open {
+ fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
+ let date = crate::core::ArbitraryDate::arbitrary(u)?.into();
+ let account = <_>::arbitrary(u)?;
+ let commodities = <_>::arbitrary(u)?;
+ let booking = <_>::arbitrary(u)?;
+ let meta = <_>::arbitrary(u)?;
edit in beancount/types/src/directive/open.rs at line 124
+ Ok(Self {
+ date,
+ account,
+ commodities,
+ booking,
+ meta,
+ })
+ }
+ }
+
edit in beancount/types/src/directive/close.rs at line 74
+
+ #[cfg(feature = "arbitrary")]
+ impl<'a> arbitrary::Arbitrary<'a> for Close {
+ fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
+ let date = crate::core::ArbitraryDate::arbitrary(u)?.into();
+ let account = <_>::arbitrary(u)?;
+ let meta = <_>::arbitrary(u)?;
edit in beancount/types/src/directive/close.rs at line 82
+ Ok(Self {
+ date,
+ account,
+ meta,
+ })
+ }
+ }
+
edit in beancount/types/src/directive/balance.rs at line 81
+ #[cfg(feature = "arbitrary")]
+ impl<'a> arbitrary::Arbitrary<'a> for Balance {
+ fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
+ let date = crate::core::ArbitraryDate::arbitrary(u)?.into();
+ let account = <_>::arbitrary(u)?;
+ let amount = <_>::arbitrary(u)?;
+ let meta = <_>::arbitrary(u)?;
+
+ Ok(Self {
+ date,
+ account,
+ amount,
+ meta,
+ })
+ }
+ }
+
edit in beancount/types/src/core.rs at line 6
+
+ #[cfg(feature = "arbitrary")]
+ #[derive(Clone, Copy, Debug)]
+ pub struct ArbitraryDate(time::Date);
+
+ #[cfg(feature = "arbitrary")]
+ const _: () = {
+ impl<'a> arbitrary::Arbitrary<'a> for ArbitraryDate {
+ fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
+ use time::Date;
+
+ let julian_day =
+ u.int_in_range(Date::MIN.to_julian_day()..=Date::MAX.to_julian_day())?;
+ let date = time::Date::from_julian_day(julian_day).expect("valid julian day");
+
+ Ok(Self(date))
+ }
+
+ #[inline]
+ fn size_hint(depth: usize) -> (usize, Option<usize>) {
+ i32::size_hint(depth)
+ }
+ }
+
+ impl From<ArbitraryDate> for time::Date {
+ fn from(value: ArbitraryDate) -> Self {
+ value.0
+ }
+ }
+ };
edit in beancount/types/src/core/price.rs at line 10
+ #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
edit in beancount/types/src/core/cost.rs at line 17
+ #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
edit in beancount/types/src/core/cost.rs at line 176
+ #[cfg(feature = "arbitrary")]
+ impl<'a> arbitrary::Arbitrary<'a> for Spec {
+ fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
+ let basis = <_>::arbitrary(u)?;
+ let date = Option::<crate::core::ArbitraryDate>::arbitrary(u)?.map(Date::from);
+ let label = <_>::arbitrary(u)?;
+
+ Ok(Self { basis, date, label })
+ }
+ }
+
edit in beancount/types/src/core/commodity.rs at line 25
+
+ #[cfg(feature = "arbitrary")]
+ impl<'a> arbitrary::Arbitrary<'a> for Commodity {
+ fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
+ use core::ops::ControlFlow;
+
+ const VALID_CHARS: &[u8] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZ";
edit in beancount/types/src/core/commodity.rs at line 33
+ let mut inner = String::new();
+
+ u.arbitrary_loop(Some(1), Some(24), |u| {
+ inner.push(char::from(*u.choose(VALID_CHARS)?));
+
+ Ok(ControlFlow::Continue(()))
+ })?;
+
+ Self::try_from(inner).map_err(|_| arbitrary::Error::IncorrectFormat)
+ }
+ }
+
edit in beancount/types/src/core/amount.rs at line 135
+ #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
edit in beancount/types/src/core/account.rs at line 373
+
+ #[cfg(feature = "arbitrary")]
+ impl<'a> arbitrary::Arbitrary<'a> for Account {
+ fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
+ const VALID_ROOTS: [&str; 5] = ["Assets", "Equity", "Expenses", "Income", "Liabilities"];
+
+ let this = Self::try_from(*u.choose(&VALID_ROOTS)?)
+ .map_err(|_| arbitrary::Error::IncorrectFormat)?;
+
+ u.arbitrary_iter::<Segment>()?
+ .try_fold(this, |this, seg| Ok(this.join(seg?)))
+ }
edit in beancount/types/src/core/account.rs at line 386
+ fn arbitrary_take_rest(mut u: arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
+ const VALID_ROOTS: [&str; 5] = ["Assets", "Equity", "Expenses", "Income", "Liabilities"];
+
+ let this = Self::try_from(*u.choose(&VALID_ROOTS)?)
+ .map_err(|_| arbitrary::Error::IncorrectFormat)?;
+
+ u.arbitrary_take_rest_iter::<Segment>()?
+ .try_fold(this, |this, seg| Ok(this.join(seg?)))
+ }
+ }
+
edit in beancount/types/src/core/account.rs at line 982
+
+ #[cfg(feature = "arbitrary")]
+ impl<'a> arbitrary::Arbitrary<'a> for Segment {
+ fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
+ use core::ops::ControlFlow;
edit in beancount/types/src/core/account.rs at line 988
+ const VALID_CHARS: &[u8] =
+ b"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz-";
+
+ let mut inner = String::new();
+ inner.push(char::from(*u.choose(&VALID_CHARS[..36])?));
+
+ u.arbitrary_loop(None, Some(29), |u| {
+ inner.push(char::from(*u.choose(VALID_CHARS)?));
+
+ Ok(ControlFlow::Continue(()))
+ })?;
+
+ Self::try_from(inner).map_err(|_| arbitrary::Error::IncorrectFormat)
+ }
+ }
+
file move: Cargo.toml (---r------) → Cargo.toml (----------)
edit in beancount/types/Cargo.toml at line 26
+
+ [dependencies.arbitrary]
+ optional = true
+ workspace = true
edit in beancount/types/Cargo.toml at line 39
+
+ [features]
+ arbitrary = ["dep:arbitrary", "rust_decimal/rust-fuzz"]
+
+ [[test]]
+ name = "arbitrary"
+ required-features = ["arbitrary"]
edit in Cargo.toml at line 92
+
+ [workspace.dependencies.arbitrary]
+ features = ["derive"]
+ version = "1.3.2"
edit in Cargo.lock at line 105
+
+ [[package]]
+ name = "arbitrary"
+ version = "1.3.2"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+ checksum = "7d5a26814d8dcb93b0e5a0ff3c6d80a8843bafb21b39e8e18a6f05471870e110"
+ dependencies = [
+ "derive_arbitrary",
+ ]
+
+ [[package]]
edit in Cargo.lock at line 488
edit in Cargo.lock at line 988
+ name = "derive_arbitrary"
+ version = "1.3.2"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+ checksum = "67e77553c4162a157adbf834ebae5b415acbecbeafc7a74b0e886657506a7611"
+ dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.58",
+ ]
+
+ [[package]]
resolve order conflict in Cargo.lock at line 5015