Skip to content

Commit

Permalink
Merge pull request #16 from rodrimati1992/0.2patch
Browse files Browse the repository at this point in the history
0.2.14 release
  • Loading branch information
rodrimati1992 committed Mar 27, 2021
2 parents 2946cfe + 25ff07a commit 14f470e
Show file tree
Hide file tree
Showing 18 changed files with 128 additions and 90 deletions.
9 changes: 9 additions & 0 deletions .github/workflows/rust.yml
Expand Up @@ -27,6 +27,15 @@ jobs:
cd "${{github.workspace}}/const_format/"
cargo test --features "testing"
- uses: actions/checkout@v2
- name: ci-stable
# apparently github hadn't updated stable by 2021-03-27?
if: ${{ matrix.rust == 'beta' }}
run: |
cargo update
cd "${{github.workspace}}/const_format/"
cargo test --features "testing const_generics"
- uses: actions/checkout@v2
- name: ci-nighly
Expand Down
9 changes: 9 additions & 0 deletions Changelog.md
Expand Up @@ -2,6 +2,15 @@ This is the changelog,summarising changes in each version(some minor changes may

# 0.2

### 0.2.14

Fixed a few documentation issues.

Made the `const_format::fmt` API that uses const generics unconditional, since const generics were stabilized in late 2020 and the `fmt` API requires the nightly compiler.

Repurposed the "const_generics" feature to generate less code in the `concatcp` and `formatcp` macros,
by moving some of their implementation to a function that uses const generics.

### 0.2.13

Fixed the assertion macros not to use `std::panic`, using `core::panic` instead, since `core::panic` changed to allow passing a non-literal `&'static str` argument.
Expand Down
11 changes: 3 additions & 8 deletions README.md
Expand Up @@ -269,14 +269,9 @@ An optimization that requires a few additional nightly features,
allowing the `as_bytes_alt` methods and `slice_up_to_len_alt` methods to run
in constant time, rather than linear time proportional to the truncated part of the slice.

- "const_generics":
Enables impls that use const generics, currently only used for ergonomics.
Use this when const generics are usable in stable Rust.

- "nightly_const_generics":
Enables impls that use const generics, currently only used for ergonomics.
This requires a nightly Rust compiler.

- "const_generics": Requires Rust 1.51.0.
Uses const generics in the implementation of the [`concatcp`] and [`formatcp`]
macros to output less code.

# No-std support

Expand Down
6 changes: 3 additions & 3 deletions const_format/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "const_format"
version = "0.2.13"
version = "0.2.14"
authors = ["rodrimati1992 <rodrimatt1985@gmail.com>"]
edition = "2018"
license = "Zlib"
Expand All @@ -24,7 +24,7 @@ travis-ci = { repository = "rodrimati1992/const_format_crates/" }
default = []
const_generics = []
nightly_const_generics = ["const_generics"]
fmt = []
fmt = ["const_generics"]
derive = ["fmt", "const_format_proc_macros/derive"]
assert = ["fmt"]
constant_time_as_str = ["fmt"]
Expand All @@ -37,7 +37,7 @@ docsrs = []
all = ["fmt", "derive", "constant_time_as_str", "nightly_const_generics", "assert", "docsrs"]

[dependencies.const_format_proc_macros]
version = "=0.2.8"
version = "=0.2.14"
path = "../const_format_proc_macros"

[dev-dependencies]
Expand Down
24 changes: 12 additions & 12 deletions const_format/src/const_debug_derive.rs
Expand Up @@ -51,16 +51,6 @@
/// When this attribute is used it disables the default implementation
/// that uses the type parameters generically.
///
/// ### `#[cdeb(crate = "foo::bar")]`
///
/// The path to the `const_format` crate, useful if you want to reexport the ConstDebug macro,
/// or rename the const_format crate in the Cargo.toml .
///
/// Example of renaming the `const_format` crate in the Cargo.toml file:
/// ```toml
/// cfmt = {version = "0.*", package = "const_format"}
/// ```
///
/// Example:
///
/// ```rust
Expand All @@ -77,11 +67,21 @@
/// In this example, there's exactly three impls of
/// the `const_debug_fmt` method and [`FormatMarker`] trait.
///
/// ### `#[cdeb(crate = "foo::bar")]`
///
/// The path to the `const_format` crate, useful if you want to reexport the ConstDebug macro,
/// or rename the `const_format` crate in the Cargo.toml .
///
/// Example of renaming the `const_format` crate in the Cargo.toml file:
/// ```toml
/// cfmt = {version = "0.*", package = "const_format"}
/// ```
///
/// # Field attributes
///
/// ### `#[cdeb(ignore)]`
///
/// Ignoes the field, pretending that it doesn't exist.
/// Ignores the field, pretending that it doesn't exist.
///
/// ### `#[cdeb(with = "module::function")]`
///
Expand Down Expand Up @@ -195,7 +195,7 @@
///
/// This example demonstrates the `#[cdeb(impls)]` attribute,
/// a workaround for deriving this trait for generic types,
/// specifying a list of impls of types that uncnoditionally implement debug formatting
/// specifying a list of impls of types that unconditionally implement debug formatting
///
/// ```rust
/// #![feature(const_mut_refs)]
Expand Down
22 changes: 22 additions & 0 deletions const_format/src/const_generic_concatcp.rs
@@ -0,0 +1,22 @@
//! Reimplements some stuff from concatcp to be const generic instead of macro generated

use crate::pmr::{LenAndArray, PArgument, PVariant};

#[doc(hidden)]
pub const fn __priv_concatenate<const LEN: usize>(input: &[PArgument]) -> LenAndArray<[u8; LEN]> {
let mut out = LenAndArray {
len: 0,
array: [0u8; LEN],
};

crate::__for_range! { outer_i in 0..input.len() =>
let current = &input[outer_i];

match current.elem {
PVariant::Str(s) => crate::__write_pvariant!(str, current, s => out),
PVariant::Int(int) => crate::__write_pvariant!(int, current, int => out),
}
}

out
}
4 changes: 2 additions & 2 deletions const_format/src/fmt.rs
Expand Up @@ -53,7 +53,7 @@
//! - Named, from constant (eg: `formatc!("{FOO}")`):
//! Uses the `FOO` constant from the enclosing scope.
//!
//! - Named, from locals (eg: `formatc!("{foo}")`):
//! - Named, from locals (eg: `writec!(writable, "{foo}")`):
//! Uses the `foo` local variable from the enclosing scope,
//! only usable with the [`writec`] macro.
//!
Expand Down Expand Up @@ -187,7 +187,7 @@
//! impl[U,] Foo<u32, U>;
//! impl[U,] Foo<&str, U>;
//!
//! pub const fn const_debug_fmt(&mut self, f: &mut Formatter<'_>) -> Result<(), Error> {
//! pub const fn const_debug_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
//! let mut f = f.debug_struct("Foo");
//!
//! // PWrapper is a wrapper for std types, which defines the formatter methods for them.
Expand Down
2 changes: 0 additions & 2 deletions const_format/src/fmt/str_writer.rs
Expand Up @@ -455,8 +455,6 @@ impl StrWriter {
}
}

#[cfg_attr(feature = "docsrs", doc(cfg(feature = "const_generics")))]
#[cfg(feature = "const_generics")]
impl<const N: usize> StrWriter<[u8; N]> {
/// Casts a `&StrWriter<[u8; N]>` to a `&StrWriter<[u8]>`,
/// for calling methods defined on `StrWriter<[u8]>` (most of them).
Expand Down
16 changes: 9 additions & 7 deletions const_format/src/lib.rs
Expand Up @@ -257,13 +257,9 @@
//! allowing the `as_bytes_alt` methods and `slice_up_to_len_alt` methods to run
//! in constant time, rather than linear time proportional to the truncated part of the slice.
//!
//! "const_generics":
//! Enables impls that use const generics, currently only used for ergonomics.
//! Use this when const generics are usable in stable Rust.
//!
//! "nightly_const_generics":
//! Enables impls that use const generics, currently only used for ergonomics.
//! This requires a nightly Rust compiler.
//! - "const_generics": Requires Rust 1.51.0.
//! Uses const generics in the implementation of the [`concatcp`] and [`formatcp`]
//! macros to output less code.
//!
//!
//!
Expand Down Expand Up @@ -353,6 +349,9 @@ pub mod panicking;

mod pargument;

#[cfg(feature = "const_generics")]
mod const_generic_concatcp;

#[cfg_attr(feature = "docsrs", doc(cfg(feature = "fmt")))]
#[cfg(feature = "fmt")]
pub mod utils;
Expand Down Expand Up @@ -421,6 +420,9 @@ pub mod pmr {
result::Result::{self, Err, Ok},
};

#[cfg(feature = "const_generics")]
pub use crate::const_generic_concatcp::__priv_concatenate;

#[cfg(feature = "fmt")]
pub use crate::{
fmt::{ComputeStrLength, Error, Formatter, StrWriter, StrWriterMut, ToResult},
Expand Down
29 changes: 26 additions & 3 deletions const_format/src/macros/fmt_macros.rs
Expand Up @@ -63,9 +63,10 @@ macro_rules! concatcp {

#[doc(hidden)]
#[macro_export]
#[cfg(not(feature = "const_generics"))]
macro_rules! __concatcp_inner {
($variables:ident) => {{
const ARR_LEN: usize = $variables.0;
const ARR_LEN: usize = $crate::pmr::PArgument::calc_len($variables);

const CONCAT_ARR: &$crate::pmr::LenAndArray<[u8; ARR_LEN]> = {
use $crate::{__write_pvariant, pmr::PVariant};
Expand All @@ -75,7 +76,7 @@ macro_rules! __concatcp_inner {
array: [0u8; ARR_LEN],
};

let input = $variables.1;
let input = $variables;

$crate::__for_range! { outer_i in 0..input.len() =>
let current = &input[outer_i];
Expand All @@ -100,6 +101,28 @@ macro_rules! __concatcp_inner {
}};
}

#[doc(hidden)]
#[macro_export]
#[cfg(feature = "const_generics")]
macro_rules! __concatcp_inner {
($variables:ident) => {{
const ARR_LEN: usize = $crate::pmr::PArgument::calc_len($variables);

const CONCAT_ARR: &$crate::pmr::LenAndArray<[u8; ARR_LEN]> =
&$crate::pmr::__priv_concatenate($variables);

#[allow(clippy::transmute_ptr_to_ptr)]
const CONCAT_STR: &str = unsafe {
// This transmute truncates the length of the array to the amound of written bytes.
let slice =
$crate::pmr::transmute::<&[u8; ARR_LEN], &[u8; CONCAT_ARR.len]>(&CONCAT_ARR.array);

$crate::pmr::transmute::<&[u8], &str>(slice)
};
CONCAT_STR
}};
}

////////////////////////////////////////////////////////////////////////////////

/// Formats constants of primitive types into a `&'static str`
Expand All @@ -120,7 +143,7 @@ macro_rules! __concatcp_inner {
/// - Use constants from scope as arguments: `formatcp!("{FOO}")`,
/// equivalent to the [`format_args_implicits` RFC]
///
/// - Use Debug-like formatting (eg: `formatcp!("{:?}", "hello" ):
/// - Use Debug-like formatting (eg: `formatcp!("{:?}", "hello" )`:
/// Similar to how Debug formatting in the standard library works,
/// except that it does not escape unicode characters.`
///
Expand Down
30 changes: 5 additions & 25 deletions const_format/src/marker_traits/format_marker.rs
Expand Up @@ -113,23 +113,20 @@ pub trait FormatMarker {
/// used as the [`Kind`] associated type in [`FormatMarker`].
///
/// [`Kind`]: ./trait.FormatMarker.html#associatedtype.Kind
/// [`FormatMarker`]: ./trait.FormatMarker.html
///
pub struct IsArrayKind<T>(PhantomData<T>);

/// Marker type for the remaining standard library types,,
/// used as the [`Kind`] associated type in [`FormatMarker`].
///
/// [`Kind`]: ./trait.FormatMarker.html#associatedtype.Kind
/// [`FormatMarker`]: ./trait.FormatMarker.html
///
pub struct IsStdKind;

/// Marker type for non-standard library types,
/// used as the [`Kind`] associated type in [`FormatMarker`].
///
/// [`Kind`]: ./trait.FormatMarker.html#associatedtype.Kind
/// [`FormatMarker`]: ./trait.FormatMarker.html
///
pub struct IsNotStdKind;

Expand Down Expand Up @@ -168,6 +165,8 @@ macro_rules! std_kind_impls {
/// `T` is `<R as FormatMarker>::This`:
/// The `R` type after removing all layers of references.
///
/// `R`: a type that implements [`FormatMarker`].
///
/// # Coerce Method
///
/// The `coerce` method is what does the conversion from a `&T` depending on
Expand All @@ -179,12 +178,6 @@ macro_rules! std_kind_impls {
///
/// - [`IsNotStdKind`]: the reference is simply returned as a `&T`.
///
/// [`IsArrayKind`]: ./struct.IsArrayKind.html
/// [`IsStdKind`]: ./struct.IsStdKind.html
/// [`IsNotStdKind`]: ./struct.IsNotStdKind.html
///
/// [`PWrapper`]: ../struct.PWrapper.html
///
#[allow(clippy::type_complexity)]
pub struct IsAFormatMarker<K, T: ?Sized, R: ?Sized>(
PhantomData<(
Expand Down Expand Up @@ -249,17 +242,6 @@ impl<T: ?Sized, R: ?Sized> IsAFormatMarker<IsNotStdKind, T, R> {

/////////////////////////////////////////////////////////////////////////////

macro_rules! array_impls {
($($len:literal),* $(,)* ) => (
$(
impl<T> FormatMarker for [T; $len] {
type Kind = IsArrayKind<T>;
type This = Self;
}
)*
)
}

std_kind_impls! {
i8, u8,
i16, u16,
Expand All @@ -283,11 +265,9 @@ impl<R: ?Sized> IsAFormatMarker<IsStdKind, str, R> {
}
}

array_impls! {
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,
32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,
48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,
impl<T, const N: usize> FormatMarker for [T; N] {
type Kind = IsArrayKind<T>;
type This = Self;
}

impl<T> FormatMarker for [T] {
Expand Down
2 changes: 2 additions & 0 deletions const_format/src/marker_traits/write_marker.rs
Expand Up @@ -163,6 +163,8 @@ where
/// `T` is `<R as WriteMarker>::This`:
/// The `R` type after removing all layers of references.
///
/// `R`: A type that implements `WriteMarker`.
///
/// # Coerce Method
///
/// The `coerce` method is what does the conversion from a `&mut T`
Expand Down
14 changes: 14 additions & 0 deletions const_format/src/pargument.rs
Expand Up @@ -14,6 +14,20 @@ pub struct PArgument {
pub fmt_flags: FormattingFlags,
}

impl PArgument {
/// Calculates the length of the string after adding up all the PArguments
pub const fn calc_len(mut args: &[PArgument]) -> usize {
let mut sum = 0;

while let [curr, rem @ ..] = args {
args = rem;
sum += curr.fmt_len;
}

sum
}
}

#[doc(hidden)]
pub enum PVariant {
Str(&'static str),
Expand Down
2 changes: 1 addition & 1 deletion const_format/tests/fmt_tests/str_writer_methods.rs
Expand Up @@ -337,7 +337,7 @@ fn write_str_debug() {
while let Err(_) = w.write_str_range_debug(ALL_ASCII, gen_range()) {}
let end = w.len();
start + 1..end - 1
};
}

#[cfg(not(miri))]
const ITERATIONS: usize = 1000;
Expand Down
2 changes: 1 addition & 1 deletion const_format_proc_macros/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "const_format_proc_macros"
version = "0.2.8"
version = "0.2.14"
authors = ["rodrimati1992 <rodrimatt1985@gmail.com>"]
edition = "2018"
license = "Zlib"
Expand Down

0 comments on commit 14f470e

Please sign in to comment.