Use stdlib RangeBounds
This commit is contained in:
parent
d07bd9fed4
commit
abddd7c6f7
|
@ -9,7 +9,7 @@ use pulldown_cmark::{html, CowStr, Event, Options, Parser, Tag};
|
||||||
|
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
|
||||||
pub use self::string::{take_lines, RangeArgument};
|
pub use self::string::take_lines;
|
||||||
|
|
||||||
/// Replaces multiple consecutive whitespace characters with a single space character.
|
/// Replaces multiple consecutive whitespace characters with a single space character.
|
||||||
pub fn collapse_whitespace(text: &str) -> Cow<'_, str> {
|
pub fn collapse_whitespace(text: &str) -> Cow<'_, str> {
|
||||||
|
|
|
@ -1,57 +1,19 @@
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use std::ops::{Range, RangeFrom, RangeFull, RangeTo};
|
use std::ops::Bound::{Excluded, Included, Unbounded};
|
||||||
|
use std::ops::RangeBounds;
|
||||||
// This trait is already contained in the standard lib, however it is unstable.
|
|
||||||
// TODO: Remove when the `collections_range` feature stabilises
|
|
||||||
// (https://github.com/rust-lang/rust/issues/30877)
|
|
||||||
pub trait RangeArgument<T: ?Sized> {
|
|
||||||
fn start(&self) -> Option<&T>;
|
|
||||||
fn end(&self) -> Option<&T>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: ?Sized> RangeArgument<T> for RangeFull {
|
|
||||||
fn start(&self) -> Option<&T> {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
fn end(&self) -> Option<&T> {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> RangeArgument<T> for RangeFrom<T> {
|
|
||||||
fn start(&self) -> Option<&T> {
|
|
||||||
Some(&self.start)
|
|
||||||
}
|
|
||||||
fn end(&self) -> Option<&T> {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> RangeArgument<T> for RangeTo<T> {
|
|
||||||
fn start(&self) -> Option<&T> {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
fn end(&self) -> Option<&T> {
|
|
||||||
Some(&self.end)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> RangeArgument<T> for Range<T> {
|
|
||||||
fn start(&self) -> Option<&T> {
|
|
||||||
Some(&self.start)
|
|
||||||
}
|
|
||||||
fn end(&self) -> Option<&T> {
|
|
||||||
Some(&self.end)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Take a range of lines from a string.
|
/// Take a range of lines from a string.
|
||||||
pub fn take_lines<R: RangeArgument<usize>>(s: &str, range: R) -> String {
|
pub fn take_lines<R: RangeBounds<usize>>(s: &str, range: R) -> String {
|
||||||
let start = *range.start().unwrap_or(&0);
|
let start = match range.start_bound() {
|
||||||
|
Excluded(&n) => n + 1,
|
||||||
|
Included(&n) => n,
|
||||||
|
Unbounded => 0,
|
||||||
|
};
|
||||||
let mut lines = s.lines().skip(start);
|
let mut lines = s.lines().skip(start);
|
||||||
match range.end() {
|
match range.end_bound() {
|
||||||
Some(&end) => lines.take(end.saturating_sub(start)).join("\n"),
|
Excluded(end) => lines.take(end.saturating_sub(start)).join("\n"),
|
||||||
None => lines.join("\n"),
|
Included(end) => lines.take((end + 1).saturating_sub(start)).join("\n"),
|
||||||
|
Unbounded => lines.join("\n"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue