Skip to content

Commit

Permalink
Merge pull request #43 from rodrimati1992/split
Browse files Browse the repository at this point in the history
0.2.26 release
  • Loading branch information
rodrimati1992 authored Jul 5, 2022
2 parents 180460e + a024d3e commit a3c79b1
Show file tree
Hide file tree
Showing 28 changed files with 608 additions and 114 deletions.
38 changes: 25 additions & 13 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
strategy:
max-parallel: 2
matrix:
rust: [stable, beta, nightly, 1.46.0, 1.51.0]
rust: [stable, beta, nightly, 1.46.0, 1.51.0, 1.57.0]

steps:
- uses: actions/checkout@v2
Expand All @@ -25,7 +25,7 @@ jobs:
cargo test
cd "${{github.workspace}}/const_format/"
cargo test --features "testing"
cargo test --features "__test"
- uses: actions/checkout@v2
- name: ci-stable
Expand All @@ -34,7 +34,17 @@ jobs:
cargo update
cd "${{github.workspace}}/const_format/"
cargo test --features "testing const_generics"
cargo test --features "__test const_generics"
- uses: actions/checkout@v2
- name: ci-stable
if: ${{ matrix.rust == '1.57.0' }}
run: |
cargo update
cd "${{github.workspace}}/const_format/"
cargo test --features "__test const_generics"
cargo test --features "__test assertcp"
- uses: actions/checkout@v2
Expand All @@ -50,14 +60,16 @@ jobs:
cd "${{github.workspace}}/const_format/"
cargo test --features "testing"
cargo test --features "testing assertcp"
cargo test --features "testing fmt"
cargo test --features "testing assertc"
cargo test --features "testing derive"
cargo test --features "testing constant_time_as_str"
cargo test --features "testing derive constant_time_as_str"
cargo test --features "testing derive constant_time_as_str assertc"
cargo test --features "__test"
cargo test --features "__test more_str_macros"
cargo test --features "__test assertcp"
cargo test --features "__test fmt"
cargo test --features "__test assertc"
cargo test --features "__test derive"
cargo test --features "__test constant_time_as_str"
cargo test --features "__test derive constant_time_as_str"
cargo test --features "__test derive constant_time_as_str assertc"
cargo test --features "__test derive constant_time_as_str assertc more_str_macros"
MIRI_NIGHTLY=nightly-$(curl -s https://rust-lang.github.io/rustup-components-history/x86_64-unknown-linux-gnu/miri)
MIRIFLAGS="-Zmiri-strict-provenance -Zmiri-check-number-validity -Zmiri-symbolic-alignment-check"
Expand All @@ -71,5 +83,5 @@ jobs:
cargo clean
cargo miri test --tests --features "testing derive fmt assertc"
cargo miri test --features "testing derive fmt constant_time_as_str assertc"
cargo miri test --tests --features "__test derive fmt assertc"
cargo miri test --features "__test derive fmt constant_time_as_str assertc"
10 changes: 9 additions & 1 deletion Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,20 @@ This is the changelog,summarising changes in each version(some minor changes may

# 0.2

### 0.2.26

Added `"more_str_macros"` crate feature.

Added `str_split` macro, conditional on the `"more_str_macros"` feature.

Added `char` pattern support to `str_replace`.

### 0.2.25

Fixed the `clippy::double_parens` (false positive) warning by
encoding the `&'static str` type annotation some other way.

Made `SplicedStr`, `Formatting`, `NumberFormatting`,
Made `SplicedStr`, `Formatting`, and `NumberFormatting` derive `Eq` .

### 0.2.24

Expand Down
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,9 @@ Enables the macros listed in the [Rust 1.51.0](#rust-1510) section.
Also changes the the implementation of the [`concatcp`] and [`formatcp`]
macros to use const generics.

- "more_str_macros": Requires Rust nightly, implies the "const_generics" feature.
Enables the [`str_split`] macro.

# No-std support

`const_format` is `#![no_std]`, it can be used anywhere Rust can be used.
Expand Down Expand Up @@ -355,4 +358,6 @@ need to be explicitly enabled with cargo features.

[`str_replace`]: https://docs.rs/const_format/0.2.*/const_format/macro.str_replace.html

[`str_split`]: https://docs.rs/const_format/0.2.*/const_format/macro.str_split.html

[`str::replace`]: https://doc.rust-lang.org/std/primitive.str.html#method.replace
34 changes: 26 additions & 8 deletions const_format/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "const_format"
version = "0.2.25"
version = "0.2.26"
authors = ["rodrimati1992 <rodrimatt1985@gmail.com>"]
edition = "2018"
license = "Zlib"
Expand Down Expand Up @@ -31,22 +31,40 @@ assert = ["assertc"]
assertc = ["fmt", "assertcp"]
assertcp = ["const_generics"]
constant_time_as_str = ["fmt"]
more_str_macros = ["konst", "konst/constant_time_slice", "const_generics"]

# "private" features
debug = ["const_format_proc_macros/debug"]
testing = []
only_new_tests = ["testing"]
docsrs = []
all = ["fmt", "derive", "constant_time_as_str", "nightly_const_generics", "assert", "docsrs"]
# enables all the features, requires (potentially) the latest nightly
all = [
"fmt",
"derive",
"constant_time_as_str",
"more_str_macros",
"nightly_const_generics",
"assert",
]

##############
### "private" features

#
__debug = ["const_format_proc_macros/debug"]
__test = []
__only_new_tests = ["__test"]
__docsrs = []

[dependencies.const_format_proc_macros]
version = "=0.2.22"
path = "../const_format_proc_macros"

[dependencies.konst]
version = "0.2.13"
default-features = false
optional = true

[dev-dependencies]
fastrand = {version = "1.3.5", default_features = false}
arrayvec = {version = "0.5.1", default_features = false}

[package.metadata.docs.rs]
features = ["all"]
features = ["all", "__docsrs"]

12 changes: 12 additions & 0 deletions const_format/src/__str_methods.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,18 @@ pub use str_splice::{DecomposedString, SplicedStr, StrSplceArgsConv, StrSpliceAr
mod str_indexing;
pub use str_indexing::{IndexValidity, StrIndexArgs, StrIndexArgsConv};

#[cfg(feature = "more_str_macros")]
mod str_split;

#[cfg(feature = "more_str_macros")]
pub use str_split::{SplitInput, SplitInputConv};

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

#[cfg(feature = "const_generics")]
use pattern::{Pattern, PatternCtor, PatternNorm};

#[cfg(feature = "const_generics")]
mod ascii_byte {
#[derive(Copy, Clone)]
Expand Down
52 changes: 52 additions & 0 deletions const_format/src/__str_methods/pattern.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
use super::AsciiByte;

pub(crate) struct PatternCtor<T>(pub(crate) T);

impl PatternCtor<u8> {
pub(crate) const fn conv(self) -> Pattern {
Pattern::AsciiByte(AsciiByte::new(self.0))
}
}

impl PatternCtor<&'static str> {
pub(crate) const fn conv(self) -> Pattern {
if let [b @ 0..=127] = *self.0.as_bytes() {
Pattern::AsciiByte(AsciiByte::new(b))
} else {
Pattern::Str(self.0)
}
}
}

impl PatternCtor<char> {
pub(crate) const fn conv(self) -> Pattern {
let code = self.0 as u32;
if let c @ 0..=127 = code {
Pattern::AsciiByte(AsciiByte::new(c as u8))
} else {
Pattern::Char(crate::char_encoding::char_to_display(self.0))
}
}
}

#[derive(Copy, Clone)]
pub(crate) enum Pattern {
AsciiByte(AsciiByte),
Str(&'static str),
Char(crate::char_encoding::FmtChar),
}

pub(crate) enum PatternNorm<'a> {
AsciiByte(AsciiByte),
Str(&'a [u8]),
}

impl Pattern {
pub(crate) const fn normalize(&self) -> PatternNorm<'_> {
match self {
Pattern::AsciiByte(ab) => PatternNorm::AsciiByte(*ab),
Pattern::Str(str) => PatternNorm::Str(str.as_bytes()),
Pattern::Char(char) => PatternNorm::Str(char.as_bytes()),
}
}
}
58 changes: 24 additions & 34 deletions const_format/src/__str_methods/str_replace.rs
Original file line number Diff line number Diff line change
@@ -1,39 +1,31 @@
use super::{bytes_find, AsciiByte};
use super::{bytes_find, Pattern, PatternCtor, PatternNorm};

pub struct ReplaceInputConv<T>(pub &'static str, pub T, pub &'static str);

impl ReplaceInputConv<u8> {
pub const fn conv(self) -> ReplaceInput {
ReplaceInput {
str: self.0,
pattern: ReplacePattern::AsciiByte(AsciiByte::new(self.1)),
replaced_with: self.2,
macro_rules! ctor {
($ty:ty) => {
impl ReplaceInputConv<$ty> {
pub const fn conv(self) -> ReplaceInput {
ReplaceInput {
str: self.0,
pattern: PatternCtor(self.1).conv(),
replaced_with: self.2,
}
}
}
}
};
}

impl ReplaceInputConv<&'static str> {
pub const fn conv(self) -> ReplaceInput {
ReplaceInput {
str: self.0,
pattern: ReplacePattern::Str(self.1),
replaced_with: self.2,
}
}
}
ctor! {u8}
ctor! {&'static str}
ctor! {char}

pub struct ReplaceInput {
str: &'static str,
pattern: ReplacePattern,
pattern: Pattern,
replaced_with: &'static str,
}

#[derive(Copy, Clone)]
pub enum ReplacePattern {
AsciiByte(AsciiByte),
Str(&'static str),
}

impl ReplaceInput {
pub const fn replace_length(&self) -> usize {
str_replace_length(self.str, self.pattern, self.replaced_with)
Expand All @@ -43,24 +35,23 @@ impl ReplaceInput {
}
}

const fn str_replace_length(inp: &str, r: ReplacePattern, replaced_with: &str) -> usize {
const fn str_replace_length(inp: &str, r: Pattern, replaced_with: &str) -> usize {
let inp = inp.as_bytes();

let replaced_len = replaced_with.len();
let mut out_len = 0;

match r {
ReplacePattern::AsciiByte(byte) => {
match r.normalize() {
PatternNorm::AsciiByte(byte) => {
let byte = byte.get();
iter_copy_slice! {b in inp =>
out_len += if b == byte { replaced_len } else { 1 };
}
}
ReplacePattern::Str(str) => {
PatternNorm::Str(str) => {
if str.is_empty() {
return inp.len();
}
let str = str.as_bytes();
let str_len = str.len();
let mut i = 0;
while let Some(next_match) = bytes_find(inp, str, i) {
Expand All @@ -74,7 +65,7 @@ const fn str_replace_length(inp: &str, r: ReplacePattern, replaced_with: &str) -
out_len
}

const fn str_replace<const L: usize>(inp: &str, r: ReplacePattern, replaced_with: &str) -> [u8; L] {
const fn str_replace<const L: usize>(inp: &str, r: Pattern, replaced_with: &str) -> [u8; L] {
let inp = inp.as_bytes();

let replaced_with_bytes = replaced_with.as_bytes();
Expand All @@ -96,8 +87,8 @@ const fn str_replace<const L: usize>(inp: &str, r: ReplacePattern, replaced_with
};
}

match r {
ReplacePattern::AsciiByte(byte) => {
match r.normalize() {
PatternNorm::AsciiByte(byte) => {
let byte = byte.get();
iter_copy_slice! {b in inp =>
if b == byte {
Expand All @@ -107,14 +98,13 @@ const fn str_replace<const L: usize>(inp: &str, r: ReplacePattern, replaced_with
}
}
}
ReplacePattern::Str(str) => {
PatternNorm::Str(str) => {
if str.is_empty() {
iter_copy_slice! {b in inp =>
write_byte!(b);
}
return out;
}
let str = str.as_bytes();
let str_len = str.len();
let mut i = 0;
while let Some(next_match) = bytes_find(inp, str, i) {
Expand Down
Loading

0 comments on commit a3c79b1

Please sign in to comment.