String Manipulation

RecipeCratesCategories
heckheckcat-text-processing
indocindoccat-text-processing
textwraptextwrapcat-text-processing

heck

heck heck-crates.io heck-github heck-lib.rs cat-no-std

heck is a case conversion library. This library exists to provide case conversion between common cases like CamelCase and snake_case.


// Add to Cargo.toml:
// [dependencies]
// heck = "0.4.1"

use heck::ToKebabCase;
use heck::ToLowerCamelCase;
use heck::ToPascalCase;
use heck::ToSnakeCase;
use heck::ToTitleCase;

fn main() {
    let input = "hello_world example-string";

    println!("Original: {}", input);
    println!("Snake case: {}", input.to_snake_case()); // hello_world_example_string
    println!("Kebab case: {}", input.to_kebab_case()); // hello-world-example-string
    println!("Pascal case: {}", input.to_pascal_case()); // HelloWorldExampleString
    println!("Camel case: {}", input.to_lower_camel_case()); // helloWorldExampleString
    println!("Title case: {}", input.to_title_case()); // Hello World Example String
}

textwrap

textwrap textwrap-crates.io textwrap-github textwrap-lib.rs cat-command-line-interface cat-text-processing

textwrap provides word wrapping, indenting, and dedenting strings. It has optional support for Unicode and emojis, as well as machine hyphenation.

use std::borrow::Cow;

use hyphenation::Language;
use hyphenation::Load;
use hyphenation::Standard;
use textwrap::Options;
use textwrap::WordSplitter;
use textwrap::fill;
use textwrap::wrap;

// Add the dependency to Cargo.toml:
// [dependencies]
// textwrap = "0.16.0"

fn main() {
    let text = "The quick brown fox jumps over the lazy dog. This is an example of text that will be wrapped to demonstrate the textwrap crate functionality in Rust. It offers various options to control how text wrapping behaves.";

    // Basic usage - `wrap` text to a specified width.
    println!("Basic wrap to 40 columns:");
    let wrapped: Vec<Cow<_>> = wrap(text, 40);
    for line in wrapped {
        println!("{}", line);
    }

    // Using `fill` to directly get a string with newlines.
    println!("\nUsing fill with 50 columns:");
    let filled: String = fill(text, 50);
    println!("{}", filled);

    // Customizing `wrap` or `fill` behavior with `Options`.
    println!("\nCustom options (indent of 4 spaces, width of 35):");
    let options = Options::new(35)
        .initial_indent("    ")
        .subsequent_indent("    ");
    let indented = fill(text, &options);
    println!("{}", indented);

    // Controlling hyphenation.
    println!("\nWith hyphenation enabled:");
    let dictionary = Standard::from_embedded(Language::EnglishUS).unwrap();
    let options =
        Options::new(15).word_splitter(WordSplitter::Hyphenation(dictionary));
    let hyphenated = fill(text, &options);
    println!("{}", hyphenated);

    // Handling long words
    let text_with_long_word =
        "This contains supercalifragilisticexpialidocious which is quite long.";
    println!("\nHandling long words (width: 20):");
    let long_word_wrapped = fill(text_with_long_word, 20);
    println!("{}", long_word_wrapped);

    // Preserving indentation of the first line
    let indented_text =
        "    This paragraph has\nan indentation that should be preserved.";
    println!("\nPreserving first-line indent:");
    let options = Options::new(30).subsequent_indent("    ");
    let preserved = fill(indented_text, &options);
    println!("{}", preserved);
}

indoc

indoc indoc-crates.io indoc-github indoc-lib.rs cat-no-std cat-no-std::no-alloc cat-rust-patterns cat-text-processing

The indoc!() macro takes a multiline string literal and un-indents it at compile time so the leftmost non-space character is in the first column.

The indoc crate exports five additional macros to substitute conveniently for the standard library's formatting macros:

formatdoc!($fmt, ...) — equivalent to format!(indoc!($fmt), ...) printdoc!($fmt, ...) — equivalent to print!(indoc!($fmt), ...) eprintdoc!($fmt, ...) — equivalent to eprint!(indoc!($fmt), ...) writedoc!($dest, $fmt, ...) — equivalent to write!($dest, indoc!($fmt), ...) concatdoc!(...) — equivalent to concat!(...) with each string literal wrapped in indoc!

use indoc::indoc;

fn main() {
    // Without indoc, multi-line strings preserve indentation from source code
    let regular_string = "
        This string preserves all leading whitespace
        which makes it harder to read in source code
        when you want to format your code nicely.
    ";
    println!("Regular string:\n{}", regular_string);

    // With indoc, leading whitespace is automatically stripped
    let indoc_string = indoc! {"
        This string is nicely indented in the source code,
        but when printed, the common leading whitespace
        is automatically removed.

        Empty lines are preserved.
          Additional indentation beyond the common prefix
          is also preserved.
    "};
    println!("\nIndoc string:\n{}", indoc_string);

    // indoc also works with raw strings
    let raw_indoc = indoc! {r#"
        This raw string can contain "quotes" without escaping.
        It also handles special characters like \n \t without interpreting them.
        All while still removing the common leading whitespace.
    "#};
    println!("\nRaw indoc string:\n{}", raw_indoc);

    // Practical example: SQL queries
    let sql_query = indoc! {"
        SELECT users.name, COUNT(orders.id) as order_count
        FROM users
        LEFT JOIN orders
            ON users.id = orders.user_id
        WHERE users.active = true
        GROUP BY users.id
        ORDER BY order_count DESC
        LIMIT 10
    "};
    println!("\nSQL query:\n{}", sql_query);
}
  • Strings.