diff --git a/Cargo.toml b/Cargo.toml index cfd3298..321e3f6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,6 +15,7 @@ autoexamples = false # Remove when edition 2018 https://github.com/rust-lang/car # Should make docs.rs show all functions, even those behind non-default features [package.metadata.docs.rs] features = [ "rand", "rand-std", "serde", "recovery" ] +rustdoc-args = ["--cfg", "docsrs"] [features] unstable = ["recovery", "rand-std"] diff --git a/secp256k1-sys/Cargo.toml b/secp256k1-sys/Cargo.toml index 9d5f4fb..6191efd 100644 --- a/secp256k1-sys/Cargo.toml +++ b/secp256k1-sys/Cargo.toml @@ -17,6 +17,7 @@ links = "rustsecp256k1_v0_4_1" # Should make docs.rs show all functions, even those behind non-default features [package.metadata.docs.rs] features = [ "recovery", "lowmemory" ] +rustdoc-args = ["--cfg", "docsrs"] [build-dependencies] cc = "1.0.28" diff --git a/secp256k1-sys/src/lib.rs b/secp256k1-sys/src/lib.rs index 4f0f0d5..313e3e6 100644 --- a/secp256k1-sys/src/lib.rs +++ b/secp256k1-sys/src/lib.rs @@ -23,6 +23,8 @@ #![deny(unused_mut)] #![cfg_attr(all(not(test), not(feature = "std")), no_std)] +#![cfg_attr(docsrs, feature(doc_cfg))] + #[cfg(any(test, feature = "std"))] extern crate core; @@ -34,6 +36,7 @@ mod macros; pub mod types; #[cfg(feature = "recovery")] +#[cfg_attr(docsrs, doc(cfg(feature = "recovery")))] pub mod recovery; use core::{slice, ptr}; @@ -524,6 +527,7 @@ extern "C" { // In: flags: which parts of the context to initialize. #[no_mangle] #[cfg(all(feature = "std", not(rust_secp_no_symbol_renaming)))] +#[cfg_attr(docsrs, doc(cfg(all(feature = "std", not(rust_secp_no_symbol_renaming)))))] pub unsafe extern "C" fn rustsecp256k1_v0_4_1_context_create(flags: c_uint) -> *mut Context { use core::mem; use std::alloc; @@ -543,6 +547,7 @@ pub unsafe extern "C" fn rustsecp256k1_v0_4_1_context_create(flags: c_uint) -> * } #[cfg(all(feature = "std", not(rust_secp_no_symbol_renaming)))] +#[cfg_attr(docsrs, doc(cfg(all(feature = "std", not(rust_secp_no_symbol_renaming)))))] pub unsafe fn secp256k1_context_create(flags: c_uint) -> *mut Context { rustsecp256k1_v0_4_1_context_create(flags) } @@ -555,6 +560,7 @@ pub unsafe fn secp256k1_context_create(flags: c_uint) -> *mut Context { /// #[no_mangle] #[cfg(all(feature = "std", not(rust_secp_no_symbol_renaming)))] +#[cfg_attr(docsrs, doc(cfg(all(feature = "std", not(rust_secp_no_symbol_renaming)))))] pub unsafe extern "C" fn rustsecp256k1_v0_4_1_context_destroy(ctx: *mut Context) { use std::alloc; secp256k1_context_preallocated_destroy(ctx); @@ -565,6 +571,7 @@ pub unsafe extern "C" fn rustsecp256k1_v0_4_1_context_destroy(ctx: *mut Context) } #[cfg(all(feature = "std", not(rust_secp_no_symbol_renaming)))] +#[cfg_attr(docsrs, doc(cfg(all(feature = "std", not(rust_secp_no_symbol_renaming)))))] pub unsafe fn secp256k1_context_destroy(ctx: *mut Context) { rustsecp256k1_v0_4_1_context_destroy(ctx) } diff --git a/src/context.rs b/src/context.rs index 59831d3..627e016 100644 --- a/src/context.rs +++ b/src/context.rs @@ -6,9 +6,11 @@ use Error; use Secp256k1; #[cfg(any(feature = "std", feature = "alloc"))] +#[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))] pub use self::alloc_only::*; #[cfg(feature = "global-context-less-secure")] +#[cfg_attr(docsrs, doc(cfg(feature = "global-context-less-secure")))] /// Module implementing a singleton pattern for a global `Secp256k1` context pub mod global { #[cfg(feature = "global-context")] @@ -94,6 +96,7 @@ mod private { } #[cfg(any(feature = "std", feature = "alloc"))] +#[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))] mod alloc_only { #[cfg(feature = "std")] use std::alloc; @@ -108,12 +111,15 @@ mod alloc_only { const ALIGN_TO: usize = ::core::mem::align_of::(); /// Represents the set of capabilities needed for signing. + #[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))] pub enum SignOnly {} /// Represents the set of capabilities needed for verification. + #[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))] pub enum VerifyOnly {} /// Represents the set of all capabilities. + #[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))] pub enum All {} impl Signing for SignOnly {} diff --git a/src/ecdsa/mod.rs b/src/ecdsa/mod.rs index 0bc68f6..df4a24e 100644 --- a/src/ecdsa/mod.rs +++ b/src/ecdsa/mod.rs @@ -9,6 +9,7 @@ use ffi::CPtr; mod recovery; #[cfg(feature = "recovery")] +#[cfg_attr(docsrs, doc(cfg(feature = "recovery")))] pub use self::recovery::{RecoveryId, RecoverableSignature}; /// An ECDSA signature @@ -279,6 +280,7 @@ impl From for Signature { } #[cfg(feature = "serde")] +#[cfg_attr(docsrs, doc(cfg(feature = "serde")))] impl ::serde::Serialize for Signature { fn serialize(&self, s: S) -> Result { if s.is_human_readable() { @@ -290,6 +292,7 @@ impl ::serde::Serialize for Signature { } #[cfg(feature = "serde")] +#[cfg_attr(docsrs, doc(cfg(feature = "serde")))] impl<'de> ::serde::Deserialize<'de> for Signature { fn deserialize>(d: D) -> Result { if d.is_human_readable() { diff --git a/src/key.rs b/src/key.rs index f2152b6..9dc2875 100644 --- a/src/key.rs +++ b/src/key.rs @@ -95,9 +95,10 @@ fn random_32_bytes(rng: &mut R) -> [u8; 32] { } impl SecretKey { - /// Creates a new random secret key. Requires compilation with the "rand" feature. + /// Generates a new random secret key. #[inline] #[cfg(any(test, feature = "rand"))] + #[cfg_attr(docsrs, doc(cfg(feature = "rand")))] pub fn new(rng: &mut R) -> SecretKey { let mut data = random_32_bytes(rng); unsafe { @@ -221,6 +222,7 @@ impl SecretKey { } #[cfg(feature = "serde")] +#[cfg_attr(docsrs, doc(cfg(feature = "serde")))] impl ::serde::Serialize for SecretKey { fn serialize(&self, s: S) -> Result { if s.is_human_readable() { @@ -233,6 +235,7 @@ impl ::serde::Serialize for SecretKey { } #[cfg(feature = "serde")] +#[cfg_attr(docsrs, doc(cfg(feature = "serde")))] impl<'de> ::serde::Deserialize<'de> for SecretKey { fn deserialize>(d: D) -> Result { if d.is_human_readable() { @@ -467,6 +470,7 @@ impl From for PublicKey { } #[cfg(feature = "serde")] +#[cfg_attr(docsrs, doc(cfg(feature = "serde")))] impl ::serde::Serialize for PublicKey { fn serialize(&self, s: S) -> Result { if s.is_human_readable() { @@ -478,6 +482,7 @@ impl ::serde::Serialize for PublicKey { } #[cfg(feature = "serde")] +#[cfg_attr(docsrs, doc(cfg(feature = "serde")))] impl<'de> ::serde::Deserialize<'de> for PublicKey { fn deserialize>(d: D) -> Result { if d.is_human_readable() { @@ -586,9 +591,10 @@ impl KeyPair { } } - /// Creates a new random secret key. Requires compilation with the "rand" feature. + /// Generates a new random secret key. #[inline] #[cfg(any(test, feature = "rand"))] + #[cfg_attr(docsrs, doc(cfg(feature = "rand")))] pub fn new(secp: &Secp256k1, rng: &mut R) -> KeyPair { let mut random_32_bytes = || { let mut ret = [0u8; 32]; @@ -686,6 +692,7 @@ impl str::FromStr for KeyPair { } #[cfg(feature = "serde")] +#[cfg_attr(docsrs, doc(cfg(feature = "serde")))] impl ::serde::Serialize for KeyPair { fn serialize(&self, s: S) -> Result { if s.is_human_readable() { @@ -699,6 +706,7 @@ impl ::serde::Serialize for KeyPair { } #[cfg(feature = "serde")] +#[cfg_attr(docsrs, doc(cfg(feature = "serde")))] impl<'de> ::serde::Deserialize<'de> for KeyPair { fn deserialize>(d: D) -> Result { if d.is_human_readable() { @@ -936,6 +944,7 @@ impl From<::key::PublicKey> for XOnlyPublicKey { } #[cfg(feature = "serde")] +#[cfg_attr(docsrs, doc(cfg(feature = "serde")))] impl ::serde::Serialize for XOnlyPublicKey { fn serialize(&self, s: S) -> Result { if s.is_human_readable() { @@ -947,6 +956,7 @@ impl ::serde::Serialize for XOnlyPublicKey { } #[cfg(feature = "serde")] +#[cfg_attr(docsrs, doc(cfg(feature = "serde")))] impl<'de> ::serde::Deserialize<'de> for XOnlyPublicKey { fn deserialize>(d: D) -> Result { if d.is_human_readable() { diff --git a/src/lib.rs b/src/lib.rs index 6cd6a63..c12e614 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -110,6 +110,21 @@ //! Observe that the same code using, say [`signing_only`](struct.Secp256k1.html#method.signing_only) //! to generate a context would simply not compile. //! +//! ## Crate features/optional dependencies +//! +//! The crate provides following opt-in Cargo features: +//! +//! * `std` - use standard Rust library, enabled by default. +//! * `alloc` - use the `alloc` standard Rust library to provide heap allocations. +//! * `rand` - use `rand` library to provide random generator (to e.g. generate keys) +//! * `rand-std` - use `rand` library with its `std` feature enabled. (Implies `rand`.) +//! * `recovery` - enable functions that can compute the public key from signature +//! * `lowmemory` - optimize the library for low-memory environments +//! * `global-context` - enable use of global secp256k1 context. (Implies `std`, `rand-std` and +//! `global-context-less-secure`.) +//! * `global-context-less-secure` - enables global context and opts-in to lower security. +//! * `serde` - implements serialization and deserialization for types in this crate using `serde` +//! * `bitcoin_hashes` - enables interaction with the `bitcoin-hashes` crate (e.g. conversions) // Coding conventions #![deny(non_upper_case_globals)] @@ -121,21 +136,35 @@ #![cfg_attr(all(not(test), not(feature = "std")), no_std)] #![cfg_attr(all(test, feature = "unstable"), feature(test))] +#![cfg_attr(docsrs, feature(doc_cfg))] #[macro_use] pub extern crate secp256k1_sys; pub use secp256k1_sys as ffi; -#[cfg(feature = "bitcoin_hashes")] pub extern crate bitcoin_hashes as hashes; -#[cfg(all(test, feature = "unstable"))] extern crate test; -#[cfg(any(test, feature = "rand"))] pub extern crate rand; -#[cfg(any(test))] extern crate rand_core; -#[cfg(feature = "serde")] pub extern crate serde; -#[cfg(all(test, feature = "serde"))] extern crate serde_test; -#[cfg(any(test, feature = "rand"))] use rand::Rng; -#[cfg(any(test, feature = "std"))] extern crate core; -#[cfg(all(test, target_arch = "wasm32"))] extern crate wasm_bindgen_test; -#[cfg(feature = "alloc")] extern crate alloc; +#[cfg(feature = "bitcoin_hashes")] +#[cfg_attr(docsrs, doc(cfg(feature = "bitcoin_hashes")))] +pub extern crate bitcoin_hashes as hashes; +#[cfg(all(test, feature = "unstable"))] +extern crate test; +#[cfg(any(test, feature = "rand"))] +#[cfg_attr(docsrs, doc(cfg(feature = "rand")))] +pub extern crate rand; +#[cfg(any(test))] +extern crate rand_core; +#[cfg(feature = "serde")] +#[cfg_attr(docsrs, doc(cfg(feature = "serde")))] +pub extern crate serde; +#[cfg(all(test, feature = "serde"))] +extern crate serde_test; +#[cfg(any(test, feature = "rand"))] +use rand::Rng; +#[cfg(any(test, feature = "std"))] +extern crate core; +#[cfg(all(test, target_arch = "wasm32"))] +extern crate wasm_bindgen_test; +#[cfg(feature = "alloc")] +extern crate alloc; #[macro_use] @@ -163,6 +192,7 @@ use core::{mem, fmt, str}; use ffi::{CPtr, types::AlignedType}; #[cfg(feature = "global-context-less-secure")] +#[cfg_attr(docsrs, doc(cfg(feature = "global-context-less-secure")))] pub use context::global::SECP256K1; #[cfg(feature = "bitcoin_hashes")] @@ -196,6 +226,7 @@ pub trait ThirtyTwoByteHash { } #[cfg(feature = "bitcoin_hashes")] +#[cfg_attr(docsrs, doc(cfg(feature = "bitcoin_hashes")))] impl ThirtyTwoByteHash for hashes::sha256::Hash { fn into_32(self) -> [u8; 32] { self.into_inner() @@ -203,6 +234,7 @@ impl ThirtyTwoByteHash for hashes::sha256::Hash { } #[cfg(feature = "bitcoin_hashes")] +#[cfg_attr(docsrs, doc(cfg(feature = "bitcoin_hashes")))] impl ThirtyTwoByteHash for hashes::sha256d::Hash { fn into_32(self) -> [u8; 32] { self.into_inner() @@ -210,6 +242,7 @@ impl ThirtyTwoByteHash for hashes::sha256d::Hash { } #[cfg(feature = "bitcoin_hashes")] +#[cfg_attr(docsrs, doc(cfg(feature = "bitcoin_hashes")))] impl ThirtyTwoByteHash for hashes::sha256t::Hash { fn into_32(self) -> [u8; 32] { self.into_inner() @@ -256,6 +289,7 @@ impl Message { /// assert_eq!(m1, m2); /// ``` #[cfg(feature = "bitcoin_hashes")] + #[cfg_attr(docsrs, doc(cfg(feature = "bitcoin_hashes")))] pub fn from_hashed_data(data: &[u8]) -> Self { ::hash(data).into() } @@ -316,6 +350,7 @@ impl fmt::Display for Error { } #[cfg(feature = "std")] +#[cfg_attr(docsrs, doc(cfg(feature = "std")))] impl std::error::Error for Error {} @@ -374,6 +409,7 @@ impl Secp256k1 { /// see comment in libsecp256k1 commit d2275795f by Gregory Maxwell. Requires /// compilation with "rand" feature. #[cfg(any(test, feature = "rand"))] + #[cfg_attr(docsrs, doc(cfg(feature = "rand")))] pub fn randomize(&mut self, rng: &mut R) { let mut seed = [0u8; 32]; rng.fill_bytes(&mut seed); @@ -406,6 +442,7 @@ impl Secp256k1 { /// with the "rand" feature. #[inline] #[cfg(any(test, feature = "rand"))] + #[cfg_attr(docsrs, doc(cfg(feature = "rand")))] pub fn generate_keypair(&self, rng: &mut R) -> (key::SecretKey, key::PublicKey) { let sk = key::SecretKey::new(rng); diff --git a/src/schnorr.rs b/src/schnorr.rs index 4516f2d..c1f1b0a 100644 --- a/src/schnorr.rs +++ b/src/schnorr.rs @@ -19,6 +19,7 @@ impl_array_newtype!(Signature, u8, constants::SCHNORRSIG_SIGNATURE_SIZE); impl_pretty_debug!(Signature); #[cfg(feature = "serde")] +#[cfg_attr(docsrs, doc(cfg(feature = "serde")))] impl ::serde::Serialize for Signature { fn serialize(&self, s: S) -> Result { if s.is_human_readable() { @@ -30,6 +31,7 @@ impl ::serde::Serialize for Signature { } #[cfg(feature = "serde")] +#[cfg_attr(docsrs, doc(cfg(feature = "serde")))] impl<'de> ::serde::Deserialize<'de> for Signature { fn deserialize>(d: D) -> Result { if d.is_human_readable() { @@ -117,6 +119,7 @@ impl Secp256k1 { /// generator to generate the auxiliary random data. /// Requires compilation with "rand-std" feature. #[cfg(any(test, feature = "rand-std"))] + #[cfg_attr(docsrs, doc(cfg(feature = "rand-std")))] #[deprecated(since = "0.21.0", note = "Use sign_schnorr instead.")] pub fn schnorrsig_sign(&self, msg: &Message, keypair: &KeyPair) -> Signature { self.sign_schnorr(msg, keypair) @@ -126,6 +129,7 @@ impl Secp256k1 { /// generator to generate the auxiliary random data. /// Requires compilation with "rand-std" feature. #[cfg(any(test, feature = "rand-std"))] + #[cfg_attr(docsrs, doc(cfg(feature = "rand-std")))] pub fn sign_schnorr(&self, msg: &Message, keypair: &KeyPair) -> Signature { let mut rng = thread_rng(); self.sign_schnorr_with_rng(msg, keypair, &mut rng) @@ -179,6 +183,7 @@ impl Secp256k1 { /// generate the auxiliary random data. Requires compilation with "rand" /// feature. #[cfg(any(test, feature = "rand"))] + #[cfg_attr(docsrs, doc(cfg(feature = "rand")))] #[deprecated(since = "0.21.0", note = "Use sign_schnorr_with_rng instead.")] pub fn schnorrsig_sign_with_rng( &self, @@ -193,6 +198,7 @@ impl Secp256k1 { /// generate the auxiliary random data. Requires compilation with "rand" /// feature. #[cfg(any(test, feature = "rand"))] + #[cfg_attr(docsrs, doc(cfg(feature = "rand")))] pub fn sign_schnorr_with_rng( &self, msg: &Message, @@ -250,6 +256,7 @@ impl Secp256k1 { /// with the "rand" feature. #[inline] #[cfg(any(test, feature = "rand"))] + #[cfg_attr(docsrs, doc(cfg(feature = "rand")))] pub fn generate_schnorrsig_keypair( &self, rng: &mut R, diff --git a/src/secret.rs b/src/secret.rs index 564e17e..c174122 100644 --- a/src/secret.rs +++ b/src/secret.rs @@ -22,6 +22,7 @@ macro_rules! impl_display_secret { // Default hasher exists only in standard library and not alloc ($thing:ident) => { #[cfg(feature = "std")] + #[cfg_attr(docsrs, doc(cfg(feature = "std")))] impl ::core::fmt::Debug for $thing { fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { use ::core::hash::Hasher;