diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index 1865d31f..8abcd50c 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -5,8 +5,8 @@
### Checklist
- [ ] Formatted code using `cargo fmt --all`
- [ ] Linted code using clippy
- - [ ] with reqwest feature: `cargo clippy --manifest-path influxdb/Cargo.toml --all-targets --no-default-features --features serde,derive,reqwest-client-rustls -- -D warnings`
- - [ ] with surf feature: `cargo clippy --manifest-path influxdb/Cargo.toml --all-targets --no-default-features --features serde,derive,hyper-client -- -D warnings`
+ - [ ] with reqwest feature: `cargo clippy --manifest-path influxdb/Cargo.toml --all-targets --no-default-features --features chrono,time,serde,derive,reqwest-client-rustls -- -D warnings`
+ - [ ] with surf feature: `cargo clippy --manifest-path influxdb/Cargo.toml --all-targets --no-default-features --features chrono,time,serde,derive,hyper-client -- -D warnings`
- [ ] Updated README.md using `cargo doc2readme -p influxdb --expand-macros`
- [ ] Reviewed the diff. Did you leave any print statements or unnecessary comments?
- [ ] Any unfinished work that warrants a separate issue captured in an issue with a TODO code comment
diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml
index b07f4a4f..21c560ce 100644
--- a/.github/workflows/rust.yml
+++ b/.github/workflows/rust.yml
@@ -30,9 +30,9 @@ jobs:
- name: Update Cargo.lock
run: cargo --config 'resolver.incompatible-rust-versions="fallback"' update
- name: Check Clippy lints (reqwest)
- run: cargo clippy --manifest-path influxdb/Cargo.toml --locked --all-targets --no-default-features --features serde,derive,reqwest-client-rustls -- -D warnings
+ run: cargo clippy --manifest-path influxdb/Cargo.toml --locked --all-targets --no-default-features --features chrono,time,serde,derive,reqwest-client-rustls -- -D warnings
- name: Check Clippy lints (surf)
- run: cargo clippy --manifest-path influxdb/Cargo.toml --locked --all-targets --no-default-features --features serde,derive,hyper-client -- -D warnings
+ run: cargo clippy --manifest-path influxdb/Cargo.toml --locked --all-targets --no-default-features --features chrono,time,serde,derive,hyper-client -- -D warnings
# this checks that the code is formatted with rustfmt
rustfmt:
@@ -108,8 +108,8 @@ jobs:
key: "${{runner.os}} Rust ${{steps.msrv-toolchain.outputs.cachekey}}"
if: matrix.rust.name == 'MSRV'
# finally we can run tests
- - run: cargo test --lib --locked
- - run: cargo test --doc --locked
+ - run: cargo test --lib --locked --features 'chrono time serde derive'
+ - run: cargo test --doc --locked --features 'chrono time serde derive'
# this tests that all integration tests are successful
integration_tests:
@@ -124,10 +124,6 @@ jobs:
toolchain: stable
nightly: false
http-backend:
- - curl-client
- - h1-client
- - h1-client-rustls
- - hyper-client
- reqwest-client-rustls
- reqwest-client-native-tls
- reqwest-client-native-tls-vendored
@@ -172,10 +168,12 @@ jobs:
key: "${{runner.os}} Rust ${{steps.rust-toolchain.outputs.cachekey}}"
- name: Run tests
run: |
- for test in integration_tests{,_v2}
- do
- cargo test -p influxdb --no-default-features --features 'serde derive ${{matrix.http-backend}}' --no-fail-fast --test $test
- done
+ cargo test -p influxdb \
+ --no-default-features \
+ --features "serde derive chrono time ${{matrix.http-backend}}" \
+ --no-fail-fast \
+ --test integration_tests \
+ --test integration_tests_v2
# this uses cargo-tarpaulin to inspect the code coverage
coverage:
@@ -221,7 +219,7 @@ jobs:
cargo tarpaulin -v \
--target-dir target/tarpaulin \
--workspace \
- --features serde,derive \
+ --features chrono,time,serde,derive \
--exclude-files 'derive/*' \
--exclude-files 'target/*' \
--ignore-panics --ignore-tests \
diff --git a/Cargo.toml b/Cargo.toml
index 37508cab..1b3a9f76 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -7,7 +7,7 @@ resolver = "2"
[workspace.package]
authors = ["Gero Gerke ", "Dominic "]
edition = "2018"
-rust-version = "1.65"
+rust-version = "1.67.1"
license = "MIT"
repository = "https://github.com/influxdb-rs/influxdb-rust"
diff --git a/README.md b/README.md
index 289ed652..bb33e0ea 100644
--- a/README.md
+++ b/README.md
@@ -25,8 +25,8 @@
-
-
+
+
@@ -155,7 +155,7 @@ To communicate with InfluxDB, you can choose the HTTP backend to be used configu
@ 2020-2024 Gero Gerke, msrd0 and [contributors].
[contributors]: https://github.com/influxdb-rs/influxdb-rust/graphs/contributors
- [__cargo_doc2readme_dependencies_info]: ggGkYW0BYXSEGzJ_QpW55zB1G0S-TER-rIfLG2gXv8EYBG3jG1nuXXn-kdx-YXKEG1LaAVLASZMqG5J2qfpyCvbMG_Rohh5BobOmG0DqLv5454SZYWSBgmhpbmZsdXhkYmUwLjcuMg
+ [__cargo_doc2readme_dependencies_info]: ggGkYW0CYXSEGzJ_QpW55zB1G0S-TER-rIfLG2gXv8EYBG3jG1nuXXn-kdx-YXKEG1LaAVLASZMqG5J2qfpyCvbMG_Rohh5BobOmG0DqLv5454SZYWSBgmhpbmZsdXhkYmUwLjcuMg
[__link0]: https://github.com/influxdb-rs/influxdb-rust/blob/main/CONTRIBUTING.md
[__link1]: https://github.com/influxdb-rs/influxdb-rust/blob/main/CODE_OF_CONDUCT.md
[__link10]: https://github.com/alexcrichton/curl-rust
diff --git a/influxdb/Cargo.toml b/influxdb/Cargo.toml
index b0ca36e4..77a9aee8 100644
--- a/influxdb/Cargo.toml
+++ b/influxdb/Cargo.toml
@@ -17,17 +17,18 @@ repository.workspace = true
workspace = true
[dependencies]
-chrono = { version = "0.4.23", features = ["serde"], default-features = false }
+chrono = { version = "0.4.23", features = ["serde"], default-features = false, optional = true }
futures-util = "0.3.17"
http = "0.2.4"
influxdb_derive = { version = "0.5.1", optional = true }
lazy-regex = "3.1"
reqwest = { version = "0.11.4", default-features = false, optional = true }
-surf = { version = "2.2.0", default-features = false, optional = true }
serde = { version = "1.0.186", optional = true }
serde_derive = { version = "1.0.186", optional = true }
serde_json = { version = "1.0.48", optional = true }
+surf = { version = "2.2.0", default-features = false, optional = true }
thiserror = "1.0"
+time = { version = "0.3.39", optional = true }
[features]
default = ["serde", "reqwest-client-rustls"]
@@ -44,6 +45,10 @@ reqwest-client-native-tls = ["reqwest", "reqwest/native-tls-alpn"]
reqwest-client-native-tls-vendored = ["reqwest", "reqwest/native-tls-vendored"]
wasm-client = ["surf", "surf/wasm-client"]
+# etc
+time = ["dep:time"]
+chrono = ["dep:chrono"]
+
[dev-dependencies]
async-std = { version = "1.6.5", features = ["attributes", "tokio02", "tokio1"] }
indoc = "1.0"
diff --git a/influxdb/src/query/mod.rs b/influxdb/src/query/mod.rs
index e83c2241..6268d3ef 100644
--- a/influxdb/src/query/mod.rs
+++ b/influxdb/src/query/mod.rs
@@ -20,9 +20,6 @@
//! assert!(read_query.is_ok());
//! ```
-use chrono::prelude::{DateTime, TimeZone, Utc};
-use std::convert::TryInto;
-
pub mod consts;
mod line_proto_term;
pub mod read_query;
@@ -47,6 +44,21 @@ pub enum Timestamp {
Hours(u128),
}
+impl Timestamp {
+ pub fn nanos(&self) -> u128 {
+ match self {
+ Timestamp::Hours(h) => {
+ h * MINUTES_PER_HOUR * SECONDS_PER_MINUTE * MILLIS_PER_SECOND * NANOS_PER_MILLI
+ }
+ Timestamp::Minutes(m) => m * SECONDS_PER_MINUTE * MILLIS_PER_SECOND * NANOS_PER_MILLI,
+ Timestamp::Seconds(s) => s * MILLIS_PER_SECOND * NANOS_PER_MILLI,
+ Timestamp::Milliseconds(millis) => millis * NANOS_PER_MILLI,
+ Timestamp::Microseconds(micros) => micros * NANOS_PER_MICRO,
+ Timestamp::Nanoseconds(nanos) => *nanos,
+ }
+ }
+}
+
impl fmt::Display for Timestamp {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
use Timestamp::*;
@@ -57,44 +69,52 @@ impl fmt::Display for Timestamp {
}
}
-impl From for DateTime {
- fn from(ts: Timestamp) -> DateTime {
- match ts {
- Timestamp::Hours(h) => {
- let nanos =
- h * MINUTES_PER_HOUR * SECONDS_PER_MINUTE * MILLIS_PER_SECOND * NANOS_PER_MILLI;
- Utc.timestamp_nanos(nanos.try_into().unwrap())
- }
- Timestamp::Minutes(m) => {
- let nanos = m * SECONDS_PER_MINUTE * MILLIS_PER_SECOND * NANOS_PER_MILLI;
- Utc.timestamp_nanos(nanos.try_into().unwrap())
- }
- Timestamp::Seconds(s) => {
- let nanos = s * MILLIS_PER_SECOND * NANOS_PER_MILLI;
- Utc.timestamp_nanos(nanos.try_into().unwrap())
- }
- Timestamp::Milliseconds(millis) => {
- let nanos = millis * NANOS_PER_MILLI;
- Utc.timestamp_nanos(nanos.try_into().unwrap())
- }
- Timestamp::Nanoseconds(nanos) => Utc.timestamp_nanos(nanos.try_into().unwrap()),
- Timestamp::Microseconds(micros) => {
- let nanos = micros * NANOS_PER_MICRO;
- Utc.timestamp_nanos(nanos.try_into().unwrap())
- }
- }
+#[cfg(feature = "chrono")]
+impl From for chrono::DateTime {
+ fn from(ts: Timestamp) -> chrono::DateTime {
+ use chrono::TimeZone as _;
+ chrono::Utc.timestamp_nanos(ts.nanos() as i64)
}
}
-impl From> for Timestamp
+#[cfg(feature = "chrono")]
+impl From> for Timestamp
where
- T: TimeZone,
+ T: chrono::TimeZone,
{
- fn from(date_time: DateTime) -> Self {
+ fn from(date_time: chrono::DateTime) -> Self {
Timestamp::Nanoseconds(date_time.timestamp_nanos_opt().unwrap() as u128)
}
}
+#[cfg(feature = "time")]
+impl From for time::UtcDateTime {
+ fn from(value: Timestamp) -> Self {
+ time::UtcDateTime::from_unix_timestamp_nanos(value.nanos() as i128).unwrap()
+ }
+}
+
+#[cfg(feature = "time")]
+impl From for Timestamp {
+ fn from(value: time::UtcDateTime) -> Self {
+ Timestamp::Nanoseconds(value.unix_timestamp_nanos() as u128)
+ }
+}
+
+#[cfg(feature = "time")]
+impl From for time::OffsetDateTime {
+ fn from(value: Timestamp) -> Self {
+ time::OffsetDateTime::from_unix_timestamp_nanos(value.nanos() as i128).unwrap()
+ }
+}
+
+#[cfg(feature = "time")]
+impl From for Timestamp {
+ fn from(value: time::OffsetDateTime) -> Self {
+ Timestamp::Nanoseconds(value.unix_timestamp_nanos() as u128)
+ }
+}
+
pub trait Query {
/// Builds valid InfluxSQL which can be run against the Database.
/// In case no fields have been specified, it will return an error,
@@ -235,7 +255,6 @@ mod tests {
MILLIS_PER_SECOND, MINUTES_PER_HOUR, NANOS_PER_MICRO, NANOS_PER_MILLI, SECONDS_PER_MINUTE,
};
use crate::query::{Timestamp, ValidQuery};
- use chrono::prelude::{DateTime, TimeZone, Utc};
use std::convert::TryInto;
#[test]
fn test_equality_str() {
@@ -252,8 +271,10 @@ mod tests {
fn test_format_for_timestamp_else() {
assert!(format!("{}", Timestamp::Nanoseconds(100)) == "100");
}
+ #[cfg(feature = "chrono")]
#[test]
fn test_chrono_datetime_from_timestamp_hours() {
+ use chrono::prelude::*;
let datetime_from_timestamp: DateTime = Timestamp::Hours(2).into();
assert_eq!(
Utc.timestamp_nanos(
@@ -264,8 +285,10 @@ mod tests {
datetime_from_timestamp
)
}
+ #[cfg(feature = "chrono")]
#[test]
fn test_chrono_datetime_from_timestamp_minutes() {
+ use chrono::prelude::*;
let datetime_from_timestamp: DateTime = Timestamp::Minutes(2).into();
assert_eq!(
Utc.timestamp_nanos(
@@ -276,8 +299,10 @@ mod tests {
datetime_from_timestamp
)
}
+ #[cfg(feature = "chrono")]
#[test]
fn test_chrono_datetime_from_timestamp_seconds() {
+ use chrono::prelude::*;
let datetime_from_timestamp: DateTime = Timestamp::Seconds(2).into();
assert_eq!(
Utc.timestamp_nanos(
@@ -288,29 +313,37 @@ mod tests {
datetime_from_timestamp
)
}
+ #[cfg(feature = "chrono")]
#[test]
fn test_chrono_datetime_from_timestamp_millis() {
+ use chrono::prelude::*;
let datetime_from_timestamp: DateTime = Timestamp::Milliseconds(2).into();
assert_eq!(
Utc.timestamp_nanos((2 * NANOS_PER_MILLI).try_into().unwrap()),
datetime_from_timestamp
)
}
+ #[cfg(feature = "chrono")]
#[test]
fn test_chrono_datetime_from_timestamp_nanos() {
+ use chrono::prelude::*;
let datetime_from_timestamp: DateTime = Timestamp::Nanoseconds(1).into();
assert_eq!(Utc.timestamp_nanos(1), datetime_from_timestamp)
}
+ #[cfg(feature = "chrono")]
#[test]
fn test_chrono_datetime_from_timestamp_micros() {
+ use chrono::prelude::*;
let datetime_from_timestamp: DateTime = Timestamp::Microseconds(2).into();
assert_eq!(
Utc.timestamp_nanos((2 * NANOS_PER_MICRO).try_into().unwrap()),
datetime_from_timestamp
)
}
+ #[cfg(feature = "chrono")]
#[test]
fn test_timestamp_from_chrono_date() {
+ use chrono::prelude::*;
let timestamp_from_datetime: Timestamp = Utc
.with_ymd_and_hms(1970, 1, 1, 0, 0, 1)
.single()