Repository: rust-bitcoin/rust-bitcoin
Pull request #4343 (2025-04-14 14:54:25)

units: Go over the rendered docs for the whole crate
I have read through all of the `units` docs and made a few changes.

- Highlight `Warning!` in bold in `Amount` and `SignedAmount`

- Change the one occurrence of fee-rate to fee rate to be consistent with the rest.

- Make all of the error structs have the same title format of `Error returned...`

- Make all other structs have the same format concisely stating what it is opposed to what it does.

coveralls: ## Pull Request Test Coverage Report for [Build 14448810885](https://coveralls.io/builds/73216097)


### Details

* **0** of **0**   changed or added relevant lines in **0** files are covered.
* **1** unchanged line in **1** file lost coverage.
* Overall coverage increased (+**0.02%**) to **83.784%**

---


|  Files with Coverage Reduction | New Missed Lines | % |
| :-----|--------------|--: |
| [bitcoin/src/psbt/mod.rs](https://coveralls.io/builds/73216097/source?filename=bitcoin%2Fsrc%2Fpsbt%2Fmod.rs#L857) | 1 | 86.21% |
<!-- | **Total:** | **1** |  | -->

|  Totals | [![Coverage Status](https://coveralls.io/builds/73216097/badge)](https://coveralls.io/builds/73216097) |
| :-- | --: |
| Change from base [Build 14447440676](https://coveralls.io/builds/73214663): |  0.02% |
| Covered Lines: | 22347 |
| Relevant Lines: | 26672 |

---
##### 💛  - [Coveralls](https://coveralls.io)


Patch:
diff --git a/Cargo-minimal.lock b/Cargo-minimal.lock
index afb80f59..aedf19df 100644
--- a/Cargo-minimal.lock
+++ b/Cargo-minimal.lock
@@ -213,7 +213,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "4afe881d0527571892c4034822e59bb10c6c991cce6abe8199b6f5cf10766f55"
 dependencies = [
  "arrayvec",
- "serde",
 ]
 
 [[package]]
diff --git a/Cargo-recent.lock b/Cargo-recent.lock
index f33ae82e..4d452dcd 100644
--- a/Cargo-recent.lock
+++ b/Cargo-recent.lock
@@ -215,7 +215,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "4afe881d0527571892c4034822e59bb10c6c991cce6abe8199b6f5cf10766f55"
 dependencies = [
  "arrayvec",
- "serde",
 ]
 
 [[package]]
diff --git a/bitcoin/Cargo.toml b/bitcoin/Cargo.toml
index 60f93fcd..85b7291f 100644
--- a/bitcoin/Cargo.toml
+++ b/bitcoin/Cargo.toml
@@ -31,7 +31,7 @@ hashes = { package = "bitcoin_hashes", path = "../hashes", default-features = fa
 hex = { package = "hex-conservative", version = "0.3.0", default-features = false, features = ["alloc"] }
 internals = { package = "bitcoin-internals", path = "../internals", features = ["alloc", "hex"] }
 io = { package = "bitcoin-io", path = "../io", default-features = false, features = ["alloc", "hashes"] }
-primitives = { package = "bitcoin-primitives", path = "../primitives", default-features = false, features = ["alloc", "hex"] }
+primitives = { package = "bitcoin-primitives", path = "../primitives", default-features = false, features = ["alloc"] }
 secp256k1 = { version = "0.30.0", default-features = false, features = ["hashes", "alloc", "rand"] }
 units = { package = "bitcoin-units", path = "../units", default-features = false, features = ["alloc"] }
 
diff --git a/bitcoin/src/address/mod.rs b/bitcoin/src/address/mod.rs
index 1dde641f..2072cc25 100644
--- a/bitcoin/src/address/mod.rs
+++ b/bitcoin/src/address/mod.rs
@@ -135,9 +135,7 @@ impl NetworkValidationUnchecked for super::NetworkUnchecked {}
 
 /// Marker of status of address's network validation. See section [*Parsing addresses*](Address#parsing-addresses)
 /// on [`Address`] for details.
-pub trait NetworkValidation:
-    sealed::NetworkValidation + Sync + Send + Sized + Unpin + Copy
-{
+pub trait NetworkValidation: sealed::NetworkValidation + Sync + Send + Sized + Unpin + Copy {
     /// Indicates whether this `NetworkValidation` is `NetworkChecked` or not.
     const IS_CHECKED: bool;
 }
diff --git a/bitcoin/src/bip152.rs b/bitcoin/src/bip152.rs
index 5aed10c9..b31f900a 100644
--- a/bitcoin/src/bip152.rs
+++ b/bitcoin/src/bip152.rs
@@ -484,7 +484,7 @@ fn compact_block_vector() {
     #[test]
     fn getblocktx_differential_encoding_de_and_serialization() {
         let testcases = vec![
-            // differentially encoded VarInts, indices
+            // differentially encoded VarInts, indicies
             (vec![4, 0, 5, 1, 10], vec![0, 6, 8, 19]),
             (vec![1, 0], vec![0]),
             (vec![5, 0, 0, 0, 0, 0], vec![0, 1, 2, 3, 4]),
diff --git a/bitcoin/src/blockdata/script/borrowed.rs b/bitcoin/src/blockdata/script/borrowed.rs
index 481145e8..c048ba36 100644
--- a/bitcoin/src/blockdata/script/borrowed.rs
+++ b/bitcoin/src/blockdata/script/borrowed.rs
@@ -261,7 +261,7 @@ fn redeem_script(&self) -> Option<&Script> {
         /// Returns the minimum value an output with this script should have in order to be
         /// broadcastable on today’s Bitcoin network.
         #[deprecated(since = "0.32.0", note = "use `minimal_non_dust` etc. instead")]
-        fn dust_value(&self) -> Amount { self.minimal_non_dust() }
+        fn dust_value(&self) -> Option<Amount> { self.minimal_non_dust() }
 
         /// Returns the minimum value an output with this script should have in order to be
         /// broadcastable on today's Bitcoin network.
@@ -272,9 +272,8 @@ fn dust_value(&self) -> Amount { self.minimal_non_dust() }
         /// To use a custom value, use [`minimal_non_dust_custom`].
         ///
         /// [`minimal_non_dust_custom`]: Script::minimal_non_dust_custom
-        fn minimal_non_dust(&self) -> Amount {
+        fn minimal_non_dust(&self) -> Option<Amount> {
             self.minimal_non_dust_internal(DUST_RELAY_TX_FEE.into())
-                .expect("dust_relay_fee or script length should not be absurdly large")
         }
 
         /// Returns the minimum value an output with this script should have in order to be
diff --git a/bitcoin/src/blockdata/transaction.rs b/bitcoin/src/blockdata/transaction.rs
index bdb7a383..341fba10 100644
--- a/bitcoin/src/blockdata/transaction.rs
+++ b/bitcoin/src/blockdata/transaction.rs
@@ -183,8 +183,8 @@ fn size(&self) -> usize { size_from_script_pubkey(&self.script_pubkey) }
         /// To use a custom value, use [`minimal_non_dust_custom`].
         ///
         /// [`minimal_non_dust_custom`]: TxOut::minimal_non_dust_custom
-        fn minimal_non_dust(script_pubkey: ScriptBuf) -> TxOut {
-            TxOut { value: script_pubkey.minimal_non_dust(), script_pubkey }
+        fn minimal_non_dust(script_pubkey: ScriptBuf) -> Option<TxOut> {
+            Some(TxOut { value: script_pubkey.minimal_non_dust()?, script_pubkey })
         }
 
         /// Constructs a new `TxOut` with given script and the smallest possible `value` that is **not** dust
diff --git a/primitives/Cargo.toml b/primitives/Cargo.toml
index d2ed5268..6a565954 100644
--- a/primitives/Cargo.toml
+++ b/primitives/Cargo.toml
@@ -15,20 +15,19 @@ rust-version = "1.63.0"
 exclude = ["tests", "contrib"]
 
 [features]
-default = ["std", "hex"]
-std = ["alloc", "hashes/std", "hex?/std", "internals/std", "units/std"]
-alloc = ["hashes/alloc", "hex?/alloc", "internals/alloc", "units/alloc"]
-serde = ["dep:serde", "hashes/serde", "hex?/serde", "internals/serde", "units/serde", "alloc", "hex"]
+default = ["std"]
+std = ["alloc", "hashes/std", "hex/std", "internals/std", "units/std"]
+alloc = ["hashes/alloc", "hex/alloc", "internals/alloc", "units/alloc"]
+serde = ["dep:serde", "hashes/serde", "internals/serde", "units/serde", "alloc"]
 arbitrary = ["dep:arbitrary", "units/arbitrary"]
-hex = ["dep:hex", "hashes/hex", "internals/hex"]
 
 [dependencies]
-hashes = { package = "bitcoin_hashes", path = "../hashes", default-features = false }
-internals = { package = "bitcoin-internals", path = "../internals" }
+hashes = { package = "bitcoin_hashes", path = "../hashes", default-features = false, features = ["hex"] }
+hex = { package = "hex-conservative", version = "0.3.0", default-features = false }
+internals = { package = "bitcoin-internals", path = "../internals", features = ["hex"] }
 units = { package = "bitcoin-units", path = "../units", default-features = false }
 
 arbitrary = { version = "1.4", optional = true }
-hex = { package = "hex-conservative", version = "0.3.0", default-features = false, optional = true }
 serde = { version = "1.0.103", default-features = false, features = ["derive", "alloc"], optional = true }
 
 [dev-dependencies]
diff --git a/primitives/src/block.rs b/primitives/src/block.rs
index 003e2d90..a4d49b0a 100644
--- a/primitives/src/block.rs
+++ b/primitives/src/block.rs
@@ -310,10 +310,7 @@ fn default() -> Version { Self::NO_SOFT_FORK_SIGNALLING }
     pub struct WitnessCommitment(sha256d::Hash);
 }
 
-#[cfg(feature = "hex")]
 hashes::impl_hex_for_newtype!(BlockHash, WitnessCommitment);
-#[cfg(not(feature = "hex"))]
-hashes::impl_debug_only_for_newtype!(BlockHash, WitnessCommitment);
 #[cfg(feature = "serde")]
 hashes::impl_serde_for_newtype!(BlockHash, WitnessCommitment);
 
diff --git a/primitives/src/merkle_tree.rs b/primitives/src/merkle_tree.rs
index e5cc6010..18a16a5a 100644
--- a/primitives/src/merkle_tree.rs
+++ b/primitives/src/merkle_tree.rs
@@ -11,9 +11,6 @@
     pub struct WitnessMerkleNode(sha256d::Hash);
 }
 
-#[cfg(feature = "hex")]
 hashes::impl_hex_for_newtype!(TxMerkleNode, WitnessMerkleNode);
-#[cfg(not(feature = "hex"))]
-hashes::impl_debug_only_for_newtype!(TxMerkleNode, WitnessMerkleNode);
 #[cfg(feature = "serde")]
 hashes::impl_serde_for_newtype!(TxMerkleNode, WitnessMerkleNode);
diff --git a/primitives/src/script/mod.rs b/primitives/src/script/mod.rs
index 3a0244c5..51d18bca 100644
--- a/primitives/src/script/mod.rs
+++ b/primitives/src/script/mod.rs
@@ -10,7 +10,6 @@
 use core::fmt;
 
 use hashes::{hash160, sha256};
-#[cfg(feature = "hex")]
 use hex::DisplayHex;
 use internals::script::{self, PushDataLenLen};
 
@@ -50,10 +49,7 @@
     pub struct WScriptHash(sha256::Hash);
 }
 
-#[cfg(feature = "hex")]
 hashes::impl_hex_for_newtype!(ScriptHash, WScriptHash);
-#[cfg(not(feature = "hex"))]
-hashes::impl_debug_only_for_newtype!(ScriptHash, WScriptHash);
 #[cfg(feature = "serde")]
 hashes::impl_serde_for_newtype!(ScriptHash, WScriptHash);
 
@@ -429,7 +425,6 @@ impl fmt::Display for ScriptBuf {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Display::fmt(self.as_script(), f) }
 }
 
-#[cfg(feature = "hex")]
 impl fmt::LowerHex for Script {
     #[inline]
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
@@ -437,19 +432,15 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 #[cfg(feature = "alloc")]
-#[cfg(feature = "hex")]
 internals::impl_to_hex_from_lower_hex!(Script, |script: &Self| script.len() * 2);
 
-#[cfg(feature = "hex")]
 impl fmt::LowerHex for ScriptBuf {
     #[inline]
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::LowerHex::fmt(self.as_script(), f) }
 }
 #[cfg(feature = "alloc")]
-#[cfg(feature = "hex")]
 internals::impl_to_hex_from_lower_hex!(ScriptBuf, |script_buf: &Self| script_buf.len() * 2);
 
-#[cfg(feature = "hex")]
 impl fmt::UpperHex for Script {
     #[inline]
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
@@ -457,7 +448,6 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
-#[cfg(feature = "hex")]
 impl fmt::UpperHex for ScriptBuf {
     #[inline]
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::UpperHex::fmt(self.as_script(), f) }
@@ -766,24 +756,16 @@ fn try_from_script_for_wscript_hash() {
     fn script_display() {
         let script = Script::from_bytes(&[0xa1, 0xb2, 0xc3]);
         assert_eq!(format!("{}", script), "OP_LESSTHANOREQUAL OP_CSV OP_RETURN_195");
-
-        #[cfg(feature = "hex")]
-        {
-            assert_eq!(format!("{:x}", script), "a1b2c3");
-            assert_eq!(format!("{:X}", script), "A1B2C3");
-        }
+        assert_eq!(format!("{:x}", script), "a1b2c3");
+        assert_eq!(format!("{:X}", script), "A1B2C3");
     }
 
     #[test]
     fn scriptbuf_display() {
         let script_buf = ScriptBuf::from(vec![0xa1, 0xb2, 0xc3]);
         assert_eq!(format!("{}", script_buf), "OP_LESSTHANOREQUAL OP_CSV OP_RETURN_195");
-
-        #[cfg(feature = "hex")]
-        {
-            assert_eq!(format!("{:x}", script_buf), "a1b2c3");
-            assert_eq!(format!("{:X}", script_buf), "A1B2C3");
-        }
+        assert_eq!(format!("{:x}", script_buf), "a1b2c3");
+        assert_eq!(format!("{:X}", script_buf), "A1B2C3");
     }
 
     #[test]
diff --git a/primitives/src/transaction.rs b/primitives/src/transaction.rs
index 53cd51a4..1c79a187 100644
--- a/primitives/src/transaction.rs
+++ b/primitives/src/transaction.rs
@@ -13,7 +13,6 @@
 #[cfg(feature = "alloc")]
 use core::cmp;
 #[cfg(feature = "alloc")]
-#[cfg(feature = "hex")]
 use core::convert::Infallible;
 use core::fmt;
 
@@ -21,13 +20,9 @@
 use arbitrary::{Arbitrary, Unstructured};
 use hashes::sha256d;
 #[cfg(feature = "alloc")]
-use internals::compact_size;
-#[cfg(feature = "hex")]
-use internals::write_err;
-#[cfg(feature = "hex")]
-use units::parse;
+use internals::{compact_size, write_err};
 #[cfg(feature = "alloc")]
-use units::{Amount, Weight};
+use units::{parse, Amount, Weight};
 
 #[cfg(feature = "alloc")]
 use crate::locktime::absolute;
@@ -394,7 +389,6 @@ impl OutPoint {
     pub const COINBASE_PREVOUT: Self = Self { txid: Txid::COINBASE_PREVOUT, vout: u32::MAX };
 }
 
-#[cfg(feature = "hex")]
 impl fmt::Display for OutPoint {
     #[inline]
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
@@ -403,7 +397,6 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 }
 
 #[cfg(feature = "alloc")]
-#[cfg(feature = "hex")]
 impl core::str::FromStr for OutPoint {
     type Err = ParseOutPointError;
 
@@ -431,7 +424,6 @@ fn from_str(s: &str) -> Result<Self, Self::Err> {
 ///
 /// Does not permit leading zeroes or non-digit characters.
 #[cfg(feature = "alloc")]
-#[cfg(feature = "hex")]
 fn parse_vout(s: &str) -> Result<u32, ParseOutPointError> {
     if s.len() > 1 {
         let first = s.chars().next().unwrap();
@@ -446,7 +438,6 @@ fn parse_vout(s: &str) -> Result<u32, ParseOutPointError> {
 #[derive(Debug, Clone, PartialEq, Eq)]
 #[non_exhaustive]
 #[cfg(feature = "alloc")]
-#[cfg(feature = "hex")]
 pub enum ParseOutPointError {
     /// Error in TXID part.
     Txid(hex::HexToArrayError),
@@ -461,14 +452,12 @@ pub enum ParseOutPointError {
 }
 
 #[cfg(feature = "alloc")]
-#[cfg(feature = "hex")]
 impl From<Infallible> for ParseOutPointError {
     #[inline]
     fn from(never: Infallible) -> Self { match never {} }
 }
 
 #[cfg(feature = "alloc")]
-#[cfg(feature = "hex")]
 impl fmt::Display for ParseOutPointError {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         use ParseOutPointError as E;
@@ -484,7 +473,6 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 }
 
 #[cfg(feature = "std")]
-#[cfg(feature = "hex")]
 impl std::error::Error for ParseOutPointError {
     fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
         use ParseOutPointError as E;
@@ -512,10 +500,7 @@ fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
     pub struct Wtxid(sha256d::Hash);
 }
 
-#[cfg(feature = "hex")]
 hashes::impl_hex_for_newtype!(Txid, Wtxid);
-#[cfg(not(feature = "hex"))]
-hashes::impl_debug_only_for_newtype!(Txid, Wtxid);
 #[cfg(feature = "serde")]
 hashes::impl_serde_for_newtype!(Txid, Wtxid);
 
@@ -714,7 +699,6 @@ fn transaction_functions() {
     }
 
     #[test]
-    #[cfg(feature = "hex")]
     fn outpoint_from_str() {
         // Check format errors
         let mut outpoint_str = "0".repeat(64); // No ":"
@@ -741,7 +725,6 @@ fn outpoint_from_str() {
     }
 
     #[test]
-    #[cfg(feature = "hex")]
     fn canonical_vout() {
         assert_eq!(parse_vout("0").unwrap(), 0);
         assert_eq!(parse_vout("1").unwrap(), 1);
diff --git a/primitives/src/witness.rs b/primitives/src/witness.rs
index 3eb62a02..0ffa7f15 100644
--- a/primitives/src/witness.rs
+++ b/primitives/src/witness.rs
@@ -9,6 +9,7 @@
 
 #[cfg(feature = "arbitrary")]
 use arbitrary::{Arbitrary, Unstructured};
+use hex::DisplayHex;
 use internals::compact_size;
 use internals::slice::SliceExt;
 use internals::wrap_debug::WrapDebug;
@@ -313,7 +314,7 @@ fn eq(&self, rhs: &Witness) -> bool { *rhs == *self }
 /// Debug implementation that displays the witness as a structured output containing:
 /// - Number of witness elements
 /// - Total bytes across all elements
-/// - List of hex-encoded witness elements if `hex` features is enabled.
+/// - List of hex-encoded witness elements
 #[allow(clippy::missing_fields_in_debug)] // We don't want to show `indices_start`.
 impl fmt::Debug for Witness {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
@@ -325,14 +326,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
             .field(
                 "elements",
                 &WrapDebug(|f| {
-                    #[cfg(feature = "hex")]
-                    {
-                        f.debug_list().entries(self.iter().map(hex::DisplayHex::as_hex)).finish()
-                    }
-                    #[cfg(not(feature = "hex"))]
-                    {
-                        f.debug_list().entries(self.iter()).finish()
-                    }
+                    f.debug_list().entries(self.iter().map(DisplayHex::as_hex)).finish()
                 }),
             )
             .finish()
@@ -702,7 +696,7 @@ fn witness_from_impl() {
     fn witness_from_array_impl() {
         const DATA_1: [u8; 3] = [1, 2, 3];
         const DATA_2: [u8; 3] = [4, 5, 6];
-        let witness = Witness::from_slice(&[DATA_1, DATA_2]);
+        let witness  = Witness::from_slice(&[DATA_1, DATA_2]);
 
         let witness_from_array_ref = Witness::from(&[DATA_1, DATA_2]);
         let witness_from_array_of_refs = Witness::from([&DATA_1, &DATA_2]);
diff --git a/units/src/amount/error.rs b/units/src/amount/error.rs
index 2c91392b..dd06db04 100644
--- a/units/src/amount/error.rs
+++ b/units/src/amount/error.rs
@@ -10,7 +10,7 @@
 
 use super::INPUT_STRING_LEN_LIMIT;
 
-/// An error during amount parsing amount with denomination.
+/// Error returned when parsing an amount with denomination fails.
 #[derive(Debug, Clone, PartialEq, Eq)]
 pub struct ParseError(pub(crate) ParseErrorInner);
 
@@ -84,7 +84,7 @@ fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
     }
 }
 
-/// An error during amount parsing.
+/// Error returned when parsing an amount fails.
 #[derive(Debug, Clone, PartialEq, Eq)]
 pub struct ParseAmountError(pub(crate) ParseAmountErrorInner);
 
diff --git a/units/src/amount/signed.rs b/units/src/amount/signed.rs
index 7070adf7..3bd4d5b9 100644
--- a/units/src/amount/signed.rs
+++ b/units/src/amount/signed.rs
@@ -25,7 +25,7 @@ mod encapsulate {
     /// conversion to various denominations. The [`SignedAmount`] type does not implement [`serde`]
     /// traits but we do provide modules for serializing as satoshis or bitcoin.
     ///
-    /// Warning!
+    /// **Warning!**
     ///
     /// This type implements several arithmetic operations from [`core::ops`].
     /// To prevent errors due to an overflow when using these operations,
diff --git a/units/src/amount/unsigned.rs b/units/src/amount/unsigned.rs
index 20bb6f82..4a1d875b 100644
--- a/units/src/amount/unsigned.rs
+++ b/units/src/amount/unsigned.rs
@@ -25,7 +25,7 @@ mod encapsulate {
     /// conversion to various denominations. The [`Amount`] type does not implement [`serde`] traits
     /// but we do provide modules for serializing as satoshis or bitcoin.
     ///
-    /// Warning!
+    /// **Warning!**
     ///
     /// This type implements several arithmetic operations from [`core::ops`].
     /// To prevent errors due to an overflow when using these operations,
diff --git a/units/src/fee.rs b/units/src/fee.rs
index 4bf0792a..86f4a5b5 100644
--- a/units/src/fee.rs
+++ b/units/src/fee.rs
@@ -15,13 +15,11 @@
 
 use crate::{Amount, FeeRate, MathOp, NumOpResult, OptionExt, Weight};
 
-use NumOpResult as R;
-
 impl Amount {
     /// Checked weight ceiling division.
     ///
     /// Be aware that integer division loses the remainder if no exact division
-    /// can be made. This method rounds up ensuring the transaction fee-rate is
+    /// can be made. This method rounds up ensuring the transaction fee rate is
     /// sufficient. See also [`Self::checked_div_by_weight_floor`].
     ///
     /// Returns [`None`] if overflow occurred.
@@ -170,36 +168,6 @@ fn mul(self, rhs: FeeRate) -> Self::Output {
             rhs.checked_mul_by_weight(self).valid_or_error(MathOp::Mul)
         }
     }
-    impl ops::Mul<FeeRate> for NumOpResult<Weight> {
-        type Output = NumOpResult<Amount>;
-        fn mul(self, rhs: FeeRate) -> Self::Output {
-            match self {
-                R::Valid(lhs) => lhs * rhs,
-                R::Error(e) => NumOpResult::Error(e),
-            }
-        }
-    }
-    impl ops::Mul<NumOpResult<FeeRate>> for Weight {
-        type Output = NumOpResult<Amount>;
-        fn mul(self, rhs: NumOpResult<FeeRate>) -> Self::Output {
-            match rhs {
-                R::Valid(fee_rate) => self * fee_rate,
-                R::Error(e) => NumOpResult::Error(e),
-            }
-        }
-    }
-    impl ops::Mul<NumOpResult<FeeRate>> for NumOpResult<Weight> {
-        type Output = NumOpResult<Amount>;
-        fn mul(self, rhs: NumOpResult<FeeRate>) -> Self::Output {
-            match self {
-                R::Valid(lhs) => { match rhs {
-                    R::Valid(fee_rate) => lhs * fee_rate,
-                    R::Error(e) => NumOpResult::Error(e),
-                }}
-                R::Error(e) => NumOpResult::Error(e),
-            }
-        }
-    }
 
     impl ops::Mul<Weight> for FeeRate {
         type Output = NumOpResult<Amount>;
@@ -207,36 +175,6 @@ fn mul(self, rhs: Weight) -> Self::Output {
             self.checked_mul_by_weight(rhs).valid_or_error(MathOp::Mul)
         }
     }
-    impl ops::Mul<Weight> for NumOpResult<FeeRate> {
-        type Output = NumOpResult<Amount>;
-        fn mul(self, rhs: Weight) -> Self::Output {
-            match self {
-                R::Valid(lhs) => lhs * rhs,
-                R::Error(e) => NumOpResult::Error(e),
-            }
-        }
-    }
-    impl ops::Mul<NumOpResult<Weight>> for FeeRate {
-        type Output = NumOpResult<Amount>;
-        fn mul(self, rhs: NumOpResult<Weight>) -> Self::Output {
-            match rhs {
-                R::Valid(weight) => self * weight,
-                R::Error(e) => NumOpResult::Error(e),
-            }
-        }
-    }
-    impl ops::Mul<NumOpResult<Weight>> for NumOpResult<FeeRate> {
-        type Output = NumOpResult<Amount>;
-        fn mul(self, rhs: NumOpResult<Weight>) -> Self::Output {
-            match self {
-                R::Valid(lhs) => { match rhs {
-                    R::Valid(weight) => lhs * weight,
-                    R::Error(e) => NumOpResult::Error(e),
-                }}
-                R::Error(e) => NumOpResult::Error(e),
-            }
-        }
-    }
 
     impl ops::Div<Weight> for Amount {
         type Output = NumOpResult<FeeRate>;
@@ -245,39 +183,6 @@ fn div(self, rhs: Weight) -> Self::Output {
             self.checked_div_by_weight_floor(rhs).valid_or_error(MathOp::Div)
         }
     }
-    impl ops::Div<Weight> for NumOpResult<Amount> {
-        type Output = NumOpResult<FeeRate>;
-
-        fn div(self, rhs: Weight) -> Self::Output {
-            match self {
-                R::Valid(lhs) => lhs / rhs,
-                R::Error(e) => NumOpResult::Error(e),
-            }
-        }
-    }
-    impl ops::Div<NumOpResult<Weight>> for Amount {
-        type Output = NumOpResult<FeeRate>;
-
-        fn div(self, rhs: NumOpResult<Weight>) -> Self::Output {
-            match rhs {
-                R::Valid(weight) => self / weight,
-                R::Error(e) => NumOpResult::Error(e),
-            }
-        }
-    }
-    impl ops::Div<NumOpResult<Weight>> for NumOpResult<Amount> {
-        type Output = NumOpResult<FeeRate>;
-
-        fn div(self, rhs: NumOpResult<Weight>) -> Self::Output {
-            match self {
-                R::Valid(lhs) => { match rhs {
-                    R::Valid(weight) => lhs / weight,
-                    R::Error(e) => NumOpResult::Error(e),
-                }}
-                R::Error(e) => NumOpResult::Error(e),
-            }
-        }
-    }
 
     impl ops::Div<FeeRate> for Amount {
         type Output = NumOpResult<Weight>;
@@ -286,39 +191,6 @@ fn div(self, rhs: FeeRate) -> Self::Output {
             self.checked_div_by_fee_rate_floor(rhs).valid_or_error(MathOp::Div)
         }
     }
-    impl ops::Div<FeeRate> for NumOpResult<Amount> {
-        type Output = NumOpResult<Weight>;
-
-        fn div(self, rhs: FeeRate) -> Self::Output {
-            match self {
-                R::Valid(lhs) => lhs / rhs,
-                R::Error(e) => NumOpResult::Error(e),
-            }
-        }
-    }
-    impl ops::Div<NumOpResult<FeeRate>> for Amount {
-        type Output = NumOpResult<Weight>;
-
-        fn div(self, rhs: NumOpResult<FeeRate>) -> Self::Output {
-            match rhs {
-                R::Valid(fee_rate) => self / fee_rate,
-                R::Error(e) => NumOpResult::Error(e),
-            }
-        }
-    }
-    impl ops::Div<NumOpResult<FeeRate>> for NumOpResult<Amount> {
-        type Output = NumOpResult<Weight>;
-
-        fn div(self, rhs: NumOpResult<FeeRate>) -> Self::Output {
-            match self {
-                R::Valid(lhs) => { match rhs {
-                    R::Valid(fee_rate) => lhs / fee_rate,
-                    R::Error(e) => NumOpResult::Error(e),
-                }}
-                R::Error(e) => NumOpResult::Error(e),
-            }
-        }
-    }
 }
 
 impl Weight {
diff --git a/units/src/fee_rate/mod.rs b/units/src/fee_rate/mod.rs
index 0daafa2d..709e3f98 100644
--- a/units/src/fee_rate/mod.rs
+++ b/units/src/fee_rate/mod.rs
@@ -10,7 +10,7 @@
 #[cfg(feature = "arbitrary")]
 use arbitrary::{Arbitrary, Unstructured};
 
-/// Represents fee rate.
+/// Fee rate.
 ///
 /// This is an integer newtype representing fee rate in `sat/kwu`. It provides protection against
 /// mixing up the types as well as basic formatting features.
diff --git a/units/src/lib.rs b/units/src/lib.rs
index b00a254c..0919efb7 100644
--- a/units/src/lib.rs
+++ b/units/src/lib.rs
@@ -3,20 +3,6 @@
 //! # Rust Bitcoin - unit types
 //!
 //! This library provides basic types used by the Rust Bitcoin ecosystem.
-//!
-//! If you are using `rust-bitcoin` then you do not need to access this crate directly. Everything
-//! here is re-exported in `rust-bitcoin` at the same path. Also the same re-exports exist in
-//! `primitives` if you are using that crate instead of `bitcoin`.
-//!
-//! # Examples
-//!
-//! ```
-//! // Exactly the same as `use bitcoin::{amount, Amount}`.
-//! use bitcoin_units::{amount, Amount};
-//!
-//! let amount = Amount::from_sat(1_000)?;
-//! # Ok::<_, amount::OutOfRangeError>(())
-//! ```
 
 #![no_std]
 // Experimental features we need.
diff --git a/units/src/locktime/absolute.rs b/units/src/locktime/absolute.rs
index 69851607..153aa0e3 100644
--- a/units/src/locktime/absolute.rs
+++ b/units/src/locktime/absolute.rs
@@ -256,7 +256,7 @@ pub const fn is_block_height(n: u32) -> bool { n < LOCK_TIME_THRESHOLD }
 /// Returns true if `n` is a UNIX timestamp i.e., greater than or equal to 500,000,000.
 pub const fn is_block_time(n: u32) -> bool { n >= LOCK_TIME_THRESHOLD }
 
-/// An error that occurs when converting a `u32` to a lock time variant.
+/// Error returned when converting a `u32` to a lock time variant fails.
 #[derive(Debug, Clone, PartialEq, Eq)]
 #[non_exhaustive]
 pub struct ConversionError {
diff --git a/units/src/locktime/relative.rs b/units/src/locktime/relative.rs
index 7f8b4413..9b1abadf 100644
--- a/units/src/locktime/relative.rs
+++ b/units/src/locktime/relative.rs
@@ -128,7 +128,7 @@ impl fmt::Display for Time {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Display::fmt(&self.0, f) }
 }
 
-/// Input time in seconds was too large to be encoded to a 16 bit 512 second interval.
+/// Error returned when the input time in seconds was too large to be encoded to a 16 bit 512 second interval.
 #[derive(Debug, Clone, PartialEq, Eq)]
 pub struct TimeOverflowError {
     /// Time value in seconds that overflowed.
diff --git a/units/src/result.rs b/units/src/result.rs
index 8276e6cc..97d6fefa 100644
--- a/units/src/result.rs
+++ b/units/src/result.rs
@@ -127,7 +127,7 @@ fn valid_or_error(self, op: MathOp) -> NumOpResult<$ty> {
 }
 impl_opt_ext!(Amount, SignedAmount, u64, i64, FeeRate, Weight);
 
-/// An error occurred while doing a mathematical operation.
+/// Error returned when a mathematical operation fails.
 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
 #[non_exhaustive]
 pub struct NumOpError(MathOp);
diff --git a/units/src/weight.rs b/units/src/weight.rs
index 50c08df9..22aea383 100644
--- a/units/src/weight.rs
+++ b/units/src/weight.rs
@@ -12,7 +12,7 @@
 /// The factor that non-witness serialization data is multiplied by during weight calculation.
 pub const WITNESS_SCALE_FACTOR: usize = 4;
 
-/// Represents weight - the weight of a transaction or block.
+/// The weight of a transaction or block.
 ///
 /// This is an integer newtype representing [`Weight`] in `wu`. It provides protection against mixing
 /// up types as well as basic formatting features.


Test patch:
diff --git a/bitcoin/src/blockdata/script/tests.rs b/bitcoin/src/blockdata/script/tests.rs
index a7878b3b..1dae63f1 100644
--- a/bitcoin/src/blockdata/script/tests.rs
+++ b/bitcoin/src/blockdata/script/tests.rs
@@ -556,11 +556,11 @@ fn p2sh_p2wsh_conversion() {
     // Test vectors taken from Core tests/data/script_tests.json
     // bare p2wsh
     let witness_script = ScriptBuf::from_hex("410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8ac").unwrap();
-    let expected_without =
+    let expected_witout =
         ScriptBuf::from_hex("0020b95237b48faaa69eb078e1170be3b5cbb3fddf16d0a991e14ad274f7b33a4f64")
             .unwrap();
     assert!(witness_script.to_p2wsh().unwrap().is_p2wsh());
-    assert_eq!(witness_script.to_p2wsh().unwrap(), expected_without);
+    assert_eq!(witness_script.to_p2wsh().unwrap(), expected_witout);
 
     // p2sh
     let redeem_script = ScriptBuf::from_hex("0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8").unwrap();
@@ -571,13 +571,13 @@ fn p2sh_p2wsh_conversion() {
 
     // p2sh-p2wsh
     let witness_script = ScriptBuf::from_hex("410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8ac").unwrap();
-    let expected_without =
+    let expected_witout =
         ScriptBuf::from_hex("0020b95237b48faaa69eb078e1170be3b5cbb3fddf16d0a991e14ad274f7b33a4f64")
             .unwrap();
     let expected_out =
         ScriptBuf::from_hex("a914f386c2ba255cc56d20cfa6ea8b062f8b5994551887").unwrap();
     assert!(witness_script.to_p2sh().unwrap().is_p2sh());
-    assert_eq!(witness_script.to_p2wsh().unwrap(), expected_without);
+    assert_eq!(witness_script.to_p2wsh().unwrap(), expected_witout);
     assert_eq!(witness_script.to_p2wsh().unwrap().to_p2sh().unwrap(), expected_out);
 }
 
@@ -684,7 +684,7 @@ fn default_dust_value() {
     // well-known scriptPubKey types.
     let script_p2wpkh = Builder::new().push_int_unchecked(0).push_slice([42; 20]).into_script();
     assert!(script_p2wpkh.is_p2wpkh());
-    assert_eq!(script_p2wpkh.minimal_non_dust(), Amount::from_sat_u32(294));
+    assert_eq!(script_p2wpkh.minimal_non_dust(), Some(Amount::from_sat_u32(294)));
     assert_eq!(
         script_p2wpkh.minimal_non_dust_custom(FeeRate::from_sat_per_vb_unchecked(6)),
         Some(Amount::from_sat_u32(588))
@@ -698,7 +698,7 @@ fn default_dust_value() {
         .push_opcode(OP_CHECKSIG)
         .into_script();
     assert!(script_p2pkh.is_p2pkh());
-    assert_eq!(script_p2pkh.minimal_non_dust(), Amount::from_sat_u32(546));
+    assert_eq!(script_p2pkh.minimal_non_dust(), Some(Amount::from_sat_u32(546)));
     assert_eq!(
         script_p2pkh.minimal_non_dust_custom(FeeRate::from_sat_per_vb_unchecked(6)),
         Some(Amount::from_sat_u32(1092))
diff --git a/bitcoin/tests/psbt-sign-taproot.rs b/bitcoin/tests/psbt-sign-taproot.rs
index 78f3a77b..74e5b978 100644
--- a/bitcoin/tests/psbt-sign-taproot.rs
+++ b/bitcoin/tests/psbt-sign-taproot.rs
@@ -83,8 +83,11 @@ fn get_key<C: Signing>(
         //
         // Step 1: create psbt for key path spend.
         //
-        let mut psbt_key_path_spend =
-            create_psbt_for_taproot_key_path_spend(address, to_address, tree.clone());
+        let mut psbt_key_path_spend = create_psbt_for_taproot_key_path_spend(
+            address,
+            to_address,
+            tree.clone(),
+        );
 
         //
         // Step 2: sign psbt.