Crate v_escape

source ·
Expand description

Crate v_escape provides two macros, new_escape! and new_escape_sized!, that define a struct with escaping functionalities. These macros are optimized using simd by default, but this can be alter using sub-attributes.

Quick start

In order to use v_escape you will have to call one of the two macros to create a escape struct. In this example, when using the macro new_escape!(MyEscape, "62->bar"); a new a struct MyEscape will be created that every time its method MyEscape::fmt is called will replace all characters ">" with "bar".

#[macro_use]
extern crate v_escape;

new_escape_sized!(MyEscape, "62->bar");

let escaped = MyEscape::from(s);

print!("#{} : {}", escaped.size(), escaped);

To check if rust version has simd functionality. The following code has to be added to file build.rs.

use version_check::is_min_version;

fn main() {
    enable_simd_optimizations();
}

fn enable_simd_optimizations() {
    if !is_min_version("1.27.0").map_or(false, |(yes, _)| yes) {
        println!("cargo:rustc-cfg=v_escape_nosimd");
    }
}

Pairs syntax

v_escape uses a simple syntax to replace characters with their respective quotes. The tuple is named Pair, and several can be defined, refered as Pairs. The syntax to define Pairs consists of a character, followed by the delimiter ->, followed by the substitution quote and the delimiter || (last delimiter is optional):

([character]->[quote] || )*

  • character : Character to substitute. Acceptsi8+ from 0 to i8::MAX and accepts the following formats: decimal (49), hexadecimal (0x31), octal (0o61) or character (#1). Note: Numbers are read in ASCII: #6->foo

  • quote : Characters that will replace character

new_escape_sized!(MyEscape, "49->bar");
assert_eq!(MyEscape::from("foo 1").to_string(), "foo bar");
new_escape_sized!(MyEscape, "0x31->bar");
assert_eq!(MyEscape::from("foo 1").to_string(), "foo bar");
new_escape_sized!(MyEscape, "0o61->bar");
assert_eq!(MyEscape::from("foo 1").to_string(), "foo bar");
new_escape_sized!(MyEscape, "#1->bar");
assert_eq!(MyEscape::from("foo 1").to_string(), "foo bar");

The sub-attribute sse, true by default, can process a maximum of 16 Pairs. If more Pairs are needed, sse optimizations has to be deactivated using sub-attribute sse = false

new_escape_sized!(
    MyEscape,
    "62->b || 60->f || A->b || 65->f || 0o67->b || #6->f || 68->b || \
    71->f || 72->b || 73->f || 74->b || 75->f || 76->b || 77->f || \
    78->b || 79->f || 0x1A->f",
    sse = false
);
assert_eq!(MyEscape::from("foo>bar<").to_string(), "foobbarf");

Optimization for avx requires the creation of ranges. If the distance between the escaped characters is very large, sub-attribute avx = false should be disabled

new_escape!(MyEscape, "0-> || 33->foo || 66->bar || 127->", avx = false);
assert_eq!(MyEscape::from("fooBbar").to_string(), "foobarbar");

For debugging purposes, sub-attribute print, can be set to true to print generated code

new_escape_sized!(MyEscape, "o->bar", print = true);

Macros

Macro loop_m128 is the main loop that searches in byte slice with a bit mask using sse4.2 optimizations.
Macro loop_m256_64 is the main loop that searches in byte slice with a bit mask using avx2 optimizations. Differs from loop_m256_128 in the fact that it process 64 bytes every loop.
Macro loop_m256_128 is the main loop that searches in byte slice with a bit mask using avx2 optimizations.
Generates struct $name with escaping functionality at fmt
Generates struct $name with escaping functionality at fmt and size method