use core::{slice, str};
use crate::ext::Pointer;
pub trait Writer<R>: FnMut(&str) -> Result<(), R> {}
impl<R, T: FnMut(&str) -> Result<(), R>> Writer<R> for T {}
#[inline(always)]
pub(crate) fn write<R>(src: &str, writer: &mut impl Writer<R>) -> Result<(), R> {
(writer)(src)
}
#[inline(always)]
pub(crate) unsafe fn write_slice<R>(
start: *const u8,
end: *const u8,
writer: &mut impl Writer<R>,
) -> Result<(), R> {
unsafe {
write(
str::from_utf8_unchecked(slice::from_raw_parts(start, end.distance(start))),
writer,
)
}
}
#[doc(hidden)]
#[macro_export]
#[cfg(feature = "fmt")]
macro_rules! builder_fmt {
($name:ident, $fn:path, $fn_name:ident, $builder:ty) => {
fn $name(haystack: &str, buffer: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
use $fn;
let writer = |s: &str| buffer.write_str(s);
$fn_name::<$builder, _>(haystack, writer)
}
};
}
#[doc(hidden)]
#[macro_export]
#[cfg(feature = "fmt")]
macro_rules! struct_display {
($name:ident, $internal:ident, $body:expr, $builder:ty) => {
pub fn $name<'a>(haystack: &'a str) -> impl core::fmt::Display + 'a {
struct __SDisplay<'a>(&'a str);
impl<'a> core::fmt::Display for __SDisplay<'a> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
$body;
$internal(self.0, f)
}
}
__SDisplay(haystack)
}
};
}
#[cfg(not(feature = "fmt"))]
#[macro_export]
#[doc(hidden)]
macro_rules! struct_display {
($($tt:tt)*) => {};
}
#[doc(hidden)]
#[macro_export]
#[cfg(feature = "string")]
macro_rules! builder_string {
($name:ident, $fn:path, $fn_name:ident, $builder:ty) => {
pub fn $name(haystack: &str, buffer: &mut String) {
use $fn;
let writer = |s: &str| {
buffer.push_str(s);
Ok::<(), ()>(())
};
let _ = $fn_name::<$builder, _>(haystack, writer);
}
};
}
#[doc(hidden)]
#[macro_export]
#[cfg(feature = "string")]
macro_rules! struct_string {
($($tt:tt)*) => {
$($tt)*;
};
}
#[cfg(not(feature = "string"))]
#[macro_export]
#[doc(hidden)]
macro_rules! struct_string {
($($tt:tt)*) => {};
}
#[doc(hidden)]
#[macro_export]
#[cfg(feature = "bytes")]
macro_rules! builder_bytes {
($name:ident, $fn:path, $fn_name:ident, $builder:ty) => {
pub fn $name(haystack: &str, buffer: &mut Vec<u8>) {
use $fn;
let writer = |s: &str| {
buffer.extend_from_slice(s.as_bytes());
Ok::<(), ()>(())
};
let _ = $fn_name::<$builder, _>(haystack, writer);
}
};
}
#[doc(hidden)]
#[macro_export]
#[cfg(feature = "bytes")]
macro_rules! struct_bytes {
($($tt:tt)*) => {
$($tt)*;
};
}
#[cfg(not(feature = "bytes"))]
#[macro_export]
#[doc(hidden)]
macro_rules! struct_bytes {
($($tt:tt)*) => {};
}