use std::fmt;
use std::ops::Deref;
#[derive(Copy, Clone)]
pub struct ColumnName(ConstString<63>);
impl ColumnName {
pub const fn placeholder() -> Self {
Self(ConstString::new())
}
pub const fn new(name: &str) -> Self {
let mut this = ConstString::<63>::new();
if this.try_push_str(name).is_err() {
panic!("Column names can't be larger than 63 bytes. Please choose a shorter name or consider using #[rorm(rename = \"...\")].");
}
Self(this)
}
pub const fn as_str(&self) -> &str {
self.0.as_str()
}
pub const fn as_bytes(&self) -> &[u8] {
self.0.as_bytes()
}
pub const fn join(mut self, sub_field: &str) -> Self {
let r1 = self.0.try_push_str("_");
let r2 = self.0.try_push_str(sub_field);
if r1.is_err() || r2.is_err() {
panic!("Column names can't be larger than 63 bytes. Please choose a shorter name or consider using #[rorm(rename = \"...\")].");
}
self
}
}
impl Deref for ColumnName {
type Target = str;
fn deref(&self) -> &Self::Target {
self.as_str()
}
}
impl fmt::Debug for ColumnName {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Debug::fmt(self.as_str(), f)
}
}
impl fmt::Display for ColumnName {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Display::fmt(self.as_str(), f)
}
}
#[derive(Copy, Clone)]
struct ConstString<const MAX_LEN: usize> {
len: u8,
bytes: [u8; MAX_LEN],
}
impl<const MAX_LEN: usize> ConstString<MAX_LEN> {
pub const fn new() -> Self {
if MAX_LEN > u8::MAX as usize {
panic!("ConstString only supports a MAX_LENGTH of at most 255");
}
Self {
len: 0,
bytes: [0; MAX_LEN],
}
}
pub const fn len(&self) -> usize {
self.len as usize
}
pub const fn as_str(&self) -> &str {
let bytes = self.as_bytes();
unsafe { std::str::from_utf8_unchecked(bytes) }
}
pub const fn as_bytes<'a>(&'a self) -> &'a [u8] {
let mut len = self.len();
if len > self.bytes.len() {
len = self.bytes.len();
}
unsafe { std::slice::from_raw_parts::<'a, u8>(self.bytes.as_ptr(), len) }
}
pub const fn try_push_str(&mut self, string: &str) -> Result<(), ()> {
let mut bytes = string.as_bytes();
while let [byte, remaining @ ..] = bytes {
bytes = remaining;
if self.len() == MAX_LEN {
return Err(());
}
self.bytes[self.len()] = *byte;
self.len += 1;
}
Ok(())
}
}