You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
98 lines
2.3 KiB
Rust
98 lines
2.3 KiB
Rust
use core::fmt;
|
|
|
|
pub trait StrSink {
|
|
type Error;
|
|
|
|
fn sink_str(&mut self, s: &str) -> Result<(), Self::Error>;
|
|
|
|
fn sink_char(&mut self, c: char) -> Result<(), Self::Error> {
|
|
let mut buf = [0u8; 4];
|
|
let s = c.encode_utf8(&mut buf);
|
|
self.sink_str(s)
|
|
}
|
|
}
|
|
|
|
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)
|
|
}
|
|
}
|
|
|
|
#[cfg(feature = "alloc")]
|
|
pub use string_sink::SinkString;
|
|
|
|
#[cfg(feature = "alloc")]
|
|
mod string_sink {
|
|
use core::convert::Infallible;
|
|
|
|
#[cfg(not(feature = "std"))]
|
|
use alloc::string::String;
|
|
|
|
use super::StrSink;
|
|
|
|
#[repr(transparent)]
|
|
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
|
|
pub struct SinkString(pub String);
|
|
|
|
impl SinkString {
|
|
#[inline]
|
|
#[must_use]
|
|
pub fn from_string_ref(s: &String) -> &Self {
|
|
// SAFETY:
|
|
// Since `StringSink` uses `repr(transparent)`, it has the same memory layout as
|
|
// `String`.
|
|
unsafe { &*(s as *const String as *const Self) }
|
|
}
|
|
|
|
#[inline]
|
|
#[must_use]
|
|
pub fn from_string_mut(s: &mut String) -> &mut Self {
|
|
// SAFETY:
|
|
// Since `StringSink` uses `repr(transparent)`, it has the same memory layout as
|
|
// `String`.
|
|
unsafe { &mut *(s as *mut String as *mut Self) }
|
|
}
|
|
}
|
|
|
|
impl AsRef<SinkString> for String {
|
|
#[inline]
|
|
fn as_ref(&self) -> &SinkString {
|
|
SinkString::from_string_ref(self)
|
|
}
|
|
}
|
|
|
|
impl AsMut<SinkString> for String {
|
|
#[inline]
|
|
fn as_mut(&mut self) -> &mut SinkString {
|
|
SinkString::from_string_mut(self)
|
|
}
|
|
}
|
|
|
|
impl StrSink for SinkString {
|
|
type Error = Infallible;
|
|
|
|
#[inline]
|
|
fn sink_str(&mut self, s: &str) -> Result<(), Self::Error> {
|
|
self.0.push_str(s);
|
|
Ok(())
|
|
}
|
|
|
|
#[inline]
|
|
fn sink_char(&mut self, c: char) -> Result<(), Self::Error> {
|
|
self.0.push(c);
|
|
Ok(())
|
|
}
|
|
}
|
|
}
|