1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
use std::{fmt, rc};
use std::marker;
use serde_json;
use chrono;
use uuid;

use super::from;
use super::sql;
use super::expression;

pub trait Field {
    fn name(&self) -> &str;
    fn table_name(&self) -> &str;
    fn qual(&self) -> Option<&String>;
    fn upcast_field(&self) -> SharedField;
}

impl fmt::Debug for Field {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Field: {}", self.name())
    }
}

pub type BoxedField = Box<Field + 'static>;
pub type SharedField = rc::Rc<BoxedField>;

#[derive(Clone, Debug)]
pub struct NamedField<T> {
    pub name: String,
    pub table_name: String,
    pub qual: Option<String>,

    _marker: marker::PhantomData<T>,
}

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,

            _marker: marker::PhantomData,
        }
    }

    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()),

            _marker: marker::PhantomData,
        }
    }

    pub fn field_of(name: &str, table: &from::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()),

            _marker: marker::PhantomData,
        }
    }

    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: &from::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 + 'static + fmt::Debug> expression::UntypedExpression for NamedField<T> {
    fn expression_as_sql(&self) -> &sql::ToSql {
        self
    }

    fn upcast_expression(&self) -> expression::SharedExpression {
        rc::Rc::new(Box::new(self.clone()) as expression::BoxedExpression)
    }
}

impl<T: Clone + 'static> Field for NamedField<T> {
    fn name(&self) -> &str {
        &self.name
    }

    fn table_name(&self) -> &str {
        &self.table_name
    }

    fn qual(&self) -> Option<&String> {
        self.qual.as_ref()
    }

    fn upcast_field(&self) -> SharedField {
        rc::Rc::new(Box::new(self.clone()))
    }
}

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<serde_json::Value>;
pub type TimespecField = NamedField<chrono::NaiveDateTime>;
pub type UuidField = NamedField<uuid::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<serde_json::Value>>;
pub type OptionalTimespecField = NamedField<Option<chrono::NaiveDateTime>>;
pub type OptionalUuidField = NamedField<Option<uuid::Uuid>>;