RE2

Struct RE2 

Source
pub struct RE2(/* private fields */);
Expand description

High-level string search and replacement with a single pattern.

 use re2::RE2;

 let r: RE2 = "a(.+)f".parse()?;
 let [m] = r.full_match_capturing("asdf").unwrap();
 assert_eq!(m, "sd");

Implementations§

Source§

impl RE2

§RE2 = (pattern, options)

Basic components of RE2 objects. Self::quote_meta() is a common utility method to construct pattern strings.

Source

pub fn compile(pattern: &str, options: Options) -> Result<Self, CompileError>

Compile an RE2 pattern.

A FromStr implementation is also provided which calls this method with Options::default(), enabling the use of str::parse():

 use re2::{RE2, options::Options};

 let r = RE2::compile("asdf".into(), Options::default())?;
 assert!(r.full_match("asdf"));

 let r2: RE2 = "asdf".parse()?;
 assert_eq!(r, r2);

The error contains the original pattern string as well as a description of the compile failure:

 use re2::{RE2, error::*};

 assert_eq!(
   "a(sdf".parse::<RE2>().err().unwrap(),
   CompileError {
     message: "missing ): a(sdf".to_string(),
     arg: "a(sdf".to_string(),
     code: RE2ErrorCode::MissingParen,
   },
 );
Source

pub fn pattern(&self) -> &str

Extract the pattern string provided to the compiler.

 let r: re2::RE2 = "asdf".parse()?;
 assert_eq!(r.pattern(), "asdf");
Source

pub fn options(&self) -> Options

Extract the options object provided to the compiler.

 use re2::{RE2, options::*};

 let o: Options = CannedOptions::POSIX.into();
 let r = RE2::compile("asdf".into(), o)?;
 assert_eq!(o, r.options());
 assert_ne!(o, Options::default());
Source

pub fn expensive_clone(&self) -> Self

Create a new instance of this RE2 with the same semantics.

This method is largely intended for documentation purposes; Clone is not implemented because of several performance reasons to re-use the same instance, e.g. with an Arc.

The matching implementation may use a lazy NFA, which is partially constructed as it is matched against input strings, so it improves performance to use a reference to the same instance where possible, to avoid reconstructing the same NFA components. Upfront compilation of this NFA is also somewhat expensive in itself (even if less expensive than a DFA), and best to avoid repeating.

 use re2::{RE2, options::*};

 let o: Options = CannedOptions::POSIX.into();
 let r = RE2::compile("asdf".into(), o)?;
 assert_eq!(o, r.options());
 assert_ne!(o, Options::default());

 let r2 = r.expensive_clone();
 assert_eq!(&r, &r2);
Source

pub fn quote_meta(pattern: &str) -> StringWrapper

Escape any metacharacters in pattern.

 use re2::RE2;

 let q = RE2::quote_meta("1.5-1.8?".into());
 let r: RE2 = unsafe { q.as_view().as_str() }.parse()?;
 assert_eq!(r"1\.5\-1\.8\?", r.pattern());
 assert!(r.full_match("1.5-1.8?"));

Note that literal patterns can be used instead in some cases:

 use re2::{RE2, options::Options};

 let o = Options { literal: true, ..Default::default() };
 let r = RE2::compile("1.5-1.8?".into(), o)?;
 assert_eq!("1.5-1.8?", r.pattern());
 assert!(r.full_match("1.5-1.8?"));
Source§

impl RE2

§Matching

Matching methods tend to have a few variants:

  • Methods with a *_capturing suffix will return a variable array of strings corresponding to matching capture groups. For these methods, requesting more groups than the result of Self::num_captures() will immediately return None without performing the search.

Self::match_routine() also returns a variable array of strings, but presents a slightly different interface. It is the most general matching entry point along with Self::match_no_captures() and is suitable for building higher-level matching interfaces.

Source

pub fn full_match(&self, text: &str) -> bool

Match against text without capturing. Pattern must match entire string.

 let r: re2::RE2 = "a.df".parse()?;
 assert!(r.full_match("asdf"));
 assert!(!r.full_match("asdfe"));
 assert!(!r.full_match("basdf"));
Source

pub fn full_match_capturing<'a, const N: usize>( &self, text: &'a str, ) -> Option<[&'a str; N]>

Match against text and return a subset of declared capture groups. Pattern must match entire string.

 let r: re2::RE2 = "a(.)d(f)".parse()?;
 assert_eq!(2, r.num_captures());

 let msg = "asdf";
 // The 0 case still works, but just calls .full_match():
 assert!(r.full_match_capturing::<0>(msg).is_some());

 let [s1, s2] = r.full_match_capturing(msg).unwrap();
 assert_eq!(s1, "s");
 assert_eq!(s2, "f");
 // The result isn't copied, it points to the same memory:
 assert_eq!(s1.as_bytes().as_ptr(), msg[1..].as_bytes().as_ptr());
 assert_eq!(s2.as_bytes().as_ptr(), msg[3..].as_bytes().as_ptr());
Source

pub fn partial_match(&self, text: &str) -> bool

Like Self::full_match(), except that the pattern may match a substring of text.

 let r: re2::RE2 = "a.df".parse()?;
 assert!(r.partial_match("asdf"));
 assert!(r.partial_match("asdfe"));
 assert!(r.partial_match("basdf"));
 assert!(!r.partial_match("ascf"));
Source

pub fn partial_match_capturing<'a, const N: usize>( &self, text: &'a str, ) -> Option<[&'a str; N]>

Match against text and return a subset of declared capture groups.

Like Self::full_match_capturing(), except that the pattern may match a substring of text.

 use re2::*;

 let o: Options = CannedOptions::POSIX.into();
 let r = RE2::compile("a(.+)d(f)".into(), o)?;
 assert_eq!(2, r.num_captures());

 let msg = "the asdf is withdfin me";
 // The 0 case still works, but just calls .partial_match():
 assert!(r.partial_match_capturing::<0>(msg).is_some());

 let [s1, s2] = r.partial_match_capturing(msg).unwrap();
 assert_eq!(s1, "sdf is with");
 assert_eq!(s2, "f");
 // The result isn't copied, it points to the same memory:
 assert_eq!(s1.as_bytes().as_ptr(), msg[5..].as_bytes().as_ptr());
 assert_eq!(s2.as_bytes().as_ptr(), msg[17..].as_bytes().as_ptr());
Source

pub fn consume(&self, text: &mut &str) -> bool

If the pattern matches some prefix of text, advance text past the match.

 let r: re2::RE2 = "a.{2}".parse()?;
 let mut s = "asdf";
 assert!(r.consume(&mut s));
 assert_eq!(s, "f");
Source

pub fn consume_capturing<'a, const N: usize>( &self, text: &mut &'a str, ) -> Option<[&'a str; N]>

If the pattern matches some prefix of text, advance text past the match and return some subset of captured sub-patterns.

 let r: re2::RE2 = "a(.)d(f)".parse()?;
 assert_eq!(2, r.num_captures());

 let mut msg = "asdfasdfe";
 // The 0 case still works, but just calls .consume():
 assert!(r.consume_capturing::<0>(&mut msg).is_some());
 assert_eq!(msg, "asdfe");

 let [s1, s2] = r.consume_capturing(&mut msg).unwrap();
 assert_eq!(s1, "s");
 assert_eq!(s2, "f");
 assert_eq!(msg, "e");
Source

pub fn find_and_consume(&self, text: &mut &str) -> bool

If the pattern matches anywhere in text, advance text past the match.

Like Self::consume(), but does not anchor the match at the beginning of the text.

 let r: re2::RE2 = "a.{2}".parse()?;
 let mut s = "the asdf";
 assert!(r.find_and_consume(&mut s));
 assert_eq!(s, "f");
Source

pub fn find_and_consume_capturing<'a, const N: usize>( &self, text: &mut &'a str, ) -> Option<[&'a str; N]>

If the pattern matches anywhere in text, advance text past the match and return some subset of captured sub-patterns.

Like Self::consume_capturing(), but does not anchor the match at the beginning of the text.

 let r: re2::RE2 = "a(.)d(f)".parse()?;
 assert_eq!(2, r.num_captures());

 let mut msg = "the asdf and the asdfe";
 // The 0 case still works, but just calls .find_and_consume():
 assert!(r.find_and_consume_capturing::<0>(&mut msg).is_some());
 assert_eq!(msg, " and the asdfe");

 let [s1, s2] = r.find_and_consume_capturing(&mut msg).unwrap();
 assert_eq!(s1, "s");
 assert_eq!(s2, "f");
 assert_eq!(msg, "e");
Source

pub fn match_no_captures( &self, text: &str, range: Range<usize>, anchor: Anchor, ) -> bool

General matching routine. Suitable for calling from higher-level code.

Match against text within range, taking into account anchor. Returns true if match found, false if not.

 use re2::{RE2, options::Anchor};

 let r: RE2 = "(foo)|(bar)baz".parse()?;
 let msg = "barbazbla";

 assert!(r.match_no_captures(msg, 0..msg.len(), Anchor::Unanchored));
 assert!(r.match_no_captures(msg, 0..msg.len(), Anchor::AnchorStart));
 assert!(!r.match_no_captures(msg, 0..msg.len(), Anchor::AnchorBoth));
 assert!(r.match_no_captures(msg, 0..6, Anchor::AnchorBoth));
 assert!(!r.match_no_captures(msg, 1..msg.len(), Anchor::Unanchored));
Source

pub fn match_routine<'a, const N: usize>( &self, text: &'a str, range: Range<usize>, anchor: Anchor, ) -> Option<[&'a str; N]>

General matching routine with capture groups. Suitable for calling from higher-level code.

Match against text within range, taking into account anchor. Returns Some if match found, None if not.

NB: Unlike other matching methods, the 0th element of the result corresponds to the entire matched text, so the indices of the returned array correspond to the indices of declared capture groups e.g. from Self::named_groups(). Also unlike other matching methods, requesting more captures than the number of declared capture groups will simply return empty strings for the excessive captures instead of failing the match.

Performance-wise, N == 0 (capturing nothing, like Self::match_no_captures()) is much faster than N == 1 (only capturing the entire match text), which is faster than N > 1 (if any capture groups are selected).

 use re2::{RE2, options::Anchor};

 let r: RE2 = "(foo)|(bar)baz".parse()?;
 let msg = "barbazbla";

 let [s0, s1, s2, s3] = r.match_routine(msg, 0..msg.len(), Anchor::AnchorStart).unwrap();
 assert_eq!(s0, "barbaz");
 assert_eq!(s1, "");
 assert_eq!(s2, "bar");
 assert_eq!(s3, "");
Source§

impl RE2

§String Replacement with a Rewrite String

These methods use a mutable StringWrapper instance with dynamically allocated data to record the result of applying a “rewrite string” to the capture groups for a given match using Self::vector_rewrite(). They may mutate data from the string or append to the string upon a successful match.

Within a rewrite string, backslash-escaped digits (\1 to \9) can be used to insert text matching corresponding parenthesized group from the pattern. \0 refers to the entire matched text:

 use re2::{RE2, string::StringWrapper};

 let r: RE2 = "b+".parse()?;
 let mut s = StringWrapper::from_view("yabba dabba doo".into());

 assert!(r.replace(&mut s, "d"));
 assert_eq!("yada dabba doo", unsafe { s.as_view().as_str() });

 assert!(r.replace(&mut s, r"!\0!"));
 assert_eq!("yada da!bb!a doo", unsafe { s.as_view().as_str() });
Source

pub fn replace(&self, text: &mut StringWrapper, rewrite: &str) -> bool

Replace the first match of this pattern in text with rewrite.

Returns true if the pattern matches and a replacement occurs, false otherwise.

 let r: re2::RE2 = ".he".parse()?;
 let mut s = re2::string::StringWrapper::from_view("all the king's men".into());
 assert!(r.replace(&mut s, "duh"));
 assert_eq!(unsafe { s.as_view().as_str() }, "all duh king's men");
Source

pub fn replace_n( &self, text: &mut StringWrapper, rewrite: &str, limit: usize, ) -> usize

Applies Self::replace() to text at most limit times. Returns the number of replacements made.

 let r: re2::RE2 = ".he".parse()?;
 let mut s = re2::string::StringWrapper::from_view(
   "all the king's horses and all the king's men".into());
 assert_eq!(2, r.replace_n(&mut s, "duh", 3));
 assert_eq!(
   unsafe { s.as_view().as_str() },
   "all duh king's horses and all duh king's men",
 );
Source

pub fn global_replace(&self, text: &mut StringWrapper, rewrite: &str) -> usize

Applies Self::replace() to text for all non-overlapping occurrences of the pattern. Returns the number of replacements made.

 let r: re2::RE2 = ".he".parse()?;
 let mut s = re2::string::StringWrapper::from_view(
   "all the king's horses and all the king's men".into());
 assert_eq!(2, r.global_replace(&mut s, "duh"));
 assert_eq!(
   unsafe { s.as_view().as_str() },
   "all duh king's horses and all duh king's men",
 );
Source

pub fn extract( &self, text: &str, rewrite: &str, out: &mut StringWrapper, ) -> bool

Like Self::replace(), except that if the pattern matches, rewrite is copied into out with substitutions. The non-matching portions of text are ignored.

Returns true iff a match occured and the extraction happened successfully; if no match occurs, the string is left unaffected.

REQUIRES: text must not alias any part of out!

 let r: re2::RE2 = "(.h)e".parse()?;
 let mut s = re2::string::StringWrapper::blank();
 assert!(r.extract("all the king's men", r"\1a", &mut s));
 assert_eq!(unsafe { s.as_view().as_str() }, "tha");
Source§

impl RE2

§Iterators

These methods make use of lower-level matching methods like Self::match_routine() to produce lazy streams of results.

Source

pub fn find_iter<'r, 'h: 'r, const N: usize>( &'r self, hay: &'h str, ) -> impl Iterator<Item = [&'h str; N]> + 'r

Yields all non-overlapping matches in hay. Supports capture groups.

The N argument is interpreted the same way as in Self::match_routine(), where requesting fewer submatches is more performant, and the 0th submatch corresponds to the entire matched text. However, note that N must be at least 1 when calling this method in order to record match boundaries to avoid overlaps.

NB: if no input is consumed upon searching the regex, iteration will end to avoid looping infinitely.

 let r: re2::RE2 = "a+(.)".parse()?;

 let hay = "aardvarks all ailing: awesome";
 let whole_matches: Vec<&str> = r.find_iter::<1>(hay).map(|[m]| m).collect();
 let submatches: Vec<&str> = r.find_iter::<2>(hay).map(|[_, m]| m).collect();
 assert_eq!(&whole_matches, &["aar", "ar", "al", "ai", "aw"]);
 assert_eq!(&submatches, &["r", "r", "l", "i", "w"]);
Source

pub fn split<'r, 'h: 'r>( &'r self, hay: &'h str, ) -> impl Iterator<Item = &'h str> + 'r

Yields all slices between matches of the pattern.

Split by arbitrary amount of tabs or whitespace:

 let r: re2::RE2 = r"[ \t]+".parse()?;

 let hay = "a b \t  c\td    e";
 let fields: Vec<&str> = r.split(hay).collect();
 assert_eq!(&fields, &["a", "b", "c", "d", "e"]);

Multiple contiguous matches yield empty slices:

 let r: re2::RE2 = "X".parse()?;

 let hay = "XXXXaXXbXc";
 let chunks: Vec<&str> = r.split(hay).collect();
 assert_eq!(&chunks, &["", "", "", "", "a", "", "b", "c"]);

Separators at start or end also yield empty slices:

 let r: re2::RE2 = "0".parse()?;

 let hay = "010";
 let chunks: Vec<&str> = r.split(hay).collect();
 assert_eq!(&chunks, &["", "1", ""]);
Source§

impl RE2

§Introspection

Introspection methods to investigate match groups and rewrite strings.

Source

pub fn max_submatch(rewrite: &str) -> usize

Returns the maximum submatch needed for the rewrite to be done by Self::replace(). E.g. if rewrite == r"foo \2,\1", returns 2.

Self::check_rewrite() ensures that this number is no larger than the result of Self::num_captures().

 use re2::RE2;

 assert_eq!(0, RE2::max_submatch("asdf".into()));
 assert_eq!(0, RE2::max_submatch(r"\0asdf".into()));
 assert_eq!(1, RE2::max_submatch(r"\0a\1sdf".into()));
 assert_eq!(3, RE2::max_submatch(r"\3a\1sdf".into()));
Source

pub fn num_captures(&self) -> usize

Return the number of capture groups in the current pattern.

Alternately, this can be understood as the highest capture group index which this pattern can support in a rewrite string, with 0 referring to the entire match. Also see Self::max_submatch().

 use re2::RE2;

 assert_eq!(0, "a.df".parse::<RE2>()?.num_captures());
 assert_eq!(1, "a(.)df".parse::<RE2>()?.num_captures());
 assert_eq!(2, "a((.)df)".parse::<RE2>()?.num_captures());
 assert_eq!(3, "(?P<foo>a)((.)df)".parse::<RE2>()?.num_captures());
Source

pub fn named_groups(&self) -> impl Iterator<Item = NamedGroup<'_>> + '_

Return an FFI handle to a C++ iterator over the named capture groups.

This method does not provide information about positional-only capture groups. Use Self::named_and_numbered_groups() for an iterator that covers positional as well as named groups.

 use re2::RE2;

 assert_eq!(0, "a(.)df".parse::<RE2>()?.named_groups().count());
 assert_eq!(1, "a(?P<hey>.)df".parse::<RE2>()?.named_groups().count());

 // Not all captures are named:
 let r: RE2 = "a(?P<y>(?P<x>.)d(f)(?P<z>e))".parse()?;
 assert_eq!(4, r.num_captures());

 // Results are sorted by number:
 let groups: Vec<(&str, usize)> = r.named_groups()
   .map(|g| (g.name(), *g.index()))
   .collect();
 assert_eq!(vec![("y", 1), ("x", 2), ("z", 4)], groups);
Source

pub fn named_and_numbered_groups( &self, ) -> impl ExactSizeIterator<Item = Option<&str>>

Return an iterator covering both named and positional-only groups.

Positional-only groups are represented with None instead of a str.

The index of each group can be recovered by calling .enumerate() on the result. This is possible because this iterator also generates a positional-only group at index 0, which can be thought of as corresponding to the 0th group in a rewrite string (aka the entire match).

While most use cases will likely employ either only positional or only named groups, this method can be useful for introspection over uncontrolled inputs.

 let r: re2::RE2 = "a(?P<y>(?P<x>.)d(f)(?P<z>e)(n))".parse()?;
 assert_eq!(5, r.num_captures());

 let indexed: Vec<(usize, Option<&str>)> = r.named_and_numbered_groups()
   .enumerate()
   .collect();
 assert_eq!(
   &indexed,
   &[(0, None), (1, Some("y")), (2, Some("x")), (3, None), (4, Some("z")), (5, None)] );
Source

pub fn check_rewrite(&self, rewrite: &str) -> Result<(), RewriteError>

Check that the given rewrite string is suitable for use with this regular expression.

It checks that:

  • The regular expression has enough parenthesized subexpressions to satisfy all of the \N tokens in rewrite
  • The rewrite string doesn’t have any syntax errors. E.g., \ followed by anything other than a digit or \.

A true return value guarantees that Self::replace() and Self::extract() won’t fail because of a bad rewrite string.

 use re2::{RE2, error::RewriteError};

 let r: RE2 = "asdf".parse()?;
 r.check_rewrite("a").unwrap();
 r.check_rewrite(r"a\0b").unwrap();
 assert_eq!(
   RewriteError {
     message: "Rewrite schema requests 1 matches, but the regexp only has 0 parenthesized subexpressions.".to_string(),
   },
   r.check_rewrite(r"a\0b\1").err().unwrap(),
 );
Source

pub fn vector_rewrite<const N: usize>( &self, out: &mut StringWrapper, rewrite: &str, inputs: [&str; N], ) -> bool

Append the rewrite string, with backslash substitutions from inputs, to string out.

Returns true on success. This method can fail because of a malformed rewrite string. Self::check_rewrite() guarantees that the rewrite will be sucessful.

 let mut sw = re2::string::StringWrapper::blank();
 let r: re2::RE2 = "a(s+)d(f+)".parse()?;
 assert!(r.vector_rewrite(&mut sw, r"bb\1cc\0dd\2", ["asdff", "s", "ff"]));
 assert_eq!(unsafe { sw.as_view().as_str() }, "bbsccasdffddff");

Trait Implementations§

Source§

impl Debug for RE2

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Display for RE2

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Drop for RE2

Deletes the underlying C++ object on drop.

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

impl FromStr for RE2

Source§

type Err = CompileError

The associated error which can be returned from parsing.
Source§

fn from_str(s: &str) -> Result<Self, Self::Err>

Parses a string s to return a value of this type. Read more
Source§

impl Hash for RE2

Source§

fn hash<H>(&self, state: &mut H)
where H: Hasher,

Feeds this value into the given Hasher. Read more
1.3.0 · Source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
Source§

impl Ord for RE2

Source§

fn cmp(&self, other: &Self) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 · Source§

fn max(self, other: Self) -> Self
where Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 · Source§

fn min(self, other: Self) -> Self
where Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 · Source§

fn clamp(self, min: Self, max: Self) -> Self
where Self: Sized,

Restrict a value to a certain interval. Read more
Source§

impl PartialEq for RE2

Source§

fn eq(&self, other: &Self) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl PartialOrd for RE2

Source§

fn partial_cmp(&self, other: &Self) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · Source§

fn lt(&self, other: &Rhs) -> bool

Tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · Source§

fn le(&self, other: &Rhs) -> bool

Tests less than or equal to (for self and other) and is used by the <= operator. Read more
1.0.0 · Source§

fn gt(&self, other: &Rhs) -> bool

Tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · Source§

fn ge(&self, other: &Rhs) -> bool

Tests greater than or equal to (for self and other) and is used by the >= operator. Read more
Source§

impl Eq for RE2

Auto Trait Implementations§

§

impl Freeze for RE2

§

impl RefUnwindSafe for RE2

§

impl Send for RE2

§

impl Sync for RE2

§

impl Unpin for RE2

§

impl UnwindSafe for RE2

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

Source§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.