/*
Copyright 2020-2023, Savanni D'Gerinel <savanni@luminescent-dreams.com>

This file is part of the Luminescent Dreams Tools.

Luminescent Dreams Tools is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

Luminescent Dreams Tools is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with Lumeto. If not, see <https://www.gnu.org/licenses/>.
*/

/*! An Embedded Time Series Database

This library provides a low-intensity time series database meant to be embedded inside of an
application.

From the signature of the series

```text
pub struct Series<T: Clone + Recordable + DeserializeOwned + Serialize> {
```

you can know that you must parameterize the series over the data type that you want to store,
which must also have several traits implemented.

```text
#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
struct BikeTrip {
    datetime: DateTime<Utc>,
    distance: Distance,
    duration: Duration,
    comments: String,
}

impl Recordable for BikeTrip {
    fn timestamp(&self) -> DateTime<Utc> {
        self.datetime
    }
    fn tags(&self) -> Vec<String> {
        Vec::new()
    }
}
```

Recordable requires implementations for `timestamp` and `tags`, both of which can be used for
searching for records, and both of which may be used for indexing in the future.

The series can only store a single data type, but you can always store multiple data types by
wrapping them into a single enum.

Open the series:

```text
let mut ts: Series<BikeTrip> = Series::open("var/bike_trips.json")
    .expect("expect the time series to open correctly");
```

The series file will be created if it does not already exist. If it does already exist, the existing data will be read into memory and made available.

Note: all of the data is read into memory at once. For human-scale things, this probably takes up very little memory, but this software is not optimized for IoT scale deployments. Additionally, this library assumes only one process is writing to the file. Behavior from more than one process writing to the file is currently undefined.
*/

#[macro_use]
extern crate serde_derive;
extern crate chrono;
extern crate chrono_tz;
extern crate serde;
extern crate serde_json;
extern crate thiserror;
extern crate uuid;

mod criteria;
mod series;
mod types;

pub use criteria::*;
pub use series::Series;
pub use types::{EmseriesReadError, EmseriesWriteError, Record, RecordId, Recordable, Timestamp};
