twenty_first/
lib.rs

1#![warn(clippy::shadow_unrelated)]
2//
3// If code coverage tool `cargo-llvm-cov` is running with the nightly toolchain,
4// enable the unstable “coverage” attribute. This allows using the annotation
5// `#[coverage(off)]` to explicitly exclude certain parts of the code from
6// being considered as “code under test.” Most prominently, the annotation
7// should be added to every `#[cfg(test)]` module. Since the “coverage”
8// feature is enable only conditionally, the annotation to use is:
9// #[cfg_attr(coverage_nightly, coverage(off))]
10//
11// See also:
12// - https://github.com/taiki-e/cargo-llvm-cov#exclude-code-from-coverage
13// - https://github.com/rust-lang/rust/issues/84605
14#![cfg_attr(coverage_nightly, feature(coverage_attribute))]
15
16pub mod config;
17pub mod error;
18pub mod math;
19pub mod prelude;
20pub mod tip5;
21pub mod util_types;
22
23#[cfg(test)]
24#[cfg_attr(coverage_nightly, feature(coverage_attribute))]
25mod proptest_arbitrary_interop;
26
27// This is needed for `#[derive(BFieldCodec)]` macro to work consistently across crates.
28// Specifically:
29// From inside the `twenty-first` crate, we need to refer to `twenty-first` by `crate`.
30// However, from outside the `twenty-first` crate, we need to refer to it by `twenty_first`.
31// The re-export below allows using identifier `twenty_first` even from inside `twenty-first`.
32//
33// See also:
34// https://github.com/bkchr/proc-macro-crate/issues/2#issuecomment-572914520
35extern crate self as twenty_first;
36
37// re-export crates used in our public API
38pub use bfieldcodec_derive;
39
40#[cfg(test)]
41#[cfg_attr(coverage_nightly, coverage(off))]
42pub(crate) mod tests {
43    use prelude::*;
44
45    use super::*;
46
47    /// A crate-specific replacement of the `#[test]` attribute for tests that
48    /// should also be executed on `wasm` targets (which is almost all tests).
49    ///
50    /// If you specifically want to exclude a test from `wasm` targets, use the
51    /// usual `#[test]` attribute instead.
52    ///
53    /// # Usage
54    ///
55    /// ```
56    /// #[macro_rules_attr::apply(test)]
57    /// fn foo() {
58    ///     assert_eq!(4, 2 + 2);
59    /// }
60    /// ```
61    macro_rules! test {
62        ($item:item) => {
63            #[test]
64            #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
65            $item
66        };
67    }
68    pub(crate) use test;
69
70    /// A crate-specific replacement of the `#[test_strategy::proptest]`
71    /// attribute for tests that should also be executed on `wasm` targets
72    /// (which is almost all tests).
73    ///
74    /// If you specifically want to exclude a test from `wasm` targets, use the
75    /// usual `#[test_strategy::proptest]` attribute instead.
76    ///
77    /// # Usage
78    ///
79    /// ```
80    /// # use proptest::prop_assert_eq;
81    /// #[macro_rules_attr::apply(proptest)]
82    /// fn foo(#[strategy(0..=42)] x: i32) {
83    ///     prop_assert_eq!(2 * x, x + x);
84    /// }
85    /// ```
86    ///
87    /// If you want to configure the test, use the usual syntax defined by
88    /// [`test_strategy`]:
89    /// ```
90    /// # use proptest::prop_assert_eq;
91    /// #[macro_rules_attr::apply(proptest(cases = 10, max_local_rejects = 5))]
92    /// fn foo(#[strategy(0..=42)] x: i32) {
93    ///     prop_assert_eq!(2 * x, x + x);
94    /// }
95    /// ```
96    macro_rules! proptest {
97        ($item:item $(($($config:tt)*))?) => {
98            #[test_strategy::proptest $(($($config)*))?]
99            #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
100            $item
101        };
102    }
103    pub(crate) use proptest;
104
105    /// The compiler automatically adds any applicable auto trait (all of which are
106    /// marker traits) to self-defined types. This implies that these trait bounds
107    /// might vanish if the necessary pre-conditions are no longer met. That'd be a
108    /// breaking API change!
109    ///
110    /// To prevent _accidental_ removal of auto trait implementations, this method
111    /// tests for their presence. If you are re-designing any of the types below
112    /// and a test fails as a result, that might be fine. You are now definitely
113    /// aware of a consequence you might not have known about otherwise. (If you
114    /// were already aware you know how subtle this stuff can be and are hopefully
115    /// fine with reading this comment.)
116    ///
117    /// Inspired by “Rust for Rustaceans” by Jon Gjengset.
118    pub fn implements_usual_auto_traits<T: Sized + Send + Sync + Unpin>() {}
119
120    #[macro_rules_attr::apply(test)]
121    fn types_in_prelude_implement_the_usual_auto_traits() {
122        implements_usual_auto_traits::<BFieldElement>();
123        implements_usual_auto_traits::<Polynomial<BFieldElement>>();
124        implements_usual_auto_traits::<Polynomial<XFieldElement>>();
125        implements_usual_auto_traits::<Digest>();
126        implements_usual_auto_traits::<Tip5>();
127        implements_usual_auto_traits::<XFieldElement>();
128        implements_usual_auto_traits::<MerkleTree>();
129        implements_usual_auto_traits::<MerkleTreeInclusionProof>();
130        implements_usual_auto_traits::<MmrMembershipProof>();
131    }
132
133    #[macro_rules_attr::apply(test)]
134    fn public_types_implement_the_usual_auto_traits() {
135        implements_usual_auto_traits::<math::lattice::CyclotomicRingElement>();
136        implements_usual_auto_traits::<math::lattice::ModuleElement<42>>();
137        implements_usual_auto_traits::<math::lattice::kem::SecretKey>();
138        implements_usual_auto_traits::<math::lattice::kem::PublicKey>();
139        implements_usual_auto_traits::<math::lattice::kem::Ciphertext>();
140        implements_usual_auto_traits::<util_types::sponge::Domain>();
141        implements_usual_auto_traits::<util_types::mmr::mmr_accumulator::MmrAccumulator>();
142        implements_usual_auto_traits::<math::zerofier_tree::Branch<BFieldElement>>();
143        implements_usual_auto_traits::<math::zerofier_tree::Leaf<BFieldElement>>();
144        implements_usual_auto_traits::<math::zerofier_tree::ZerofierTree<BFieldElement>>();
145        implements_usual_auto_traits::<
146            math::polynomial::ModularInterpolationPreprocessingData<BFieldElement>,
147        >();
148    }
149
150    #[macro_rules_attr::apply(test)]
151    fn errors_implement_the_usual_auto_traits() {
152        implements_usual_auto_traits::<error::BFieldCodecError>();
153        implements_usual_auto_traits::<error::PolynomialBFieldCodecError>();
154        implements_usual_auto_traits::<error::MerkleTreeError>();
155        implements_usual_auto_traits::<error::ParseBFieldElementError>();
156        implements_usual_auto_traits::<error::TryFromDigestError>();
157        implements_usual_auto_traits::<error::TryFromHexDigestError>();
158        implements_usual_auto_traits::<error::TryFromU32sError>();
159        implements_usual_auto_traits::<error::TryFromXFieldElementError>();
160    }
161}