use std::fmt::Display;
use crate::errors::PgmqError;
#[derive(Clone, Copy)]
pub struct CheckedName<'a>(&'a str);
impl<'a> CheckedName<'a> {
pub fn new(input: &'a str) -> Result<Self, PgmqError> {
check_input(input)?;
Ok(Self(input))
}
}
impl AsRef<str> for CheckedName<'_> {
fn as_ref(&self) -> &str {
self.0
}
}
impl Display for CheckedName<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(self.0)
}
}
pub fn check_input(input: &str) -> Result<(), PgmqError> {
const NAMEDATALEN: usize = 64;
const MAX_IDENTIFIER_LEN: usize = NAMEDATALEN - 1;
const BIGGEST_CONCAT: &str = "archived_at_idx_";
const MAX_PGMQ_QUEUE_LEN: usize = MAX_IDENTIFIER_LEN - BIGGEST_CONCAT.len();
let is_short_enough = input.len() <= MAX_PGMQ_QUEUE_LEN;
let has_valid_characters = input
.as_bytes()
.iter()
.all(|&c| c.is_ascii_alphanumeric() || c == b'_');
let valid = is_short_enough && has_valid_characters;
match valid {
true => Ok(()),
false => Err(PgmqError::InvalidQueueName {
name: input.to_owned(),
}),
}
}