Compare commits
4
Commits
44e27e9d23
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7858cd68cf | ||
|
|
706e8ca22a | ||
|
|
3dcb61021f | ||
|
|
fc6caf0de6 |
No files matched your search
@@ -1,5 +1,25 @@
|
||||
use core::convert::Infallible;
|
||||
|
||||
pub trait Apply: Sized {
|
||||
fn apply<U, F>(self, f: F) -> U
|
||||
where
|
||||
F: FnOnce(Self) -> U;
|
||||
}
|
||||
|
||||
impl<T> Apply for T
|
||||
where
|
||||
T: Sized,
|
||||
{
|
||||
#[inline]
|
||||
#[must_use]
|
||||
fn apply<U, F>(self, f: F) -> U
|
||||
where
|
||||
F: FnOnce(Self) -> U
|
||||
{
|
||||
f(self)
|
||||
}
|
||||
}
|
||||
|
||||
/// Consumes an element of type `Infallible` and produces an element of any type `T`. This is
|
||||
/// possible because `Infallible` has no elements and thus this function can never be called, so
|
||||
/// the statement "for any given type `T`, whenever this function returns, it returns an element of
|
||||
|
||||
+79
-1
@@ -2,7 +2,7 @@ use core::{
|
||||
convert::identity,
|
||||
fmt,
|
||||
hint,
|
||||
ops::{Deref, DerefMut},
|
||||
ops::{Deref, DerefMut}, iter::FusedIterator,
|
||||
};
|
||||
|
||||
use crate::convert::{clone, clone_mut, copy, copy_mut, Empty};
|
||||
@@ -398,6 +398,16 @@ impl<L, R> Either<L, R> {
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
pub fn iter<'a>(&'a self)
|
||||
-> Iter<<&'a L as IntoIterator>::IntoIter, <&'a R as IntoIterator>::IntoIter>
|
||||
where
|
||||
&'a L: IntoIterator,
|
||||
&'a R: IntoIterator,
|
||||
{
|
||||
self.as_ref().into_iter()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
impl<L, R> Either<&L, &R> {
|
||||
@@ -610,3 +620,71 @@ where
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<L, R> IntoIterator for Either<L, R>
|
||||
where
|
||||
L: IntoIterator,
|
||||
R: IntoIterator,
|
||||
{
|
||||
type Item = Either<<L as IntoIterator>::Item, <R as IntoIterator>::Item>;
|
||||
|
||||
type IntoIter = Iter<<L as IntoIterator>::IntoIter, <R as IntoIterator>::IntoIter>;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
Iter {
|
||||
inner: self.map(<L as IntoIterator>::into_iter, <R as IntoIterator>::into_iter),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Iter<L, R> {
|
||||
inner: Either<L, R>,
|
||||
}
|
||||
|
||||
impl<L, R> Iterator for Iter<L, R>
|
||||
where
|
||||
L: Iterator,
|
||||
R: Iterator,
|
||||
{
|
||||
type Item = Either<<L as IntoIterator>::Item, <R as IntoIterator>::Item>;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
match &mut self.inner {
|
||||
Inl(l) => l.next().map(Inl),
|
||||
Inr(r) => r.next().map(Inr),
|
||||
}
|
||||
}
|
||||
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
self.inner.as_ref().fold(L::size_hint, R::size_hint)
|
||||
}
|
||||
|
||||
fn count(self) -> usize {
|
||||
self.inner.fold(L::count, R::count)
|
||||
}
|
||||
}
|
||||
|
||||
impl<L, R> DoubleEndedIterator for Iter<L, R>
|
||||
where
|
||||
L: DoubleEndedIterator,
|
||||
R: DoubleEndedIterator,
|
||||
{
|
||||
fn next_back(&mut self) -> Option<Self::Item> {
|
||||
match &mut self.inner {
|
||||
Inl(l) => l.next_back().map(Inl),
|
||||
Inr(r) => r.next_back().map(Inr),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<L, R> ExactSizeIterator for Iter<L, R>
|
||||
where
|
||||
L: ExactSizeIterator,
|
||||
R: ExactSizeIterator,
|
||||
{}
|
||||
|
||||
impl<L, R> FusedIterator for Iter<L, R>
|
||||
where
|
||||
L: FusedIterator,
|
||||
R: FusedIterator,
|
||||
{}
|
||||
+90
-26
@@ -12,36 +12,10 @@ pub trait StrSink {
|
||||
}
|
||||
}
|
||||
|
||||
impl<W> StrSink for W
|
||||
where
|
||||
W: fmt::Write,
|
||||
{
|
||||
type Error = fmt::Error;
|
||||
|
||||
#[inline]
|
||||
fn sink_str(&mut self, s: &str) -> Result<(), Self::Error> {
|
||||
self.write_str(s)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn sink_char(&mut self, c: char) -> Result<(), Self::Error> {
|
||||
self.write_char(c)
|
||||
}
|
||||
}
|
||||
|
||||
pub trait FmtSink: StrSink {
|
||||
fn sink_fmt<'a>(&mut self, args: Arguments<'a>) -> Result<(), <Self as StrSink>::Error>;
|
||||
}
|
||||
|
||||
impl<W> FmtSink for W
|
||||
where
|
||||
W: fmt::Write,
|
||||
{
|
||||
fn sink_fmt<'a>(&mut self, args: Arguments<'a>) -> Result<(), <Self as StrSink>::Error> {
|
||||
self.write_fmt(args)
|
||||
}
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! sink_fmt {
|
||||
($dst:expr, $($arg:tt)*) => {
|
||||
@@ -51,6 +25,48 @@ macro_rules! sink_fmt {
|
||||
|
||||
pub use sink_fmt;
|
||||
|
||||
#[repr(transparent)]
|
||||
pub struct FmtWriteSink<W: fmt::Write>(pub W);
|
||||
|
||||
impl<W: fmt::Write> FmtWriteSink<W> {
|
||||
#[inline]
|
||||
#[must_use]
|
||||
pub fn from_ref(w: &W) -> &Self {
|
||||
// SAFETY:
|
||||
// `FmtWriteSink` uses `repr(transparent)`, so it has the same memory layout as `W`.
|
||||
unsafe { &*(w as *const W as *const Self) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[must_use]
|
||||
pub fn from_mut(w: &mut W) -> &mut Self {
|
||||
// SAFETY:
|
||||
// `FmtWriteSink` uses `repr(transparent)`, so it has the same memory layout as `W`.
|
||||
unsafe { &mut *(w as *mut W as *mut Self) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<W: fmt::Write> StrSink for FmtWriteSink<W> {
|
||||
type Error = fmt::Error;
|
||||
|
||||
#[inline]
|
||||
fn sink_str(&mut self, s: &str) -> Result<(), Self::Error> {
|
||||
self.0.write_str(s)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn sink_char(&mut self, c: char) -> Result<(), Self::Error> {
|
||||
self.0.write_char(c)
|
||||
}
|
||||
}
|
||||
|
||||
impl<W: fmt::Write> FmtSink for FmtWriteSink<W> {
|
||||
#[inline]
|
||||
fn sink_fmt<'a>(&mut self, args: Arguments<'a>) -> Result<(), <Self as StrSink>::Error> {
|
||||
self.0.write_fmt(args)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "alloc")]
|
||||
pub use string_sink::SinkString;
|
||||
|
||||
@@ -138,3 +154,51 @@ mod string_sink {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
pub use io_sink::IoWriteSink;
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
mod io_sink {
|
||||
use core::fmt::Arguments;
|
||||
use std::io;
|
||||
|
||||
use super::{StrSink, FmtSink};
|
||||
|
||||
#[repr(transparent)]
|
||||
pub struct IoWriteSink<W: io::Write>(pub W);
|
||||
|
||||
impl<W: io::Write> IoWriteSink<W> {
|
||||
#[inline]
|
||||
#[must_use]
|
||||
pub fn from_ref(w: &W) -> &Self {
|
||||
// SAFETY:
|
||||
// `IoWriteSink` uses `repr(transparent)`, so it has the same memory layout as `W`.
|
||||
unsafe { &*(w as *const W as *const Self) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[must_use]
|
||||
pub fn from_mut(w: &mut W) -> &mut Self {
|
||||
// SAFETY:
|
||||
// `IoWriteSink` uses `repr(transparent)`, so it has the same memory layout as `W`.
|
||||
unsafe { &mut *(w as *mut W as *mut Self) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<W: io::Write> StrSink for IoWriteSink<W> {
|
||||
type Error = io::Error;
|
||||
|
||||
#[inline]
|
||||
fn sink_str(&mut self, s: &str) -> Result<(), Self::Error> {
|
||||
self.0.write_all(s.as_bytes())
|
||||
}
|
||||
}
|
||||
|
||||
impl<W: io::Write> FmtSink for IoWriteSink<W> {
|
||||
#[inline]
|
||||
fn sink_fmt<'a>(&mut self, args: Arguments<'a>) -> Result<(), <Self as StrSink>::Error> {
|
||||
self.0.write_fmt(args)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user