diff --git a/README.md b/README.md index 47baae3..0370295 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,11 @@ This crate provides multiple semantic wrappers and utilities for byte size repre * `FromStr` impl for `ByteSize`, allowing for parsing string size representations like "1.5 KiB" and "521 TB". * `Display` impl for `ByteSize`, allowing for formatting byte sizes as human-readable strings in both binary (e.g., "1.5 MiB") and decimal (e.g., "1.5 MB") styles. * Optional `serde` support for binary and human-readable format. -* Optional `nightly` support for generic const unit constructors, allowing calls like `ByteSize::kib(16_u64)`. +* Optional `nightly` support for a broader const-friendly API surface powered by nightly-only Rust features. + +## Nightly + +With the `nightly` feature enabled on a nightly compiler, this crate can use unstable Rust capabilities such as const trait support. The visible effect is a broader const surface for generic byte-size expressions, including unit helpers and simple transformations over the underlying byte count. Because this follows Rust nightly, exact capabilities may evolve with upstream language features. ## Documentation diff --git a/bsize/src/lib.rs b/bsize/src/lib.rs index f8e1e2a..b91d3ff 100644 --- a/bsize/src/lib.rs +++ b/bsize/src/lib.rs @@ -13,7 +13,10 @@ // limitations under the License. #![cfg_attr(docsrs, feature(doc_cfg))] -#![cfg_attr(feature = "nightly", feature(const_ops, const_trait_impl))] +#![cfg_attr( + feature = "nightly", + feature(const_closures, const_destruct, const_ops, const_trait_impl) +)] #![deny(missing_docs)] //! This crate provides multiple semantic wrappers and utilities for byte size representations. @@ -29,8 +32,16 @@ //! * [`Display`] impl for `ByteSize`, allowing for formatting byte sizes as human-readable strings //! in both binary (e.g., "1.5 MiB") and decimal (e.g., "1.5 MB") styles. //! * Optional `serde` support for binary and human-readable format. -//! * Optional `nightly` support for generic const unit constructors, allowing calls like -//! `ByteSize::kib(16_u64)`. +//! * Optional `nightly` support for a broader const-friendly API surface powered by nightly-only +//! Rust features. +//! +//! # Nightly +//! +//! With the `nightly` feature enabled on a nightly compiler, this crate can use unstable Rust +//! capabilities such as const trait support. The visible effect is a broader const surface for +//! generic byte-size expressions, including unit helpers and simple transformations over the +//! underlying byte count. Because this follows Rust nightly, exact capabilities may evolve with +//! upstream language features. //! //! # Examples //! diff --git a/bsize/src/types/mod.rs b/bsize/src/types/mod.rs index a24bd85..45a8941 100644 --- a/bsize/src/types/mod.rs +++ b/bsize/src/types/mod.rs @@ -54,11 +54,6 @@ impl fmt::Display for ByteSize { } impl ByteSize { - /// Calculate a new byte size with the provided function, returning a new struct. - pub fn map(self, f: impl FnOnce(T) -> T) -> Self { - ByteSize(f(self.0)) - } - /// Constructs a byte size wrapper from a quantity of bytes. #[inline(always)] pub const fn b(size: T) -> Self { diff --git a/bsize/src/types/nightly.rs b/bsize/src/types/nightly.rs index ed85b93..2e733c5 100644 --- a/bsize/src/types/nightly.rs +++ b/bsize/src/types/nightly.rs @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +use core::marker::Destruct; + use super::ByteSize; use crate::traits::BaseByteSize; use crate::traits::ExaByteSize; @@ -22,6 +24,16 @@ use crate::traits::PetaByteSize; use crate::traits::TeraByteSize; impl ByteSize { + /// Calculate a new byte size with the provided function, returning a new struct. + /// + /// This method can be used in const contexts when the provided function is const-compatible. + pub const fn map(self, f: F) -> Self + where + F: [const] FnOnce(T) -> T + [const] Destruct, + { + ByteSize(f(self.0)) + } + /// Returns byte count as bytes. /// /// The result is approximate when the byte count cannot be represented @@ -325,4 +337,11 @@ mod tests { assert_close(BYTES, 16.0); assert_close(KIB, 16.0); } + + #[test] + fn map_is_const() { + const SIZE: ByteSize = ByteSize::kib(4_u64).map(const |bytes| bytes + 64); + + assert_eq!(SIZE, ByteSize::b(4_160)); + } } diff --git a/bsize/src/types/stable.rs b/bsize/src/types/stable.rs index 9064c63..d61db25 100644 --- a/bsize/src/types/stable.rs +++ b/bsize/src/types/stable.rs @@ -13,6 +13,14 @@ // limitations under the License. use super::ByteSize; +use crate::traits::BaseByteSize; + +impl ByteSize { + /// Calculate a new byte size with the provided function, returning a new struct. + pub fn map(self, f: impl FnOnce(T) -> T) -> Self { + ByteSize(f(self.0)) + } +} macroweave::repeat!((Ty, Name, Trait, Size) in [ (u16, kb, KiloByteSize, KB),