Thanks to visit codestin.com
Credit goes to docs.rs

Crate convert_case

Crate convert_case 

Source
Expand description

Convert to and from different string cases.

§Basic Usage

The most common use of this crate is to just convert a string into a particular case, like snake, camel, or kebab. You can use the ccase macro to convert most string types into the new case.

use convert_case::ccase;

let s = "myVarName";
assert_eq!(ccase!(snake, s),  "my_var_name");
assert_eq!(ccase!(kebab, s),  "my-var-name");
assert_eq!(ccase!(pascal, s), "MyVarName");
assert_eq!(ccase!(title, s),  "My Var Name");

For more explicit conversion, import the Casing trait which adds methods to string types that perform the conversion based on a variant of the Case enum.

use convert_case::{Case, Casing};

let s = "myVarName";
assert_eq!(s.to_case(Case::Snake),  "my_var_name");
assert_eq!(s.to_case(Case::Kebab),  "my-var-name");
assert_eq!(s.to_case(Case::Pascal), "MyVarName");
assert_eq!(s.to_case(Case::Title),  "My Var Name");

For a full list of cases, see Case.

§Splitting Conditions

Case conversion starts by splitting a single identifier into a list of words. The condition for when to split and how to perform the split is defined by a Boundary.

By default, ccase and Casing::to_case will split identifiers at all locations based on a list of default boundaries.

use convert_case::ccase;

assert_eq!(ccase!(pascal, "hyphens-and_underscores"), "HyphensAndUnderscores");
assert_eq!(ccase!(pascal, "lowerUpper space"), "LowerUpperSpace");
assert_eq!(ccase!(snake, "HTTPRequest"), "http_request");
assert_eq!(ccase!(snake, "vector4d"), "vector_4_d")

Associated with each case is a list of boundaries that can be used to split identifiers instead of the defaults. We can use the following notation with the ccase macro.

use convert_case::ccase;

assert_eq!(
    ccase!(title, "1999-25-01_family_photo.png"),
    "1999 25 01 Family Photo.png",
);
assert_eq!(
    ccase!(snake -> title, "1999-25-01_family_photo.png"),
    "1999-25-01 Family Photo.png",
);

Or we can use the from_case method on Casing before calling to_case.

use convert_case::{Case, Casing};

assert_eq!(
    "John McCarthy".to_case(Case::Snake),
    "john_mc_carthy",
);
assert_eq!(
    "John McCarthy".from_case(Case::Title).to_case(Case::Snake),
    "john_mccarthy",
);

You can remove boundaries from the list of defaults with Casing::without_boundaries. See the list of constants on Boundary for splitting conditions.

use convert_case::{Boundary, Case, Casing};

assert_eq!(
    "Vector4D".without_boundaries(&[Boundary::DigitUpper]).to_case(Case::Snake),
    "vector_4d",
);

§Other Behavior

§Acronyms

Part of the default list of boundaries is acronym which will detect two capital letters followed by a lowercase letter. But there is no memory that the word itself was parsed considered an acronym.

assert_eq!(ccase!(snake, "HTTPRequest"), "http_request");
assert_eq!(ccase!(pascal, "HTTPRequest"), "HttpRequest");

§Digits

The default list of boundaries includes splitting before and after digits.

assert_eq!(ccase!(title, "word2vec"), "Word 2 Vec");

§Unicode

Conversion works on graphemes as defined by the unicode_segmentation library. This means that transforming letters to lowercase or uppercase works on all unicode characters, which also means that the number of characters isn’t necessarily the same after conversion.

assert_eq!(ccase!(kebab, "GranatÄpfel"), "granat-äpfel");
assert_eq!(ccase!(title, "ПЕРСПЕКТИВА24"), "Перспектива 24");
assert_eq!(ccase!(lower, "ὈΔΥΣΣΕΎΣ"), "ὀδυσσεύς");

§Symbols

All symbols that are not part of the default boundary conditions are ignored. This is any symbol that isn’t an underscore, hyphen, or space.

assert_eq!(ccase!(snake, "dots.arent.default"), "dots.arent.default");
assert_eq!(ccase!(pascal, "path/to/file_name"), "Path/to/fileName");
assert_eq!(ccase!(pascal, "list\nof\nwords"),   "List\nof\nwords");

§Delimiters

Leading, trailing, and duplicate delimiters create empty words. This propogates and the converted string will share the behavior. This can cause unintuitive behavior for patterns that transform words based on index.

assert_eq!(ccase!(constant, "_leading_score"), "_LEADING_SCORE");
assert_eq!(ccase!(ada, "trailing-dash-"), "Trailing_Dash_");
assert_eq!(ccase!(train, "duplicate----hyphens"), "Duplicate----Hyphens");
assert_eq!(ccase!(camel, "_empty__first_word"), "EmptyFirstWord");

§Customizing Behavior

Case conversion takes place in three steps:

  1. Splitting the identifier into a list of words
  2. Mutating the letter case of graphemes within each word
  3. Joining the words back into an identifier using a delimiter

Those are defined by boundaries, patterns, and delimiters respectively. Graphically:

Identifier        Identifier'
    |                 ^
    | boundaries      | delimiter
    V                 |
  Words ----------> Words'
          pattern

§Patterns

How to change the case of letters across a list of words is called a pattern. A pattern is a function that when passed a &[&str], produces a Vec<String>. The Pattern enum encapsulates the common transformations used across all cases. Although custom functions can be supplied with the Custom variant.

§Boundaries

The condition for splitting at part of an identifier, where to perform the split, and if any characters are removed are defined by boundaries. By default, identifiers are split based on Boundary::defaults. This list contains word boundaries that you would likely see after creating a multi-word identifier of any case.

Custom boundary conditions can be created. Commonly, you might split based on some character or list of characters. The Boundary::from_delim method builds a boundary that splits on the presence of a string, and removes the string from the final list of words.

You can also use of Boundary::Custom to explicitly define boundary conditions. If you actually need to create a boundary condition from scratch, you should file an issue to let the author know how you used it.

§Cases

A case is defined by a list of boundaries, a pattern, and a delimiter: the string to intersperse between words before concatenation. Case::Custom is a struct enum variant with exactly those three fields. You could create your own case like so.

use convert_case::{Case, Casing, Boundary, Pattern};

let dot_case = Case::Custom {
    boundaries: &[Boundary::from_delim(".")],
    pattern: Pattern::Lowercase,
    delim: ".",
};

assert_eq!("AnimalFactoryFactory".to_case(dot_case), "animal.factory.factory");

assert_eq!(
    "pd.options.mode.copy_on_write"
        .from_case(dot_case)
        .to_case(Case::Title),
    "Pd Options Mode Copy_on_write",
)

§Converter

Case conversion with convert_case allows using attributes from two cases. From the first case is how you split the identifier (the from case), and from the second is how to mutate and join the words (the to case.) The Converter is used to define the conversion process, not a case directly.

It has the same fields as case, but is exposed via a builder interface and can be used to apply a conversion on a string directly, without specifying all the parameters at the time of conversion.

In the below example, we build a converter that maps the double colon delimited module path in rust into a series of file directories.

use convert_case::{Case, Converter, Boundary};

let modules_into_path = Converter::new()
    .set_boundaries(&[Boundary::from_delim("::")])
    .set_delim("/");

assert_eq!(
    modules_into_path.convert("std::os::unix"),
    "std/os/unix",
);

§Random Feature

This feature adds two additional cases with non-deterministic behavior. The random feature depends on the rand crate.

The [Case::Random] variant will flip a coin at every letter to make it uppercase or lowercase. Here are some examples:

ccase!(random, "What's the deal with airline food?");
// WhAT's tHe Deal WitH aIRline fOOD?

For a more even distribution of uppercase and lowercase letters, which might look more random, use the [Case::PseudoRandom] variant. This variant randomly decides if every pair of letters is upper then lower or lower then upper. This guarantees that no three consecutive characters is all uppercase or all lowercase.

ccase!(random, "What's the deal with airline food?");
// wHAt'S The DeAl WIth AiRlInE fOoD?

§Associated Projects

§stringcase.org

While developing convert_case, the author became fascinated in the naming conventions used for cases as well as different implementations for conversion. On stringcase.org is documentation of the history of naming conventions, a catalogue of case conversion tools, and a more mathematical definition of what it means to “convert the string case of an identifier.”

§Command Line Utility ccase

convert_case was originally developed for the purposes of a command line utility for converting the case of strings and filenames. You can check out ccase on Github.

Macros§

case
The variant of case from a token.
ccase
Convert an identifier into a case.

Structs§

Converter
The parameters for performing a case conversion.
StateConverter
Holds information about parsing before converting into a case.

Enums§

Boundary
Conditions for splitting an identifier into words.
Case
Defines the case of an identifier.
Pattern
Transformations on a list of words.

Traits§

Casing
Describes items that can be converted into a case. This trait is used in conjunction with the StateConverter struct which is returned from a couple methods on Casing.

Functions§

split
Split an identifier into a list of words using the list of boundaries.