You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
genmarkov/src/ext.rs

153 lines
3.0 KiB

//! Extensions
use std::{
iter,
ops::{
Range,
Deref,DerefMut,
},
marker::{
PhantomData,
Send,
},
};
pub trait StringJoinExt: Sized
{
fn join<P: AsRef<str>>(self, sep: P) -> String;
}
impl<I,T> StringJoinExt for I
where I: IntoIterator<Item=T>,
T: AsRef<str>
{
fn join<P: AsRef<str>>(self, sep: P) -> String
{
let mut string = String::new();
for (first, s) in iter::successors(Some(true), |_| Some(false)).zip(self.into_iter())
{
if !first {
string.push_str(sep.as_ref());
}
string.push_str(s.as_ref());
}
string
}
}
pub trait FindSliceBounds
{
type SliceType: ?Sized;
fn slice_bounds(&self, from: &Self::SliceType) -> Range<usize>;
}
impl<T: ?Sized + AsRef<str>> FindSliceBounds for T
{
type SliceType = str;
fn slice_bounds(&self, from: &Self::SliceType) -> Range<usize>{
let this = self.as_ref();
unsafe {
let sptr = from.as_ptr();
let eptr = sptr.add(from.len());
let ssptr = this.as_ptr();
let septr = ssptr.add(this.len());
let sptr = sptr as usize;
let ssptr = ssptr as usize;
let eptr = eptr as usize;
let septr = septr as usize;
assert!(sptr >= ssptr && sptr <= septr, "Start index of slice is outside the bounds of self");
assert!(eptr >= ssptr && eptr <= septr, "End index of slice is outside the bounds of self");
(sptr - ssptr)..(eptr - ssptr)
}
}
}
pub trait SliceInPlace
{
fn drain_inverse<R: std::ops::RangeBounds<usize>>(&mut self, slice: R);
}
impl SliceInPlace for String
{
fn drain_inverse<R: std::ops::RangeBounds<usize>>(&mut self, slice: R)
{
use std::ops::Bound;
match slice.end_bound() {
Bound::Excluded(&ex) => drop(self.drain(ex..)),
Bound::Included(&inc) => drop(self.drain(inc+1..)),
_ => (),
};
match slice.start_bound() {
Bound::Included(&ex) => drop(self.drain(..ex)),
Bound::Excluded(&ex) => drop(..ex+1),
_ => ()
};
}
}
pub trait TrimInPlace
{
fn trim_in_place(&mut self) -> &mut Self;
}
impl TrimInPlace for String
{
fn trim_in_place(&mut self) -> &mut Self {
let bounds = self.slice_bounds(self.trim());
self.drain_inverse(bounds);
self
}
}
pub trait MapTuple2<T,U>
{
fn map<V,W, F: FnOnce((T,U)) -> (V,W)>(self, fun: F) -> (V,W);
}
impl<T,U> MapTuple2<T,U> for (T,U)
{
#[inline] fn map<V,W, F: FnOnce((T,U)) -> (V,W)>(self, fun: F) -> (V,W)
{
fun(self)
}
}
/// To make sure we don't keep this data across an `await` boundary.
#[repr(transparent)]
pub struct AssertNotSend<T>(pub T, PhantomData<*const T>);
impl<T> AssertNotSend<T>
{
pub const fn new(from :T) -> Self
{
Self(from, PhantomData)
}
pub fn into_inner(self) -> T
{
self.0
}
}
/// Require a future is Send
#[inline(always)] pub fn require_send<T: Send>(t: T) -> T
{
t
}
impl<T> Deref for AssertNotSend<T>
{
type Target = T;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<T> DerefMut for AssertNotSend<T>
{
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}