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
139
140
141
142
/*!
Implementation of the Elasticsearch `date` type.

Dates in Elasticsearch are exposed as a formatted `string` which can contain a `date` and/or a `time` component.

All dates used by `elastic_types` are expected to be given in `Utc`, and if no time is supplied, then 12:00am will be used instead.
Where performance is paramount, the `EpochMillis` date format will parse and format dates the fastest.

# Date types

## `Date<M>`

The `Date<M>` type and `chrono`s `DateTime<Utc>` are the main `date` field types you add to document types.
If the mapping and format aren't important, use `DateTime<Utc>`.
If you need to specify mapping properties like `boost`, or use a specific format like `epoch_millis`, use `Date<M>`.

## `DateValue` and `FormattableDateValue<F>`

The `DateValue` and `FormattableDateValue<F>` types are used in methods to represent dates that either don't have a format or have a specific format respectively.
`Date` and `DateTime<Utc>` can freely convert to and from these types, so you probably won't need to interact with them directly.

# Examples

For defining your own date mapping, see [mapping details](mapping/trait.DateMapping.html#derive-mapping).

Map with a default `date`:

```
# extern crate chrono;
# extern crate elastic_types;
# use elastic_types::prelude::*;
# fn main() {
use chrono::{DateTime, Utc};

struct MyType {
    pub field: DateTime<Utc>
}
# }
```

For custom formats, the most ergonomic approach is to declare a type alias using the mapping and format:

```
# use elastic_types::prelude::*;
type Timestamp = Date<DefaultDateMapping<EpochMillis>>;

struct MyType {
    pub field: Timestamp
}
```

Map with a custom `date` mapping:

```
# extern crate serde;
# #[macro_use]
# extern crate elastic_types;
# use std::marker::PhantomData;
# use elastic_types::prelude::*;
# fn main() {
# use elastic_types::prelude::*;
# #[derive(Default)]
# struct MyDateMapping;
# impl DateMapping for MyDateMapping { type Format = EpochMillis; }
struct MyType {
    pub field: Date<MyDateMapping>
}
# }
```

## Creating Formats

To make it easier to build your own date formats, derive `ElasticDateFormat` on a unit struct.
This will convert an Elasticsearch format string into a `Vec<chrono::format::Item>` for efficient parsing and formatting at runtime:

```
# #[macro_use]
# extern crate elastic_types;
# #[macro_use]
# extern crate elastic_types_derive;
# extern crate chrono;
# use elastic_types::prelude::*;
# fn main() {
#[derive(Default, ElasticDateFormat)]
#[elastic(date_format="yyyy-MM-dd'T'HH:mm:ss")]
struct MyFormat;
# }
```

You can also manually implement `DateFormat` and write your own arbitrary format/parse logic:

```
# extern crate elastic_types;
# extern crate chrono;
# use elastic_types::prelude::*;
# fn main() {
use chrono::{DateTime, Utc};

#[derive(Default, Clone)]
struct Rfc3339Format;
impl DateFormat for Rfc3339Format {
    fn name() -> &'static str { "yyyy-MM-dd'T'HH:mm:ssZ" }

    fn format<'a>(date: &'a DateValue) -> FormattedDate<'a> {
        date.to_rfc3339().into()
    }

    fn parse(date: &str) -> Result<DateValue, ParseError> {
        let date = DateTime::parse_from_rfc3339(date)?;

        Ok(DateTime::from_utc(date.naive_local(), Utc).into())
    }
}
# }
```

# Links
- [Elasticsearch Doc](https://www.elastic.co/guide/en/elasticsearch/reference/current/date.html)
*/

pub mod mapping;

mod format;
mod formats;
mod impls;
pub use self::format::*;
pub use self::impls::*;
pub use self::formats::*;

pub mod prelude {
    /*!
    Includes all types for the `date` type.
    
    This is a convenience module to make it easy to build mappings for multiple types without too many `use` statements.
    */

    pub use super::DefaultDateFormat;
    pub use super::format::*;
    pub use super::impls::*;
    pub use super::formats::*;
    pub use super::mapping::*;
}