use crate::errors::IdError;
use surrealdb::sql::Id;
pub trait NewId: Sized {
const TABLE: &'static str;
fn new<T: AsRef<str>>(id: T) -> Result<Self, IdError> {
let id_ref = id.as_ref();
let is_empty = id_ref.is_empty();
if is_empty {
return Err(IdError::IdCannotBeEmpty);
}
let mut split_at_colon = id_ref.splitn(2, ':');
let table_part = split_at_colon.next().unwrap_or(Self::TABLE);
let id_part = split_at_colon.next().unwrap_or(id_ref);
let start_bracket_count = id_ref.chars().filter(|&c| c == '⟨').count();
let end_bracket_count = id_ref.chars().filter(|&c| c == '⟩').count();
let is_valid_format = id_part.starts_with('⟨')
&& id_part.ends_with('⟩')
&& start_bracket_count == 1
&& end_bracket_count == 1;
if is_valid_format {
let id_inner: String = id_part.chars().skip(1).take_while(|&c| c != '⟩').collect();
if id_inner.is_empty() {
return Err(IdError::IdCannotBeEmpty);
}
if table_part != Self::TABLE {
return Err(IdError::InvalidTable(
Self::TABLE.to_string(),
table_part.to_string(),
));
}
return Ok(Self::from_inner_id(id_inner));
}
if id_ref.contains(':') {
return Err(IdError::InvalidIdFormat(id_ref.to_string()));
}
Ok(Self::from_inner_id(id_part.to_string()))
}
fn from_inner_id<T: Into<Id>>(inner_id: T) -> Self;
fn table(&self) -> &'static str {
Self::TABLE
}
fn id_with_brackets(&self) -> String {
format!("⟨{}⟩", &self.id_without_brackets())
}
fn id_without_brackets(&self) -> String {
let original_id = self.get_inner_string();
original_id
.split(':')
.next()
.unwrap_or(&original_id)
.chars()
.filter(|&c| c != '⟨' && c != '⟩')
.collect()
}
fn get_inner_string(&self) -> String;
}