pub struct Msg(/* private fields */);
Expand description
§Message.
The Msg
struct provides a partitioned, contiguous byte source to hold
arbitrary messages of the “Error: Oh no!” variety. They can be modified
efficiently in place (per-part) and printed to STDOUT
with Msg::print
or STDERR
with Msg::eprint
.
Take a look at examples/msg
, which covers just about all the standard use
cases.
There are two crate feature gates that augment this struct (at the expense of additional dependencies):
fitted
adds theMsg::fitted
method, which returns a byte slice that should fit within a given display width, shrinking the message part of the message as necessary to make room (leaving prefixes and suffixes in tact).timestamps
addsMsg::with_timestamp
andMsg::set_timestamp
methods for adding a local datetime value before the prefix.
Everything else comes stock!
§Examples
use fyi_msg::{Msg, MsgKind};
Msg::new(MsgKind::Success, "You did it!")
.with_newline(true)
.print();
There are a bunch of built-in prefix types, each of which (except
MsgKind::Confirm
) has a corresponding “quick” method on this struct,
like Msg::error
, Msg::success
, etc. See MsgKind
for the full
list. These are equivalent to chaining Msg::new
and Msg::with_newline
for the given type.
Confirmations have a convenience macro instead, confirm
,
that handles all the setup and prompting, returning a simple bool
indicating the yes/noness of the user response.
Again, the examples/msg
demo covers just about all the possibilities.
§Conversion
While Msg
objects are perfectly usable as-is, they can be easily
converted to other formats. They dereference to a byte slice and implement
AsRef<[u8]>
. They also implement AsRef<str>
and
Borrow<str>
for stringy situations. And if you want to consume the struct
into an owned type, there’s also Msg::into_vec
and Msg::into_string
.
Implementations§
source§impl Msg
impl Msg
§Instantiation.
sourcepub fn new<S>(kind: MsgKind, msg: S) -> Self
pub fn new<S>(kind: MsgKind, msg: S) -> Self
§New Message.
This creates a new message with a built-in prefix (which can be
MsgKind::None
, though in that case, Msg::plain
is better).
If your prefix choice is built-in and known at compile time and you
want the message to have a trailing line break, consider using the
corresponding dedicated method instead (Msg::error
, Msg::success
,
etc.), as it will be slightly faster.
§Examples
use fyi_msg::{Msg, MsgKind};
let msg = Msg::new(MsgKind::Info, "This is a message.");
sourcepub fn custom<S>(prefix: S, color: u8, msg: S) -> Self
pub fn custom<S>(prefix: S, color: u8, msg: S) -> Self
§Custom Prefix.
This creates a new message with a user-defined prefix and color. See here for a BASH color code primer.
The prefix you provide will automatically have a ": "
added to the
end, so you should pass “Prefix” rather than “Prefix:”.
If you don’t like the colonics, use Msg::custom_preformatted
instead.
§Examples
use fyi_msg::{Msg, MsgKind};
let msg = Msg::custom("Prefix", 199, "This message has a pink prefix.");
sourcepub fn custom_preformatted<S>(prefix: S, msg: S) -> Self
pub fn custom_preformatted<S>(prefix: S, msg: S) -> Self
§Custom Prefix (Pre-formatted)
Same as Msg::custom
, except no validation or formatting is applied
to the provided prefix. This can be useful in cases where the prefix
requires special spacing, delimiters, or formatting that don’t match
the default format.
It is worth noting that when using this method, you must provide the punctuation and space that will separate the prefix and message parts, otherwise you’ll end up with “prefixmessage” glued together.
§Examples
use fyi_msg::{Msg, MsgKind};
let msg = Msg::custom_preformatted(
"e.g. ",
"This message has an unformatted prefix."
);
source§impl Msg
impl Msg
§Built-ins.
This contains convenience methods for creating a new message with a
built-in prefix and trailing line break. All of the stock kinds are covered
except for MsgKind::Confirm
, which does not have trailing line breaks
in its prompt form, and is kind of weird to use without a prompt.
Speaking of, there is a dedicated confirm
macro, that
renders the message with the right prefix, pops the prompt, and returns the
bool
.
sourcepub fn crunched<S>(msg: S) -> Self
pub fn crunched<S>(msg: S) -> Self
§New Crunched
This is a convenience method to create a thusly prefixed message with a trailing line break.
This is equivalent to combining Msg::new
with Msg::with_newline
,
but optimized for this specific prefix.
§Examples
use fyi_msg::Msg;
Msg::crunched("Hello World").print(); // Crunched: Hello World
sourcepub fn debug<S>(msg: S) -> Self
pub fn debug<S>(msg: S) -> Self
§New Debug
This is a convenience method to create a thusly prefixed message with a trailing line break.
This is equivalent to combining Msg::new
with Msg::with_newline
,
but optimized for this specific prefix.
§Examples
use fyi_msg::Msg;
Msg::debug("Hello World").print(); // Debug: Hello World
sourcepub fn done<S>(msg: S) -> Self
pub fn done<S>(msg: S) -> Self
§New Done
This is a convenience method to create a thusly prefixed message with a trailing line break.
This is equivalent to combining Msg::new
with Msg::with_newline
,
but optimized for this specific prefix.
§Examples
use fyi_msg::Msg;
Msg::done("Hello World").print(); // Done: Hello World
sourcepub fn info<S>(msg: S) -> Self
pub fn info<S>(msg: S) -> Self
§New Info
This is a convenience method to create a thusly prefixed message with a trailing line break.
This is equivalent to combining Msg::new
with Msg::with_newline
,
but optimized for this specific prefix.
§Examples
use fyi_msg::Msg;
Msg::info("Hello World").print(); // Info: Hello World
sourcepub fn error<S>(msg: S) -> Self
pub fn error<S>(msg: S) -> Self
§New Error
This is a convenience method to create a thusly prefixed message with a trailing line break.
This is equivalent to combining Msg::new
with Msg::with_newline
,
but optimized for this specific prefix.
§Examples
use fyi_msg::Msg;
Msg::error("Hello World").print(); // Error: Hello World
sourcepub fn notice<S>(msg: S) -> Self
pub fn notice<S>(msg: S) -> Self
§New Notice
This is a convenience method to create a thusly prefixed message with a trailing line break.
This is equivalent to combining Msg::new
with Msg::with_newline
,
but optimized for this specific prefix.
§Examples
use fyi_msg::Msg;
Msg::notice("Hello World").print(); // Notice: Hello World
sourcepub fn review<S>(msg: S) -> Self
pub fn review<S>(msg: S) -> Self
§New Review
This is a convenience method to create a thusly prefixed message with a trailing line break.
This is equivalent to combining Msg::new
with Msg::with_newline
,
but optimized for this specific prefix.
§Examples
use fyi_msg::Msg;
Msg::review("Hello World").print(); // Review: Hello World
sourcepub fn success<S>(msg: S) -> Self
pub fn success<S>(msg: S) -> Self
§New Success
This is a convenience method to create a thusly prefixed message with a trailing line break.
This is equivalent to combining Msg::new
with Msg::with_newline
,
but optimized for this specific prefix.
§Examples
use fyi_msg::Msg;
Msg::success("Hello World").print(); // Success: Hello World
sourcepub fn task<S>(msg: S) -> Self
pub fn task<S>(msg: S) -> Self
§New Task
This is a convenience method to create a thusly prefixed message with a trailing line break.
This is equivalent to combining Msg::new
with Msg::with_newline
,
but optimized for this specific prefix.
§Examples
use fyi_msg::Msg;
Msg::task("Hello World").print(); // Task: Hello World
sourcepub fn warning<S>(msg: S) -> Self
pub fn warning<S>(msg: S) -> Self
§New Warning
This is a convenience method to create a thusly prefixed message with a trailing line break.
This is equivalent to combining Msg::new
with Msg::with_newline
,
but optimized for this specific prefix.
§Examples
use fyi_msg::Msg;
Msg::warning("Hello World").print(); // Warning: Hello World
source§impl Msg
impl Msg
§Builders.
sourcepub fn with_flags(self, flags: u8) -> Self
pub fn with_flags(self, flags: u8) -> Self
§With Flags.
This can be used to quickly set indentation, timestamps, and/or a trailing line break, but only affirmatively; it will not unset any missing value.
There are 2-3 flags total (depending on whether or not the timestamps
feature has been enabled):
FLAG_INDENT
indents the message one level (four spaces);FLAG_NEWLINE
adds a trailing line break to the end;FLAG_TIMESTAMP
adds a[YYYY-MM-DD HH:MM:SS]
-style timestamp between the indentation and prefix;
§Examples
use fyi_msg::{Msg, FLAG_INDENT, FLAG_NEWLINE};
let msg = Msg::plain("Indented message with trailing line.")
.with_flags(FLAG_INDENT | FLAG_NEWLINE);
sourcepub fn with_indent(self, indent: u8) -> Self
pub fn with_indent(self, indent: u8) -> Self
sourcepub fn with_timestamp(self, timestamp: bool) -> Self
Available on crate feature timestamps
only.
pub fn with_timestamp(self, timestamp: bool) -> Self
timestamps
only.sourcepub fn with_newline(self, newline: bool) -> Self
pub fn with_newline(self, newline: bool) -> Self
§With Linebreak.
Add a trailing linebreak to the end of the message. This is either one or none; calling it multiple times won’t add more lines.
Without a linebreak, Msg::print
is analogous to print!()
,
whereas with a linebreak, it is more like println!()
. (The newline
isn’t limited to print contexts, but that’s mainly what it is for.)
§Examples
use fyi_msg::Msg;
let msg = Msg::plain("This has a trailing newline.")
.with_newline(true);
sourcepub fn with_prefix(self, kind: MsgKind) -> Self
pub fn with_prefix(self, kind: MsgKind) -> Self
sourcepub fn with_custom_prefix<S>(self, prefix: S, color: u8) -> Self
pub fn with_custom_prefix<S>(self, prefix: S, color: u8) -> Self
sourcepub fn with_suffix<S>(self, suffix: S) -> Self
pub fn with_suffix<S>(self, suffix: S) -> Self
§With Suffix.
Set or reset the message suffix.
Unlike prefixes, there are no built-in suffixes, and as such, no assumptions or automatic formatting is applied. The value you set must include any spacing, delimiters, and formatting needed to have it look right. Generally you’ll want to at least have a leading space, otherwise you’ll get “messagesuffix” all glued together.
§Examples
use fyi_msg::Msg;
// A contrived example…
let mut msg = Msg::plain("5,000 matching files were found.")
.with_suffix(" (75%)");
sourcepub fn without_ansi(self) -> Self
pub fn without_ansi(self) -> Self
§Without ANSI Formatting.
Strip any ANSI formatting from the message.
Note that subsequent changes might re-introduce ANSI formatting, so this should generally be the last operation before display.
For unchained usage, see Msg::strip_ansi
.
§Examples
use fyi_msg::Msg;
Msg::info("5,000 matching files were found.")
.without_ansi()
.print();
source§impl Msg
impl Msg
§Setters.
sourcepub fn set_indent(&mut self, indent: u8)
pub fn set_indent(&mut self, indent: u8)
§Set Indentation.
This is the setter companion to the Msg::with_indent
builder
method. Refer to that documentation for more information.
sourcepub fn set_timestamp(&mut self, timestamp: bool)
Available on crate feature timestamps
only.
pub fn set_timestamp(&mut self, timestamp: bool)
timestamps
only.§Set Timestamp.
This is the setter companion to the Msg::with_timestamp
builder
method. Refer to that documentation for more information.
This requires the timestamps
crate feature.
sourcepub fn set_newline(&mut self, newline: bool)
pub fn set_newline(&mut self, newline: bool)
§Set Linebreak.
This is the setter companion to the Msg::with_newline
builder
method. Refer to that documentation for more information.
sourcepub fn set_prefix(&mut self, kind: MsgKind)
pub fn set_prefix(&mut self, kind: MsgKind)
§Set Prefix.
This is the setter companion to the Msg::with_prefix
builder
method. Refer to that documentation for more information.
sourcepub fn set_custom_prefix<S>(&mut self, prefix: S, color: u8)
pub fn set_custom_prefix<S>(&mut self, prefix: S, color: u8)
§Set Custom Prefix.
This is the setter companion to the Msg::with_custom_prefix
builder
method. Refer to that documentation for more information.
sourcepub fn set_msg<S>(&mut self, msg: S)
pub fn set_msg<S>(&mut self, msg: S)
§Set Message.
This is the setter companion to the Msg::with_msg
builder method.
Refer to that documentation for more information.
sourcepub fn set_suffix<S>(&mut self, suffix: S)
pub fn set_suffix<S>(&mut self, suffix: S)
§Set Suffix.
This is the setter companion to the Msg::with_suffix
builder
method. Refer to that documentation for more information.
sourcepub fn strip_ansi(&mut self) -> bool
pub fn strip_ansi(&mut self) -> bool
§Strip ANSI Formatting.
Remove colors, bold, etc. from the message.
Note that subsequent changes might re-introduce ANSI formatting, so this should generally be the last operation before display.
See also Msg::without_ansi
.
Returns true if the content was modified.
source§impl Msg
impl Msg
§Bytes Saved Suffix.
A lot of our own programs crunch data and report the savings as a suffix. This section just adds a quick helper for that.
sourcepub fn with_bytes_saved(self, state: BeforeAfter) -> Self
Available on crate feature progress
only.
pub fn with_bytes_saved(self, state: BeforeAfter) -> Self
progress
only.§Bytes Saved Suffix.
A lot of our own programs using this lib crunch data and report the savings as a suffix. This method just provides a quick way to generate that.
source§impl Msg
impl Msg
§Conversion.
sourcepub fn as_bytes(&self) -> &[u8] ⓘ
pub fn as_bytes(&self) -> &[u8] ⓘ
§As Bytes.
Return the entire message as a byte slice. Alternatively, you could
dereference the struct or use Msg::as_ref
.
sourcepub fn as_str(&self) -> &str
pub fn as_str(&self) -> &str
§As Str.
Return the entire message as a string slice. Alternatively, you could
use Msg::as_ref
or Msg::borrow
.
sourcepub fn into_string(self) -> String
pub fn into_string(self) -> String
§Into String.
Consume the message, returning an owned string.
sourcepub fn fitted(&self, width: usize) -> Cow<'_, [u8]>
Available on crate feature fitted
only.
pub fn fitted(&self, width: usize) -> Cow<'_, [u8]>
fitted
only.§Capped Width Slice.
This will return a byte string that should fit a given console width if
printed. This is subject to the usual disclaimers of “Unicode is
monstrously complicated…”, but it does its best, and will be more
accurate than simply chopping to the Msg::len
.
Only the user-defined message portion of the Msg
will be trimmed for
space. Prefixes, suffixes, the trailing newline, etc., are left
unchanged.
If the message cannot be made to fit, an empty byte string is returned.
This requires the fitted
crate feature.
source§impl Msg
impl Msg
§Printing.
sourcepub fn print(&self)
pub fn print(&self)
§Locked Print to STDOUT
.
This is equivalent to calling either print!()
or println()
depending on whether or not a trailing linebreak has been set.
In fact, Msg
does implement Display
, so you could do just that,
but this method avoids the allocation penalty.
§Examples
use fyi_msg::Msg;
Msg::plain("Hello world!").with_newline(true).print();
sourcepub fn eprint(&self)
pub fn eprint(&self)
§Locked Print to STDERR
.
This is equivalent to calling either eprint!()
or eprintln()
depending on whether or not a trailing linebreak has been set.
In fact, Msg
does implement Display
, so you could do just that,
but this method avoids the allocation penalty.
§Examples
use fyi_msg::Msg;
Msg::error("Oh no!").with_newline(true).eprint();
sourcepub fn die(&self, code: i32) -> !
pub fn die(&self, code: i32) -> !
§Print and Die.
This is a convenience method for printing a message to STDERR
and
terminating the thread with the provided exit code. Generally you’d
want to pass a non-zero value here.
Be careful calling this method in parallel contexts as it will only stop the current thread, not the entire program execution.
§Examples
use fyi_msg::Msg;
Msg::error("Oh no!").with_newline(true).die(1);
unreachable!();
sourcepub fn prompt(&self) -> bool
pub fn prompt(&self) -> bool
§Prompt.
This produces a simple y/N input prompt, requiring the user type “Y” or
“N” to proceed. Positive values return true
, negative values return
false
. The default (if the user just hits <enter>) is “N”.
Note: the prompt normalizes the suffix and newline parts for display. If your message contains these parts, they will be ignored by the prompt action, but will be retained in the original struct should you wish to use it in some other manner later in your code.
Every example in the docs shows this in combination with the built-in
MsgKind::Confirm
prefix, but this can be called on any Msg
object. The main thing worth noting is the suffix portion is
overridden for display, so don’t bother putting anything there.
§Example
use fyi_msg::{confirm, Msg, MsgKind};
// The manual way:
if Msg::new(MsgKind::Confirm, "Do you like chickens?").prompt() {
println!("That's great! They like you too!");
}
// The macro way:
if confirm!("Do you like chickens?") {
println!("That's great! They like you too!");
}
sourcepub fn prompt_with_default(&self, default: bool) -> bool
pub fn prompt_with_default(&self, default: bool) -> bool
§Prompt (w/ Default).
This is identical to Msg::prompt
, except you specify the default
return value — true
for Yes, false
for No — that is returned when
the user just hits <ENTER>
.
sourcepub fn eprompt(&self) -> bool
pub fn eprompt(&self) -> bool
§Prompt (STDERR).
Same as Msg::prompt
, but printed to STDERR instead of STDOUT.
sourcepub fn eprompt_with_default(&self, default: bool) -> bool
pub fn eprompt_with_default(&self, default: bool) -> bool
§Prompt (w/ Default, STDERR).
Same as Msg::prompt_with_default
, but printed to STDERR instead of
STDOUT.
Methods from Deref<Target = [u8]>§
1.0.0 · sourcepub fn is_empty(&self) -> bool
pub fn is_empty(&self) -> bool
Returns true
if the slice has a length of 0.
§Examples
let a = [1, 2, 3];
assert!(!a.is_empty());
let b: &[i32] = &[];
assert!(b.is_empty());
1.0.0 · sourcepub fn first(&self) -> Option<&T>
pub fn first(&self) -> Option<&T>
Returns the first element of the slice, or None
if it is empty.
§Examples
let v = [10, 40, 30];
assert_eq!(Some(&10), v.first());
let w: &[i32] = &[];
assert_eq!(None, w.first());
1.5.0 · sourcepub fn split_first(&self) -> Option<(&T, &[T])>
pub fn split_first(&self) -> Option<(&T, &[T])>
Returns the first and all the rest of the elements of the slice, or None
if it is empty.
§Examples
let x = &[0, 1, 2];
if let Some((first, elements)) = x.split_first() {
assert_eq!(first, &0);
assert_eq!(elements, &[1, 2]);
}
1.5.0 · sourcepub fn split_last(&self) -> Option<(&T, &[T])>
pub fn split_last(&self) -> Option<(&T, &[T])>
Returns the last and all the rest of the elements of the slice, or None
if it is empty.
§Examples
let x = &[0, 1, 2];
if let Some((last, elements)) = x.split_last() {
assert_eq!(last, &2);
assert_eq!(elements, &[0, 1]);
}
1.0.0 · sourcepub fn last(&self) -> Option<&T>
pub fn last(&self) -> Option<&T>
Returns the last element of the slice, or None
if it is empty.
§Examples
let v = [10, 40, 30];
assert_eq!(Some(&30), v.last());
let w: &[i32] = &[];
assert_eq!(None, w.last());
1.77.0 · sourcepub fn first_chunk<const N: usize>(&self) -> Option<&[T; N]>
pub fn first_chunk<const N: usize>(&self) -> Option<&[T; N]>
Return an array reference to the first N
items in the slice.
If the slice is not at least N
in length, this will return None
.
§Examples
let u = [10, 40, 30];
assert_eq!(Some(&[10, 40]), u.first_chunk::<2>());
let v: &[i32] = &[10];
assert_eq!(None, v.first_chunk::<2>());
let w: &[i32] = &[];
assert_eq!(Some(&[]), w.first_chunk::<0>());
1.77.0 · sourcepub fn split_first_chunk<const N: usize>(&self) -> Option<(&[T; N], &[T])>
pub fn split_first_chunk<const N: usize>(&self) -> Option<(&[T; N], &[T])>
Return an array reference to the first N
items in the slice and the remaining slice.
If the slice is not at least N
in length, this will return None
.
§Examples
let x = &[0, 1, 2];
if let Some((first, elements)) = x.split_first_chunk::<2>() {
assert_eq!(first, &[0, 1]);
assert_eq!(elements, &[2]);
}
assert_eq!(None, x.split_first_chunk::<4>());
1.77.0 · sourcepub fn split_last_chunk<const N: usize>(&self) -> Option<(&[T], &[T; N])>
pub fn split_last_chunk<const N: usize>(&self) -> Option<(&[T], &[T; N])>
Return an array reference to the last N
items in the slice and the remaining slice.
If the slice is not at least N
in length, this will return None
.
§Examples
let x = &[0, 1, 2];
if let Some((elements, last)) = x.split_last_chunk::<2>() {
assert_eq!(elements, &[0]);
assert_eq!(last, &[1, 2]);
}
assert_eq!(None, x.split_last_chunk::<4>());
1.77.0 · sourcepub fn last_chunk<const N: usize>(&self) -> Option<&[T; N]>
pub fn last_chunk<const N: usize>(&self) -> Option<&[T; N]>
Return an array reference to the last N
items in the slice.
If the slice is not at least N
in length, this will return None
.
§Examples
let u = [10, 40, 30];
assert_eq!(Some(&[40, 30]), u.last_chunk::<2>());
let v: &[i32] = &[10];
assert_eq!(None, v.last_chunk::<2>());
let w: &[i32] = &[];
assert_eq!(Some(&[]), w.last_chunk::<0>());
1.0.0 · sourcepub fn get<I>(&self, index: I) -> Option<&<I as SliceIndex<[T]>>::Output>where
I: SliceIndex<[T]>,
pub fn get<I>(&self, index: I) -> Option<&<I as SliceIndex<[T]>>::Output>where
I: SliceIndex<[T]>,
Returns a reference to an element or subslice depending on the type of index.
- If given a position, returns a reference to the element at that
position or
None
if out of bounds. - If given a range, returns the subslice corresponding to that range,
or
None
if out of bounds.
§Examples
let v = [10, 40, 30];
assert_eq!(Some(&40), v.get(1));
assert_eq!(Some(&[10, 40][..]), v.get(0..2));
assert_eq!(None, v.get(3));
assert_eq!(None, v.get(0..4));
1.0.0 · sourcepub unsafe fn get_unchecked<I>(
&self,
index: I
) -> &<I as SliceIndex<[T]>>::Outputwhere
I: SliceIndex<[T]>,
pub unsafe fn get_unchecked<I>(
&self,
index: I
) -> &<I as SliceIndex<[T]>>::Outputwhere
I: SliceIndex<[T]>,
Returns a reference to an element or subslice, without doing bounds checking.
For a safe alternative see get
.
§Safety
Calling this method with an out-of-bounds index is undefined behavior even if the resulting reference is not used.
You can think of this like .get(index).unwrap_unchecked()
. It’s UB
to call .get_unchecked(len)
, even if you immediately convert to a
pointer. And it’s UB to call .get_unchecked(..len + 1)
,
.get_unchecked(..=len)
, or similar.
§Examples
let x = &[1, 2, 4];
unsafe {
assert_eq!(x.get_unchecked(1), &2);
}
1.0.0 · sourcepub fn as_ptr(&self) -> *const T
pub fn as_ptr(&self) -> *const T
Returns a raw pointer to the slice’s buffer.
The caller must ensure that the slice outlives the pointer this function returns, or else it will end up pointing to garbage.
The caller must also ensure that the memory the pointer (non-transitively) points to
is never written to (except inside an UnsafeCell
) using this pointer or any pointer
derived from it. If you need to mutate the contents of the slice, use as_mut_ptr
.
Modifying the container referenced by this slice may cause its buffer to be reallocated, which would also make any pointers to it invalid.
§Examples
let x = &[1, 2, 4];
let x_ptr = x.as_ptr();
unsafe {
for i in 0..x.len() {
assert_eq!(x.get_unchecked(i), &*x_ptr.add(i));
}
}
1.48.0 · sourcepub fn as_ptr_range(&self) -> Range<*const T>
pub fn as_ptr_range(&self) -> Range<*const T>
Returns the two raw pointers spanning the slice.
The returned range is half-open, which means that the end pointer points one past the last element of the slice. This way, an empty slice is represented by two equal pointers, and the difference between the two pointers represents the size of the slice.
See as_ptr
for warnings on using these pointers. The end pointer
requires extra caution, as it does not point to a valid element in the
slice.
This function is useful for interacting with foreign interfaces which use two pointers to refer to a range of elements in memory, as is common in C++.
It can also be useful to check if a pointer to an element refers to an element of this slice:
let a = [1, 2, 3];
let x = &a[1] as *const _;
let y = &5 as *const _;
assert!(a.as_ptr_range().contains(&x));
assert!(!a.as_ptr_range().contains(&y));
1.0.0 · sourcepub fn iter(&self) -> Iter<'_, T>
pub fn iter(&self) -> Iter<'_, T>
Returns an iterator over the slice.
The iterator yields all items from start to end.
§Examples
let x = &[1, 2, 4];
let mut iterator = x.iter();
assert_eq!(iterator.next(), Some(&1));
assert_eq!(iterator.next(), Some(&2));
assert_eq!(iterator.next(), Some(&4));
assert_eq!(iterator.next(), None);
1.0.0 · sourcepub fn windows(&self, size: usize) -> Windows<'_, T>
pub fn windows(&self, size: usize) -> Windows<'_, T>
Returns an iterator over all contiguous windows of length
size
. The windows overlap. If the slice is shorter than
size
, the iterator returns no values.
§Panics
Panics if size
is 0.
§Examples
let slice = ['l', 'o', 'r', 'e', 'm'];
let mut iter = slice.windows(3);
assert_eq!(iter.next().unwrap(), &['l', 'o', 'r']);
assert_eq!(iter.next().unwrap(), &['o', 'r', 'e']);
assert_eq!(iter.next().unwrap(), &['r', 'e', 'm']);
assert!(iter.next().is_none());
If the slice is shorter than size
:
let slice = ['f', 'o', 'o'];
let mut iter = slice.windows(4);
assert!(iter.next().is_none());
There’s no windows_mut
, as that existing would let safe code violate the
“only one &mut
at a time to the same thing” rule. However, you can sometimes
use Cell::as_slice_of_cells
in
conjunction with windows
to accomplish something similar:
use std::cell::Cell;
let mut array = ['R', 'u', 's', 't', ' ', '2', '0', '1', '5'];
let slice = &mut array[..];
let slice_of_cells: &[Cell<char>] = Cell::from_mut(slice).as_slice_of_cells();
for w in slice_of_cells.windows(3) {
Cell::swap(&w[0], &w[2]);
}
assert_eq!(array, ['s', 't', ' ', '2', '0', '1', '5', 'u', 'R']);
1.0.0 · sourcepub fn chunks(&self, chunk_size: usize) -> Chunks<'_, T>
pub fn chunks(&self, chunk_size: usize) -> Chunks<'_, T>
Returns an iterator over chunk_size
elements of the slice at a time, starting at the
beginning of the slice.
The chunks are slices and do not overlap. If chunk_size
does not divide the length of the
slice, then the last chunk will not have length chunk_size
.
See chunks_exact
for a variant of this iterator that returns chunks of always exactly
chunk_size
elements, and rchunks
for the same iterator but starting at the end of the
slice.
§Panics
Panics if chunk_size
is 0.
§Examples
let slice = ['l', 'o', 'r', 'e', 'm'];
let mut iter = slice.chunks(2);
assert_eq!(iter.next().unwrap(), &['l', 'o']);
assert_eq!(iter.next().unwrap(), &['r', 'e']);
assert_eq!(iter.next().unwrap(), &['m']);
assert!(iter.next().is_none());
1.31.0 · sourcepub fn chunks_exact(&self, chunk_size: usize) -> ChunksExact<'_, T>
pub fn chunks_exact(&self, chunk_size: usize) -> ChunksExact<'_, T>
Returns an iterator over chunk_size
elements of the slice at a time, starting at the
beginning of the slice.
The chunks are slices and do not overlap. If chunk_size
does not divide the length of the
slice, then the last up to chunk_size-1
elements will be omitted and can be retrieved
from the remainder
function of the iterator.
Due to each chunk having exactly chunk_size
elements, the compiler can often optimize the
resulting code better than in the case of chunks
.
See chunks
for a variant of this iterator that also returns the remainder as a smaller
chunk, and rchunks_exact
for the same iterator but starting at the end of the slice.
§Panics
Panics if chunk_size
is 0.
§Examples
let slice = ['l', 'o', 'r', 'e', 'm'];
let mut iter = slice.chunks_exact(2);
assert_eq!(iter.next().unwrap(), &['l', 'o']);
assert_eq!(iter.next().unwrap(), &['r', 'e']);
assert!(iter.next().is_none());
assert_eq!(iter.remainder(), &['m']);
sourcepub unsafe fn as_chunks_unchecked<const N: usize>(&self) -> &[[T; N]]
🔬This is a nightly-only experimental API. (slice_as_chunks
)
pub unsafe fn as_chunks_unchecked<const N: usize>(&self) -> &[[T; N]]
slice_as_chunks
)Splits the slice into a slice of N
-element arrays,
assuming that there’s no remainder.
§Safety
This may only be called when
- The slice splits exactly into
N
-element chunks (akaself.len() % N == 0
). N != 0
.
§Examples
#![feature(slice_as_chunks)]
let slice: &[char] = &['l', 'o', 'r', 'e', 'm', '!'];
let chunks: &[[char; 1]] =
// SAFETY: 1-element chunks never have remainder
unsafe { slice.as_chunks_unchecked() };
assert_eq!(chunks, &[['l'], ['o'], ['r'], ['e'], ['m'], ['!']]);
let chunks: &[[char; 3]] =
// SAFETY: The slice length (6) is a multiple of 3
unsafe { slice.as_chunks_unchecked() };
assert_eq!(chunks, &[['l', 'o', 'r'], ['e', 'm', '!']]);
// These would be unsound:
// let chunks: &[[_; 5]] = slice.as_chunks_unchecked() // The slice length is not a multiple of 5
// let chunks: &[[_; 0]] = slice.as_chunks_unchecked() // Zero-length chunks are never allowed
sourcepub fn as_chunks<const N: usize>(&self) -> (&[[T; N]], &[T])
🔬This is a nightly-only experimental API. (slice_as_chunks
)
pub fn as_chunks<const N: usize>(&self) -> (&[[T; N]], &[T])
slice_as_chunks
)Splits the slice into a slice of N
-element arrays,
starting at the beginning of the slice,
and a remainder slice with length strictly less than N
.
§Panics
Panics if N
is 0. This check will most probably get changed to a compile time
error before this method gets stabilized.
§Examples
#![feature(slice_as_chunks)]
let slice = ['l', 'o', 'r', 'e', 'm'];
let (chunks, remainder) = slice.as_chunks();
assert_eq!(chunks, &[['l', 'o'], ['r', 'e']]);
assert_eq!(remainder, &['m']);
If you expect the slice to be an exact multiple, you can combine
let
-else
with an empty slice pattern:
#![feature(slice_as_chunks)]
let slice = ['R', 'u', 's', 't'];
let (chunks, []) = slice.as_chunks::<2>() else {
panic!("slice didn't have even length")
};
assert_eq!(chunks, &[['R', 'u'], ['s', 't']]);
sourcepub fn as_rchunks<const N: usize>(&self) -> (&[T], &[[T; N]])
🔬This is a nightly-only experimental API. (slice_as_chunks
)
pub fn as_rchunks<const N: usize>(&self) -> (&[T], &[[T; N]])
slice_as_chunks
)Splits the slice into a slice of N
-element arrays,
starting at the end of the slice,
and a remainder slice with length strictly less than N
.
§Panics
Panics if N
is 0. This check will most probably get changed to a compile time
error before this method gets stabilized.
§Examples
#![feature(slice_as_chunks)]
let slice = ['l', 'o', 'r', 'e', 'm'];
let (remainder, chunks) = slice.as_rchunks();
assert_eq!(remainder, &['l']);
assert_eq!(chunks, &[['o', 'r'], ['e', 'm']]);
sourcepub fn array_chunks<const N: usize>(&self) -> ArrayChunks<'_, T, N>
🔬This is a nightly-only experimental API. (array_chunks
)
pub fn array_chunks<const N: usize>(&self) -> ArrayChunks<'_, T, N>
array_chunks
)Returns an iterator over N
elements of the slice at a time, starting at the
beginning of the slice.
The chunks are array references and do not overlap. If N
does not divide the
length of the slice, then the last up to N-1
elements will be omitted and can be
retrieved from the remainder
function of the iterator.
This method is the const generic equivalent of chunks_exact
.
§Panics
Panics if N
is 0. This check will most probably get changed to a compile time
error before this method gets stabilized.
§Examples
#![feature(array_chunks)]
let slice = ['l', 'o', 'r', 'e', 'm'];
let mut iter = slice.array_chunks();
assert_eq!(iter.next().unwrap(), &['l', 'o']);
assert_eq!(iter.next().unwrap(), &['r', 'e']);
assert!(iter.next().is_none());
assert_eq!(iter.remainder(), &['m']);
sourcepub fn array_windows<const N: usize>(&self) -> ArrayWindows<'_, T, N>
🔬This is a nightly-only experimental API. (array_windows
)
pub fn array_windows<const N: usize>(&self) -> ArrayWindows<'_, T, N>
array_windows
)Returns an iterator over overlapping windows of N
elements of a slice,
starting at the beginning of the slice.
This is the const generic equivalent of windows
.
If N
is greater than the size of the slice, it will return no windows.
§Panics
Panics if N
is 0. This check will most probably get changed to a compile time
error before this method gets stabilized.
§Examples
#![feature(array_windows)]
let slice = [0, 1, 2, 3];
let mut iter = slice.array_windows();
assert_eq!(iter.next().unwrap(), &[0, 1]);
assert_eq!(iter.next().unwrap(), &[1, 2]);
assert_eq!(iter.next().unwrap(), &[2, 3]);
assert!(iter.next().is_none());
1.31.0 · sourcepub fn rchunks(&self, chunk_size: usize) -> RChunks<'_, T>
pub fn rchunks(&self, chunk_size: usize) -> RChunks<'_, T>
Returns an iterator over chunk_size
elements of the slice at a time, starting at the end
of the slice.
The chunks are slices and do not overlap. If chunk_size
does not divide the length of the
slice, then the last chunk will not have length chunk_size
.
See rchunks_exact
for a variant of this iterator that returns chunks of always exactly
chunk_size
elements, and chunks
for the same iterator but starting at the beginning
of the slice.
§Panics
Panics if chunk_size
is 0.
§Examples
let slice = ['l', 'o', 'r', 'e', 'm'];
let mut iter = slice.rchunks(2);
assert_eq!(iter.next().unwrap(), &['e', 'm']);
assert_eq!(iter.next().unwrap(), &['o', 'r']);
assert_eq!(iter.next().unwrap(), &['l']);
assert!(iter.next().is_none());
1.31.0 · sourcepub fn rchunks_exact(&self, chunk_size: usize) -> RChunksExact<'_, T>
pub fn rchunks_exact(&self, chunk_size: usize) -> RChunksExact<'_, T>
Returns an iterator over chunk_size
elements of the slice at a time, starting at the
end of the slice.
The chunks are slices and do not overlap. If chunk_size
does not divide the length of the
slice, then the last up to chunk_size-1
elements will be omitted and can be retrieved
from the remainder
function of the iterator.
Due to each chunk having exactly chunk_size
elements, the compiler can often optimize the
resulting code better than in the case of rchunks
.
See rchunks
for a variant of this iterator that also returns the remainder as a smaller
chunk, and chunks_exact
for the same iterator but starting at the beginning of the
slice.
§Panics
Panics if chunk_size
is 0.
§Examples
let slice = ['l', 'o', 'r', 'e', 'm'];
let mut iter = slice.rchunks_exact(2);
assert_eq!(iter.next().unwrap(), &['e', 'm']);
assert_eq!(iter.next().unwrap(), &['o', 'r']);
assert!(iter.next().is_none());
assert_eq!(iter.remainder(), &['l']);
1.77.0 · sourcepub fn chunk_by<F>(&self, pred: F) -> ChunkBy<'_, T, F>
pub fn chunk_by<F>(&self, pred: F) -> ChunkBy<'_, T, F>
Returns an iterator over the slice producing non-overlapping runs of elements using the predicate to separate them.
The predicate is called for every pair of consecutive elements,
meaning that it is called on slice[0]
and slice[1]
,
followed by slice[1]
and slice[2]
, and so on.
§Examples
let slice = &[1, 1, 1, 3, 3, 2, 2, 2];
let mut iter = slice.chunk_by(|a, b| a == b);
assert_eq!(iter.next(), Some(&[1, 1, 1][..]));
assert_eq!(iter.next(), Some(&[3, 3][..]));
assert_eq!(iter.next(), Some(&[2, 2, 2][..]));
assert_eq!(iter.next(), None);
This method can be used to extract the sorted subslices:
let slice = &[1, 1, 2, 3, 2, 3, 2, 3, 4];
let mut iter = slice.chunk_by(|a, b| a <= b);
assert_eq!(iter.next(), Some(&[1, 1, 2, 3][..]));
assert_eq!(iter.next(), Some(&[2, 3][..]));
assert_eq!(iter.next(), Some(&[2, 3, 4][..]));
assert_eq!(iter.next(), None);
1.0.0 · sourcepub fn split_at(&self, mid: usize) -> (&[T], &[T])
pub fn split_at(&self, mid: usize) -> (&[T], &[T])
Divides one slice into two at an index.
The first will contain all indices from [0, mid)
(excluding
the index mid
itself) and the second will contain all
indices from [mid, len)
(excluding the index len
itself).
§Panics
Panics if mid > len
. For a non-panicking alternative see
split_at_checked
.
§Examples
let v = [1, 2, 3, 4, 5, 6];
{
let (left, right) = v.split_at(0);
assert_eq!(left, []);
assert_eq!(right, [1, 2, 3, 4, 5, 6]);
}
{
let (left, right) = v.split_at(2);
assert_eq!(left, [1, 2]);
assert_eq!(right, [3, 4, 5, 6]);
}
{
let (left, right) = v.split_at(6);
assert_eq!(left, [1, 2, 3, 4, 5, 6]);
assert_eq!(right, []);
}
sourcepub unsafe fn split_at_unchecked(&self, mid: usize) -> (&[T], &[T])
🔬This is a nightly-only experimental API. (slice_split_at_unchecked
)
pub unsafe fn split_at_unchecked(&self, mid: usize) -> (&[T], &[T])
slice_split_at_unchecked
)Divides one slice into two at an index, without doing bounds checking.
The first will contain all indices from [0, mid)
(excluding
the index mid
itself) and the second will contain all
indices from [mid, len)
(excluding the index len
itself).
For a safe alternative see split_at
.
§Safety
Calling this method with an out-of-bounds index is undefined behavior
even if the resulting reference is not used. The caller has to ensure that
0 <= mid <= self.len()
.
§Examples
#![feature(slice_split_at_unchecked)]
let v = [1, 2, 3, 4, 5, 6];
unsafe {
let (left, right) = v.split_at_unchecked(0);
assert_eq!(left, []);
assert_eq!(right, [1, 2, 3, 4, 5, 6]);
}
unsafe {
let (left, right) = v.split_at_unchecked(2);
assert_eq!(left, [1, 2]);
assert_eq!(right, [3, 4, 5, 6]);
}
unsafe {
let (left, right) = v.split_at_unchecked(6);
assert_eq!(left, [1, 2, 3, 4, 5, 6]);
assert_eq!(right, []);
}
sourcepub fn split_at_checked(&self, mid: usize) -> Option<(&[T], &[T])>
🔬This is a nightly-only experimental API. (split_at_checked
)
pub fn split_at_checked(&self, mid: usize) -> Option<(&[T], &[T])>
split_at_checked
)Divides one slice into two at an index, returning None
if the slice is
too short.
If mid ≤ len
returns a pair of slices where the first will contain all
indices from [0, mid)
(excluding the index mid
itself) and the
second will contain all indices from [mid, len)
(excluding the index
len
itself).
Otherwise, if mid > len
, returns None
.
§Examples
#![feature(split_at_checked)]
let v = [1, -2, 3, -4, 5, -6];
{
let (left, right) = v.split_at_checked(0).unwrap();
assert_eq!(left, []);
assert_eq!(right, [1, -2, 3, -4, 5, -6]);
}
{
let (left, right) = v.split_at_checked(2).unwrap();
assert_eq!(left, [1, -2]);
assert_eq!(right, [3, -4, 5, -6]);
}
{
let (left, right) = v.split_at_checked(6).unwrap();
assert_eq!(left, [1, -2, 3, -4, 5, -6]);
assert_eq!(right, []);
}
assert_eq!(None, v.split_at_checked(7));
1.0.0 · sourcepub fn split<F>(&self, pred: F) -> Split<'_, T, F>
pub fn split<F>(&self, pred: F) -> Split<'_, T, F>
Returns an iterator over subslices separated by elements that match
pred
. The matched element is not contained in the subslices.
§Examples
let slice = [10, 40, 33, 20];
let mut iter = slice.split(|num| num % 3 == 0);
assert_eq!(iter.next().unwrap(), &[10, 40]);
assert_eq!(iter.next().unwrap(), &[20]);
assert!(iter.next().is_none());
If the first element is matched, an empty slice will be the first item returned by the iterator. Similarly, if the last element in the slice is matched, an empty slice will be the last item returned by the iterator:
let slice = [10, 40, 33];
let mut iter = slice.split(|num| num % 3 == 0);
assert_eq!(iter.next().unwrap(), &[10, 40]);
assert_eq!(iter.next().unwrap(), &[]);
assert!(iter.next().is_none());
If two matched elements are directly adjacent, an empty slice will be present between them:
let slice = [10, 6, 33, 20];
let mut iter = slice.split(|num| num % 3 == 0);
assert_eq!(iter.next().unwrap(), &[10]);
assert_eq!(iter.next().unwrap(), &[]);
assert_eq!(iter.next().unwrap(), &[20]);
assert!(iter.next().is_none());
1.51.0 · sourcepub fn split_inclusive<F>(&self, pred: F) -> SplitInclusive<'_, T, F>
pub fn split_inclusive<F>(&self, pred: F) -> SplitInclusive<'_, T, F>
Returns an iterator over subslices separated by elements that match
pred
. The matched element is contained in the end of the previous
subslice as a terminator.
§Examples
let slice = [10, 40, 33, 20];
let mut iter = slice.split_inclusive(|num| num % 3 == 0);
assert_eq!(iter.next().unwrap(), &[10, 40, 33]);
assert_eq!(iter.next().unwrap(), &[20]);
assert!(iter.next().is_none());
If the last element of the slice is matched, that element will be considered the terminator of the preceding slice. That slice will be the last item returned by the iterator.
let slice = [3, 10, 40, 33];
let mut iter = slice.split_inclusive(|num| num % 3 == 0);
assert_eq!(iter.next().unwrap(), &[3]);
assert_eq!(iter.next().unwrap(), &[10, 40, 33]);
assert!(iter.next().is_none());
1.27.0 · sourcepub fn rsplit<F>(&self, pred: F) -> RSplit<'_, T, F>
pub fn rsplit<F>(&self, pred: F) -> RSplit<'_, T, F>
Returns an iterator over subslices separated by elements that match
pred
, starting at the end of the slice and working backwards.
The matched element is not contained in the subslices.
§Examples
let slice = [11, 22, 33, 0, 44, 55];
let mut iter = slice.rsplit(|num| *num == 0);
assert_eq!(iter.next().unwrap(), &[44, 55]);
assert_eq!(iter.next().unwrap(), &[11, 22, 33]);
assert_eq!(iter.next(), None);
As with split()
, if the first or last element is matched, an empty
slice will be the first (or last) item returned by the iterator.
let v = &[0, 1, 1, 2, 3, 5, 8];
let mut it = v.rsplit(|n| *n % 2 == 0);
assert_eq!(it.next().unwrap(), &[]);
assert_eq!(it.next().unwrap(), &[3, 5]);
assert_eq!(it.next().unwrap(), &[1, 1]);
assert_eq!(it.next().unwrap(), &[]);
assert_eq!(it.next(), None);
1.0.0 · sourcepub fn splitn<F>(&self, n: usize, pred: F) -> SplitN<'_, T, F>
pub fn splitn<F>(&self, n: usize, pred: F) -> SplitN<'_, T, F>
Returns an iterator over subslices separated by elements that match
pred
, limited to returning at most n
items. The matched element is
not contained in the subslices.
The last element returned, if any, will contain the remainder of the slice.
§Examples
Print the slice split once by numbers divisible by 3 (i.e., [10, 40]
,
[20, 60, 50]
):
let v = [10, 40, 30, 20, 60, 50];
for group in v.splitn(2, |num| *num % 3 == 0) {
println!("{group:?}");
}
1.0.0 · sourcepub fn rsplitn<F>(&self, n: usize, pred: F) -> RSplitN<'_, T, F>
pub fn rsplitn<F>(&self, n: usize, pred: F) -> RSplitN<'_, T, F>
Returns an iterator over subslices separated by elements that match
pred
limited to returning at most n
items. This starts at the end of
the slice and works backwards. The matched element is not contained in
the subslices.
The last element returned, if any, will contain the remainder of the slice.
§Examples
Print the slice split once, starting from the end, by numbers divisible
by 3 (i.e., [50]
, [10, 40, 30, 20]
):
let v = [10, 40, 30, 20, 60, 50];
for group in v.rsplitn(2, |num| *num % 3 == 0) {
println!("{group:?}");
}
sourcepub fn split_once<F>(&self, pred: F) -> Option<(&[T], &[T])>
🔬This is a nightly-only experimental API. (slice_split_once
)
pub fn split_once<F>(&self, pred: F) -> Option<(&[T], &[T])>
slice_split_once
)Splits the slice on the first element that matches the specified predicate.
If any matching elements are present in the slice, returns the prefix
before the match and suffix after. The matching element itself is not
included. If no elements match, returns None
.
§Examples
#![feature(slice_split_once)]
let s = [1, 2, 3, 2, 4];
assert_eq!(s.split_once(|&x| x == 2), Some((
&[1][..],
&[3, 2, 4][..]
)));
assert_eq!(s.split_once(|&x| x == 0), None);
sourcepub fn rsplit_once<F>(&self, pred: F) -> Option<(&[T], &[T])>
🔬This is a nightly-only experimental API. (slice_split_once
)
pub fn rsplit_once<F>(&self, pred: F) -> Option<(&[T], &[T])>
slice_split_once
)Splits the slice on the last element that matches the specified predicate.
If any matching elements are present in the slice, returns the prefix
before the match and suffix after. The matching element itself is not
included. If no elements match, returns None
.
§Examples
#![feature(slice_split_once)]
let s = [1, 2, 3, 2, 4];
assert_eq!(s.rsplit_once(|&x| x == 2), Some((
&[1, 2, 3][..],
&[4][..]
)));
assert_eq!(s.rsplit_once(|&x| x == 0), None);
1.0.0 · sourcepub fn contains(&self, x: &T) -> boolwhere
T: PartialEq,
pub fn contains(&self, x: &T) -> boolwhere
T: PartialEq,
Returns true
if the slice contains an element with the given value.
This operation is O(n).
Note that if you have a sorted slice, binary_search
may be faster.
§Examples
let v = [10, 40, 30];
assert!(v.contains(&30));
assert!(!v.contains(&50));
If you do not have a &T
, but some other value that you can compare
with one (for example, String
implements PartialEq<str>
), you can
use iter().any
:
let v = [String::from("hello"), String::from("world")]; // slice of `String`
assert!(v.iter().any(|e| e == "hello")); // search with `&str`
assert!(!v.iter().any(|e| e == "hi"));
1.0.0 · sourcepub fn starts_with(&self, needle: &[T]) -> boolwhere
T: PartialEq,
pub fn starts_with(&self, needle: &[T]) -> boolwhere
T: PartialEq,
Returns true
if needle
is a prefix of the slice or equal to the slice.
§Examples
let v = [10, 40, 30];
assert!(v.starts_with(&[10]));
assert!(v.starts_with(&[10, 40]));
assert!(v.starts_with(&v));
assert!(!v.starts_with(&[50]));
assert!(!v.starts_with(&[10, 50]));
Always returns true
if needle
is an empty slice:
let v = &[10, 40, 30];
assert!(v.starts_with(&[]));
let v: &[u8] = &[];
assert!(v.starts_with(&[]));
1.0.0 · sourcepub fn ends_with(&self, needle: &[T]) -> boolwhere
T: PartialEq,
pub fn ends_with(&self, needle: &[T]) -> boolwhere
T: PartialEq,
Returns true
if needle
is a suffix of the slice or equal to the slice.
§Examples
let v = [10, 40, 30];
assert!(v.ends_with(&[30]));
assert!(v.ends_with(&[40, 30]));
assert!(v.ends_with(&v));
assert!(!v.ends_with(&[50]));
assert!(!v.ends_with(&[50, 30]));
Always returns true
if needle
is an empty slice:
let v = &[10, 40, 30];
assert!(v.ends_with(&[]));
let v: &[u8] = &[];
assert!(v.ends_with(&[]));
1.51.0 · sourcepub fn strip_prefix<P>(&self, prefix: &P) -> Option<&[T]>
pub fn strip_prefix<P>(&self, prefix: &P) -> Option<&[T]>
Returns a subslice with the prefix removed.
If the slice starts with prefix
, returns the subslice after the prefix, wrapped in Some
.
If prefix
is empty, simply returns the original slice. If prefix
is equal to the
original slice, returns an empty slice.
If the slice does not start with prefix
, returns None
.
§Examples
let v = &[10, 40, 30];
assert_eq!(v.strip_prefix(&[10]), Some(&[40, 30][..]));
assert_eq!(v.strip_prefix(&[10, 40]), Some(&[30][..]));
assert_eq!(v.strip_prefix(&[10, 40, 30]), Some(&[][..]));
assert_eq!(v.strip_prefix(&[50]), None);
assert_eq!(v.strip_prefix(&[10, 50]), None);
let prefix : &str = "he";
assert_eq!(b"hello".strip_prefix(prefix.as_bytes()),
Some(b"llo".as_ref()));
1.51.0 · sourcepub fn strip_suffix<P>(&self, suffix: &P) -> Option<&[T]>
pub fn strip_suffix<P>(&self, suffix: &P) -> Option<&[T]>
Returns a subslice with the suffix removed.
If the slice ends with suffix
, returns the subslice before the suffix, wrapped in Some
.
If suffix
is empty, simply returns the original slice. If suffix
is equal to the
original slice, returns an empty slice.
If the slice does not end with suffix
, returns None
.
§Examples
let v = &[10, 40, 30];
assert_eq!(v.strip_suffix(&[30]), Some(&[10, 40][..]));
assert_eq!(v.strip_suffix(&[40, 30]), Some(&[10][..]));
assert_eq!(v.strip_suffix(&[10, 40, 30]), Some(&[][..]));
assert_eq!(v.strip_suffix(&[50]), None);
assert_eq!(v.strip_suffix(&[50, 30]), None);
1.0.0 · sourcepub fn binary_search(&self, x: &T) -> Result<usize, usize>where
T: Ord,
pub fn binary_search(&self, x: &T) -> Result<usize, usize>where
T: Ord,
Binary searches this slice for a given element. If the slice is not sorted, the returned result is unspecified and meaningless.
If the value is found then Result::Ok
is returned, containing the
index of the matching element. If there are multiple matches, then any
one of the matches could be returned. The index is chosen
deterministically, but is subject to change in future versions of Rust.
If the value is not found then Result::Err
is returned, containing
the index where a matching element could be inserted while maintaining
sorted order.
See also binary_search_by
, binary_search_by_key
, and partition_point
.
§Examples
Looks up a series of four elements. The first is found, with a
uniquely determined position; the second and third are not
found; the fourth could match any position in [1, 4]
.
let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
assert_eq!(s.binary_search(&13), Ok(9));
assert_eq!(s.binary_search(&4), Err(7));
assert_eq!(s.binary_search(&100), Err(13));
let r = s.binary_search(&1);
assert!(match r { Ok(1..=4) => true, _ => false, });
If you want to find that whole range of matching items, rather than
an arbitrary matching one, that can be done using partition_point
:
let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
let low = s.partition_point(|x| x < &1);
assert_eq!(low, 1);
let high = s.partition_point(|x| x <= &1);
assert_eq!(high, 5);
let r = s.binary_search(&1);
assert!((low..high).contains(&r.unwrap()));
assert!(s[..low].iter().all(|&x| x < 1));
assert!(s[low..high].iter().all(|&x| x == 1));
assert!(s[high..].iter().all(|&x| x > 1));
// For something not found, the "range" of equal items is empty
assert_eq!(s.partition_point(|x| x < &11), 9);
assert_eq!(s.partition_point(|x| x <= &11), 9);
assert_eq!(s.binary_search(&11), Err(9));
If you want to insert an item to a sorted vector, while maintaining
sort order, consider using partition_point
:
let mut s = vec![0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
let num = 42;
let idx = s.partition_point(|&x| x < num);
// The above is equivalent to `let idx = s.binary_search(&num).unwrap_or_else(|x| x);`
s.insert(idx, num);
assert_eq!(s, [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 42, 55]);
1.0.0 · sourcepub fn binary_search_by<'a, F>(&'a self, f: F) -> Result<usize, usize>
pub fn binary_search_by<'a, F>(&'a self, f: F) -> Result<usize, usize>
Binary searches this slice with a comparator function.
The comparator function should return an order code that indicates
whether its argument is Less
, Equal
or Greater
the desired
target.
If the slice is not sorted or if the comparator function does not
implement an order consistent with the sort order of the underlying
slice, the returned result is unspecified and meaningless.
If the value is found then Result::Ok
is returned, containing the
index of the matching element. If there are multiple matches, then any
one of the matches could be returned. The index is chosen
deterministically, but is subject to change in future versions of Rust.
If the value is not found then Result::Err
is returned, containing
the index where a matching element could be inserted while maintaining
sorted order.
See also binary_search
, binary_search_by_key
, and partition_point
.
§Examples
Looks up a series of four elements. The first is found, with a
uniquely determined position; the second and third are not
found; the fourth could match any position in [1, 4]
.
let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
let seek = 13;
assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Ok(9));
let seek = 4;
assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Err(7));
let seek = 100;
assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Err(13));
let seek = 1;
let r = s.binary_search_by(|probe| probe.cmp(&seek));
assert!(match r { Ok(1..=4) => true, _ => false, });
1.10.0 · sourcepub fn binary_search_by_key<'a, B, F>(
&'a self,
b: &B,
f: F
) -> Result<usize, usize>
pub fn binary_search_by_key<'a, B, F>( &'a self, b: &B, f: F ) -> Result<usize, usize>
Binary searches this slice with a key extraction function.
Assumes that the slice is sorted by the key, for instance with
sort_by_key
using the same key extraction function.
If the slice is not sorted by the key, the returned result is
unspecified and meaningless.
If the value is found then Result::Ok
is returned, containing the
index of the matching element. If there are multiple matches, then any
one of the matches could be returned. The index is chosen
deterministically, but is subject to change in future versions of Rust.
If the value is not found then Result::Err
is returned, containing
the index where a matching element could be inserted while maintaining
sorted order.
See also binary_search
, binary_search_by
, and partition_point
.
§Examples
Looks up a series of four elements in a slice of pairs sorted by
their second elements. The first is found, with a uniquely
determined position; the second and third are not found; the
fourth could match any position in [1, 4]
.
let s = [(0, 0), (2, 1), (4, 1), (5, 1), (3, 1),
(1, 2), (2, 3), (4, 5), (5, 8), (3, 13),
(1, 21), (2, 34), (4, 55)];
assert_eq!(s.binary_search_by_key(&13, |&(a, b)| b), Ok(9));
assert_eq!(s.binary_search_by_key(&4, |&(a, b)| b), Err(7));
assert_eq!(s.binary_search_by_key(&100, |&(a, b)| b), Err(13));
let r = s.binary_search_by_key(&1, |&(a, b)| b);
assert!(match r { Ok(1..=4) => true, _ => false, });
1.30.0 · sourcepub unsafe fn align_to<U>(&self) -> (&[T], &[U], &[T])
pub unsafe fn align_to<U>(&self) -> (&[T], &[U], &[T])
Transmute the slice to a slice of another type, ensuring alignment of the types is maintained.
This method splits the slice into three distinct slices: prefix, correctly aligned middle slice of a new type, and the suffix slice. How exactly the slice is split up is not specified; the middle part may be smaller than necessary. However, if this fails to return a maximal middle part, that is because code is running in a context where performance does not matter, such as a sanitizer attempting to find alignment bugs. Regular code running in a default (debug or release) execution will return a maximal middle part.
This method has no purpose when either input element T
or output element U
are
zero-sized and will return the original slice without splitting anything.
§Safety
This method is essentially a transmute
with respect to the elements in the returned
middle slice, so all the usual caveats pertaining to transmute::<T, U>
also apply here.
§Examples
Basic usage:
unsafe {
let bytes: [u8; 7] = [1, 2, 3, 4, 5, 6, 7];
let (prefix, shorts, suffix) = bytes.align_to::<u16>();
// less_efficient_algorithm_for_bytes(prefix);
// more_efficient_algorithm_for_aligned_shorts(shorts);
// less_efficient_algorithm_for_bytes(suffix);
}
sourcepub fn as_simd<const LANES: usize>(&self) -> (&[T], &[Simd<T, LANES>], &[T])
🔬This is a nightly-only experimental API. (portable_simd
)
pub fn as_simd<const LANES: usize>(&self) -> (&[T], &[Simd<T, LANES>], &[T])
portable_simd
)Split a slice into a prefix, a middle of aligned SIMD types, and a suffix.
This is a safe wrapper around slice::align_to
, so has the same weak
postconditions as that method. You’re only assured that
self.len() == prefix.len() + middle.len() * LANES + suffix.len()
.
Notably, all of the following are possible:
prefix.len() >= LANES
.middle.is_empty()
despiteself.len() >= 3 * LANES
.suffix.len() >= LANES
.
That said, this is a safe method, so if you’re only writing safe code, then this can at most cause incorrect logic, not unsoundness.
§Panics
This will panic if the size of the SIMD type is different from
LANES
times that of the scalar.
At the time of writing, the trait restrictions on Simd<T, LANES>
keeps
that from ever happening, as only power-of-two numbers of lanes are
supported. It’s possible that, in the future, those restrictions might
be lifted in a way that would make it possible to see panics from this
method for something like LANES == 3
.
§Examples
#![feature(portable_simd)]
use core::simd::prelude::*;
let short = &[1, 2, 3];
let (prefix, middle, suffix) = short.as_simd::<4>();
assert_eq!(middle, []); // Not enough elements for anything in the middle
// They might be split in any possible way between prefix and suffix
let it = prefix.iter().chain(suffix).copied();
assert_eq!(it.collect::<Vec<_>>(), vec![1, 2, 3]);
fn basic_simd_sum(x: &[f32]) -> f32 {
use std::ops::Add;
let (prefix, middle, suffix) = x.as_simd();
let sums = f32x4::from_array([
prefix.iter().copied().sum(),
0.0,
0.0,
suffix.iter().copied().sum(),
]);
let sums = middle.iter().copied().fold(sums, f32x4::add);
sums.reduce_sum()
}
let numbers: Vec<f32> = (1..101).map(|x| x as _).collect();
assert_eq!(basic_simd_sum(&numbers[1..99]), 4949.0);
sourcepub fn is_sorted(&self) -> boolwhere
T: PartialOrd,
🔬This is a nightly-only experimental API. (is_sorted
)
pub fn is_sorted(&self) -> boolwhere
T: PartialOrd,
is_sorted
)Checks if the elements of this slice are sorted.
That is, for each element a
and its following element b
, a <= b
must hold. If the
slice yields exactly zero or one element, true
is returned.
Note that if Self::Item
is only PartialOrd
, but not Ord
, the above definition
implies that this function returns false
if any two consecutive items are not
comparable.
§Examples
#![feature(is_sorted)]
let empty: [i32; 0] = [];
assert!([1, 2, 2, 9].is_sorted());
assert!(![1, 3, 2, 4].is_sorted());
assert!([0].is_sorted());
assert!(empty.is_sorted());
assert!(![0.0, 1.0, f32::NAN].is_sorted());
sourcepub fn is_sorted_by<'a, F>(&'a self, compare: F) -> bool
🔬This is a nightly-only experimental API. (is_sorted
)
pub fn is_sorted_by<'a, F>(&'a self, compare: F) -> bool
is_sorted
)Checks if the elements of this slice are sorted using the given comparator function.
Instead of using PartialOrd::partial_cmp
, this function uses the given compare
function to determine whether two elements are to be considered in sorted order.
§Examples
#![feature(is_sorted)]
assert!([1, 2, 2, 9].is_sorted_by(|a, b| a <= b));
assert!(![1, 2, 2, 9].is_sorted_by(|a, b| a < b));
assert!([0].is_sorted_by(|a, b| true));
assert!([0].is_sorted_by(|a, b| false));
let empty: [i32; 0] = [];
assert!(empty.is_sorted_by(|a, b| false));
assert!(empty.is_sorted_by(|a, b| true));
sourcepub fn is_sorted_by_key<'a, F, K>(&'a self, f: F) -> bool
🔬This is a nightly-only experimental API. (is_sorted
)
pub fn is_sorted_by_key<'a, F, K>(&'a self, f: F) -> bool
is_sorted
)Checks if the elements of this slice are sorted using the given key extraction function.
Instead of comparing the slice’s elements directly, this function compares the keys of the
elements, as determined by f
. Apart from that, it’s equivalent to is_sorted
; see its
documentation for more information.
§Examples
#![feature(is_sorted)]
assert!(["c", "bb", "aaa"].is_sorted_by_key(|s| s.len()));
assert!(![-2i32, -1, 0, 3].is_sorted_by_key(|n| n.abs()));
1.52.0 · sourcepub fn partition_point<P>(&self, pred: P) -> usize
pub fn partition_point<P>(&self, pred: P) -> usize
Returns the index of the partition point according to the given predicate (the index of the first element of the second partition).
The slice is assumed to be partitioned according to the given predicate.
This means that all elements for which the predicate returns true are at the start of the slice
and all elements for which the predicate returns false are at the end.
For example, [7, 15, 3, 5, 4, 12, 6]
is partitioned under the predicate x % 2 != 0
(all odd numbers are at the start, all even at the end).
If this slice is not partitioned, the returned result is unspecified and meaningless, as this method performs a kind of binary search.
See also binary_search
, binary_search_by
, and binary_search_by_key
.
§Examples
let v = [1, 2, 3, 3, 5, 6, 7];
let i = v.partition_point(|&x| x < 5);
assert_eq!(i, 4);
assert!(v[..i].iter().all(|&x| x < 5));
assert!(v[i..].iter().all(|&x| !(x < 5)));
If all elements of the slice match the predicate, including if the slice is empty, then the length of the slice will be returned:
let a = [2, 4, 8];
assert_eq!(a.partition_point(|x| x < &100), a.len());
let a: [i32; 0] = [];
assert_eq!(a.partition_point(|x| x < &100), 0);
If you want to insert an item to a sorted vector, while maintaining sort order:
let mut s = vec![0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
let num = 42;
let idx = s.partition_point(|&x| x < num);
s.insert(idx, num);
assert_eq!(s, [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 42, 55]);
1.23.0 · sourcepub fn is_ascii(&self) -> bool
pub fn is_ascii(&self) -> bool
Checks if all bytes in this slice are within the ASCII range.
sourcepub fn as_ascii(&self) -> Option<&[AsciiChar]>
🔬This is a nightly-only experimental API. (ascii_char
)
pub fn as_ascii(&self) -> Option<&[AsciiChar]>
ascii_char
)If this slice is_ascii
, returns it as a slice of
ASCII characters, otherwise returns None
.
sourcepub unsafe fn as_ascii_unchecked(&self) -> &[AsciiChar]
🔬This is a nightly-only experimental API. (ascii_char
)
pub unsafe fn as_ascii_unchecked(&self) -> &[AsciiChar]
ascii_char
)Converts this slice of bytes into a slice of ASCII characters, without checking whether they’re valid.
§Safety
Every byte in the slice must be in 0..=127
, or else this is UB.
1.23.0 · sourcepub fn eq_ignore_ascii_case(&self, other: &[u8]) -> bool
pub fn eq_ignore_ascii_case(&self, other: &[u8]) -> bool
Checks that two slices are an ASCII case-insensitive match.
Same as to_ascii_lowercase(a) == to_ascii_lowercase(b)
,
but without allocating and copying temporaries.
1.60.0 · sourcepub fn escape_ascii(&self) -> EscapeAscii<'_>
pub fn escape_ascii(&self) -> EscapeAscii<'_>
Returns an iterator that produces an escaped version of this slice, treating it as an ASCII string.
§Examples
let s = b"0\t\r\n'\"\\\x9d";
let escaped = s.escape_ascii().to_string();
assert_eq!(escaped, "0\\t\\r\\n\\'\\\"\\\\\\x9d");
sourcepub fn trim_ascii_start(&self) -> &[u8] ⓘ
🔬This is a nightly-only experimental API. (byte_slice_trim_ascii
)
pub fn trim_ascii_start(&self) -> &[u8] ⓘ
byte_slice_trim_ascii
)Returns a byte slice with leading ASCII whitespace bytes removed.
‘Whitespace’ refers to the definition used by
u8::is_ascii_whitespace
.
§Examples
#![feature(byte_slice_trim_ascii)]
assert_eq!(b" \t hello world\n".trim_ascii_start(), b"hello world\n");
assert_eq!(b" ".trim_ascii_start(), b"");
assert_eq!(b"".trim_ascii_start(), b"");
sourcepub fn trim_ascii_end(&self) -> &[u8] ⓘ
🔬This is a nightly-only experimental API. (byte_slice_trim_ascii
)
pub fn trim_ascii_end(&self) -> &[u8] ⓘ
byte_slice_trim_ascii
)Returns a byte slice with trailing ASCII whitespace bytes removed.
‘Whitespace’ refers to the definition used by
u8::is_ascii_whitespace
.
§Examples
#![feature(byte_slice_trim_ascii)]
assert_eq!(b"\r hello world\n ".trim_ascii_end(), b"\r hello world");
assert_eq!(b" ".trim_ascii_end(), b"");
assert_eq!(b"".trim_ascii_end(), b"");
sourcepub fn trim_ascii(&self) -> &[u8] ⓘ
🔬This is a nightly-only experimental API. (byte_slice_trim_ascii
)
pub fn trim_ascii(&self) -> &[u8] ⓘ
byte_slice_trim_ascii
)Returns a byte slice with leading and trailing ASCII whitespace bytes removed.
‘Whitespace’ refers to the definition used by
u8::is_ascii_whitespace
.
§Examples
#![feature(byte_slice_trim_ascii)]
assert_eq!(b"\r hello world\n ".trim_ascii(), b"hello world");
assert_eq!(b" ".trim_ascii(), b"");
assert_eq!(b"".trim_ascii(), b"");
sourcepub fn as_str(&self) -> &str
🔬This is a nightly-only experimental API. (ascii_char
)
pub fn as_str(&self) -> &str
ascii_char
)Views this slice of ASCII characters as a UTF-8 str
.
sourcepub fn as_bytes(&self) -> &[u8] ⓘ
🔬This is a nightly-only experimental API. (ascii_char
)
pub fn as_bytes(&self) -> &[u8] ⓘ
ascii_char
)Views this slice of ASCII characters as a slice of u8
bytes.
sourcepub fn flatten(&self) -> &[T]
🔬This is a nightly-only experimental API. (slice_flatten
)
pub fn flatten(&self) -> &[T]
slice_flatten
)Takes a &[[T; N]]
, and flattens it to a &[T]
.
§Panics
This panics if the length of the resulting slice would overflow a usize
.
This is only possible when flattening a slice of arrays of zero-sized
types, and thus tends to be irrelevant in practice. If
size_of::<T>() > 0
, this will never panic.
§Examples
#![feature(slice_flatten)]
assert_eq!([[1, 2, 3], [4, 5, 6]].flatten(), &[1, 2, 3, 4, 5, 6]);
assert_eq!(
[[1, 2, 3], [4, 5, 6]].flatten(),
[[1, 2], [3, 4], [5, 6]].flatten(),
);
let slice_of_empty_arrays: &[[i32; 0]] = &[[], [], [], [], []];
assert!(slice_of_empty_arrays.flatten().is_empty());
let empty_slice_of_arrays: &[[u32; 10]] = &[];
assert!(empty_slice_of_arrays.flatten().is_empty());
1.23.0 · sourcepub fn to_ascii_uppercase(&self) -> Vec<u8>
pub fn to_ascii_uppercase(&self) -> Vec<u8>
Returns a vector containing a copy of this slice where each byte is mapped to its ASCII upper case equivalent.
ASCII letters ‘a’ to ‘z’ are mapped to ‘A’ to ‘Z’, but non-ASCII letters are unchanged.
To uppercase the value in-place, use make_ascii_uppercase
.
1.23.0 · sourcepub fn to_ascii_lowercase(&self) -> Vec<u8>
pub fn to_ascii_lowercase(&self) -> Vec<u8>
Returns a vector containing a copy of this slice where each byte is mapped to its ASCII lower case equivalent.
ASCII letters ‘A’ to ‘Z’ are mapped to ‘a’ to ‘z’, but non-ASCII letters are unchanged.
To lowercase the value in-place, use make_ascii_lowercase
.
1.0.0 · sourcepub fn to_vec(&self) -> Vec<T>where
T: Clone,
pub fn to_vec(&self) -> Vec<T>where
T: Clone,
Copies self
into a new Vec
.
§Examples
let s = [10, 40, 30];
let x = s.to_vec();
// Here, `s` and `x` can be modified independently.
sourcepub fn to_vec_in<A>(&self, alloc: A) -> Vec<T, A>
🔬This is a nightly-only experimental API. (allocator_api
)
pub fn to_vec_in<A>(&self, alloc: A) -> Vec<T, A>
allocator_api
)Copies self
into a new Vec
with an allocator.
§Examples
#![feature(allocator_api)]
use std::alloc::System;
let s = [10, 40, 30];
let x = s.to_vec_in(System);
// Here, `s` and `x` can be modified independently.
1.0.0 · sourcepub fn concat<Item>(&self) -> <[T] as Concat<Item>>::Output ⓘ
pub fn concat<Item>(&self) -> <[T] as Concat<Item>>::Output ⓘ
Flattens a slice of T
into a single value Self::Output
.
§Examples
assert_eq!(["hello", "world"].concat(), "helloworld");
assert_eq!([[1, 2], [3, 4]].concat(), [1, 2, 3, 4]);
1.3.0 · sourcepub fn join<Separator>(
&self,
sep: Separator
) -> <[T] as Join<Separator>>::Output ⓘ
pub fn join<Separator>( &self, sep: Separator ) -> <[T] as Join<Separator>>::Output ⓘ
Flattens a slice of T
into a single value Self::Output
, placing a
given separator between each.
§Examples
assert_eq!(["hello", "world"].join(" "), "hello world");
assert_eq!([[1, 2], [3, 4]].join(&0), [1, 2, 0, 3, 4]);
assert_eq!([[1, 2], [3, 4]].join(&[0, 0][..]), [1, 2, 0, 0, 3, 4]);
1.0.0 · sourcepub fn connect<Separator>(
&self,
sep: Separator
) -> <[T] as Join<Separator>>::Output ⓘ
👎Deprecated since 1.3.0: renamed to join
pub fn connect<Separator>( &self, sep: Separator ) -> <[T] as Join<Separator>>::Output ⓘ
Flattens a slice of T
into a single value Self::Output
, placing a
given separator between each.
§Examples
assert_eq!(["hello", "world"].connect(" "), "hello world");
assert_eq!([[1, 2], [3, 4]].connect(&0), [1, 2, 0, 3, 4]);