use std::fmt::Write;
#[cfg(feature = "thread-safe")]
pub type SharedRc<T> = std::sync::Arc<T>;
#[cfg(not(feature = "thread-safe"))]
pub type SharedRc<T> = std::rc::Rc<T>;
#[allow(deprecated)]
#[deprecated(since = "0.1.0-rc.16", note = "use `SharedRc` instead")]
pub type SeaRc<T> = SharedRc<T>;
pub type DynIden = SharedRc<dyn Iden>;
pub trait Iden: Send + Sync + std::fmt::Debug {
fn unquoted(&self, s: &mut dyn Write);
fn quoted(&self, q: char, s: &mut dyn Write) {
write!(s, "{}", q).unwrap();
let mut tmp = String::new();
self.unquoted(&mut tmp);
for c in tmp.chars() {
if c == q {
write!(s, "{}{}", q, q).unwrap();
} else {
write!(s, "{}", c).unwrap();
}
}
write!(s, "{}", q).unwrap();
}
fn to_string(&self) -> String {
let mut s = String::new();
self.unquoted(&mut s);
s
}
}
pub trait IdenStatic: Iden + Copy {
fn as_str(&self) -> &'static str;
}
pub trait IntoIden {
fn into_iden(self) -> DynIden;
}
impl<I> IntoIden for I
where
I: Iden + 'static,
{
fn into_iden(self) -> DynIden {
SharedRc::new(self)
}
}
impl IntoIden for DynIden {
fn into_iden(self) -> DynIden {
self
}
}
impl Iden for &'static str {
fn unquoted(&self, s: &mut dyn Write) {
write!(s, "{}", self).unwrap();
}
}
impl Iden for String {
fn unquoted(&self, s: &mut dyn Write) {
write!(s, "{}", self).unwrap();
}
}
#[cfg(test)]
mod tests {
use super::*;
use rstest::rstest;
#[allow(dead_code)]
#[derive(Debug, Clone, Copy)]
enum TestTable {
Table,
Id,
Name,
}
impl Iden for TestTable {
fn unquoted(&self, s: &mut dyn Write) {
let name = match self {
Self::Table => "test_table",
Self::Id => "id",
Self::Name => "name",
};
write!(s, "{}", name).unwrap();
}
}
#[rstest]
fn test_iden_unquoted() {
assert_eq!(TestTable::Table.to_string(), "test_table");
assert_eq!(TestTable::Id.to_string(), "id");
}
#[rstest]
fn test_iden_quoted() {
let mut s = String::new();
TestTable::Table.quoted('"', &mut s);
assert_eq!(s, "\"test_table\"");
}
#[rstest]
fn test_iden_quoted_with_escape() {
#[derive(Debug)]
struct Quoted;
impl Iden for Quoted {
fn unquoted(&self, s: &mut dyn Write) {
write!(s, "table\"with\"quotes").unwrap();
}
}
let mut s = String::new();
Quoted.quoted('"', &mut s);
assert_eq!(s, "\"table\"\"with\"\"quotes\"");
}
#[rstest]
fn test_str_iden() {
assert_eq!("my_column".to_string(), "my_column");
}
#[rstest]
fn test_into_iden() {
let _dyn_iden: DynIden = TestTable::Table.into_iden();
let _dyn_iden2: DynIden = "column_name".into_iden();
}
#[rstest]
fn test_shared_rc_stores_value() {
let value: SharedRc<String> = SharedRc::new("hello".to_string());
assert_eq!(*value, "hello");
}
}