pub struct Ident<B, D, P> { /* private fields */ }Expand description
An immutable, UTF-8 encoded, valid identifier string slice.
§Construction
It’s not expected that you interact with this type directly. Instead, you should interact with it through a type alias which fully defines the identifier.
The common way to get a reasonable alias is through the presets module.
use typed_ident::presets::unicode::LowerSnakeIdent;
// By-Reference (`&LowerSnakeIdent`)
let ident = LowerSnakeIdent::new("lower_snake")?;
// Owned (`Box<LowerSnakeIdent>`) (requires `alloc` feature)
let owned = ident.to_boxed_ident(); // From pre-validated reference
let owned = LowerSnakeIdent::new_boxed(String::from("lower_snake"))?;These presets are all just type aliases to Ident with the generic type
parameters filled-in. If you would like to define your own custom
identifier, it’s recommended that you do so by defining your own type alias.
use typed_ident::Ident;
use typed_ident::syntax::{boundary, delimiter, profile};
// An ASCII identifier using the uppercase ASCII profile.
// Any ASCII punctuation is permitted as delimiters.
type CustomIdent = Ident<
boundary::Standard,
delimiter::AsciiPunctuation,
profile::Upper<profile::Ascii>,
>;
let ident = CustomIdent::new("UPPER#@IDENT")?;See the core module definition to understand how this type relates to
other types (such as Fragment and Chunk), as well as additional
information for how to use these types effectively.
§Type Conversion
There’s several ways to convert between types depending on what you want to accomplish. These type conversions DO NOT reformat or change the input string. They just produce a new type of the target identifier syntax.
| I Have a… | I Want a… | Method | Validation Cost | Allocation Cost |
|---|---|---|---|---|
&Ident<A..> | &Ident<B..> | cast / as_ref | None | None |
&Ident<A..> | &Ident<B..> | try_cast | Same as new | None |
&Ident | Box<Ident> | to_boxed_ident | None | O(strlen) |
&Box<Ident> | &Ident | as_ident / as_ref | None | None |
Box<Ident<A..>> | Box<Ident<B..>> | convert | None | None |
Box<Ident<A..>> | Box<Ident<B..>> | try_convert | Same as new | None |
§Type Parameters
The type parameters used on this type are:
B:Boundary(a boundary definition; usuallyStandard)D:Delimiter(a delimiter type;HyphenMinus,LowLine, etc.)P:CasedProfile(a cased profile; which is…)
See the syntax module definition if you plan on defining your own type
aliases to understand better what these types mean and how they work.
Implementations§
Source§impl<B: Boundary, D: Delimiter, P: CasedProfile> Ident<B, D, P>
impl<B: Boundary, D: Delimiter, P: CasedProfile> Ident<B, D, P>
Sourcepub fn join<F>(&self, fragment: F) -> Result<Box<Ident<B, D, P>>, Error>where
D: Default,
F: IntoIntermediate<B, D, P>,
pub fn join<F>(&self, fragment: F) -> Result<Box<Ident<B, D, P>>, Error>where
D: Default,
F: IntoIntermediate<B, D, P>,
Returns a heap-allocated identifier, joined with the original identifier in a way that preserves chunk boundaries.
At the end of the operation, the total number of chunked segments present in the fragment will be equal to the sum of each fragment, potentially plus one additional fragment in the case where we needed to join using a delimiter to preserve chunk boundaries.
This call is identical to join_with with the default delimiter.
§Errors
Returns Err if the fragment formed from the combination of self and
fragment is invalid. If invalid, an Error is returned with the
error_kind set to FailedLeftJoin.
The value byte_offset will NOT be set from this function. None of
the individual characters are invalid, it’s just that the combination of
joining the fragments themselves is invalid.
§Examples
Basic Usage:
let ident = LowerSnakeIdent::new("snake")?;
let ident = ident.join(
LowerSnakeFragment::new("ident")?,
)?;
assert_eq!(ident.as_ref(), "snake_ident");Sourcepub fn join_with<F>(
&self,
fragment: F,
delim: D,
) -> Result<Box<Ident<B, D, P>>, Error>where
F: IntoIntermediate<B, D, P>,
pub fn join_with<F>(
&self,
fragment: F,
delim: D,
) -> Result<Box<Ident<B, D, P>>, Error>where
F: IntoIntermediate<B, D, P>,
Returns a heap-allocated identifier, joined with the original identifier in a way that preserves chunk boundaries.
At the end of the operation, the total number of chunked segments present in the identifier will be equal to the sum of each fragment, potentially plus one additional fragment in the case where we needed to join using a delimiter to preserve chunk boundaries.
§Errors
Returns Err if the fragment formed from the combination of self and
fragment is invalid. If invalid, an Error is returned with the
error_kind set to FailedLeftJoin.
The value byte_offset will NOT be set from this function. None of
the individual characters are invalid, it’s just that the combination of
joining the fragments themselves is invalid.
§Examples
Basic Usage:
let ident = LowerSnakeIdent::new("snake")?;
let ident = ident.join_with(
LowerSnakeFragment::new("ident")?,
LowLine,
)?;
assert_eq!(ident.as_ref(), "snake_ident");Sourcepub fn new_boxed(string: String) -> Result<Box<Ident<B, D, P>>, Error>
pub fn new_boxed(string: String) -> Result<Box<Ident<B, D, P>>, Error>
Converts a string into a boxed identifier if its valid.
§Examples
Basic Usage:
let ident: Box<LowerSnakeIdent> =
Ident::new_boxed(String::from("snake_ident"))?;Sourcepub fn with_circumfix<F1, F2>(
&self,
prefix: F1,
suffix: F2,
) -> Result<Box<Ident<B, D, P>>, Error>where
F1: IntoIntermediate<B, D, P>,
F2: IntoIntermediate<B, D, P>,
pub fn with_circumfix<F1, F2>(
&self,
prefix: F1,
suffix: F2,
) -> Result<Box<Ident<B, D, P>>, Error>where
F1: IntoIntermediate<B, D, P>,
F2: IntoIntermediate<B, D, P>,
Returns a heap-allocated identifier with the provided prefix and suffix attached to the original identifier.
§Errors
Returns Err if the fragment formed from the combination of prefix,
self, and suffix is invalid. If invalid, an Error is returned
with the error_kind set either to InvalidPrefix or InvalidSuffix
(depending on which has caused the failure).
The value byte_offset will NOT be set from this function. None of
the individual characters are invalid, it’s just that the combination of
joining the fragments themselves is invalid.
§Examples
Basic Usage:
let ident = LowerSnakeIdent::new("snake")?;
let ident = ident.with_circumfix(
LowerSnakeFragment::new("lower_")?,
LowerSnakeFragment::new("_ident")?,
)?;
assert_eq!(ident.as_ref(), "lower_snake_ident");Sourcepub fn with_prefix<F>(&self, prefix: F) -> Result<Box<Ident<B, D, P>>, Error>where
F: IntoIntermediate<B, D, P>,
pub fn with_prefix<F>(&self, prefix: F) -> Result<Box<Ident<B, D, P>>, Error>where
F: IntoIntermediate<B, D, P>,
Returns a heap-allocated identifier with the provided prefix attached to the original identifier.
§Errors
Returns Err if the fragment formed from the combination of prefix
and self is invalid. If invalid, an Error is returned with the
error_kind set to InvalidPrefix.
The value byte_offset will NOT be set from this function. None of
the individual characters are invalid, it’s just that the combination of
joining the fragments themselves is invalid.
§Examples
Basic Usage:
let ident = LowerSnakeIdent::new("snake")?;
let ident = ident.with_prefix(
LowerSnakeFragment::new("lower_")?,
)?;
assert_eq!(ident.as_ref(), "lower_snake");Sourcepub fn with_suffix<F>(&self, suffix: F) -> Result<Box<Ident<B, D, P>>, Error>where
F: IntoIntermediate<B, D, P>,
pub fn with_suffix<F>(&self, suffix: F) -> Result<Box<Ident<B, D, P>>, Error>where
F: IntoIntermediate<B, D, P>,
Returns a heap-allocated identifier with the provided suffix attached to the original identifier.
§Errors
Returns Err if the fragment formed from the combination of self and
suffix is invalid. If invalid, an Error is returned with the
error_kind set to InvalidPrefix.
The value byte_offset will NOT be set from this function. None of
the individual characters are invalid, it’s just that the combination of
joining the fragments themselves is invalid.
§Examples
Basic Usage:
let ident = LowerSnakeIdent::new("snake")?;
let ident = ident.with_suffix(
LowerSnakeFragment::new("_ident")?,
)?;
assert_eq!(ident.as_ref(), "snake_ident");Source§impl<B, D, P> Ident<B, D, P>
impl<B, D, P> Ident<B, D, P>
Sourcepub fn convert<B2, D2, P2>(self: Box<Self>) -> Box<Ident<B2, D2, P2>>
pub fn convert<B2, D2, P2>(self: Box<Self>) -> Box<Ident<B2, D2, P2>>
Zero-cost conversion into a different boxed, type-configured identifier.
This is the boxed, by-value equivalent of cast, see that function
for details on how this works. If you don’t need to consume the boxed
value, you can instead use that function to get a reference to a
different type-configured identifier.
§Examples
Example traversing case profile boundary:
// Compilable Cast:
let original = LowerSnakeIdent::new_boxed(String::from("apple"))?;
let converted: Box<LowerCamelIdent> = original.convert();// Bad Cast (Fails Compilation):
let original = LowerCamelIdent::new_boxed(String::from("apple"))?;
let converted: Box<LowerSnakeIdent> = original.convert();Example traversing character profile boundary:
// Compilable Cast:
let original = ascii::LowerSnakeIdent::new_boxed(String::from("apple"))?;
let converted: Box<unicode::LowerSnakeIdent> = original.convert();// Bad Cast (Fails Compilation):
let original = unicode::LowerSnakeIdent::new_boxed(String::from("apple"))?;
let converted: Box<ascii::LowerSnakeIdent> = original.convert();Example traversing delimiter boundary:
// Compilable Cast:
let original = LowerSnakeIdent::new_boxed(String::from("apple"))?;
let converted: Box<HybridIdent> = original.convert();// Bad Cast (Fails Compilation):
let original = HybridIdent::new_boxed(String::from("apple"))?;
let converted: Box<LowerSnakeIdent> = original.convert();Sourcepub fn try_convert<B2, D2, P2>(
self: Box<Self>,
) -> Result<Box<Ident<B2, D2, P2>>, Error>
pub fn try_convert<B2, D2, P2>( self: Box<Self>, ) -> Result<Box<Ident<B2, D2, P2>>, Error>
Attempts a fallible convert into a different boxed type-configured identifier.
You should first attempt to call convert on a type, if that compiles
it is preferred to this function (and you will not need to call this
function), because it is truly zero-cost.
This is equivalent to just calling new_boxed on the target type with
the current type’s string contents. This function is provided for
ergonomic convenience.
Sourcepub fn into_boxed_str(self: Box<Ident<B, D, P>>) -> Box<str>
pub fn into_boxed_str(self: Box<Ident<B, D, P>>) -> Box<str>
Converts a boxed identifier into a boxed string slice.
§Examples
Basic Usage:
let ident: Box<LowerSnakeIdent> =
Ident::new_boxed(String::from("snake_ident"))?;
let ident: Box<str> = ident.into_boxed_str();Sourcepub fn into_fragment_buf(self: Box<Ident<B, D, P>>) -> FragmentBuf<B, D, P>
pub fn into_fragment_buf(self: Box<Ident<B, D, P>>) -> FragmentBuf<B, D, P>
Converts a boxed identifier into a fragment buffer.
§Examples
Basic Usage:
let ident: Box<LowerSnakeIdent> =
Ident::new_boxed(String::from("snake_ident"))?;
let buffer: LowerSnakeFragmentBuf = ident.into_fragment_buf();Sourcepub fn into_string(self: Box<Ident<B, D, P>>) -> String
pub fn into_string(self: Box<Ident<B, D, P>>) -> String
Converts a boxed identifier into a string.
§Examples
Basic Usage:
let ident: Box<LowerSnakeIdent> =
Ident::new_boxed(String::from("snake_ident"))?;
let ident: String = ident.into_string();Sourcepub fn to_boxed_ident(&self) -> Box<Ident<B, D, P>>
pub fn to_boxed_ident(&self) -> Box<Ident<B, D, P>>
Converts an identifier into an owned boxed identifier.
§Examples
Basic Usage:
let ident: &LowerSnakeIdent = Ident::new("snake_ident")?;
let ident: Box<LowerSnakeIdent> = ident.to_boxed_ident();Sourcepub fn to_fragment_buf(&self) -> FragmentBuf<B, D, P>
pub fn to_fragment_buf(&self) -> FragmentBuf<B, D, P>
Converts an identifier into a fragment buffer.
§Examples
Basic Usage:
let ident: &LowerSnakeIdent = Ident::new("snake_ident")?;
let buffer: LowerSnakeFragmentBuf = ident.to_fragment_buf();Source§impl<'a, B: 'a, D: UnitDelimiter + 'a, P: 'a> Ident<B, D, P>
impl<'a, B: 'a, D: UnitDelimiter + 'a, P: 'a> Ident<B, D, P>
Source§impl<B: Boundary, D: Delimiter, P: CasedProfile> Ident<B, D, P>
impl<B: Boundary, D: Delimiter, P: CasedProfile> Ident<B, D, P>
Sourcepub fn first_segment(&self) -> Segment<D, &Chunk<B, D, P>>
pub fn first_segment(&self) -> Segment<D, &Chunk<B, D, P>>
Returns the first segment of an identifier.
Since an identifier is always non-empty, there’s always at least one available segment. This function will simply return the first segment.
§Examples
let ident = UpperCamelIdent::new("UpperCamelIdent")?;
assert_eq!(
ident.first_segment(),
UpperCamelSegment::Chunk(UpperCamelChunk::new("Upper")?),
);Sourcepub fn from_fragment(fragment: &Fragment<B, D, P>) -> Result<&Self, Error>
pub fn from_fragment(fragment: &Fragment<B, D, P>) -> Result<&Self, Error>
Converts a fragment to an identifier.
An identifier is made of a fragment, this function converts between the two. Not all fragments are valid identifiers, however. An identifier has additional requirements.
new checks to ensure these are satisfied before the conversion.
§Errors
Returns Error if the fragment does not satisfy the character
requirements. If the fragment is empty, this will return an Empty
error kind. If an invalid character is found then a InvalidFormat
error kind is returned, with byte_offset set to the byte index for
the first invalid character.
§Examples
let fragment = UpperCamelFragment::new("AnUpperCamel_Fragment")?;
let ident = UpperCamelIdent::from_fragment(fragment)?;
assert_eq!(ident, "AnUpperCamel_Fragment");Sourcepub fn last_segment(&self) -> Segment<D, &Chunk<B, D, P>>
pub fn last_segment(&self) -> Segment<D, &Chunk<B, D, P>>
Returns the last segment of an identifier.
Since an identifier is always non-empty, there’s always at least one available segment. This function will simply return the last segment.
§Examples
let ident = UpperCamelIdent::new("UpperCamelIdent")?;
assert_eq!(
ident.last_segment(),
UpperCamelSegment::Chunk(UpperCamelChunk::new("Ident")?),
);Sourcepub fn new(s: &str) -> Result<&Self, Error>
pub fn new(s: &str) -> Result<&Self, Error>
Converts a string slice to an identifier.
An identifier is made of a Fragment, which itself is made of a
string slice (&str), this function converts between the two. Not all
string slices are valid identifiers, however. An identifier requires
that the characters it is comprised of satisfy certain requirements.
new checks to ensure these are satisfied before the conversion.
§Errors
Returns Error if the identifier does not satisfy the character
requirements. If the identifier is empty, this will return an Empty
error kind. If an invalid character is found then a InvalidFormat
error kind is returned, with byte_offset set to the byte index for
the first invalid character.
§Examples
let ident = UpperCamelIdent::new("AnUpperCamel_Identifier")?;
assert_eq!(ident, "AnUpperCamel_Identifier");Sourcepub fn trim_decorative_delims(&self) -> &Self
pub fn trim_decorative_delims(&self) -> &Self
Trims any decorative delimiters from the identifier.
This function cannot leave you with an invalid identifier, it explicitly only trims delimiters that it considers to be non-essential, or decorative.
If there’s multiple kinds of delimiters, the right-most delimiter will
be preserved. This is essentially the same as calling
trim_leading_decorative_delims followed by
trim_trailing_decorative_delims.
If you want all delimiters to be trimmed regardless of whether or not it
will leave you with a valid identifier, you can instead call the
trim_delims method, which returns a Fragment.
§Examples
Basic Usage:
let ident = UpperCamelIdent::new("__DecoratedIdent__")?;
assert_eq!(ident.trim_decorative_delims(), "DecoratedIdent");Delimiters will be preserved if the following character is not valid at ident-start:
let ident = UpperCamelIdent::new("__2DecoratedIdent__")?;
assert_eq!(ident.trim_decorative_delims(), "_2DecoratedIdent");A delimiter-only identifier becomes a single-character identifier:
let ident = UpperCamelIdent::new("____")?;
assert_eq!(ident.trim_decorative_delims(), "_");If there’s multiple allowed delimiters, the right-most is preserved:
assert_eq!(HybridIdent::new("--__")?.trim_decorative_delims(), "_");
assert_eq!(HybridIdent::new("__--")?.trim_decorative_delims(), "-");Sourcepub fn trim_leading_decorative_delims(&self) -> &Self
pub fn trim_leading_decorative_delims(&self) -> &Self
Trims any leading decorative delimiters from the identifier.
This function cannot leave you with an invalid identifier, it explicitly only trims delimiters that it considers to be non-essential, or decorative.
If there’s multiple kinds of delimiters, the right-most delimiter will be preserved (e.g. the trimming happens from left-to-right).
If you want all leading delimiters to be trimmed regardless of whether
or not it will leave you with a valid identifier, you can instead call
the trim_leading_delims method, which returns a Fragment.
§Examples
Basic Usage:
let ident = UpperCamelIdent::new("__DecoratedIdent__")?;
assert_eq!(ident.trim_leading_decorative_delims(), "DecoratedIdent__");Delimiters will be preserved if the following character is not valid at ident-start:
let ident = UpperCamelIdent::new("__2DecoratedIdent__")?;
assert_eq!(ident.trim_leading_decorative_delims(), "_2DecoratedIdent__");A delimiter-only identifier becomes a single-character identifier:
let ident = UpperCamelIdent::new("____")?;
assert_eq!(ident.trim_leading_decorative_delims(), "_");If there’s multiple allowed delimiters, the right-most is preserved:
assert_eq!(HybridIdent::new("--__")?.trim_leading_decorative_delims(), "_");
assert_eq!(HybridIdent::new("__--")?.trim_leading_decorative_delims(), "-");Sourcepub fn trim_trailing_decorative_delims(&self) -> &Self
pub fn trim_trailing_decorative_delims(&self) -> &Self
Trims any trailing decorative delimiters from the identifier.
This function cannot leave you with an invalid identifier, it explicitly only trims delimiters that it considers to be non-essential, or decorative.
If there’s multiple kinds of delimiters, the left-most delimiter will be preserved (e.g. the trimming happens from right-to-left).
If you want all trailing delimiters to be trimmed regardless of whether
or not it will leave you with a valid identifier, you can instead call
the trim_trailing_delims method, which returns a Fragment.
§Examples
Basic Usage:
let ident = UpperCamelIdent::new("__DecoratedIdent__")?;
assert_eq!(ident.trim_trailing_decorative_delims(), "__DecoratedIdent");
let ident = UpperCamelIdent::new("__2DecoratedIdent__")?;
assert_eq!(ident.trim_trailing_decorative_delims(), "__2DecoratedIdent");A delimiter-only identifier becomes a single-character identifier:
let ident = UpperCamelIdent::new("____")?;
assert_eq!(ident.trim_trailing_decorative_delims(), "_");If there’s multiple allowed delimiters, the right-most is preserved:
assert_eq!(HybridIdent::new("--__")?.trim_trailing_decorative_delims(), "-");
assert_eq!(HybridIdent::new("__--")?.trim_trailing_decorative_delims(), "_");Source§impl<B, D, P> Ident<B, D, P>
impl<B, D, P> Ident<B, D, P>
Sourcepub const fn as_fragment(&self) -> &Fragment<B, D, P>
pub const fn as_fragment(&self) -> &Fragment<B, D, P>
Returns a fragment representation of the identifier.
Note that Ident implements Deref<Target = Fragment>, so usually you
don’t need to call this function explicitly.
§Examples
let ident = UpperCamelIdent::new("ExampleIdent")?;
assert_eq!(ident.as_fragment(), UpperCamelFragment::new("ExampleIdent")?);Sourcepub const fn as_ident(&self) -> &Self
pub const fn as_ident(&self) -> &Self
Returns the identifier as a reference.
This method exists for convenience use when dealing with Box<Ident>
types. That way there’s a simple way to get the underlying reference.
§Examples
let ident = UpperCamelIdent::new_boxed(String::from("ExampleIdent"))?;
assert_eq!(ident.as_ident(), UpperCamelIdent::new("ExampleIdent")?);Sourcepub const fn as_str(&self) -> &str
pub const fn as_str(&self) -> &str
Returns a string slice representation of the identifier.
§Examples
let ident = UpperCamelIdent::new("ExampleIdent")?;
assert_eq!(ident.as_str(), "ExampleIdent");Sourcepub const fn cast<B2, D2, P2>(&self) -> &Ident<B2, D2, P2>
pub const fn cast<B2, D2, P2>(&self) -> &Ident<B2, D2, P2>
Zero-cost cast into a different type-configured identifier.
This function does not perform any checks that the format matches the
expectations of the target type. The way it’s able to be provided
depends on implementation of the SubsetOf trait.
§Casting Requirements
This function will be able to be called, if:
Source::D: SubsetOf<Target::D>, and…Source::P: SubsetOf<Target::P>
If these invariants are not upheld, attempting to call this function will result in a compilation failure.
§Pro-Tip
If an identifier can perform a zero-cost cast, then the identifier also
will implement AsRef to the target identifier. Because of this, if
you know the shape of identifier that you want, but also want to accept
the widest range of inputs, you can use an AsRef trait bounds.
// A `HybridIdent` accepts any of the other preset formats!
fn expect_hybrid_ident<I: AsRef<HybridIdent> + ?Sized>(ident: &I) {
// ...
}
expect_hybrid_ident(LowerSnakeIdent::new("lower_snake")?);
expect_hybrid_ident(UpperCamelIdent::new("UpperCamel")?);
expect_hybrid_ident(KebabIdent::new("kebab-ident")?);§Examples
Example traversing case profile boundary:
// Compilable Cast:
let original = LowerSnakeIdent::new("apple")?;
let casted: &LowerCamelIdent = original.cast();// Bad Cast (Fails Compilation):
let original = LowerCamelIdent::new("apple")?;
let casted: &LowerSnakeIdent = original.cast();Example traversing character profile boundary:
// Compilable Cast:
let original = ascii::LowerSnakeIdent::new("apple")?;
let casted: &unicode::LowerSnakeIdent = original.cast();// Bad Cast (Fails Compilation):
let original = unicode::LowerSnakeIdent::new("apple")?;
let casted: &ascii::LowerSnakeIdent = original.cast();Example traversing delimiter boundary:
// Compilable Cast:
let original = LowerSnakeIdent::new("apple")?;
let casted: &HybridIdent = original.cast();// Bad Cast (Fails Compilation):
let original = HybridIdent::new("apple")?;
let casted: &LowerSnakeIdent = original.cast();Sourcepub const fn len(&self) -> usize
pub const fn len(&self) -> usize
Returns the length of self.
This length is in bytes, not chars or graphemes. In other words, it
might not be what a human considers the length of the identifier.
§Examples
let slice = HybridIdent::new("foo")?;
let len = slice.len();
assert_eq!(len, 3);
let slice = HybridIdent::new("ƒoo")?;
assert_eq!(slice.len(), 4); // fancy f!
assert_eq!(slice.chars().count(), 3);Sourcepub fn try_cast<B2, D2, P2>(&self) -> Result<&Ident<B2, D2, P2>, Error>
pub fn try_cast<B2, D2, P2>(&self) -> Result<&Ident<B2, D2, P2>, Error>
Attempts a fallible cast into the type-configured target.
You should first attempt to call cast on a type, if that compiles it
is preferred to this function (and you will not need to call this
function), because it is truly zero-cost.
This is equivalent to just calling new on the target type with the
current type’s string contents. This function is provided for ergonomic
convenience.
§Examples
Basic Usage:
let original = LowerCamelIdent::new("apple")?;
let casted: &LowerSnakeIdent = original.try_cast()?;Methods from Deref<Target = Fragment<B, D, P>>§
Sourcepub fn join<F>(&self, fragment: F) -> Result<FragmentBuf<B, D, P>, Error>where
D: Default,
F: IntoIntermediate<B, D, P>,
pub fn join<F>(&self, fragment: F) -> Result<FragmentBuf<B, D, P>, Error>where
D: Default,
F: IntoIntermediate<B, D, P>,
Returns a heap-allocated fragment, joined with the original fragment in a way that preserves chunk boundaries.
This is a convenience function for cases when the delimiter value can be
deduced by the Default trait. For more information on this operation,
see the join_with method.
§Examples
Basic Usage:
let fragment = LowerSnakeFragment::new("snake")?;
let fragment = fragment.join("fragment")?;
assert_eq!(fragment, "snake_fragment");Sourcepub fn join_with<F>(
&self,
fragment: F,
delim: D,
) -> Result<FragmentBuf<B, D, P>, Error>where
F: IntoIntermediate<B, D, P>,
pub fn join_with<F>(
&self,
fragment: F,
delim: D,
) -> Result<FragmentBuf<B, D, P>, Error>where
F: IntoIntermediate<B, D, P>,
Returns a heap-allocated fragment, joined with the original fragment in a way that preserves chunk boundaries.
This function takes anything that can be represented as an intermediate
fragment. That means it can take a &str, char, Fragment, Chunk,
Identifier, or Segment.
If you’re working with an fragment format which has only a single valid
delimiter value, you should instead be able to use the join method,
and should prefer that.
§Preserving Chunk Boundaries
At the end of the operation, the total number of chunked segments present in the fragment will be equal to the sum of each fragment, potentially plus one additional fragment in the case where we needed to join using a delimiter to preserve chunk boundaries.
Whether or not a delimiter is needed is found using the Boundary
trait. The general strategy for joining looks like this:
- The string is joined on the end of the current fragment.
Boundary::has_boundary_atis called with the old fragment length to ensure there’s still a boundary between the end of the original fragment and the joined fragment.- If there’s no boundary, the
delimcharacter is inserted at that location to force a boundary.
The goal of any joining operation is not to merge chunks.
§Errors
Returns Error if the intermediate fragment provided is invalid, or
if the combination of self and fragment cannot produce a valid
result.
If the intermediate fragment is invalid, then the InvalidFormat error
kind will be returned, with the byte_offset set to the first invalid
character of the intermediate fragment.
If the join operation itself failed, then the FailedJoin error kind
is returned, without setting the byte_offset.
§Examples
Basic Usage:
let fragment = LowerSnakeFragment::new("snake")?;
let fragment = fragment.join_with("fragment", LowLine)?;
assert_eq!(fragment, "snake_fragment");Sourcepub fn replace<M, F>(
&self,
from: M,
to: F,
) -> Result<FragmentBuf<B, D, P>, Error>where
M: Pattern,
F: IntoIntermediate<B, D, P>,
pub fn replace<M, F>(
&self,
from: M,
to: F,
) -> Result<FragmentBuf<B, D, P>, Error>where
M: Pattern,
F: IntoIntermediate<B, D, P>,
Returns a heap-allocated fragment, replacing the provided pattern with a fragment of the user’s choice.
For from, the pattern can be a &str, char, a slice of chars,
or a function or closure that determines if a character matches.
For to, this function takes anything that can be represented as an
intermediate fragment. That means it can take a &str, char,
Fragment, Chunk, Identifier, or Segment.
§Errors
Returns Error if the intermediate fragment provided is invalid, or
if the replacement of from to to does not produce a valid fragment.
If the intermediate fragment is invalid, then the InvalidFormat error
kind will be returned, with the byte_offset set to the first invalid
character of the intermediate fragment.
If the replace operation itself failed, then the FailedReplace error
kind is returned, without setting the byte_offset.
§Examples
Basic Usage:
let fragment = LowerSnakeFragment::new("example_snake_identifier")?;
let fragment = fragment.replace("snake", "serpent")?;
assert_eq!(fragment, "example_serpent_identifier");Sourcepub fn with_circumfix<F1, F2>(
&self,
prefix: F1,
suffix: F2,
) -> Result<FragmentBuf<B, D, P>, Error>where
F1: IntoIntermediate<B, D, P>,
F2: IntoIntermediate<B, D, P>,
pub fn with_circumfix<F1, F2>(
&self,
prefix: F1,
suffix: F2,
) -> Result<FragmentBuf<B, D, P>, Error>where
F1: IntoIntermediate<B, D, P>,
F2: IntoIntermediate<B, D, P>,
Returns a heap-allocated fragment with the provided prefix and suffix attached to the original fragment.
The affixes provided to this function takes anything that can be
represented as an intermediate fragment. That means it can take a
&str, char, Fragment, Chunk, Identifier, or Segment.
§Errors
Returns Error if the intermediate fragments provided are invalid, or
if the combination of prefix, self, and fragment cannot produce a
valid result.
If an intermediate fragment is invalid, then either InvalidPrefix or
InvalidSuffix error kind will be returned (depending on which had the
format error), with the byte_offset set to the first invalid
character of the intermediate fragment.
If the affixing operation itself failed, then the FailedCircumfixing
error kind is returned, without setting the byte_offset.
§Examples
Basic Usage:
let fragment = LowerSnakeFragment::new("snake")?;
let fragment = fragment.with_circumfix("lower_", "_fragment")?;
assert_eq!(fragment, "lower_snake_fragment");Sourcepub fn with_prefix<F>(&self, prefix: F) -> Result<FragmentBuf<B, D, P>, Error>where
F: IntoIntermediate<B, D, P>,
pub fn with_prefix<F>(&self, prefix: F) -> Result<FragmentBuf<B, D, P>, Error>where
F: IntoIntermediate<B, D, P>,
Returns a heap-allocated fragment with the provided prefix attached to the original fragment.
The prefix provided to this function takes anything that can be
represented as an intermediate fragment. That means it can take a
&str, char, Fragment, Chunk, Identifier, or Segment.
§Errors
Returns Error if the intermediate fragment provided is invalid, or
if the combination of prefix and self cannot produce a valid result.
If the intermediate fragment is invalid, then the error kind will be
InvalidPrefix, with the byte_offset set to the first invalid
character of the intermediate fragment.
If the affixing operation itself failed, then the FailedPrefixing
error kind is returned, without setting the byte_offset.
§Examples
Basic Usage:
let fragment = LowerSnakeFragment::new("snake")?;
let fragment = fragment.with_prefix("lower_")?;
assert_eq!(fragment, "lower_snake");Sourcepub fn with_suffix<F>(&self, suffix: F) -> Result<FragmentBuf<B, D, P>, Error>where
F: IntoIntermediate<B, D, P>,
pub fn with_suffix<F>(&self, suffix: F) -> Result<FragmentBuf<B, D, P>, Error>where
F: IntoIntermediate<B, D, P>,
Returns a heap-allocated fragment with the provided suffix attached to the original fragment.
The suffix provided to this function takes anything that can be
represented as an intermediate fragment. That means it can take a
&str, char, Fragment, Chunk, Identifier, or Segment.
§Errors
Returns Error if the intermediate fragment provided is invalid, or
if the combination of self and suffix cannot produce a valid result.
If the intermediate fragment is invalid, then the error kind will be
InvalidSuffix, with the byte_offset set to the first invalid
character of the intermediate fragment.
If the affixing operation itself failed, then the FailedSuffixing
error kind is returned, without setting the byte_offset.
§Examples
Basic Usage:
let fragment = LowerSnakeFragment::new("snake")?;
let fragment = fragment.with_suffix("_fragment")?;
assert_eq!(fragment, "snake_fragment");Sourcepub fn to_boxed_fragment(&self) -> Box<Fragment<B, D, P>>
pub fn to_boxed_fragment(&self) -> Box<Fragment<B, D, P>>
Converts a fragment into an owned boxed fragment.
§Examples
Basic Usage:
let ident: &LowerSnakeFragment = Fragment::new("snake_ident")?;
let ident: Box<LowerSnakeFragment> = ident.to_boxed_fragment();Sourcepub fn to_fragment_buf(&self) -> FragmentBuf<B, D, P>
pub fn to_fragment_buf(&self) -> FragmentBuf<B, D, P>
Converts a fragment into a fragment buffer.
§Examples
Basic Usage:
let fragment: &LowerSnakeFragment = Fragment::new("snake_fragment")?;
let buffer: LowerSnakeFragmentBuf = fragment.to_fragment_buf();pub const EMPTY: &'a Fragment<B, D, P>
Sourcepub fn chunked_segments(&self) -> ChunkedSegments<'_, B, D, P> ⓘ
pub fn chunked_segments(&self) -> ChunkedSegments<'_, B, D, P> ⓘ
Produces an iterator over the Segments (chunks and delimiters) of a
fragment.
- The
Delimitervariant is of typeD. - The
Chunkvariant is of typeChunk<'_, B, D, P>.
Usually, when breaking into segments, you want to also break chunks into words. However, this iterator will not do that. It simply breaks into broad segments and chunks.
If you want chunk boundaries to be broken, you should instead use the
segments function.
§Type Erasure
Because segments contain type information specific to the fragment, it can be a little hard to use them in generic situations (where maybe you don’t care about the type information, and just want to see general data about the segments).
In these cases, you should call type_erased to drop type information,
mapping to a StrSegment (you can call this on the returned iterator,
or on an individual segment).
§Examples
Basic Usage:
let flat_ident = CamelIdent::new("HelloWorld_GoodbyeWorld")?;
let mut segments = flat_ident.chunked_segments().type_erased();
assert_eq!(segments.next(), Some(Segment::Chunk("HelloWorld")));
assert_eq!(segments.next(), Some(Segment::Delim('_')));
assert_eq!(segments.next(), Some(Segment::Chunk("GoodbyeWorld")));
assert_eq!(segments.next(), None);This also works in reverse:
let flat_ident = CamelIdent::new("HelloWorld_GoodbyeWorld")?;
let mut segments = flat_ident.chunked_segments().type_erased();
assert_eq!(segments.next_back(), Some(Segment::Chunk("GoodbyeWorld")));
assert_eq!(segments.next_back(), Some(Segment::Delim('_')));
assert_eq!(segments.next_back(), Some(Segment::Chunk("HelloWorld")));
assert_eq!(segments.next_back(), None);Sourcepub fn chunked_segment_indices(&self) -> ChunkedSegmentIndices<'_, B, D, P> ⓘ
pub fn chunked_segment_indices(&self) -> ChunkedSegmentIndices<'_, B, D, P> ⓘ
Produces an iterator over the Segments (chunks and delimiters) of a
fragment, and their positions.
- The
Delimitervariant is of typeD. - The
Chunkvariant is of typeChunk<'_, B, D, P>.
Usually, when breaking into segments, you want to also break chunk boundaries. However, this iterator will not do that. It simply breaks into broad segments and chunks.
If you want chunk boundaries to be broken, you should instead use the
segment_indices function.
§Type Erasure
Because segments contain type information specific to the fragment, it can be a little hard to use them in generic situations (where maybe you don’t care about the type information, and just want to see general data about the segments).
In these cases, you should call type_erased to drop type information,
mapping to a StrSegment (you can call this on the returned iterator,
or on an individual segment).
§Examples
Basic Usage:
let flat_ident = CamelIdent::new("HelloWorld_GoodbyeWorld")?;
let mut segments = flat_ident.chunked_segment_indices().type_erased();
assert_eq!(segments.next(), Some((0, Segment::Chunk("HelloWorld"))));
assert_eq!(segments.next(), Some((10, Segment::Delim('_'))));
assert_eq!(segments.next(), Some((11, Segment::Chunk("GoodbyeWorld"))));
assert_eq!(segments.next(), None);This also works in reverse:
let flat_ident = CamelIdent::new("HelloWorld_GoodbyeWorld")?;
let mut segments = flat_ident.chunked_segment_indices().type_erased();
assert_eq!(segments.next_back(), Some((11, Segment::Chunk("GoodbyeWorld"))));
assert_eq!(segments.next_back(), Some((10, Segment::Delim('_'))));
assert_eq!(segments.next_back(), Some((0, Segment::Chunk("HelloWorld"))));
assert_eq!(segments.next_back(), None);Sourcepub fn segments(&self) -> Segments<'_, B, D, P> ⓘ
pub fn segments(&self) -> Segments<'_, B, D, P> ⓘ
Produces an iterator over the Segments (chunks and delimiters) of a
fragment, with each chunk further sub-divided into words.
- The
Delimitervariant is of typeD. - The
Chunkvariant is of typeChunk<'_, B, D, P>.
This is similar to chunked_segments, except that it will also break
chunks based on the configured Boundary type parameter.
See the core module documentation for details on what a word is.
§Type Erased
Because segments contain type information specific to the fragment, it can be a little hard to use them in generic situations (where maybe you don’t care about the type information, and just want to see general data about the segments).
In these cases, you should call type_erased to drop type information,
mapping to a StrSegment (you can call this on the returned iterator,
or on an individual segment).
§Examples
Basic Usage:
let flat_ident = CamelIdent::new("HelloWorld_GoodbyeWorld")?;
let mut segments = flat_ident.segments().type_erased();
assert_eq!(segments.next(), Some(Segment::Chunk("Hello")));
assert_eq!(segments.next(), Some(Segment::Chunk("World")));
assert_eq!(segments.next(), Some(Segment::Delim('_')));
assert_eq!(segments.next(), Some(Segment::Chunk("Goodbye")));
assert_eq!(segments.next(), Some(Segment::Chunk("World")));
assert_eq!(segments.next(), None);These work in reverse as well:
let flat_ident = CamelIdent::new("HelloWorld_GoodbyeWorld")?;
let mut segments = flat_ident.segments().type_erased();
assert_eq!(segments.next_back(), Some(Segment::Chunk("World")));
assert_eq!(segments.next_back(), Some(Segment::Chunk("Goodbye")));
assert_eq!(segments.next_back(), Some(Segment::Delim('_')));
assert_eq!(segments.next_back(), Some(Segment::Chunk("World")));
assert_eq!(segments.next_back(), Some(Segment::Chunk("Hello")));
assert_eq!(segments.next_back(), None);Sourcepub fn segment_indices(&self) -> SegmentIndices<'_, B, D, P> ⓘ
pub fn segment_indices(&self) -> SegmentIndices<'_, B, D, P> ⓘ
Produces an iterator over the Segments (chunks and delimiters) of a
fragment, with each chunk further sub-divided into words, and their
positions.
This is similar to chunked_segment_indices, except that it will also
break chunks based on the configured Boundary type parameter.
See the core module documentation for details on what a word is.
§Type Erased
Because segments contain type information specific to the fragment, it can be a little hard to use them in generic situations (where maybe you don’t care about the type information, and just want to see general data about the segments).
In these cases, you should call type_erased to drop type information,
mapping to a StrSegment (you can call this on the returned iterator,
or on an individual segment).
§Examples
Basic Usage:
let flat_ident = CamelIdent::new("HelloWorld_GoodbyeWorld")?;
let mut segments = flat_ident.segment_indices().type_erased();
assert_eq!(segments.next(), Some((0, Segment::Chunk("Hello"))));
assert_eq!(segments.next(), Some((5, Segment::Chunk("World"))));
assert_eq!(segments.next(), Some((10, Segment::Delim('_'))));
assert_eq!(segments.next(), Some((11, Segment::Chunk("Goodbye"))));
assert_eq!(segments.next(), Some((18, Segment::Chunk("World"))));
assert_eq!(segments.next(), None);These work in reverse as well:
let flat_ident = CamelIdent::new("HelloWorld_GoodbyeWorld")?;
let mut segments = flat_ident.segment_indices().type_erased();
assert_eq!(segments.next_back(), Some((18, Segment::Chunk("World"))));
assert_eq!(segments.next_back(), Some((11, Segment::Chunk("Goodbye"))));
assert_eq!(segments.next_back(), Some((10, Segment::Delim('_'))));
assert_eq!(segments.next_back(), Some((5, Segment::Chunk("World"))));
assert_eq!(segments.next_back(), Some((0, Segment::Chunk("Hello"))));
assert_eq!(segments.next_back(), None);Sourcepub fn has_leading_delim(&self) -> bool
pub fn has_leading_delim(&self) -> bool
Returns true if the fragment has a leading delimiter, false
otherwise.
§Examples
let fragment = UpperCamelFragment::new("__LeadingDelim")?;
assert!(fragment.has_leading_delim());
let fragment = UpperCamelFragment::new("NoLeadingDelim")?;
assert!(!fragment.has_leading_delim());Sourcepub fn has_trailing_delim(&self) -> bool
pub fn has_trailing_delim(&self) -> bool
Returns true if the fragment has a trailing delimiter, false
otherwise.
§Examples
let fragment = UpperCamelFragment::new("TrailingDelim__")?;
assert!(fragment.has_trailing_delim());
let fragment = UpperCamelFragment::new("NoTrailingDelim")?;
assert!(!fragment.has_trailing_delim());Sourcepub fn is_anonymous(&self) -> bool
pub fn is_anonymous(&self) -> bool
Returns true if the fragment is comprised solely of delimiters,
false otherwise.
§Examples
let fragment = UpperCamelFragment::new("__NotAnonymous__")?;
assert!(!fragment.is_anonymous());
let fragment = UpperCamelFragment::new("___")?;
assert!(fragment.is_anonymous());Sourcepub fn trim_delims(&self) -> &Self
pub fn trim_delims(&self) -> &Self
Trims the leading and trailing delimiters from a fragment.
§Examples
let fragment = UpperCamelFragment::new("__SurroundingDelim__")?;
assert_eq!(fragment.trim_delims().as_str(), "SurroundingDelim");
// Note that this can leave you with an empty fragment.
let fragment = UpperCamelFragment::new("____")?;
assert_eq!(fragment.trim_delims().as_str(), "");Sourcepub fn trim_leading_delims(&self) -> &Self
pub fn trim_leading_delims(&self) -> &Self
Trims the leading delimiters from a fragment.
§Examples
let fragment = UpperCamelFragment::new("__SurroundingDelim__")?;
assert_eq!(fragment.trim_leading_delims().as_str(), "SurroundingDelim__");
// Note that this can leave you with an empty fragment.
let fragment = UpperCamelFragment::new("____")?;
assert_eq!(fragment.trim_leading_delims().as_str(), "");Sourcepub fn trim_trailing_delims(&self) -> &Self
pub fn trim_trailing_delims(&self) -> &Self
Trims the trailing delimiters from a fragment.
§Examples
let fragment = UpperCamelFragment::new("__SurroundingDelim__")?;
assert_eq!(fragment.trim_trailing_delims().as_str(), "__SurroundingDelim");
// Note that this can leave you with an empty fragment.
let fragment = UpperCamelFragment::new("____")?;
assert_eq!(fragment.trim_trailing_delims().as_str(), "");Sourcepub fn as_str(&self) -> &str
pub fn as_str(&self) -> &str
Returns a string slice representation of the fragment.
§Examples
let fragment = UpperCamelFragment::new("ExampleFragment")?;
assert_eq!(fragment.as_str(), "ExampleFragment");Sourcepub fn contains<M>(&self, pat: M) -> boolwhere
M: Pattern,
pub fn contains<M>(&self, pat: M) -> boolwhere
M: Pattern,
Returns true if the given pattern matches a sub-fragment of this
fragment.
Returns false if it does not.
The pattern can be a &str, char, a slice of chars, or a
function or closure that determines if a character matches.
§Examples
let fragment = UpperCamelFragment::new("bananas")?;
assert!(fragment.contains("nana"));
assert!(!fragment.contains("apples"));Sourcepub fn ends_with<M>(&self, pat: M) -> boolwhere
M: Pattern,
pub fn ends_with<M>(&self, pat: M) -> boolwhere
M: Pattern,
Returns true if the given pattern matches a suffix of this fragment.
Returns false if it does not.
The pattern can be a &str, char, a slice of chars, or a
function or closure that determines if a character matches.
§Examples
let fragment = UpperCamelFragment::new("bananas")?;
assert!(fragment.ends_with("anas"));
assert!(!fragment.ends_with("nana"));Sourcepub fn starts_with<M>(&self, pat: M) -> boolwhere
M: Pattern,
pub fn starts_with<M>(&self, pat: M) -> boolwhere
M: Pattern,
Returns true if the given pattern matches a prefix of this fragment.
Returns false if it does not.
The pattern can be a &str, in which case this function will return
true if the &str is a prefix of this string slice.
The pattern can also be a char, a slice of chars, or a
function or closure that determines if a character matches.
These will only be checked against the first character of this fragment.
Look at the second example below regarding behavior for slices of
chars.
§Examples
let fragment = UpperCamelFragment::new("bananas")?;
assert!(fragment.starts_with("bana"));
assert!(!fragment.starts_with("nana"));let fragment = UpperCamelFragment::new("bananas")?;
// Note that both of these assert successfully.
assert!(fragment.starts_with(&['b', 'a', 'n', 'a']));
assert!(fragment.starts_with(&['a', 'b', 'c', 'd']));Sourcepub fn find<M>(&self, pat: M) -> Option<usize>where
M: Pattern,
pub fn find<M>(&self, pat: M) -> Option<usize>where
M: Pattern,
Returns the byte index of the first character of this fragment that matches the pattern.
Returns None if the pattern doesn’t match.
The pattern can be a &str, char, a slice of chars, or a
function or closure that determines if a character matches.
§Examples
Simple patterns:
let fragment = UpperCamelFragment::new("こんにちはWorld")?;
assert_eq!(fragment.find('こ'), Some(0));
assert_eq!(fragment.find('W'), Some(15));
assert_eq!(fragment.find("orld"), Some(16));More complex patterns using point-free style and closures:
let fragment = UpperCamelFragment::new("こんにちはWorld")?;
assert_eq!(fragment.find(char::is_alphabetic), Some(0));
assert_eq!(fragment.find(char::is_lowercase), Some(16));
assert_eq!(fragment.find(|c: char| c == 'W' || c == 'w'), Some(15));Not finding the pattern:
let fragment = UpperCamelFragment::new("こんにちはWorld")?;
let x: &[_] = &['1', '2'];
assert_eq!(fragment.find(x), None);Sourcepub fn rfind<M>(&self, pat: M) -> Option<usize>where
M: Pattern,
pub fn rfind<M>(&self, pat: M) -> Option<usize>where
M: Pattern,
Returns the byte index of the first character of this fragment that matches the pattern.
Returns None if the pattern doesn’t match.
The pattern can be a &str, char, a slice of chars, or a
function or closure that determines if a character matches.
§Examples
Simple patterns:
let fragment = UpperCamelFragment::new("HelloWorld")?;
assert_eq!(fragment.rfind('o'), Some(6));
assert_eq!(fragment.rfind('H'), Some(0));
assert_eq!(fragment.rfind("lo"), Some(3));More complex patterns using point-free style and closures:
let fragment = UpperCamelFragment::new("HelloWorld")?;
assert_eq!(fragment.rfind(char::is_uppercase), Some(5));
assert_eq!(fragment.rfind(char::is_lowercase), Some(9));
assert_eq!(fragment.rfind(|c: char| c == 'o' || c == 'e'), Some(6));Not finding the pattern:
let fragment = UpperCamelFragment::new("HelloWorld")?;
let x: &[_] = &['1', '2'];
assert_eq!(fragment.rfind(x), None);Sourcepub fn cast<B2, D2, P2>(&self) -> &Fragment<B2, D2, P2>
pub fn cast<B2, D2, P2>(&self) -> &Fragment<B2, D2, P2>
Zero-cost cast into the type-configured target.
This function does not perform any checks that the format
matches the expectations of the target type. The way it’s able
to be provided depends on implementation of the SubsetOf
trait.
§Casting Requirements
This function will be able to be called, if:
Source::D: SubsetOf<Target::D>, and…Source::P: SubsetOf<Target::P>
If these invariants are not upheld, attempting to call this function will result in a compilation failure.
§Pro-Tip
If this type can perform a zero-cost cast, then it will also
implement AsRef to the target type. Because of this, if you
know the shape of target type that you want, but also want to
accept the widest range of inputs, you can use an AsRef trait
bounds.
fn expect_hybrid<I: AsRef<HybridFragment> + ?Sized>(ident: &I) {}
expect_hybrid(LowerSnakeFragment::new("apple")?);
expect_hybrid(UpperCamelFragment::new("Apple")?);§Examples
Example traversing case profile boundary:
// Compilable Cast:
let original = LowerSnakeFragment::new("apple")?;
let casted: &LowerCamelFragment = original.cast();// Bad Cast (Fails Compilation):
let original = LowerCamelFragment::new("apple")?;
let casted: &LowerSnakeFragment = original.cast();Example traversing character profile boundary:
// Compilable Cast:
let original = ascii::LowerSnakeFragment::new("apple")?;
let casted: &unicode::LowerSnakeFragment = original.cast();// Bad Cast (Fails Compilation):
let original = unicode::LowerSnakeFragment::new("apple")?;
let casted: &ascii::LowerSnakeFragment = original.cast();Example traversing delimiter boundary:
// Compilable Cast:
let original = LowerSnakeFragment::new("apple")?;
let casted: &HybridFragment = original.cast();// Bad Cast (Fails Compilation):
let original = HybridFragment::new("apple")?;
let casted: &LowerSnakeFragment = original.cast();Sourcepub fn char_indices(&self) -> CharIndices<'_, B, D, P> ⓘ
pub fn char_indices(&self) -> CharIndices<'_, B, D, P> ⓘ
Returns an iterator over the chars of the underlying string
slice, and their positions.
This is a special version of the standard-provided
CharIndices. It has additional functions on it to allow you to
cast the remainder of the string slice back to this type.
§Examples
Basic Usage:
let slice = HybridFragment::new("test")?;
let mut chars = slice.char_indices();
assert_eq!(chars.next(), Some((0, 't')));
assert_eq!(chars.next(), Some((1, 'e')));
assert_eq!(chars.next(), Some((2, 's')));
assert_eq!(chars.next(), Some((3, 't')));
assert_eq!(chars.next(), None);If needed, you can cast the remainder back to this type:
let slice = HybridFragment::new("test")?;
let mut chars = slice.char_indices();
assert_eq!(chars.next(), Some((0, 't')));
assert_eq!(chars.next(), Some((1, 'e')));
let remainder: &HybridFragment = chars.as_fragment();
assert_eq!(remainder, "st");If you don’t need type information, you can drop it with the
type_erased method:
let slice = HybridFragment::new("test")?;
let chars: std::str::CharIndices = slice.char_indices().type_erased();Sourcepub fn chars(&self) -> Chars<'_, B, D, P> ⓘ
pub fn chars(&self) -> Chars<'_, B, D, P> ⓘ
Returns an iterator over the chars of the underlying string
slice.
This is a special version of the standard-provided Chars. It
has additional functions on it to allow you to cast the
remainder of the string slice back to this type.
§Examples
Basic Usage:
let slice = HybridFragment::new("test")?;
let mut chars = slice.chars();
assert_eq!(chars.next(), Some('t'));
assert_eq!(chars.next(), Some('e'));
assert_eq!(chars.next(), Some('s'));
assert_eq!(chars.next(), Some('t'));
assert_eq!(chars.next(), None);If needed, you can cast the remainder back to this type:
let slice = HybridFragment::new("test")?;
let mut chars = slice.chars();
assert_eq!(chars.next(), Some('t'));
assert_eq!(chars.next(), Some('e'));
let remainder: &HybridFragment = chars.as_fragment();
assert_eq!(remainder, "st");If you don’t need type information, you can drop it with the
type_erased method:
let slice = HybridFragment::new("test")?;
let chars: std::str::Chars = slice.chars().type_erased();Sourcepub fn get<I: SliceIndex<Self>>(&self, i: I) -> Option<&Self>
pub fn get<I: SliceIndex<Self>>(&self, i: I) -> Option<&Self>
Returns a subslice of a Fragment
This is the non-panicking alternative to using the index operator.
Returns None whenever the equivalent indexing operation
would panic.
§Examples
let slice = HybridFragment::new("こんにちは世界")?;
// indices not on UTF-8 sequence boundaries
assert!(slice.get(1..).is_none());
assert!(slice.get(..20).is_none());
// out of bounds
assert!(slice.get(..42).is_none());Sourcepub unsafe fn get_unchecked<I: SliceIndex<Self>>(&self, i: I) -> &Self
pub unsafe fn get_unchecked<I: SliceIndex<Self>>(&self, i: I) -> &Self
Returns an unchecked subslice of a Fragment
This is the unchecked alternative to using the index operator.
§Safety
Callers of this function are responsible that these preconditions are satisfied:
- The starting index must not exceed the ending index;
- Indexes must be within bounds of the original slice;
- Indexes must lie on UTF-8 sequence boundaries.
Failing that, the returned slice may reference invalid memory or
violate the invariants communicated by the Fragment type.
§Examples
let slice = HybridFragment::new("こんにちは世界")?;
unsafe {
assert_eq!(slice.get_unchecked(0..15), HybridFragment::new("こんにちは")?);
assert_eq!(slice.get_unchecked(15..21), HybridFragment::new("世界")?);
}Sourcepub fn is_empty(&self) -> bool
pub fn is_empty(&self) -> bool
Returns true if self has a length of zero bytes.
§Examples
let slice = HybridFragment::new("")?;
assert!(slice.is_empty());
let slice = HybridFragment::new("content")?;
assert!(!slice.is_empty());Sourcepub fn len(&self) -> usize
pub fn len(&self) -> usize
Returns the length of self.
This length is in bytes, not chars or graphemes. In other
words, it might not be what a human considers the length of the
subslice.
§Examples
let slice = HybridFragment::new("foo")?;
let len = slice.len();
assert_eq!(len, 3);
let slice = HybridFragment::new("ƒoo")?;
assert_eq!(slice.len(), 4); // fancy f!
assert_eq!(slice.chars().count(), 3);Sourcepub fn match_indices<M>(&self, pat: M) -> MatchIndices<'_, B, D, P, M> ⓘwhere
M: Pattern,
pub fn match_indices<M>(&self, pat: M) -> MatchIndices<'_, B, D, P, M> ⓘwhere
M: Pattern,
Returns an iterator over the disjoint matches of a pattern within the underlying string slice as well as the index that the match starts at.
This is a special version of the standard-provided
MatchIndices. Instead of returning regular string slices, it
returns Fragment elements.
The pattern can be a &str, char, a slice of chars, or
a function or closure that determines if a character matches.
§Iterator behavior
The returned iterator will be a DoubleEndedIterator if the
pattern allows a reverse search and forward/reverse search
yields the same elements. This is true for, e.g., char, but
not for &str.
If the pattern allows a reverse search but its results might
differ from a forward search, the rmatch_indices method can
be used.
§Examples
Basic Usage:
let slice = HybridFragment::new("abcXXXabcYYYabc")?;
let mut matches = slice.match_indices("abc");
assert_eq!(matches.next(), Some((0, HybridFragment::new("abc")?)));
assert_eq!(matches.next(), Some((6, HybridFragment::new("abc")?)));
assert_eq!(matches.next(), Some((12, HybridFragment::new("abc")?)));
assert_eq!(matches.next(), None);
let slice = HybridFragment::new("1abcabc2")?;
let mut matches = slice.match_indices("abc");
assert_eq!(matches.next(), Some((1, HybridFragment::new("abc")?)));
assert_eq!(matches.next(), Some((4, HybridFragment::new("abc")?)));
assert_eq!(matches.next(), None);
let slice = HybridFragment::new("ababa")?;
let mut matches = slice.match_indices("aba");
assert_eq!(matches.next(), Some((0, HybridFragment::new("aba")?)));
assert_eq!(matches.next(), None); // only the first `aba`If you don’t need type information, you can drop it with the
type_erased method. This can be especially useful if you
don’t need the typed versions of the results.
let slice = HybridFragment::new("test")?;
let mut matches: std::str::MatchIndices<char> = slice.match_indices('t').type_erased();
assert_eq!(matches.next(), Some((0, "t")));
assert_eq!(matches.next(), Some((3, "t")));
assert_eq!(matches.next(), None);Sourcepub fn matches<M>(&self, pat: M) -> Matches<'_, B, D, P, M> ⓘwhere
M: Pattern,
pub fn matches<M>(&self, pat: M) -> Matches<'_, B, D, P, M> ⓘwhere
M: Pattern,
Returns an iterator over the disjoint matches of a pattern within the underlying string slice.
This is a special version of the standard-provided
Matches. Instead of returning regular string slices, it
returns Fragment elements.
The pattern can be a &str, char, a slice of chars, or
a function or closure that determines if a character matches.
§Iterator behavior
The returned iterator will be a DoubleEndedIterator if the
pattern allows a reverse search and forward/reverse search
yields the same elements. This is true for, e.g., char, but
not for &str.
If the pattern allows a reverse search but its results might
differ from a forward search, the rmatches method can
be used.
§Examples
Basic Usage:
let slice = HybridFragment::new("abcXXXabcYYYabc")?;
let mut matches = slice.matches("abc");
assert_eq!(matches.next(), Some(HybridFragment::new("abc")?));
assert_eq!(matches.next(), Some(HybridFragment::new("abc")?));
assert_eq!(matches.next(), Some(HybridFragment::new("abc")?));
assert_eq!(matches.next(), None);
let slice = HybridFragment::new("1abcabc2")?;
let mut matches = slice.matches("abc");
assert_eq!(matches.next(), Some(HybridFragment::new("abc")?));
assert_eq!(matches.next(), Some(HybridFragment::new("abc")?));
assert_eq!(matches.next(), None);
let slice = HybridFragment::new("ababa")?;
let mut matches = slice.matches("aba");
assert_eq!(matches.next(), Some(HybridFragment::new("aba")?));
assert_eq!(matches.next(), None); // only the first `aba`If you don’t need type information, you can drop it with the
type_erased method. This can be especially useful if you
don’t need the typed versions of the results.
let slice = HybridFragment::new("test")?;
let mut matches: std::str::Matches<char> = slice.matches('t').type_erased();
assert_eq!(matches.next(), Some("t"));
assert_eq!(matches.next(), Some("t"));
assert_eq!(matches.next(), None);Sourcepub fn rmatch_indices<M>(&self, pat: M) -> RMatchIndices<'_, B, D, P, M> ⓘwhere
M: Pattern,
pub fn rmatch_indices<M>(&self, pat: M) -> RMatchIndices<'_, B, D, P, M> ⓘwhere
M: Pattern,
Returns an iterator over the disjoint matches of a pattern within the underlying string slice yielded in reverse order, as well as the index that the match starts at
This is a special version of the standard-provided
RMatchIndices. Instead of returning regular string slices, it
returns Fragment elements.
For matches of pat within self that overlap, only the indices
corresponding to the last match are returned.
The pattern can be a &str, char, a slice of chars, or a
function or closure that determines if a character matches.
§Iterator behavior
The returned iterator requires that the pattern supports a
reverse search, and it will be a DoubleEndedIterator if a
forward/reverse search yields the same elements.
For iterating from the front, the match_indices method can
be used.
§Examples
Basic Usage:
let slice = HybridFragment::new("abcXXXabcYYYabc")?;
let mut matches = slice.rmatch_indices("abc");
assert_eq!(matches.next(), Some((12, HybridFragment::new("abc")?)));
assert_eq!(matches.next(), Some((6, HybridFragment::new("abc")?)));
assert_eq!(matches.next(), Some((0, HybridFragment::new("abc")?)));
assert_eq!(matches.next(), None);
let slice = HybridFragment::new("1abcabc2")?;
let mut matches = slice.rmatch_indices("abc");
assert_eq!(matches.next(), Some((4, HybridFragment::new("abc")?)));
assert_eq!(matches.next(), Some((1, HybridFragment::new("abc")?)));
assert_eq!(matches.next(), None);
let slice = HybridFragment::new("ababa")?;
let mut matches = slice.rmatch_indices("aba");
assert_eq!(matches.next(), Some((2, HybridFragment::new("aba")?)));
assert_eq!(matches.next(), None); // only the first `aba`If you don’t need type information, you can drop it with the
type_erased method. This can be especially useful if you
don’t need the typed versions of the results.
let slice = HybridFragment::new("test")?;
let mut matches: std::str::RMatchIndices<char> = slice.rmatch_indices('t').type_erased();
assert_eq!(matches.next(), Some((3, "t")));
assert_eq!(matches.next(), Some((0, "t")));
assert_eq!(matches.next(), None);Sourcepub fn rmatches<M>(&self, pat: M) -> RMatches<'_, B, D, P, M> ⓘwhere
M: Pattern,
pub fn rmatches<M>(&self, pat: M) -> RMatches<'_, B, D, P, M> ⓘwhere
M: Pattern,
Returns an iterator over the disjoint matches of a pattern within the underlying string slice yielded in reverse order.
This is a special version of the standard-provided
RMatches. Instead of returning regular string slices, it
returns Fragment elements.
For matches of pat within self that overlap, only the indices
corresponding to the last match are returned.
The pattern can be a &str, char, a slice of chars, or a
function or closure that determines if a character matches.
§Iterator behavior
The returned iterator requires that the pattern supports a
reverse search, and it will be a DoubleEndedIterator if a
forward/reverse search yields the same elements.
For iterating from the front, the matches method can
be used.
§Examples
Basic Usage:
let slice = HybridFragment::new("abcXXXabcYYYabc")?;
let mut matches = slice.rmatches("abc");
assert_eq!(matches.next(), Some(HybridFragment::new("abc")?));
assert_eq!(matches.next(), Some(HybridFragment::new("abc")?));
assert_eq!(matches.next(), Some(HybridFragment::new("abc")?));
assert_eq!(matches.next(), None);
let slice = HybridFragment::new("1abcabc2")?;
let mut matches = slice.rmatches("abc");
assert_eq!(matches.next(), Some(HybridFragment::new("abc")?));
assert_eq!(matches.next(), Some(HybridFragment::new("abc")?));
assert_eq!(matches.next(), None);
let slice = HybridFragment::new("ababa")?;
let mut matches = slice.rmatches("aba");
assert_eq!(matches.next(), Some(HybridFragment::new("aba")?));
assert_eq!(matches.next(), None); // only the first `aba`If you don’t need type information, you can drop it with the
type_erased method. This can be especially useful if you
don’t need the typed versions of the results.
let slice = HybridFragment::new("test")?;
let mut matches: std::str::RMatches<char> = slice.rmatches('t').type_erased();
assert_eq!(matches.next(), Some("t"));
assert_eq!(matches.next(), Some("t"));
assert_eq!(matches.next(), None);Sourcepub fn split_at(&self, mid: usize) -> (&Self, &Self)
pub fn split_at(&self, mid: usize) -> (&Self, &Self)
Divides one fragment into two at an index.
The argument, mid, should be a byte offset from the start of the
fragment.
It must also be on the boundary of a UTF-8 code point.
The two slices returned go from the start of the
fragment
to mid, and from mid to the end of the
fragment.
§Panics
Panics if mid is not on a UTF-8 code point boundary, or if it
is past the end of the last code point of the
fragment.
For a non-panicking alternative see split_at_checked.
§Examples
let slice = HybridFragment::new("こんにちは世界")?;
let (first, last) = slice.split_at(15);
assert_eq!(first, HybridFragment::new("こんにちは")?);
assert_eq!(last, HybridFragment::new("世界")?);Sourcepub fn split_at_checked(&self, mid: usize) -> Option<(&Self, &Self)>
pub fn split_at_checked(&self, mid: usize) -> Option<(&Self, &Self)>
Divides one fragment into two at an index.
The argument, mid, should be a byte offset from the start of the
fragment.
It must also be on the boundary of a UTF-8 code point. The method
returns None if that’s not the case.
The two slices returned go from the start of the
fragment
to mid, and from mid to the end of the
fragment.
§Examples
let slice = HybridFragment::new("こんにちは世界")?;
let (first, last) = slice.split_at_checked(15).unwrap();
assert_eq!(first, HybridFragment::new("こんにちは")?);
assert_eq!(last, HybridFragment::new("世界")?);
assert!(slice.split_at_checked(16).is_none()); // Inside "世"
assert!(slice.split_at_checked(42).is_none()); // Beyond the lengthSourcepub fn strip_circumfix<Prefix, Suffix>(
&self,
prefix: Prefix,
suffix: Suffix,
) -> Option<&Self>where
Prefix: Pattern,
Suffix: Pattern,
pub fn strip_circumfix<Prefix, Suffix>(
&self,
prefix: Prefix,
suffix: Suffix,
) -> Option<&Self>where
Prefix: Pattern,
Suffix: Pattern,
Returns a fragment with the prefix and suffix removed.
If the
fragment
starts with the pattern prefix and ends with the pattern
suffix, and the prefix and suffix don’t overlap, returns the
sub-fragment
after the prefix and before the suffix, wrapped in Some.
Unlike trim_start_matches and trim_end_matches, this
method removes both the prefix and suffix exactly once.
If the
fragment
does not start with prefix, does not end with suffix, or the
prefix and suffix overlap, returns None.
Each pattern can be a &str, char, a slice of chars, or a
function or closure that determines if a character matches.
§Examples
let slice = HybridFragment::new("FooHelloWorldBar")?;
assert_eq!(slice.strip_circumfix("Foo", "Bar"), Some(HybridFragment::new("HelloWorld")?));
assert_eq!(slice.strip_circumfix("FooHello", "WorldBar"), Some(HybridFragment::new("")?));
assert_eq!(slice.strip_circumfix("Foo", "Foo"), None);
assert_eq!(slice.strip_circumfix("Bar", "Bar"), None);
assert_eq!(slice.strip_circumfix("FooHello", "oWorldBar"), None);Sourcepub fn strip_prefix<M>(&self, prefix: M) -> Option<&Self>where
M: Pattern,
pub fn strip_prefix<M>(&self, prefix: M) -> Option<&Self>where
M: Pattern,
Returns a fragment with the prefix removed.
If the
fragment
starts with the pattern prefix, returns the
sub-fragment
after the prefix, wrapped in Some. Unlike
trim_start_matches, this method removes the prefix exactly
once.
If the
fragment
does not start with prefix, returns None.
The pattern can be a &str, char, a slice of chars, or a
function or closure that determines if a character matches.
§Examples
let slice = HybridFragment::new("HelloWorld")?;
assert_eq!(slice.strip_prefix("Hello"), Some(HybridFragment::new("World")?));
assert_eq!(slice.strip_prefix("HelloWorld"), Some(HybridFragment::new("")?));
assert_eq!(slice.strip_prefix("Goodbye"), None);Sourcepub fn strip_suffix<M>(&self, suffix: M) -> Option<&Self>where
M: Pattern,
pub fn strip_suffix<M>(&self, suffix: M) -> Option<&Self>where
M: Pattern,
Returns a fragment with the suffix removed.
If the
fragment
ends with the pattern suffix, returns the
sub-fragment
before the suffix, wrapped in Some. Unlike
trim_end_matches, this method removes the suffix exactly
once.
If the
fragment
does not end with suffix, returns None.
The pattern can be a &str, char, a slice of chars, or a
function or closure that determines if a character matches.
§Examples
let slice = HybridFragment::new("HelloWorld")?;
assert_eq!(slice.strip_suffix("World"), Some(HybridFragment::new("Hello")?));
assert_eq!(slice.strip_suffix("HelloWorld"), Some(HybridFragment::new("")?));
assert_eq!(slice.strip_suffix("Computer"), None);Sourcepub fn trim_start_matches<M>(&self, pat: M) -> &Selfwhere
M: Pattern,
pub fn trim_start_matches<M>(&self, pat: M) -> &Selfwhere
M: Pattern,
Returns a fragment with all prefixes that match a pattern repeatedly removed.
The pattern can be a &str, char, a slice of chars, or a
function or closure that determines if a character matches.
§Text Directionality
A
fragment
is a sequence of bytes. start in this context means the first
position of that byte string; for a left-to-right language like
English or Russian, this will be left side, and for right-to-left
languages like Arabic or Hebrew, this will be the right side.
§Examples
Simple examples:
let slice = HybridFragment::new("11foo1bar11")?;
assert_eq!(slice.trim_start_matches('1'), HybridFragment::new("foo1bar11")?);
let slice = HybridFragment::new("123foo1bar123")?;
assert_eq!(slice.trim_start_matches(char::is_numeric), HybridFragment::new("foo1bar123")?);
let x: &[_] = &['1', '2'];
let slice = HybridFragment::new("12foo1bar12")?;
assert_eq!(slice.trim_start_matches(x), HybridFragment::new("foo1bar12")?);
// Example with a right-to-left language
let slice = HybridFragment::new("שלוםעולם")?;
assert_eq!(slice.trim_start_matches("שלום"), HybridFragment::new("עולם")?);A more complex pattern, using a closure:
let slice = HybridFragment::new("1fooX")?;
assert_eq!(slice.trim_start_matches(|c| c == '1' || c == 'X'), HybridFragment::new("fooX")?);Sourcepub fn trim_end_matches<M>(&self, pat: M) -> &Selfwhere
M: Pattern,
pub fn trim_end_matches<M>(&self, pat: M) -> &Selfwhere
M: Pattern,
Returns a fragment with all suffixes that match a pattern repeatedly removed.
The pattern can be a &str, char, a slice of chars, or a
function or closure that determines if a character matches.
§Text Directionality
A
fragment
is a sequence of bytes. end in this context means the last
position of that byte string; for a left-to-right language like
English or Russian, this will be right side, and for right-to-left
languages like Arabic or Hebrew, this will be the left side.
§Examples
Simple examples:
let slice = HybridFragment::new("11foo1bar11")?;
assert_eq!(slice.trim_end_matches('1'), HybridFragment::new("11foo1bar")?);
let slice = HybridFragment::new("123foo1bar123")?;
assert_eq!(slice.trim_end_matches(char::is_numeric), HybridFragment::new("123foo1bar")?);
let x: &[_] = &['1', '2'];
let slice = HybridFragment::new("12foo1bar12")?;
assert_eq!(slice.trim_end_matches(x), HybridFragment::new("12foo1bar")?);
// Example with a right-to-left language
let slice = HybridFragment::new("שלוםעולם")?;
assert_eq!(slice.trim_end_matches("עולם"), HybridFragment::new("שלום")?);A more complex pattern, using a closure:
let slice = HybridFragment::new("1fooX")?;
assert_eq!(slice.trim_end_matches(|c| c == '1' || c == 'X'), HybridFragment::new("1foo")?);Sourcepub fn try_cast<B2, D2, P2>(&self) -> Result<&Fragment<B2, D2, P2>, Error>
pub fn try_cast<B2, D2, P2>(&self) -> Result<&Fragment<B2, D2, P2>, Error>
Attempts a fallible cast into the type-configured target.
You should first attempt to call cast on a type, if that
compiles it is preferred to this function (and you will not need
to call this), because it is truly zero-cost.
This is equivalent to just calling new on the target type
with the current type’s string contents. This function is
provided for ergonomic convenience.