use core::fmt::{self, Display, Write};
use std::str::FromStr;
type DisplayArgs<'display_data> = &'display_data [&'display_data dyn Display];
#[derive(Debug, Clone, Copy)]
pub struct CapacityError;
pub struct LazyFormat<F> {
formatter: F,
}
impl<F> LazyFormat<F>
where
F: Fn(&mut fmt::Formatter<'_>) -> fmt::Result,
{
#[must_use]
#[inline]
pub const fn new(formatter: F) -> Self {
Self { formatter }
}
}
impl<F> Display for LazyFormat<F>
where
F: Fn(&mut fmt::Formatter<'_>) -> fmt::Result,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
(self.formatter)(f)
}
}
pub struct StringBuilder<const N: usize> {
buffer: [u8; N],
len: usize,
}
impl<const N: usize> Default for StringBuilder<N> {
fn default() -> Self {
Self::new()
}
}
impl<const N: usize> StringBuilder<N> {
#[must_use]
#[inline]
pub const fn new() -> Self {
Self {
buffer: [0u8; N],
len: 0,
}
}
#[inline]
pub fn push_str(&mut self, s: &str) -> Result<(), fmt::Error> {
let bytes = s.as_bytes();
if self.len + bytes.len() > N {
return Err(fmt::Error);
}
self.buffer[self.len..self.len + bytes.len()].copy_from_slice(bytes);
self.len += bytes.len();
Ok(())
}
#[inline]
pub fn push_char(&mut self, c: char) -> Result<(), fmt::Error> {
let mut buffer = [0u8; 4];
let s = c.encode_utf8(&mut buffer);
self.push_str(s)
}
#[must_use]
#[inline]
pub fn as_str(&self) -> &str {
unsafe { std::str::from_utf8_unchecked(&self.buffer[..self.len]) }
}
#[must_use]
#[inline]
pub fn into_string(self) -> String {
self.as_str().to_string()
}
#[inline]
pub const fn clear(&mut self) {
self.len = 0;
}
}
impl<const N: usize> Write for StringBuilder<N> {
fn write_str(&mut self, s: &str) -> fmt::Result {
self.push_str(s)
}
fn write_char(&mut self, c: char) -> fmt::Result {
self.push_char(c)
}
}
impl<const N: usize> Display for StringBuilder<N> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(self.as_str())
}
}
pub struct ChunkedTargets<I> {
iter: I,
chunk_size: usize,
}
impl<I> ChunkedTargets<I> {
#[must_use]
#[inline]
pub const fn new(iter: I, chunk_size: usize) -> Self {
Self { iter, chunk_size }
}
}
impl<I, T> Iterator for ChunkedTargets<I>
where
I: Iterator<Item = T>,
{
type Item = smallvec::SmallVec<[T; 8]>;
fn next(&mut self) -> Option<Self::Item> {
let mut chunk = smallvec::SmallVec::new();
for _ in 0..self.chunk_size {
if let Some(item) = self.iter.next() {
chunk.push(item);
} else {
break;
}
}
if chunk.is_empty() {
None
} else {
Some(chunk)
}
}
}
pub struct TargetDisplay<'target_data> {
target: &'target_data crate::types::Target,
}
impl<'target_data> TargetDisplay<'target_data> {
#[must_use]
#[inline]
pub const fn new(target: &'target_data crate::types::Target) -> Self {
Self { target }
}
}
impl Display for TargetDisplay<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self.target {
crate::types::Target::Tcp { host, port } => {
write!(f, "{host}:{port}")
}
crate::types::Target::Http { url, .. } => Display::fmt(url, f),
}
}
}
pub struct ErrorMessage<'message_data> {
template: &'static str,
args: DisplayArgs<'message_data>,
}
impl<'message_data> ErrorMessage<'message_data> {
#[must_use]
#[inline]
pub const fn new(template: &'static str, args: DisplayArgs<'message_data>) -> Self {
Self { template, args }
}
}
impl Display for ErrorMessage<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut parts = self.template.split("{}");
if let Some(first) = parts.next() {
f.write_str(first)?;
}
for (i, part) in parts.enumerate() {
if let Some(arg) = self.args.get(i) {
Display::fmt(arg, f)?;
}
f.write_str(part)?;
}
Ok(())
}
}
pub struct ValidatedPort<const MIN: u16, const MAX: u16>(u16);
impl<const MIN: u16, const MAX: u16> ValidatedPort<MIN, MAX> {
#[must_use]
#[inline]
pub const fn new(port: u16) -> Option<Self> {
if port >= MIN && port <= MAX && port != 0 {
Some(Self(port))
} else {
None
}
}
#[must_use]
#[inline]
pub const fn get(&self) -> u16 {
self.0
}
}
pub type WellKnownPort = ValidatedPort<1, 1023>;
pub type RegisteredPort = ValidatedPort<1024, 49151>;
pub type DynamicPort = ValidatedPort<49152, 65535>;
pub struct ConstRetryStrategy<const MAX_ATTEMPTS: u32, const INTERVAL_MS: u64>;
impl<const MAX_ATTEMPTS: u32, const INTERVAL_MS: u64> Default
for ConstRetryStrategy<MAX_ATTEMPTS, INTERVAL_MS>
{
#[inline]
fn default() -> Self {
Self::new()
}
}
impl<const MAX_ATTEMPTS: u32, const INTERVAL_MS: u64>
ConstRetryStrategy<MAX_ATTEMPTS, INTERVAL_MS>
{
#[must_use]
#[inline]
pub const fn new() -> Self {
Self
}
#[must_use]
#[inline]
pub const fn max_attempts(&self) -> u32 {
MAX_ATTEMPTS
}
#[must_use]
#[inline]
pub const fn interval_ms(&self) -> u64 {
INTERVAL_MS
}
#[must_use]
#[inline]
pub const fn should_retry(&self, attempt: u32) -> bool {
attempt < MAX_ATTEMPTS
}
}
#[derive(Debug, Clone)]
pub struct SmallString<const N: usize> {
data: [u8; N],
len: usize,
}
impl<const N: usize> Default for SmallString<N> {
#[inline]
fn default() -> Self {
Self::new()
}
}
impl<const N: usize> SmallString<N> {
#[must_use]
#[inline]
pub const fn new() -> Self {
Self {
data: [0u8; N],
len: 0,
}
}
#[must_use]
#[inline]
pub fn try_from_str(s: &str) -> Option<Self> {
if s.len() > N {
return None;
}
let mut result = Self::new();
let bytes = s.as_bytes();
result.data[..bytes.len()].copy_from_slice(bytes);
result.len = bytes.len();
Some(result)
}
#[must_use]
#[inline]
pub fn as_str(&self) -> &str {
unsafe { std::str::from_utf8_unchecked(&self.data[..self.len]) }
}
#[must_use]
#[inline]
pub const fn len(&self) -> usize {
self.len
}
#[must_use]
#[inline]
pub const fn is_empty(&self) -> bool {
self.len == 0
}
#[inline]
pub fn push_str(&mut self, s: &str) -> Result<(), CapacityError> {
let bytes = s.as_bytes();
if self.len + bytes.len() > N {
return Err(CapacityError);
}
self.data[self.len..self.len + bytes.len()].copy_from_slice(bytes);
self.len += bytes.len();
Ok(())
}
}
impl<const N: usize> Display for SmallString<N> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(self.as_str())
}
}
impl<const N: usize> AsRef<str> for SmallString<N> {
fn as_ref(&self) -> &str {
self.as_str()
}
}
impl<const N: usize> PartialEq<str> for SmallString<N> {
fn eq(&self, other: &str) -> bool {
self.as_str() == other
}
}
impl<const N: usize> PartialEq<&str> for SmallString<N> {
fn eq(&self, other: &&str) -> bool {
self.as_str() == *other
}
}
impl<const N: usize> FromStr for SmallString<N> {
type Err = CapacityError;
fn from_str(s: &str) -> Result<Self, CapacityError> {
Self::try_from_str(s).ok_or(CapacityError)
}
}
#[macro_export]
macro_rules! zero_alloc_error {
($template:literal $(, $arg:expr)*) => {{
let args: &[&dyn std::fmt::Display] = &[$(&$arg),*];
$crate::zero_cost::ErrorMessage::new($template, args)
}};
}
#[macro_export]
macro_rules! lazy_format {
($($arg:tt)*) => {
$crate::zero_cost::LazyFormat::new(move |f| write!(f, $($arg)*))
};
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn string_builder() {
let mut builder = StringBuilder::<64>::new();
builder.push_str("Hello").unwrap();
builder.push_str(" ").unwrap();
builder.push_str("World").unwrap();
assert_eq!(builder.as_str(), "Hello World");
}
#[test]
fn small_string() {
let s = SmallString::<32>::try_from_str("test").unwrap();
assert_eq!(s.as_str(), "test");
assert_eq!(s.len(), 4);
}
#[test]
fn validated_port() {
let port = WellKnownPort::new(80).unwrap();
assert_eq!(port.get(), 80);
assert!(WellKnownPort::new(0).is_none());
assert!(WellKnownPort::new(1024).is_none());
}
#[test]
fn const_retry_strategy() {
let strategy = ConstRetryStrategy::<3, 1000>::new();
assert_eq!(strategy.max_attempts(), 3);
assert_eq!(strategy.interval_ms(), 1000);
assert!(strategy.should_retry(2));
assert!(!strategy.should_retry(3));
}
}