plutus_ledger_api/generators/correct/
primitive.rs

1//! Proptest strategies for most common primitive types
2//!
3//! These strategies always return valid values.
4use num_bigint::{BigInt, BigUint, Sign};
5use num_traits::identities::Zero;
6use proptest::arbitrary::{any, StrategyFor};
7use proptest::char::CharStrategy;
8use proptest::collection::vec;
9use proptest::collection::{btree_map, btree_set};
10use proptest::option;
11use proptest::prelude::{prop_oneof, Just};
12use proptest::result::maybe_err;
13use proptest::strategy::Strategy;
14use std::collections::{BTreeMap, BTreeSet};
15
16/// Strategy to generate an arbitrary boolean
17pub fn arb_bool() -> StrategyFor<bool> {
18    any::<bool>()
19}
20
21/// Strategy to generate an arbitrary `Sign`
22/// Only used internally, to generate `BigInt`s
23fn arb_sign() -> impl Strategy<Value = Sign> {
24    // NoSign is only used for 0 values so we're not generating it here
25    prop_oneof![Just(Sign::Minus), Just(Sign::Plus)]
26}
27
28/// Strategy to generate an arbitrary BigInt
29pub fn arb_integer() -> impl Strategy<Value = BigInt> {
30    // Wrapping around BigUint.
31    (arb_sign(), arb_biguint(2)).prop_map(|(sign, nat)| {
32        // NoSign is only used for 0 values.
33        BigInt::from_biguint(if nat.is_zero() { Sign::NoSign } else { sign }, nat)
34    })
35}
36
37/// Strategy to generate an arbitrary non-negative BigInt
38pub fn arb_natural(n: usize) -> impl Strategy<Value = BigInt> {
39    arb_biguint(n).prop_map(|x| {
40        BigInt::from_biguint(
41            if x.is_zero() {
42                Sign::NoSign
43            } else {
44                Sign::Plus
45            },
46            x,
47        )
48    })
49}
50
51/// Helper function to generate a well typed arbitrary natural number
52/// Generating `n` vectors of random u32 values, which gives a max bound of u32::MAX ^ n
53fn arb_biguint(n: usize) -> impl Strategy<Value = BigUint> {
54    vec(any::<u32>(), n).prop_map(BigUint::new)
55}
56
57/// Strategy to generate an arbitrary character
58pub fn arb_char<'a>() -> CharStrategy<'a> {
59    any::<char>()
60}
61
62/// Strategy to generate an arbitrary bytestring
63pub fn arb_bytes() -> StrategyFor<Vec<u8>> {
64    any::<Vec<u8>>()
65}
66
67/// Strategy to generate an arbitrary string
68pub fn arb_text() -> StrategyFor<String> {
69    any::<String>()
70}
71
72/// Strategy to generate a complicated data structure
73pub fn arb_complicated(
74) -> impl Strategy<Value = BTreeMap<String, Result<BTreeSet<char>, Option<Result<Vec<u8>, bool>>>>>
75{
76    btree_map(
77        arb_text(),
78        maybe_err(
79            btree_set(arb_char(), 20),
80            option::of(maybe_err(arb_bytes(), arb_bool())),
81        ),
82        20,
83    )
84}