Consider implementing something behavior like the following code:
fn as_one_elem<T>(slice: &[T]) -> &T {
let mut iter = slice.into_iter();
let elem = iter.next().unwrap();
matches!(iter.next(), None);
elem
}
fn as_one_char(s: &str) -> char {
let mut iter = s.chars();
let elem = iter.next().unwrap();
matches!(iter.next(), None);
elem
}
The code above just shows the way I do this in general. If standard library includes such methods, then I can reduce them in business logic.
Two methods could be implemented: one returns a unique element/character directly and panic when there is not only one, and one that returns a Result. It is also can be considered implementing From/TryFrom, but I think that might not be proper.
I didn't check the standard library one method by one method, but searching based on keywords didn't search for what I needed. Tell me I'm a fool if there is already a more convenient way to do the same thing.
For strings, pattern matching like this isnāt available. However for either case, you could use the Itertools crate for asserting iterators being of a small fixed length via Itertools::collect_tuple. This way you can write
use itertools::Itertools; // 0.10.3
fn main() {
let x: &[i32] = &[42];
let (i,) = x.iter().collect_tuple().unwrap();
// now, i: &i32
let s = "Ć";
let (c,) = s.chars().collect_tuple().unwrap();
// now, c: char
}
Regarding strings, checking for āone charā is typically a problematic operation, since a single char in Rust really is just a single āUnicode scalar valueā, which has - in the general case [1] - little to do with most practical notions of āa single characterā which will often be better represented by considering āgrapheme clustersā instead..
By the way this is doing nothing, matches! evaluates to a bool without side effects and by ignoring it you're making that line doing nothing. Thus your code reduces to "get the first element or panic, ignore if there are more".
There's a million things std could have, but saving a line or two sometimes is adding bloat for everyone. There's already a first() method, slice[0]. What's the value in having a shortcut for also asserting there are no more elements? Any why force it to panic?
There could be TryFrom for str to char conversion, but char is a misleading type (it's not a character). Unicode requires grapheme clusters to be represented as str.