diff --git a/units/src/amount.rs b/units/src/amount.rs index 0716cd3487..1045038d6d 100644 --- a/units/src/amount.rs +++ b/units/src/amount.rs @@ -6,7 +6,9 @@ //! We refer to the documentation on the types for more information. use core::cmp::Ordering; -use core::fmt::{self, Write as _}; +use core::fmt; +#[cfg(feature = "alloc")] +use core::fmt::Write as _; use core::str::FromStr; use core::{default, ops}; @@ -16,7 +18,7 @@ use internals::error::InputString; use internals::write_err; #[cfg(feature = "alloc")] -use crate::prelude::{String, ToString}; +use alloc::string::{String, ToString}; /// A set of denominations in which amounts can be expressed. /// @@ -701,6 +703,7 @@ impl Amount { pub fn to_sat(self) -> u64 { self.0 } /// Convert from a value expressing bitcoins to an [Amount]. + #[cfg(feature = "alloc")] pub fn from_btc(btc: f64) -> Result { Amount::from_float_in(btc, Denomination::Bitcoin) } @@ -754,6 +757,7 @@ impl Amount { /// Express this [Amount] as a floating-point value in the given denomination. /// /// Please be aware of the risk of using floating-point numbers. + #[cfg(feature = "alloc")] pub fn to_float_in(self, denom: Denomination) -> f64 { f64::from_str(&self.to_string_in(denom)).unwrap() } @@ -768,6 +772,7 @@ impl Amount { /// let amount = Amount::from_sat(100_000); /// assert_eq!(amount.to_btc(), amount.to_float_in(Denomination::Bitcoin)) /// ``` + #[cfg(feature = "alloc")] pub fn to_btc(self) -> f64 { self.to_float_in(Denomination::Bitcoin) } /// Convert this [Amount] in floating-point notation with a given @@ -775,6 +780,7 @@ impl Amount { /// Can return error if the amount is too big, too precise or negative. /// /// Please be aware of the risk of using floating-point numbers. + #[cfg(feature = "alloc")] pub fn from_float_in(value: f64, denom: Denomination) -> Result { if value < 0.0 { return Err(OutOfRangeError::negative().into()); @@ -816,6 +822,7 @@ impl Amount { /// Get a string number of this [Amount] in the given denomination. /// /// Does not include the denomination. + #[cfg(feature = "alloc")] pub fn to_string_in(self, denom: Denomination) -> String { let mut buf = String::new(); self.fmt_value_in(&mut buf, denom).unwrap(); @@ -824,6 +831,7 @@ impl Amount { /// Get a formatted string of this [Amount] in the given denomination, /// suffixed with the abbreviation for the denomination. + #[cfg(feature = "alloc")] pub fn to_string_with_denomination(self, denom: Denomination) -> String { let mut buf = String::new(); self.fmt_value_in(&mut buf, denom).unwrap(); @@ -875,7 +883,7 @@ impl default::Default for Amount { impl fmt::Debug for Amount { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "Amount({:.8} BTC)", self.to_btc()) + write!(f, "{} SAT", self.to_sat()) } } @@ -1056,6 +1064,7 @@ impl SignedAmount { pub fn to_sat(self) -> i64 { self.0 } /// Convert from a value expressing bitcoins to an [SignedAmount]. + #[cfg(feature = "alloc")] pub fn from_btc(btc: f64) -> Result { SignedAmount::from_float_in(btc, Denomination::Bitcoin) } @@ -1087,6 +1096,7 @@ impl SignedAmount { /// Express this [SignedAmount] as a floating-point value in the given denomination. /// /// Please be aware of the risk of using floating-point numbers. + #[cfg(feature = "alloc")] pub fn to_float_in(self, denom: Denomination) -> f64 { f64::from_str(&self.to_string_in(denom)).unwrap() } @@ -1096,6 +1106,7 @@ impl SignedAmount { /// Equivalent to `to_float_in(Denomination::Bitcoin)`. /// /// Please be aware of the risk of using floating-point numbers. + #[cfg(feature = "alloc")] pub fn to_btc(self) -> f64 { self.to_float_in(Denomination::Bitcoin) } /// Convert this [SignedAmount] in floating-point notation with a given @@ -1103,6 +1114,7 @@ impl SignedAmount { /// Can return error if the amount is too big, too precise or negative. /// /// Please be aware of the risk of using floating-point numbers. + #[cfg(feature = "alloc")] pub fn from_float_in( value: f64, denom: Denomination, @@ -1144,6 +1156,7 @@ impl SignedAmount { /// Get a string number of this [SignedAmount] in the given denomination. /// /// Does not include the denomination. + #[cfg(feature = "alloc")] pub fn to_string_in(self, denom: Denomination) -> String { let mut buf = String::new(); self.fmt_value_in(&mut buf, denom).unwrap(); @@ -1152,6 +1165,7 @@ impl SignedAmount { /// Get a formatted string of this [SignedAmount] in the given denomination, /// suffixed with the abbreviation for the denomination. + #[cfg(feature = "alloc")] pub fn to_string_with_denomination(self, denom: Denomination) -> String { let mut buf = String::new(); self.fmt_value_in(&mut buf, denom).unwrap(); @@ -1244,7 +1258,7 @@ impl default::Default for SignedAmount { impl fmt::Debug for SignedAmount { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "SignedAmount({:.8} BTC)", self.to_btc()) + write!(f, "SignedAmount({} SAT)", self.to_sat()) } } @@ -1360,7 +1374,7 @@ where } mod private { - use crate::{Amount, SignedAmount}; + use super::{Amount, SignedAmount}; /// Used to seal the `CheckedSum` trait pub trait SumSeal {} @@ -1393,30 +1407,32 @@ pub mod serde { use core::fmt; use serde::{Deserialize, Deserializer, Serialize, Serializer}; - use crate::amount::{Amount, Denomination, SignedAmount, ParseAmountError}; + use super::{Amount, SignedAmount, ParseAmountError}; + #[cfg(feature = "alloc")] + use super::Denomination; /// This trait is used only to avoid code duplication and naming collisions /// of the different serde serialization crates. - pub trait SerdeAmount: Copy + Sized + private::Sealed { - fn ser_sat(self, s: S) -> Result; - fn des_sat<'d, D: Deserializer<'d>>(d: D) -> Result; - fn ser_btc(self, s: S) -> Result; - fn des_btc<'d, D: Deserializer<'d>>(d: D) -> Result; + pub trait SerdeAmount: Copy + Sized { + fn ser_sat(self, s: S, _: private::Token) -> Result; + fn des_sat<'d, D: Deserializer<'d>>(d: D, _: private::Token) -> Result; + #[cfg(feature = "alloc")] + fn ser_btc(self, s: S, _: private::Token) -> Result; + #[cfg(feature = "alloc")] + fn des_btc<'d, D: Deserializer<'d>>(d: D, _: private::Token) -> Result; } mod private { - /// add this as a trait bound to traits which consumers of this library - /// should not be able to implement. - pub trait Sealed {} - impl Sealed for super::Amount {} - impl Sealed for super::SignedAmount {} + /// Controls access to the trait methods. + pub struct Token; } /// This trait is only for internal Amount type serialization/deserialization - pub trait SerdeAmountForOpt: Copy + Sized + SerdeAmount + private::Sealed { - fn type_prefix() -> &'static str; - fn ser_sat_opt(self, s: S) -> Result; - fn ser_btc_opt(self, s: S) -> Result; + pub trait SerdeAmountForOpt: Copy + Sized + SerdeAmount { + fn type_prefix(_: private::Token) -> &'static str; + fn ser_sat_opt(self, s: S, _: private::Token) -> Result; + #[cfg(feature = "alloc")] + fn ser_btc_opt(self, s: S, _: private::Token) -> Result; } struct DisplayFullError(ParseAmountError); @@ -1444,16 +1460,18 @@ pub mod serde { } impl SerdeAmount for Amount { - fn ser_sat(self, s: S) -> Result { + fn ser_sat(self, s: S, _: private::Token) -> Result { u64::serialize(&self.to_sat(), s) } - fn des_sat<'d, D: Deserializer<'d>>(d: D) -> Result { + fn des_sat<'d, D: Deserializer<'d>>(d: D, _: private::Token) -> Result { Ok(Amount::from_sat(u64::deserialize(d)?)) } - fn ser_btc(self, s: S) -> Result { + #[cfg(feature = "alloc")] + fn ser_btc(self, s: S, _: private::Token) -> Result { f64::serialize(&self.to_float_in(Denomination::Bitcoin), s) } - fn des_btc<'d, D: Deserializer<'d>>(d: D) -> Result { + #[cfg(feature = "alloc")] + fn des_btc<'d, D: Deserializer<'d>>(d: D, _: private::Token) -> Result { use serde::de::Error; Amount::from_btc(f64::deserialize(d)?) .map_err(DisplayFullError) @@ -1462,26 +1480,29 @@ pub mod serde { } impl SerdeAmountForOpt for Amount { - fn type_prefix() -> &'static str { "u" } - fn ser_sat_opt(self, s: S) -> Result { + fn type_prefix(_: private::Token) -> &'static str { "u" } + fn ser_sat_opt(self, s: S, _: private::Token) -> Result { s.serialize_some(&self.to_sat()) } - fn ser_btc_opt(self, s: S) -> Result { + #[cfg(feature = "alloc")] + fn ser_btc_opt(self, s: S, _: private::Token) -> Result { s.serialize_some(&self.to_btc()) } } impl SerdeAmount for SignedAmount { - fn ser_sat(self, s: S) -> Result { + fn ser_sat(self, s: S, _: private::Token) -> Result { i64::serialize(&self.to_sat(), s) } - fn des_sat<'d, D: Deserializer<'d>>(d: D) -> Result { + fn des_sat<'d, D: Deserializer<'d>>(d: D, _: private::Token) -> Result { Ok(SignedAmount::from_sat(i64::deserialize(d)?)) } - fn ser_btc(self, s: S) -> Result { + #[cfg(feature = "alloc")] + fn ser_btc(self, s: S, _: private::Token) -> Result { f64::serialize(&self.to_float_in(Denomination::Bitcoin), s) } - fn des_btc<'d, D: Deserializer<'d>>(d: D) -> Result { + #[cfg(feature = "alloc")] + fn des_btc<'d, D: Deserializer<'d>>(d: D, _: private::Token) -> Result { use serde::de::Error; SignedAmount::from_btc(f64::deserialize(d)?) .map_err(DisplayFullError) @@ -1490,11 +1511,12 @@ pub mod serde { } impl SerdeAmountForOpt for SignedAmount { - fn type_prefix() -> &'static str { "i" } - fn ser_sat_opt(self, s: S) -> Result { + fn type_prefix(_: private::Token) -> &'static str { "i" } + fn ser_sat_opt(self, s: S, _: private::Token) -> Result { s.serialize_some(&self.to_sat()) } - fn ser_btc_opt(self, s: S) -> Result { + #[cfg(feature = "alloc")] + fn ser_btc_opt(self, s: S, _: private::Token) -> Result { s.serialize_some(&self.to_btc()) } } @@ -1502,23 +1524,26 @@ pub mod serde { pub mod as_sat { //! Serialize and deserialize [`Amount`](crate::Amount) as real numbers denominated in satoshi. //! Use with `#[serde(with = "amount::serde::as_sat")]`. + //! + use super::private; use serde::{Deserializer, Serializer}; use crate::amount::serde::SerdeAmount; pub fn serialize(a: &A, s: S) -> Result { - a.ser_sat(s) + a.ser_sat(s, private::Token) } pub fn deserialize<'d, A: SerdeAmount, D: Deserializer<'d>>(d: D) -> Result { - A::des_sat(d) + A::des_sat(d, private::Token) } pub mod opt { //! Serialize and deserialize [`Option`](crate::Amount) as real numbers denominated in satoshi. //! Use with `#[serde(default, with = "amount::serde::as_sat::opt")]`. + use super::private; use core::fmt; use core::marker::PhantomData; @@ -1531,7 +1556,7 @@ pub mod serde { s: S, ) -> Result { match *a { - Some(a) => a.ser_sat_opt(s), + Some(a) => a.ser_sat_opt(s, private::Token), None => s.serialize_none(), } } @@ -1545,7 +1570,7 @@ pub mod serde { type Value = Option; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - write!(formatter, "An Option<{}64>", X::type_prefix()) + write!(formatter, "An Option<{}64>", X::type_prefix(private::Token)) } fn visit_none(self) -> Result @@ -1558,7 +1583,7 @@ pub mod serde { where D: Deserializer<'de>, { - Ok(Some(X::des_sat(d)?)) + Ok(Some(X::des_sat(d, private::Token)?)) } } d.deserialize_option(VisitOptAmt::(PhantomData)) @@ -1566,26 +1591,30 @@ pub mod serde { } } + #[cfg(feature = "alloc")] pub mod as_btc { //! Serialize and deserialize [`Amount`](crate::Amount) as JSON numbers denominated in BTC. //! Use with `#[serde(with = "amount::serde::as_btc")]`. + use super::private; + use serde::{Deserializer, Serializer}; use crate::amount::serde::SerdeAmount; pub fn serialize(a: &A, s: S) -> Result { - a.ser_btc(s) + a.ser_btc(s, private::Token) } pub fn deserialize<'d, A: SerdeAmount, D: Deserializer<'d>>(d: D) -> Result { - A::des_btc(d) + A::des_btc(d, private::Token) } pub mod opt { //! Serialize and deserialize `Option` as JSON numbers denominated in BTC. //! Use with `#[serde(default, with = "amount::serde::as_btc::opt")]`. + use super::private; use core::fmt; use core::marker::PhantomData; @@ -1598,7 +1627,7 @@ pub mod serde { s: S, ) -> Result { match *a { - Some(a) => a.ser_btc_opt(s), + Some(a) => a.ser_btc_opt(s, private::Token), None => s.serialize_none(), } } @@ -1625,7 +1654,7 @@ pub mod serde { where D: Deserializer<'de>, { - Ok(Some(X::des_btc(d)?)) + Ok(Some(X::des_btc(d, private::Token)?)) } } d.deserialize_option(VisitOptAmt::(PhantomData)) @@ -1759,6 +1788,10 @@ mod verification { #[cfg(test)] mod tests { use core::str::FromStr; + + #[cfg(feature = "alloc")] + use alloc::format; + #[cfg(feature = "std")] use std::panic; @@ -1768,8 +1801,9 @@ mod tests { use super::*; #[test] + #[cfg(feature = "alloc")] fn from_str_zero() { - let denoms = vec!["BTC", "mBTC", "uBTC", "nBTC", "pBTC", "bits", "sats", "msats"]; + let denoms = ["BTC", "mBTC", "uBTC", "nBTC", "pBTC", "bits", "sats", "msats"]; for denom in denoms { for v in &["0", "000"] { let s = format!("{} {}", v, denom); @@ -1844,6 +1878,7 @@ mod tests { assert_eq!(ssat(-6).checked_div(2), Some(ssat(-3))); } + #[cfg(feature = "alloc")] #[test] fn floating_point() { use super::Denomination as D; @@ -1905,7 +1940,9 @@ mod tests { assert_eq!(p("-1.0x", btc), Err(E::InvalidCharacter('x'))); assert_eq!(p("0.0 ", btc), Err(ParseAmountError::InvalidCharacter(' '))); assert_eq!(p("0.000.000", btc), Err(E::InvalidFormat)); + #[cfg(feature = "alloc")] let more_than_max = format!("1{}", Amount::MAX); + #[cfg(feature = "alloc")] assert_eq!(p(&more_than_max, btc), Err(OutOfRangeError::too_big(false).into())); assert_eq!(p("0.000000042", btc), Err(E::TooPrecise)); assert_eq!(p("999.0000000", msat), Err(E::TooPrecise)); @@ -1920,6 +1957,7 @@ mod tests { assert_eq!(p("1", btc), Ok(Amount::from_sat(1_000_000_00))); assert_eq!(sp("-.5", btc), Ok(SignedAmount::from_sat(-500_000_00))); + #[cfg(feature = "alloc")] assert_eq!(sp(&i64::MIN.to_string(), sat), Ok(SignedAmount::from_sat(i64::MIN))); assert_eq!(p("1.1", btc), Ok(Amount::from_sat(1_100_000_00))); assert_eq!(p("100", sat), Ok(Amount::from_sat(100))); @@ -1935,10 +1973,13 @@ mod tests { assert_eq!(p("1000.000000000000000000000000000", msat), Ok(Amount::from_sat(1))); // make sure satoshi > i64::MAX is checked. - let amount = Amount::from_sat(i64::MAX as u64); - assert_eq!(Amount::from_str_in(&amount.to_string_in(sat), sat), Ok(amount)); - assert!(SignedAmount::from_str_in(&(amount + Amount(1)).to_string_in(sat), sat).is_err()); - assert!(Amount::from_str_in(&(amount + Amount(1)).to_string_in(sat), sat).is_ok()); + #[cfg(feature = "alloc")] + { + let amount = Amount::from_sat(i64::MAX as u64); + assert_eq!(Amount::from_str_in(&amount.to_string_in(sat), sat), Ok(amount)); + assert!(SignedAmount::from_str_in(&(amount + Amount(1)).to_string_in(sat), sat).is_err()); + assert!(Amount::from_str_in(&(amount + Amount(1)).to_string_in(sat), sat).is_ok()); + } assert_eq!(p("12.000", Denomination::MilliSatoshi), Err(E::TooPrecise)); // exactly 50 chars. @@ -1954,6 +1995,7 @@ mod tests { } #[test] + #[cfg(feature = "alloc")] fn to_string() { use super::Denomination as D; @@ -1977,6 +2019,7 @@ mod tests { } // May help identify a problem sooner + #[cfg(feature = "alloc")] #[test] fn test_repeat_char() { let mut buf = String::new(); @@ -1992,6 +2035,7 @@ mod tests { ($denom:ident; $($test_name:ident, $val:literal, $format_string:literal, $expected:literal);* $(;)?) => { $( #[test] + #[cfg(feature = "alloc")] fn $test_name() { assert_eq!(format!($format_string, Amount::from_sat($val).display_in(Denomination::$denom)), $expected); assert_eq!(format!($format_string, SignedAmount::from_sat($val as i64).display_in(Denomination::$denom)), $expected); @@ -2004,6 +2048,7 @@ mod tests { ($denom:ident, $denom_suffix:literal; $($test_name:ident, $val:literal, $format_string:literal, $expected:literal);* $(;)?) => { $( #[test] + #[cfg(feature = "alloc")] fn $test_name() { assert_eq!(format!($format_string, Amount::from_sat($val).display_in(Denomination::$denom).show_denomination()), concat!($expected, $denom_suffix)); assert_eq!(format!($format_string, SignedAmount::from_sat($val as i64).display_in(Denomination::$denom).show_denomination()), concat!($expected, $denom_suffix)); @@ -2237,9 +2282,11 @@ mod tests { ok_scase("-5 satoshi", SignedAmount::from_sat(-5)); ok_case("0.10000000 BTC", Amount::from_sat(100_000_00)); ok_scase("-100 bits", SignedAmount::from_sat(-10_000)); + #[cfg(feature = "alloc")] ok_scase(&format!("{} SAT", i64::MIN), SignedAmount::from_sat(i64::MIN)); } + #[cfg(feature = "alloc")] #[test] #[allow(clippy::inconsistent_digit_grouping)] // Group to show 100,000,000 sats per bitcoin. fn to_from_string_in() { @@ -2326,6 +2373,7 @@ mod tests { ); } + #[cfg(feature = "alloc")] #[test] fn to_string_with_denomination_from_str_roundtrip() { use ParseDenominationError::*; @@ -2378,6 +2426,7 @@ mod tests { } #[cfg(feature = "serde")] + #[cfg(feature = "alloc")] #[test] #[allow(clippy::inconsistent_digit_grouping)] // Group to show 100,000,000 sats per bitcoin. fn serde_as_btc() { @@ -2409,10 +2458,11 @@ mod tests { serde_json::from_str("{\"amt\": 1000000.000000001, \"samt\": 1}"); assert!(t.unwrap_err().to_string().contains(&ParseAmountError::TooPrecise.to_string())); let t: Result = serde_json::from_str("{\"amt\": -1, \"samt\": 1}"); - assert!(dbg!(t.unwrap_err().to_string()).contains(&OutOfRangeError::negative().to_string())); + assert!(t.unwrap_err().to_string().contains(&OutOfRangeError::negative().to_string())); } #[cfg(feature = "serde")] + #[cfg(feature = "alloc")] #[test] #[allow(clippy::inconsistent_digit_grouping)] // Group to show 100,000,000 sats per bitcoin. fn serde_as_btc_opt() { @@ -2454,6 +2504,7 @@ mod tests { } #[cfg(feature = "serde")] + #[cfg(feature = "alloc")] #[test] #[allow(clippy::inconsistent_digit_grouping)] // Group to show 100,000,000 sats per bitcoin. fn serde_as_sat_opt() { @@ -2496,14 +2547,14 @@ mod tests { #[test] fn sum_amounts() { - assert_eq!(Amount::from_sat(0), vec![].into_iter().sum::()); - assert_eq!(SignedAmount::from_sat(0), vec![].into_iter().sum::()); + assert_eq!(Amount::from_sat(0), [].into_iter().sum::()); + assert_eq!(SignedAmount::from_sat(0), [].into_iter().sum::()); - let amounts = vec![Amount::from_sat(42), Amount::from_sat(1337), Amount::from_sat(21)]; + let amounts = [Amount::from_sat(42), Amount::from_sat(1337), Amount::from_sat(21)]; let sum = amounts.into_iter().sum::(); assert_eq!(Amount::from_sat(1400), sum); - let amounts = vec![ + let amounts = [ SignedAmount::from_sat(-42), SignedAmount::from_sat(1337), SignedAmount::from_sat(21), @@ -2514,19 +2565,19 @@ mod tests { #[test] fn checked_sum_amounts() { - assert_eq!(Some(Amount::from_sat(0)), vec![].into_iter().checked_sum()); - assert_eq!(Some(SignedAmount::from_sat(0)), vec![].into_iter().checked_sum()); + assert_eq!(Some(Amount::from_sat(0)), [].into_iter().checked_sum()); + assert_eq!(Some(SignedAmount::from_sat(0)), [].into_iter().checked_sum()); - let amounts = vec![Amount::from_sat(42), Amount::from_sat(1337), Amount::from_sat(21)]; + let amounts = [Amount::from_sat(42), Amount::from_sat(1337), Amount::from_sat(21)]; let sum = amounts.into_iter().checked_sum(); assert_eq!(Some(Amount::from_sat(1400)), sum); let amounts = - vec![Amount::from_sat(u64::MAX), Amount::from_sat(1337), Amount::from_sat(21)]; + [Amount::from_sat(u64::MAX), Amount::from_sat(1337), Amount::from_sat(21)]; let sum = amounts.into_iter().checked_sum(); assert_eq!(None, sum); - let amounts = vec![ + let amounts = [ SignedAmount::from_sat(i64::MIN), SignedAmount::from_sat(-1), SignedAmount::from_sat(21), @@ -2534,7 +2585,7 @@ mod tests { let sum = amounts.into_iter().checked_sum(); assert_eq!(None, sum); - let amounts = vec![ + let amounts = [ SignedAmount::from_sat(i64::MAX), SignedAmount::from_sat(1), SignedAmount::from_sat(21), @@ -2542,7 +2593,7 @@ mod tests { let sum = amounts.into_iter().checked_sum(); assert_eq!(None, sum); - let amounts = vec![ + let amounts = [ SignedAmount::from_sat(42), SignedAmount::from_sat(3301), SignedAmount::from_sat(21), @@ -2554,7 +2605,7 @@ mod tests { #[test] fn denomination_string_acceptable_forms() { // Non-exhaustive list of valid forms. - let valid = vec![ + let valid = [ "BTC", "btc", "mBTC", "mbtc", "uBTC", "ubtc", "SATOSHI", "satoshi", "SATOSHIS", "satoshis", "SAT", "sat", "SATS", "sats", "bit", "bits", "nBTC", "pBTC", ]; diff --git a/units/src/lib.rs b/units/src/lib.rs index 8ba67671a0..2fcd4edd06 100644 --- a/units/src/lib.rs +++ b/units/src/lib.rs @@ -4,7 +4,6 @@ //! //! This library provides basic types used by the Rust Bitcoin ecosystem. -#![cfg_attr(all(not(test), not(feature = "std")), no_std)] // Experimental features we need. #![cfg_attr(docsrs, feature(doc_auto_cfg))] // Coding conventions @@ -12,6 +11,8 @@ // Exclude clippy lints we don't think are valuable #![allow(clippy::needless_question_mark)] // https://github.com/rust-bitcoin/rust-bitcoin/pull/2134 +#![no_std] + // Disable 16-bit support at least for now as we can't guarantee it yet. #[cfg(target_pointer_width = "16")] compile_error!( @@ -19,28 +20,17 @@ compile_error!( know if you want 16-bit support. Note that we do NOT guarantee that we will implement it!" ); -#[cfg(all(feature = "alloc", not(feature = "std")))] +#[cfg(feature = "alloc")] extern crate alloc; -#[cfg(not(feature = "std"))] -extern crate core; +#[cfg(feature = "std")] +extern crate std; /// A generic serialization/deserialization framework. #[cfg(feature = "serde")] pub extern crate serde; -#[cfg(feature = "alloc")] pub mod amount; -#[cfg(feature = "alloc")] #[doc(inline)] pub use self::amount::{Amount, ParseAmountError, SignedAmount}; - -#[rustfmt::skip] -mod prelude { - #[cfg(all(feature = "alloc", not(feature = "std"), not(test)))] - pub use alloc::string::{String, ToString}; - - #[cfg(any(feature = "std", test))] - pub use std::string::{String, ToString}; -}