use core::{slice, str};
use crate::errors::{
LenNotEqual, ReplaceWithPadCharError, ReplaceWithPadError, ReplacementTooLong,
};
pub fn replace<'a>(s: &'a mut str, r: &str) -> Result<&'a mut str, LenNotEqual> {
if r.len() != s.len() {
return Err(LenNotEqual);
}
unsafe { s.as_bytes_mut() }.copy_from_slice(r.as_bytes());
Ok(s)
}
pub fn replace_with_pad_space<'a>(
s: &'a mut str,
r: &str,
) -> Result<&'a mut str, ReplacementTooLong> {
if r.len() > s.len() {
return Err(ReplacementTooLong);
}
let (slice, remaining) = unsafe { s.as_bytes_mut() }.split_at_mut(r.len());
slice.copy_from_slice(r.as_bytes());
remaining.fill(b' ');
Ok(unsafe { str::from_utf8_unchecked_mut(slice) })
}
pub fn replace_with_pad<'a>(
s: &'a mut str,
r: &str,
pad: u8,
) -> Result<&'a mut str, ReplaceWithPadError> {
if r.len() > s.len() {
return Err(ReplaceWithPadError::CHAR_LEN);
}
str::from_utf8(&[pad])?;
let (slice, remaining) = unsafe { s.as_bytes_mut() }.split_at_mut(r.len());
slice.copy_from_slice(r.as_bytes());
remaining.fill(pad);
Ok(unsafe { str::from_utf8_unchecked_mut(slice) })
}
pub fn replace_with_pad_char<'a, C>(
s: &'a mut str,
r: &str,
pad_char: C,
) -> Result<&'a mut str, ReplaceWithPadCharError>
where
C: Into<char>,
{
let pad_char = pad_char.into();
if r.len() > s.len() {
return Err(ReplaceWithPadCharError::CHAR_LEN);
}
if pad_char.len_utf8() != 1 {
return Err(ReplaceWithPadCharError::PadCharTooLong);
}
let mut pad: u8 = 0;
pad_char.encode_utf8(slice::from_mut(&mut pad));
let (slice, remaining) = unsafe { s.as_bytes_mut() }.split_at_mut(r.len());
slice.copy_from_slice(r.as_bytes());
remaining.fill(pad);
Ok(unsafe { str::from_utf8_unchecked_mut(slice) })
}
pub fn replace_with_pad_left_space<'a>(
s: &'a mut str,
r: &str,
) -> Result<&'a mut str, ReplacementTooLong> {
if r.len() > s.len() {
return Err(ReplacementTooLong);
}
let mid = s.len() - r.len();
let (remaining, slice) = unsafe { s.as_bytes_mut() }.split_at_mut(mid);
slice.copy_from_slice(r.as_bytes());
remaining.fill(b' ');
Ok(unsafe { str::from_utf8_unchecked_mut(slice) })
}
pub fn replace_with_pad_left<'a>(
s: &'a mut str,
r: &str,
pad: u8,
) -> Result<&'a mut str, ReplaceWithPadError> {
if r.len() > s.len() {
return Err(ReplaceWithPadError::CHAR_LEN);
}
str::from_utf8(&[pad])?;
let mid = s.len() - r.len();
let (remaining, slice) = unsafe { s.as_bytes_mut() }.split_at_mut(mid);
slice.copy_from_slice(r.as_bytes());
remaining.fill(pad);
Ok(unsafe { str::from_utf8_unchecked_mut(slice) })
}
pub fn replace_with_pad_left_char<'a, C>(
s: &'a mut str,
r: &str,
pad_char: C,
) -> Result<&'a mut str, ReplaceWithPadCharError>
where
C: Into<char>,
{
let pad_char = pad_char.into();
if r.len() > s.len() {
return Err(ReplaceWithPadCharError::CHAR_LEN);
}
if pad_char.len_utf8() != 1 {
return Err(ReplaceWithPadCharError::PadCharTooLong);
}
let mut pad: u8 = 0;
pad_char.encode_utf8(slice::from_mut(&mut pad));
let mid = s.len() - r.len();
let (remaining, slice) = unsafe { s.as_bytes_mut() }.split_at_mut(mid);
slice.copy_from_slice(r.as_bytes());
remaining.fill(pad);
Ok(unsafe { str::from_utf8_unchecked_mut(slice) })
}