use serialize::json::Json;
use time::Timespec;
use uuid::Uuid;
use std::sync::Arc;
use from::{Table};
use sql::{ToSql};
use expression::{Expression, UntypedExpression, RcExpression, BoxedExpression};
pub trait Field {
fn name(&self) -> &str;
fn table_name(&self) -> &str;
fn qual(&self) -> Option<&String>;
fn upcast_field(&self) -> RcField;
}
pub type BoxedField = Box<Field + Send + Sync>;
pub type RcField = Arc<BoxedField>;
#[deriving(Clone)]
pub struct NamedField<T> {
pub name: String,
pub table_name: String,
pub qual: Option<String>
}
impl<T: Clone> NamedField<T> {
pub fn new(name: &str, table_name: &str) -> NamedField<T> {
NamedField {
name: name.to_string(),
table_name: table_name.to_string(),
qual: None
}
}
pub fn new_qual(name: &str, table_name: &str, qual: &str) -> NamedField<T> {
NamedField {
name: name.to_string(),
table_name: table_name.to_string(),
qual: Some(qual.to_string())
}
}
pub fn field_of(name: &str, table: &Table) -> NamedField<T> {
NamedField {
name: name.to_string(),
table_name: table.get_table_name().to_string(),
qual: table.get_table_alias().as_ref().map(|v| v.to_string())
}
}
pub fn qual(&self) -> NamedField<T> {
let mut field = self.clone();
field.qual = Some(self.table_name.to_string());
field
}
pub fn qual_with(&self, qual: &str) -> NamedField<T> {
let mut field = self.clone();
field.qual = Some(qual.to_string());
field
}
pub fn qual_for(&self, table: &Table) -> NamedField<T> {
let mut field = self.clone();
field.qual = table.get_table_alias().as_ref().map(|v| v.to_string());
field
}
}
impl<T: Clone> UntypedExpression for NamedField<T> {
fn expression_as_sql(&self) -> &ToSql {
self
}
fn upcast_expression(&self) -> RcExpression {
Arc::new(box self.clone() as BoxedExpression)
}
}
impl<T: Clone> Expression<T> for NamedField<T> {}
impl<T: Clone> Field for NamedField<T> {
fn name(&self) -> &str {
self.name.as_slice()
}
fn table_name(&self) -> &str {
self.table_name.as_slice()
}
fn qual(&self) -> Option<&String> {
self.qual.as_ref()
}
fn upcast_field(&self) -> RcField {
Arc::new(box self.clone() as BoxedField)
}
}
pub type BoolField = NamedField<bool>;
pub type I8Field = NamedField<i8>;
pub type I16Field = NamedField<i16>;
pub type I32Field = NamedField<i32>;
pub type I64Field = NamedField<i64>;
pub type F32Field = NamedField<f32>;
pub type F64Field = NamedField<f64>;
pub type StringField = NamedField<String>;
pub type ByteListField = NamedField<Vec<u8>>;
pub type JsonField = NamedField<Json>;
pub type TimespecField = NamedField<Timespec>;
pub type UuidField = NamedField<Uuid>;
pub type OptionalBoolField = NamedField<Option<bool>>;
pub type OptionalI8Field = NamedField<Option<i8>>;
pub type OptionalI16Field = NamedField<Option<i16>>;
pub type OptionalI32Field = NamedField<Option<i32>>;
pub type OptionalI64Field = NamedField<Option<i64>>;
pub type OptionalF32Field = NamedField<Option<f32>>;
pub type OptionalF64Field = NamedField<Option<f64>>;
pub type OptionalStringField = NamedField<Option<String>>;
pub type OptionalByteListField = NamedField<Option<Vec<u8>>>;
pub type OptionalJsonField = NamedField<Option<Json>>;
pub type OptionalTimespecField = NamedField<Option<Timespec>>;
pub type OptionalUuidField = NamedField<Option<Uuid>>;