diff --git a/.dockerignore b/.dockerignore
deleted file mode 100644
index 9f97022..0000000
--- a/.dockerignore
+++ /dev/null
@@ -1 +0,0 @@
-target/
\ No newline at end of file
diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
deleted file mode 100644
index 35ffb97..0000000
--- a/.github/ISSUE_TEMPLATE/bug_report.md
+++ /dev/null
@@ -1,14 +0,0 @@
----
-name: Bug report
-about: Report a problem with the library
----
-
-<!-- Please search existing issues and link prior issues if they're closed. -->
-
--   Rust Version:
--   Runtime version (e.g. Tokio):
--   OS Version:
-
-Steps to Reproduce:
-
-1. 2.
diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md
deleted file mode 100644
index ec951b1..0000000
--- a/.github/ISSUE_TEMPLATE/feature_request.md
+++ /dev/null
@@ -1,11 +0,0 @@
----
-name: Feature request
-about: Suggest an idea for this project
----
-
-<!-- Please search existing issues to avoid creating duplicates. If it exists, is closed, and -->
-<!-- you think it should be an issue, please link the old issue and state further arguments   -->
-
-<!-- Describe the feature you'd like. -->
-
-<!-- How could your feature be implemented? -->
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
deleted file mode 100644
index 1865d31..0000000
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ /dev/null
@@ -1,12 +0,0 @@
-## Description
-
-{ describe your changes here }
-
-### 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`
-- [ ] 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/dependabot.yml b/.github/dependabot.yml
deleted file mode 100644
index ce05b98..0000000
--- a/.github/dependabot.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-version: 2
-updates:
-  - package-ecosystem: "github-actions"
-    directory: "/"
-    schedule:
-      interval: weekly
-      time: "06:00"
-      timezone: "Europe/Amsterdam"
diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml
deleted file mode 100644
index d841d77..0000000
--- a/.github/workflows/rust.yml
+++ /dev/null
@@ -1,243 +0,0 @@
-name: Rust
-
-on:
-  push:
-    branches:
-      - main
-  pull_request:
-
-jobs:
-  # this checks that the readme created from rustdoc is up to date
-  readmecheck:
-    name: README Format Check
-    runs-on: ubuntu-latest
-    steps:
-      - uses: actions/checkout@v4
-      - uses: docker://codeberg.org/msrd0/cargo-doc2readme:nightly
-        with:
-          entrypoint: cargo
-          args: doc2readme -p influxdb --expand-macros --check
-
-  # this checks that there are no clippy lints
-  clippy:
-    name: Style Check (clippy)
-    runs-on: ubuntu-latest
-    steps:
-      - uses: actions/checkout@v4
-      - uses: dtolnay/rust-toolchain@1.75.0
-        with:
-          components: clippy
-      - name: Check Clippy lints (reqwest)
-        run: cargo clippy --manifest-path influxdb/Cargo.toml --all-targets --no-default-features --features serde,derive,reqwest-client-rustls -- -D warnings
-      - name: Check Clippy lints (surf)
-        run: cargo clippy --manifest-path influxdb/Cargo.toml --all-targets --no-default-features --features serde,derive,hyper-client -- -D warnings
-
-  # this checks that the code is formatted with rustfmt
-  rustfmt:
-    name: Style Checks (rustfmt)
-    runs-on: ubuntu-latest
-    steps:
-      - uses: actions/checkout@v4
-      - uses: dtolnay/rust-toolchain@nightly
-        with:
-          components: rustfmt
-      - name: Check code formatting
-        run: cargo fmt --all -- --check
-
-  # this checks the msrv
-  msrv:
-    name: Verify MSRV
-    runs-on: ubuntu-latest
-    steps:
-      - uses: actions/checkout@v4
-      - uses: baptiste0928/cargo-install@v3
-        with:
-          crate: cargo-msrv
-      - name: Verify minimum rust version of influxdb crate
-        run: cargo msrv --path influxdb --output-format json verify
-      - name: Verify minimum rust version of influxdb_derive crate
-        run: cargo msrv --path influxdb_derive --output-format json verify
-
-  # this tests that all unit and doc tests are successful
-  unit_tests:
-    name: Unit and Doc Tests (Rust ${{matrix.rust.name}} on ${{matrix.os}})
-    runs-on: ${{matrix.os}}
-    continue-on-error: ${{matrix.rust.nightly}}
-    strategy:
-      fail-fast: false
-      matrix:
-        rust:
-          - name: Stable
-            toolchain: stable
-            nightly: false
-          - name: Beta
-            toolchain: beta
-            nightly: false
-          - name: Nightly
-            toolchain: nightly
-            nightly: true
-        os: [ubuntu-latest, windows-latest, macOS-latest]
-    steps:
-      - uses: actions/checkout@v4
-      - uses: dtolnay/rust-toolchain@master
-        with:
-          toolchain: ${{matrix.rust.toolchain}}
-        id: rust-toolchain
-      - uses: actions/cache@v4
-        with:
-          path: |
-            ~/.cargo/git
-            ~/.cargo/registry
-            target
-          key: "${{matrix.rust.toolchain}} on ${{runner.os}} Rust ${{steps.rust-toolchain.outputs.cachekey}}"
-      - run: cargo test --lib
-      - run: cargo test --doc
-
-  # this tests that all integration tests are successful
-  integration_tests:
-    name: Integration Tests (Rust ${{matrix.rust.name}} with ${{matrix.http-backend}})
-    runs-on: ubuntu-latest
-    continue-on-error: ${{matrix.rust.nightly}}
-    strategy:
-      fail-fast: false
-      matrix:
-        rust:
-          - name: Stable
-            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
-    services:
-      influxdb:
-        image: influxdb:1.8
-        ports:
-          - 8086:8086
-      authed_influxdb:
-        image: influxdb:1.8
-        ports:
-          - 9086:8086
-        env:
-          INFLUXDB_HTTP_AUTH_ENABLED: true
-          INFLUXDB_ADMIN_USER: admin
-          INFLUXDB_ADMIN_PASSWORD: password
-          INFLUXDB_USER: nopriv_user
-          INFLUXDB_USER_PASSWORD: password
-      influxdbv2:
-        image: influxdb:2.6
-        ports:
-          - 2086:8086
-        env:
-          DOCKER_INFLUXDB_INIT_MODE: setup
-          DOCKER_INFLUXDB_INIT_USERNAME: admin
-          DOCKER_INFLUXDB_INIT_PASSWORD: password
-          DOCKER_INFLUXDB_INIT_ORG: testing
-          DOCKER_INFLUXDB_INIT_BUCKET: mydb
-          DOCKER_INFLUXDB_INIT_ADMIN_TOKEN: admintoken
-    steps:
-      - uses: actions/checkout@v4
-      - uses: dtolnay/rust-toolchain@master
-        with:
-          toolchain: ${{matrix.rust.toolchain}}
-        id: rust-toolchain
-      - uses: actions/cache@v4
-        with:
-          path: |
-            ~/.cargo/git
-            ~/.cargo/registry
-            target
-          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
-
-  # this uses cargo-tarpaulin to inspect the code coverage
-  coverage:
-    name: Code Coverage (stable/ubuntu-latest)
-    runs-on: ubuntu-latest
-    services:
-      influxdb:
-        image: influxdb:1.8
-        ports:
-          - 8086:8086
-      authed_influxdb:
-        image: influxdb:1.8
-        ports:
-          - 9086:8086
-        env:
-          INFLUXDB_HTTP_AUTH_ENABLED: true
-          INFLUXDB_ADMIN_USER: admin
-          INFLUXDB_ADMIN_PASSWORD: password
-          INFLUXDB_USER: nopriv_user
-          INFLUXDB_USER_PASSWORD: password
-
-    steps:
-      - uses: actions/checkout@v4
-      - uses: dtolnay/rust-toolchain@stable
-        id: rust-toolchain
-      - name: Get Tarpaulin Version
-        id: tarpaulin-version
-        run: echo "version=$(wget -qO- 'https://crates.io/api/v1/crates/cargo-tarpaulin' | jq -r '.crate.max_stable_version')" >>$GITHUB_OUTPUT
-      - uses: actions/cache@v4
-        with:
-          path: |
-            ~/.cargo/bin/cargo-tarpaulin
-            ~/.cargo/git
-            ~/.cargo/registry
-            target
-          key: "${{runner.os}} Rust ${{steps.rust-version.outputs.version}} tarpaulin ${{steps.tarpaulin-version.outputs.version}}"
-      - name: Install Tarpaulin
-        run: |
-          ls -lh ~/.cargo/bin
-          test -e ~/.cargo/bin/cargo-tarpaulin || cargo install cargo-tarpaulin --version ${{steps.tarpaulin-version.outputs.version}}
-      - name: Run Tarpaulin coverage tests
-        run: |
-          cargo tarpaulin -v \
-            --target-dir target/tarpaulin \
-            --workspace \
-            --features serde,derive \
-            --exclude-files 'derive/*' \
-            --exclude-files 'target/*' \
-            --ignore-panics --ignore-tests \
-            --out Html --out Json
-        env:
-          RUST_BACKTRACE: 1
-          RUST_LOG: info
-      - uses: actions/upload-artifact@v4
-        with:
-          name: tarpaulin-report
-          path: |
-            tarpaulin-report.json
-            tarpaulin-report.html
-
-  # this uploads the code coverage to github pages
-  pages:
-    runs-on: ubuntu-latest
-    needs:
-      - coverage
-    if: github.ref == 'refs/heads/main'
-    steps:
-      - uses: actions/checkout@v4
-        with:
-          ref: gh-pages
-      - uses: actions/download-artifact@v4
-        with:
-          name: tarpaulin-report
-      - run: |
-          coverage=$(jq '.files | { covered: map(.covered) | add, coverable: map(.coverable) | add } | .covered / .coverable * 10000 | round | . / 100' tarpaulin-report.json)
-          color=$([[ $coverage < 80 ]] && printf yellow || printf brightgreen)
-          wget -qO coverage.svg "https://img.shields.io/badge/coverage-$coverage%25-$color"
-
-          git add coverage.svg tarpaulin-report.html
-          git status
-      - uses: stefanzweifel/git-auto-commit-action@v5
-        with:
-          commit_message: "GitHub Pages for ${{ github.sha }}"
diff --git a/.gitignore b/.gitignore
deleted file mode 100644
index 6936990..0000000
--- a/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-/target
-**/*.rs.bk
-Cargo.lock
diff --git a/CHANGELOG.md b/CHANGELOG.md
deleted file mode 100644
index 8357d58..0000000
--- a/CHANGELOG.md
+++ /dev/null
@@ -1,223 +0,0 @@
-# Changelog
-
-All notable changes to this project will be documented in this file.
-
-The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
-and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
-
-## [Unreleased]
-
-## [0.7.2] - 2024-02-14
-
-### Fixed
- - Fixed incorrect timestamp when using nanosecond precision with chrono ([#134](https://github.com/influxdb-rs/influxdb-rust/pull/134))
-
-## [0.7.1] - 2023-09-08
-
-### Added
- - `Eq` and `PartialEq` for our error type ([#127](https://github.com/influxdb-rs/influxdb-rust/pull/127))
-
-### Fixed
- - Not sending authentication token in requests to Influxdb V2 ([#128](https://github.com/influxdb-rs/influxdb-rust/pull/128))
-
-## [0.7.0] - 2023-07-03
-
-### Changed
- -  Opt-in Line-Protocol for Compatibility Mode ([#123](https://github.com/influxdb-rs/influxdb-rust/pull/123))
- -  Use cargo doc2readme instead of cargo readme ([#125](https://github.com/influxdb-rs/influxdb-rust/pull/125))
-
-## [0.6.0] - 2023-03-04
-
-### Changed
- - Unsigned integers are no longer treated as signed integers ([#113](https://github.com/influxdb-rs/influxdb-rust/pull/113))
-
-### Added
- - Support for token auth ([#118](https://github.com/influxdb-rs/influxdb-rust/pull/118))
-
-## [0.5.2] - 2022-02-04
-
-### Changed
- - disable default features of `chrono`
-
-## [0.5.1] - 2021-12-23
-
-### Changed
- - `Debug` implementation on `Client` now redacts passwords ([#106](https://github.com/influxdb-rs/influxdb-rust/pull/106))
- - `Client` and `Query` builder functions are now annotated with `#[must_use]` ([#107](https://github.com/influxdb-rs/influxdb-rust/pull/107))
-
-## [0.5.0] - 2021-11-04
-
-### Added
-
-- Reqwest client for Tokio 1.0 support
-- New client constructor `with_http_client` ([@nshaaban-cPacket](https://github.com/nshaaban-cPacket) in [#94](https://github.com/influxdb-rs/influxdb-rust/pull/94))
-
-### Changed
-
-- default client is the new reqwest client
-- deprecate `<dyn Query>::raw_read_query` in favour of `ReadQuery::new`
-- `Client::query` now accepts both owned and borrowed queries as argument
-
-## [0.4.0] - 2021-03-08
-
-### Fixed
-
--  Fix deserialization of Series in case of no values ([@JEnoch](https://github.com/JEnoch) in [#75](https://github.com/influxdb-rs/influxdb-rust/pull/75))
-
-### Added
-
--  implement `#[influxdb(tag)]` and `#[influxdb(ignore)]` ([@blasrodri](https://github.com/blasrodri) in [#81](https://github.com/influxdb-rs/influxdb-rust/pull/81))
-
-    `#[tag]` is now `#[influxdb(tag)]` and fields can be ignored with `#[influxdb(ignore)]`
-
--  Batch write support ([@sunng87](https://github.com/sunng87) in [#87](https://github.com/influxdb-rs/influxdb-rust/pull/87))
-
-    Build a query containing multiple rows to be inserted
-    ```
-    let q0 = Timestamp::Hours(11)
-        .into_query("weather")
-        .add_field("temperature", 82)
-        .add_tag("location", "us-midwest");
-
-    let q1 = Timestamp::Hours(12)
-        .into_query("weather")
-        .add_field("temperature", 65)
-        .add_tag("location", "us-midwest");
-
-    let query = vec![q0, q1].build();
-    ```
-
-### Changed
-
--  Assertion should consider case-insensitive keywords ([@rcastill](https://github.com/rcastill) in [#83](https://github.com/influxdb-rs/influxdb-rust/pull/83))
-
-    `#[tag]` is now `#[influxdb(tag)]` and fields can be ignored with `#[influxdb(ignore)]`
-
--  Add h1-client-rustls feature ([@JEnoch](https://github.com/JEnoch) in [#88](https://github.com/influxdb-rs/influxdb-rust/pull/88))
-
-    Switch between multiple http backends as described in the [README.md](README.md#Choice-of-HTTP-backend)
-
-
-## [0.3.0] - 2020-11-15
-
-### Changed
-
--  Internal request connection pooling ([@Robert-Steiner](https://github.com/Robert-Steiner) in [#73](https://github.com/influxdb-rs/influxdb-rust/pull/73))
-
-    Previously visible `Client` fields are now private. If you were using them before, please reference them from the creation of the Client.
-
--  Support async-std ([@JEnoch](https://github.com/JEnoch) in [#72](https://github.com/influxdb-rs/influxdb-rust/pull/72))
-
-    The default backend is still Tokio, but if you're keen on switching, [other backends are exposed](https://github.com/influxdb-rs/influxdb-rust/blob/main/influxdb/Cargo.toml) as Cargo features
-
-## [0.2.0] - 2020-10-25
-
-### Added
-
--  Allow `GROUP BY` queries by providing `deserialize_next_tagged` to deserialize the group fields ([@SafariMonkey](https://github.com/SafariMonkey) in [#69](https://github.com/influxdb-rs/influxdb-rust/pull/69))
--  Added `Default` for `series` in InfluxDb Response ([@SafariMonkey](https://github.com/SafariMonkey) in [#67](https://github.com/influxdb-rs/influxdb-rust/pull/67))
-- `WriteQuery` and `ReadQuery` now derive `Debug` and `Clone` ([@jaredwolff](https://github.com/jaredwolff) in [#63](https://github.com/influxdb-rs/influxdb-rust/pull/63))
-
-### Changed
-
--  Replaced `failure` crate with `thiserror` crate ([@msrd0](https://github.com/msrd0) in [#70](https://github.com/influxdb-rs/influxdb-rust/pull/70))
--  Deserialize series are now deserialized using field names not field order ([@SafariMonkey](https://github.com/SafariMonkey) in [#62](https://github.com/influxdb-rs/influxdb-rust/pull/62))
--  Due to InfluxDb inconsistencies between versions and ambiguities, `Timestamp::Now` has been removed. Please calculate the current timestamp since the epoch yourself and use the other available `Timestamp` values like so:
-
-    ```
-    use influxdb::{Timestamp};
-    use std::time::{SystemTime, UNIX_EPOCH};
-    let start = SystemTime::now();
-    let since_the_epoch = start
-      .duration_since(UNIX_EPOCH)
-      .expect("Time went backwards")
-      .as_millis();
-    let query = Timestamp::Milliseconds(since_the_epoch)
-        .into_query("weather")
-        .add_field("temperature", 82);
-    ```
-
-### Fixed
-
--  Fixed quotation marks of tag values and escaping of field values ([@Robert-Steiner](https://github.com/Robert-Steiner) in [#68](https://github.com/influxdb-rs/influxdb-rust/pull/68))
--  Fixed improper quoting on tag values when the value was text ([@sparky8251](https://github.com/sparky8251) in [#64](https://github.com/influxdb-rs/influxdb-rust/pull/64))
-
-## [0.1.0] - 2020-03-17
-
-This adds `#[derive(InfluxDbWriteable)]` for Structs, fixes escaping for the line-protocol and improves timestamp handling.
-
-### Added
-
--   `#[derive(InfluxDbWriteable)]` for deriving struct writing ([@msrd0](https://github.com/msrd0))
-
-### Changed
-
--   Change type of timestamp-variants to `u128` ([@mario-kr](https://github.com/mario-kr))
-
-### Fixed
-
--   Use `rfc3339` as default timestamp precision ([@zjhmale](https://github.com/zjhmale))
-
-## [0.0.6] - 2020-02-07
-
-### Changed
-
--   Rewrite to `async` / `await`. Rust 1.39 is now the minimum required Rust version.
-
-## [0.0.5] - 2019-08-16
-
-This release removes the prefix `InfluxDb` of most types in this library and reexports the types under the `influxdb::` path. In most cases, you can directly use the types now: e.g. `influxdb::Client` vs `influxdb::client::InfluxDbClient`.
-
-### Added
-
--   Switch to `cargo-readme` for README generation ([@senden9](https://github.com/senden9))
--   Contributing Guidelines, Code of Conduct and Issue Templates
-
-### Changed
-
--   Removed dependency `itertools` ([@mvucenovic](https://github.com/mvucenovic))
--   Replace internal representation in query of `Any` by an enum ([@pcpthm](https://github.com/pcpthm))
--   Remove `InfluxDb` in type names
--   Replace ToString with Into<String>
-
-### Fixed
-
--   Fix Crates.io detecting license incorrectly ([@mimetypes](https://github.com/mimetypes))
--   Don't commit Cargo.lock ([@msrd0](https://github.com/msrd0))
--   Fix and Enforce Clippy Lints ([@msrd0](https://github.com/msrd0))
-
-## [0.0.4] - 2019-08-16
-
-### Added
-
--   Possibility to authenticate against a InfluxDb instance ([@valkum](https://github.com/valkum))
-
-## [0.0.3] - 2019-07-14
-
-### Added
-
--   Possibility to run multiple queries in one. See the Integration Tests in `tests/integration_tests.rs` for examples.
--   Ability to specify Timestamp for write queries
-
-### Changed
-
--   You now have to borrow a query when passing it to the `query` method
-
-## [0.0.2] - 2019-07-23
-
-### Changed
-
--   URLEncode Query before sending it to InfluxDB, which caused some empty returns (#5)
--   Improved Test Coverage: There's now even more tests verifying correctness of the crate (#5)
--   It's no longer necessary to supply a wildcard generic when working with serde*integration: `client.json_query::<Weather>(query)` instead of `client.json_query::<Weather, *>(query)`
-
-[unreleased]: https://github.com/influxdb-rs/influxdb-rust/compare/v0.4.0...HEAD
-[0.4.0]: https://github.com/influxdb-rs/influxdb-rust/compare/v0.3.0...v0.4.0
-[0.3.0]: https://github.com/influxdb-rs/influxdb-rust/compare/v0.2.0...v0.3.0
-[0.2.0]: https://github.com/influxdb-rs/influxdb-rust/compare/v0.1.0...v0.2.0
-[0.1.0]: https://github.com/influxdb-rs/influxdb-rust/compare/v0.0.6...v0.1.0
-[0.0.5]: https://github.com/influxdb-rs/influxdb-rust/compare/v0.0.5...v0.0.6
-[0.0.5]: https://github.com/influxdb-rs/influxdb-rust/compare/v0.0.4...v0.0.5
-[0.0.4]: https://github.com/influxdb-rs/influxdb-rust/compare/v0.0.3...v0.0.4
-[0.0.3]: https://github.com/influxdb-rs/influxdb-rust/compare/v0.0.2...v0.0.3
-[0.0.2]: https://github.com/influxdb-rs/influxdb-rust/releases/tag/v0.0.2
diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
deleted file mode 100644
index 76847e7..0000000
--- a/CODE_OF_CONDUCT.md
+++ /dev/null
@@ -1,76 +0,0 @@
-# Contributor Covenant Code of Conduct
-
-## Our Pledge
-
-In the interest of fostering an open and welcoming environment, we as
-contributors and maintainers pledge to make participation in our project and
-our community a harassment-free experience for everyone, regardless of age, body
-size, disability, ethnicity, sex characteristics, gender identity and expression,
-level of experience, education, socio-economic status, nationality, personal
-appearance, race, religion, or sexual identity and orientation.
-
-## Our Standards
-
-Examples of behavior that contributes to creating a positive environment
-include:
-
--   Using welcoming and inclusive language
--   Being respectful of differing viewpoints and experiences
--   Gracefully accepting constructive criticism
--   Focusing on what is best for the community
--   Showing empathy towards other community members
-
-Examples of unacceptable behavior by participants include:
-
--   The use of sexualized language or imagery and unwelcome sexual attention or
-    advances
--   Trolling, insulting/derogatory comments, and personal or political attacks
--   Public or private harassment
--   Publishing others' private information, such as a physical or electronic
-    address, without explicit permission
--   Other conduct which could reasonably be considered inappropriate in a
-    professional setting
-
-## Our Responsibilities
-
-Project maintainers are responsible for clarifying the standards of acceptable
-behavior and are expected to take appropriate and fair corrective action in
-response to any instances of unacceptable behavior.
-
-Project maintainers have the right and responsibility to remove, edit, or
-reject comments, commits, code, wiki edits, issues, and other contributions
-that are not aligned to this Code of Conduct, or to ban temporarily or
-permanently any contributor for other behaviors that they deem inappropriate,
-threatening, offensive, or harmful.
-
-## Scope
-
-This Code of Conduct applies within all project spaces, and it also applies when
-an individual is representing the project or its community in public spaces.
-Examples of representing a project or community include using an official
-project e-mail address, posting via an official social media account, or acting
-as an appointed representative at an online or offline event. Representation of
-a project may be further defined and clarified by project maintainers.
-
-## Enforcement
-
-Instances of abusive, harassing, or otherwise unacceptable behavior may be
-reported by contacting the project team at [influxdbrust@gerogerke.de](mailto:influxdbrust@gerogerke.de). All
-complaints will be reviewed and investigated and will result in a response that
-is deemed necessary and appropriate to the circumstances. The project team is
-obligated to maintain confidentiality with regard to the reporter of an incident.
-Further details of specific enforcement policies may be posted separately.
-
-Project maintainers who do not follow or enforce the Code of Conduct in good
-faith may face temporary or permanent repercussions as determined by other
-members of the project's leadership.
-
-## Attribution
-
-This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
-available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
-
-[homepage]: https://www.contributor-covenant.org
-
-For answers to common questions about this code of conduct, see
-https://www.contributor-covenant.org/faq
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
deleted file mode 100644
index 0b02f30..0000000
--- a/CONTRIBUTING.md
+++ /dev/null
@@ -1,164 +0,0 @@
-# Contributing to influxdb-rust
-
-Thank you for contributing. It's much apprechiated!
-
-The following is a set of guidelines for contributing to influxdb-rust, which is hosted at [influxdb-rs/influxdb-rust](https://github.com/influxdb-rs/influxdb-rust) on GitHub. These are mostly guidelines, not rules. Use your best judgment, and feel free to propose changes to this document in a pull request.
-
-#### Table Of Contents
-
-[Code of Conduct](#code-of-conduct)
-
-[How Can I Contribute?](#how-can-i-contribute)
-
--   [Reporting Bugs](#reporting-bugs)
--   [Suggesting Enhancements](#suggesting-enhancements)
--   [Your First Code Contribution](#your-first-code-contribution)
--   [Pull Requests](#pull-requests)
-
-[Styleguides](#styleguides)
-
--   [Git Commit Messages](#git-commit-messages)
--   [Rust Styleguide](#rust-styleguide)
-
-[Additional Notes](#additional-notes)
-
--   [Issue and Pull Request Labels](#issue-and-pull-request-labels)
-
-## Code of Conduct
-
-This project and everyone participating in it is governed by the [Contributor Covenant Code of Conduct](./CODE_OF_CONDUCT.md). By participating, you are expected to uphold this code. Please report unacceptable behavior to [influxdbrust@gerogerke.de](mailto:influxdbrust@gerogerke.de).
-
-## How Can I Contribute?
-
-### Reporting Bugs
-
-Please search the closed issues list before opening a bug report. If you find a **Closed** issue that seems like it is the same thing that you're experiencing, open a new issue and include a link to the original issue in the body of your new one.
-
-#### How Do I Submit A (Good) Bug Report?
-
-Bugs are tracked as [GitHub issues](https://guides.github.com/features/issues/). Please fill out the bug report template when filing a bug.
-
-Explain the problem and include additional details to help maintainers reproduce the problem:
-
--   **Use a clear and descriptive title** for the issue to identify the problem.
--   **Describe the exact steps which reproduce the problem** in as many details as possible.
--   **Provide specific examples to demonstrate the steps**. Include links to files or GitHub projects, or copy/pasteable snippets, which you use in those examples. If you're providing snippets in the issue, use [Markdown code blocks](https://help.github.com/articles/markdown-basics/#multiple-lines).
--   **Describe the behavior you observed after following the steps** and point out what exactly is the problem with that behavior.
--   **Explain which behavior you expected to see instead and why.**
-
-Provide more context by answering these questions:
-
--   **Did the problem start happening recently** (e.g. after updating to a new version of influxdb-rust) or was this always a problem?
--   If the problem started happening recently, **can you reproduce the problem in an older version of influxdb-rust?** What's the most recent version in which the problem doesn't happen? You can download older versions of influxdb-rust from [the releases page](https://github.com/influxdb-rs/influxdb-rust/releases).
--   **Can you reliably reproduce the issue?** If not, provide details about how often the problem happens and under which conditions it normally happens.
-
-### Suggesting Enhancements
-
-This section guides you through submitting an enhancement suggestion for influxdb-rust, including completely new features and minor improvements to existing functionality. Following these guidelines helps maintainers and the community understand your suggestion and find related suggestions.
-
-When you are creating an enhancement suggestion, please [include as many details as possible](#how-do-i-submit-a-good-enhancement-suggestion). Fill in the enhancement suggestion template, including the steps that you imagine you would take if the feature you're requesting existed.
-
-#### How Do I Submit A (Good) Enhancement Suggestion?
-
-Enhancement suggestions are tracked as [GitHub issues](https://guides.github.com/features/issues/). Create an issue and provide the following information:
-
--   **Use a clear and descriptive title** for the issue to identify the suggestion.
--   **Provide a step-by-step description of the suggested enhancement** in as many details as possible.
--   **Provide specific examples to demonstrate the steps**. Include copy/pasteable snippets which you use in those examples, as [Markdown code blocks](https://help.github.com/articles/markdown-basics/#multiple-lines).
--   **Describe the current behavior** and **explain which behavior you expected to see instead** and why.
--   **Explain why this enhancement would be useful** to most influxdb-rust users.
--   **Specify the name and version of the OS you're using.**
-
-### Your First Code Contribution
-
-Unsure where to begin contributing to influxdb-rust? You can start by looking through these `good first issue` and `Type of Change: Minor` issues:
-
--   [good first issue issues](https://github.com/influxdb-rs/influxdb-rust/labels/good%20first%20issue) - issues which are suited for new developers. usually just some lines of code or just a test.
--   [Type of Change: Minor issues](https://github.com/influxdb-rs/influxdb-rust/labels/Type%20of%20Change%3A%20Minor) - issues which only change a small amount of code in the library.
--   [Hacktoberfest issues](https://github.com/influxdb-rs/influxdb-rust/labels/Hacktoberfest) - issues which are suited for someone taking part in Hacktoberfest.
-
-#### Local development
-
-influxdb-rust can be developed locally.
-
-`cargo build` can be used to check if code is compiling. To run the integration tests, first start a InfluxDB docker container which the tests will run against using `docker run -d -p127.0.0.1:8086:8086 influxdb:alpine`. Once the container has started, you can run the integration tests using `cargo test`.
-
-### Pull Requests
-
-The process described here has several goals:
-
--   Maintain influxdb-rust's quality
--   Fix problems that are important to users
--   Engage the community in working toward the best possible influxdb-rust
--   Enable a sustainable system for influxdb-rust's maintainers to review contributions
-
-Please follow these steps to have your contribution considered by the maintainers:
-
-1. Follow all instructions in [the template](./.github/PULL_REQUEST_TEMPLATE.md)
-2. Follow the [styleguides](#styleguides)
-3. After you submit your pull request, verify that all [status checks](https://help.github.com/articles/about-status-checks/) are passing <details><summary>What if the status checks are failing?</summary>If a status check is failing, and you believe that the failure is unrelated to your change, please leave a comment on the pull request explaining why you believe the failure is unrelated. A maintainer will re-run the status check for you. If we conclude that the failure was a false positive, then we will open an issue to track that problem with our status check suite.</details>
-
-While the prerequisites above must be satisfied prior to having your pull request reviewed, the reviewer(s) may ask you to complete additional design work, tests, or other changes before your pull request can be ultimately accepted.
-
-## Styleguides
-
-### Git Commit Messages
-
--   Use the present tense ("Add feature" not "Added feature")
--   Use the imperative mood ("Move cursor to..." not "Moves cursor to...")
--   Limit the first line to 72 characters or less
-
-### Rust Styleguide
-
-Please format your code using `cargo fmt --all` and make sure `cargo clippy` produces no warnings.
-
-## Additional Notes
-
-### Issue and Pull Request Labels
-
-This section lists the labels we use to help us track and manage issues and pull requests.
-
-[GitHub search](https://help.github.com/articles/searching-issues/) makes it easy to use labels for finding groups of issues or pull requests you're interested in.
-
-The labels are loosely grouped by their purpose, but it's not required that every issue have a label from every group or that an issue can't have more than one label from the same group.
-
-Please open an issue if you have suggestions for new labels.
-
-#### Type of Issue or Pull Request
-
-| Issue label                    | List issues                                                                                        | Description                                                                                                                            |
-| ------------------------------ | -------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
-| `Status: Merge when CI passes` | [search](https://github.com/influxdb-rs/influxdb-rust/labels/status%3a%20merge%20when%20ci%20passes) | Applied when the pull request has been reviewed and is ready for merge once the CI pipeline passes.                                    |
-| `Status: Awaiting Response`    | [search](https://github.com/influxdb-rs/influxdb-rust/labels/status%3a%20awaiting%20response)        | Applied to issues which have a response from the issue owner pending.                                                                  |
-| `Status: Pending Discussion`   | [search](https://github.com/influxdb-rs/influxdb-rust/labels/status%3a%20pending%20discussion)       | Applied to pull requests where a pull request review has been submitted and the pull request author has not responded to feedback yet. |
-| `Status: Pending Updates`      | [search](https://github.com/influxdb-rs/influxdb-rust/labels/Status%3A%20Pending%20Updates)          | Applied to pull requests where updates to the changeset is pending.                                                                    |
-| `Status: Work in Progress`     | [search](https://github.com/influxdb-rs/influxdb-rust/labels/Status%3A%20Work%20in%20Progress)       | Applied to pull requests that are work in progress.                                                                                    |
-
-#### Type of Change of Issue or Pull Request
-
-| Issue label          | List issues                                                                                  | Description                                                                            |
-| -------------------- | -------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- |
-| `Type: Bug`          | [search](https://github.com/influxdb-rs/influxdb-rust/labels/Status%3A%20Type%20Bug)           | Applied to issues reporting bugs.                                                      |
-| `Type: Chore`        | [search](https://github.com/influxdb-rs/influxdb-rust/labels/Status%3A%20Type%20Chore)         | Applied to issues and pull requests regarding miscellaneous tasks around the repository. |
-| `Type: Enhancement`  | [search](https://github.com/influxdb-rs/influxdb-rust/labels/Status%3A%20Type%20Enhancement)   | Applied to issues and pull requests where an existing feature is improved.             |
-| `Type: Governance`   | [search](https://github.com/influxdb-rs/influxdb-rust/labels/Status%3A%20Type%20Governance)    | Applied to issues pull requests regarding repository governance.                       |
-| `Type: New Feature`  | [search](https://github.com/influxdb-rs/influxdb-rust/labels/status%3a%20Type%20New%20Feature) | Applied to issues and pull requests requesting or implementing new features.           |  |
-| `Type: Optimization` | [search](https://github.com/influxdb-rs/influxdb-rust/labels/status%3a%20Type%20Optimization)  | Applied to issues and pull requests regarding optimizing existing code.                |  |
-| `Type: Security`     | [search](https://github.com/influxdb-rs/influxdb-rust/labels/status%3a%20Type%20Security)      | Applied to issues and pull requests regarding the security of the library.             |  |
-
-#### Size of Change Labels
-
-| Issue label              | List issues                                                                                | Description                                                   |
-| ------------------------ | ------------------------------------------------------------------------------------------ | ------------------------------------------------------------- |
-| `Type of Change: Master` | [search](https://github.com/influxdb-rs/influxdb-rust/labels/Type%20of%20Change%3A%20Master) | Applied to issues and pull requests which are major changes.  |
-| `Type of Change: Medium` | [search](https://github.com/influxdb-rs/influxdb-rust/labels/Type%20of%20Change%3A%20Medium) | Applied to issues and pull requests which are medium changes. |
-| `Type of Change: Minor`  | [search](https://github.com/influxdb-rs/influxdb-rust/labels/Type%20of%20Change%3A%20Minor)  | Applied to issues and pull requests which are small changes.  |
-
-#### Misc Labels
-
-| Issue label      | List issues                                                                      | Description                                                       |
-| ---------------- | -------------------------------------------------------------------------------- | ----------------------------------------------------------------- |
-| good first issue | [search](https://github.com/influxdb-rs/influxdb-rust/labels/good%20first%20issue) | Indicates this issue is suited for new contributors               |
-| Hacktoberfest    | [search](https://github.com/influxdb-rs/influxdb-rust/labels/Hacktoberfest)        | Issues which are suited for someone taking part in Hacktoberfest. |
-
-This document has been adopted from [Atom contributing guidelines](https://github.com/atom/atom/blob/master/CONTRIBUTING.md)
diff --git a/Cargo.toml b/Cargo.toml
deleted file mode 100644
index d87619e..0000000
--- a/Cargo.toml
+++ /dev/null
@@ -1,8 +0,0 @@
-# -*- eval: (cargo-minor-mode 1) -*-
-
-[workspace]
-members = ["influxdb", "influxdb_derive", "benches"]
-
-[patch.crates-io]
-influxdb = { path = "./influxdb" }
-influxdb_derive = { path = "./influxdb_derive" }
diff --git a/Dockerfile b/Dockerfile
deleted file mode 100644
index c83a3e4..0000000
--- a/Dockerfile
+++ /dev/null
@@ -1,9 +0,0 @@
-FROM xd009642/tarpaulin
-
-RUN wget https://dl.influxdata.com/influxdb/releases/influxdb_1.7.6_amd64.deb
-RUN dpkg -i influxdb_1.7.6_amd64.deb
-RUN INFLUXDB_HTTP_BIND_ADDRESS=9999 influxd > $HOME/influx.log 2>&1 &
-
-WORKDIR /volume
-
-CMD cargo build && cargo tarpaulin
\ No newline at end of file
diff --git a/LICENSE b/LICENSE
deleted file mode 100644
index 5a027a3..0000000
--- a/LICENSE
+++ /dev/null
@@ -1,19 +0,0 @@
-Copyright (c) 2019 Gero Gerke https://gero.dev/
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
diff --git a/README.j2 b/README.j2
deleted file mode 100644
index be728de..0000000
--- a/README.j2
+++ /dev/null
@@ -1,40 +0,0 @@
-<div align="center">
-    <br/>
-    <img
-        alt="rust-influxdb"
-        src="https://i.imgur.com/4k7l8XJ.png"
-        width=250px />
-    <br/>
-    <br/>
-    <strong>Unofficial InfluxDB Driver for Rust</strong>
-</div>
-<br/>
-<p align="center">
-    <a href="https://crates.io/crates/influxdb">
-        <img src="https://img.shields.io/crates/v/influxdb.svg"/>
-    </a>
-    <a href="https://github.com/influxdb-rs/influxdb-rust/actions/workflows/rust.yml">
-        <img src="https://github.com/influxdb-rs/influxdb-rust/actions/workflows/rust.yml/badge.svg" alt='Build Status' />
-    </a>
-    <a href="https://influxdb-rs.github.io/influxdb-rust/tarpaulin-report.html">
-        <img src="https://influxdb-rs.github.io/influxdb-rust/coverage.svg" alt="Coverage Report" />
-    </a>
-    <a href="https://docs.rs/influxdb">
-        <img src="https://docs.rs/influxdb/badge.svg" alt='Documentation Status' />
-    </a>
-    <a href="https://www.rust-lang.org/en-US/">
-        <img src="https://img.shields.io/badge/Made%20with-Rust-orange.svg" alt='Build with Rust' />
-    </a>
-    <a href="https://blog.rust-lang.org/2022/11/03/Rust-1.67.0.html">
-        <img src="https://img.shields.io/badge/rustc-1.67+-yellow.svg" alt='Minimum Rust Version: 1.67' />
-    </a>
-</p>
-
-{{readme}}
-
-@ 2020-2024 Gero Gerke, msrd0 and [contributors].
-
- [contributors]: https://github.com/influxdb-rs/influxdb-rust/graphs/contributors
-{%- if links != "" %}
-{{ links }}
-{% endif -%}
diff --git a/README.md b/README.md
deleted file mode 100644
index 9865904..0000000
--- a/README.md
+++ /dev/null
@@ -1,192 +0,0 @@
-<div align="center">
-    <br/>
-    <img
-        alt="rust-influxdb"
-        src="https://i.imgur.com/4k7l8XJ.png"
-        width=250px />
-    <br/>
-    <br/>
-    <strong>Unofficial InfluxDB Driver for Rust</strong>
-</div>
-<br/>
-<p align="center">
-    <a href="https://crates.io/crates/influxdb">
-        <img src="https://img.shields.io/crates/v/influxdb.svg"/>
-    </a>
-    <a href="https://github.com/influxdb-rs/influxdb-rust/actions/workflows/rust.yml">
-        <img src="https://github.com/influxdb-rs/influxdb-rust/actions/workflows/rust.yml/badge.svg" alt='Build Status' />
-    </a>
-    <a href="https://influxdb-rs.github.io/influxdb-rust/tarpaulin-report.html">
-        <img src="https://influxdb-rs.github.io/influxdb-rust/coverage.svg" alt="Coverage Report" />
-    </a>
-    <a href="https://docs.rs/influxdb">
-        <img src="https://docs.rs/influxdb/badge.svg" alt='Documentation Status' />
-    </a>
-    <a href="https://www.rust-lang.org/en-US/">
-        <img src="https://img.shields.io/badge/Made%20with-Rust-orange.svg" alt='Build with Rust' />
-    </a>
-    <a href="https://blog.rust-lang.org/2022/11/03/Rust-1.65.0.html">
-        <img src="https://img.shields.io/badge/rustc-1.65+-yellow.svg" alt='Minimum Rust Version: 1.65' />
-    </a>
-</p>
-
-Pull requests are always welcome. See [Contributing][__link0] and [Code of Conduct][__link1]. For a list of past changes, see [CHANGELOG.md][__link2].
-
-
-### Currently Supported Features
-
- - Reading and writing to InfluxDB
- - Optional Serde support for deserialization
- - Running multiple queries in one request (e.g. `SELECT * FROM weather_berlin; SELECT * FROM weather_london`)
- - Writing single or multiple measurements in one request (e.g. `WriteQuery` or `Vec<WriteQuery>` argument)
- - Authenticated and unauthenticated connections
- - `async`/`await` support
- - `#[derive(InfluxDbWriteable)]` derive macro for writing / reading into structs
- - `GROUP BY` support
- - Tokio and async-std support (see example below) or [available backends][__link3]
- - Swappable HTTP backends ([see below](#Choice-of-HTTP-backend))
-
-
-## Quickstart
-
-Add the following to your `Cargo.toml`
-
-
-```toml
-influxdb = { version = "0.7.2", features = ["derive"] }
-```
-
-For an example with using Serde deserialization, please refer to [serde_integration][__link4]
-
-
-```rust
-use chrono::{DateTime, Utc};
-use influxdb::{Client, Error, InfluxDbWriteable, ReadQuery, Timestamp};
-
-#[tokio::main]
-// or #[async_std::main] if you prefer
-async fn main() -> Result<(), Error> {
-    // Connect to db `test` on `http://localhost:8086`
-    let client = Client::new("http://localhost:8086", "test");
-
-    #[derive(InfluxDbWriteable)]
-    struct WeatherReading {
-        time: DateTime<Utc>,
-        humidity: i32,
-        #[influxdb(tag)]
-        wind_direction: String,
-    }
-
-    // Let's write some data into a measurement called `weather`
-    let weather_readings = vec![
-        WeatherReading {
-            time: Timestamp::Hours(1).into(),
-            humidity: 30,
-            wind_direction: String::from("north"),
-        }
-        .into_query("weather"),
-        WeatherReading {
-            time: Timestamp::Hours(2).into(),
-            humidity: 40,
-            wind_direction: String::from("west"),
-        }
-        .into_query("weather"),
-    ];
-
-    client.query(weather_readings).await?;
-
-    // Read back all records
-    let read_query = ReadQuery::new("SELECT * FROM weather");
-
-    let read_result = client.query(read_query).await?;
-    println!("{}", read_result);
-    Ok(())
-}
-```
-
-For further examples, check out the integration tests in `tests/integration_tests.rs` in the repository.
-
-
-## Choice of HTTP backend
-
-To communicate with InfluxDB, you can choose the HTTP backend to be used configuring the appropriate feature. We recommend sticking with the default reqwest-based client, unless you really need async-std compatibility.
-
- - **[hyper][__link5]** (through reqwest, used by default), with [rustls][__link6]
-	```toml
-	influxdb = { version = "0.7.2", features = ["derive"] }
-	```
-	
-	
- - **[hyper][__link7]** (through reqwest), with native TLS (OpenSSL)
-	```toml
-	influxdb = { version = "0.7.2", default-features = false, features = ["derive", "serde", "reqwest-client-native-tls"] }
-	```
-	
-	
- - **[hyper][__link8]** (through reqwest), with vendored native TLS (OpenSSL)
-	```toml
-	influxdb = { version = "0.7.2", default-features = false, features = ["derive", "serde", "reqwest-client-native-tls-vendored"] }
-	```
-	
-	
- - **[hyper][__link9]** (through surf), use this if you need tokio 0.2 compatibility
-	```toml
-	influxdb = { version = "0.7.2", default-features = false, features = ["derive", "serde", "hyper-client"] }
-	```
-	
-	
- - **[curl][__link10]**, using [libcurl][__link11]
-	```toml
-	influxdb = { version = "0.7.2", default-features = false, features = ["derive", "serde", "curl-client"] }
-	```
-	
-	
- - **[async-h1][__link12]** with native TLS (OpenSSL)
-	```toml
-	influxdb = { version = "0.7.2", default-features = false, features = ["derive", "serde", "h1-client"] }
-	```
-	
-	
- - **[async-h1][__link13]** with [rustls][__link14]
-	```toml
-	influxdb = { version = "0.7.2", default-features = false, features = ["derive", "serde", "h1-client-rustls"] }
-	```
-	
-	
- - WebAssembly’s `window.fetch`, via `web-sys` and **[wasm-bindgen][__link15]**
-	```toml
-	influxdb = { version = "0.7.2", default-features = false, features = ["derive", "serde", "wasm-client"] }
-	```
-	
-	
-
-
-## License
-
-[![License: MIT][__link16]][__link17]
-
-
-
-@ 2020-2024 Gero Gerke, msrd0 and [contributors].
-
- [contributors]: https://github.com/influxdb-rs/influxdb-rust/graphs/contributors
- [__cargo_doc2readme_dependencies_info]: ggGkYW0BYXSEG_RDmlyxxvyrG0rwcLBKoYdvG5It9hbWNgjUGzjD8iBYfsFFYXKEG1LaAVLASZMqG5J2qfpyCvbMG_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
- [__link11]: https://curl.se/libcurl/
- [__link12]: https://github.com/http-rs/async-h1
- [__link13]: https://github.com/http-rs/async-h1
- [__link14]: https://github.com/ctz/rustls
- [__link15]: https://github.com/rustwasm/wasm-bindgen
- [__link16]: https://img.shields.io/badge/License-MIT-yellow.svg
- [__link17]: https://opensource.org/licenses/MIT
- [__link2]: https://github.com/influxdb-rs/influxdb-rust/blob/main/CHANGELOG.md
- [__link3]: https://github.com/influxdb-rs/influxdb-rust/blob/main/influxdb/Cargo.toml
- [__link4]: https://docs.rs/influxdb/0.7.2/influxdb/?search=integrations::serde_integration
- [__link5]: https://github.com/hyperium/hyper
- [__link6]: https://github.com/ctz/rustls
- [__link7]: https://github.com/hyperium/hyper
- [__link8]: https://github.com/hyperium/hyper
- [__link9]: https://github.com/hyperium/hyper
-
diff --git a/RELEASING.md b/RELEASING.md
deleted file mode 100644
index 7f18385..0000000
--- a/RELEASING.md
+++ /dev/null
@@ -1,28 +0,0 @@
-# How to release this crate
-
-This project consists of two crates which need to be published to crates.io in the correct order. Additionally, there's some steps one's likely to miss when releasing.
-
-## Pre-Release-Checklist
-
-- [ ] `influxdb/Cargo.toml` and `influxdb-derive/Cargo.toml`: Bumped `influxdb` and `influxdb-derive` versions to new version number?
-- [ ] `influxdb/Cargo.toml`: Changed `influxdb` dependency on `influxdb-derive` to new version number?
-- [ ] `CHANGELOG.md`: Remove all entries from the unreleased section
-- [ ] `CHANGELOG.md`: Add new Section for the new version number with subsections `Added`, `Changed` and `Fixed`.
-- [ ] `CHANGELOG.md`: For each commit since the last release commit `Release vX.Y.Z`, added a changelog entry in the correct section linking to the author and PR in this format?
-    ```
-    ([@GithubUserName](https://github.com/GithubUserName) in [#PRNumber](https://github.com/influxdb-rs/influxdb-rust/pull/PRNumber))
-    ```
-- [ ] `CHANGELOG.md`: At the bottom, changed the unreleased section link to `NEWVERSIONNUMBER...HEAD` and created a new link for the current release?
-- [ ] `influxdb/lib.rs`: Changed the version number mentioned in the doc-comment to the new version number?
-- [ ] `influxdb/lib.rs`: If the release contains any new features that should be mentioned in the Github Readme, are they listed in the doc-comment?
-- [ ] `terminal`: Updated README with `cargo readme -r influxdb -t ../README.tpl > README.md`?
-- [ ] `terminal`: Verified there are no errors with clippy `cargo clippy --all-targets --all-features -- -D warnings`?
-
-## Releasing
-
-1) `git add .` and `git commit -m "Release vX.Y.Z"`
-2) `git tag vX.Y.Z`
-3) `git push origin main` and `git push --tags`
-4) `(cd influxdb-derive/ && cargo publish)`
-5) `(cd influxdb/ && cargo publish)`
-6) Create a Release in the Github Web UI
diff --git a/benches/Cargo.toml b/benches/Cargo.toml
deleted file mode 100644
index 6a340ce..0000000
--- a/benches/Cargo.toml
+++ /dev/null
@@ -1,18 +0,0 @@
-# -*- eval: (cargo-minor-mode 1) -*-
-
-[package]
-name = "benches"
-version = "0.0.0"
-publish = false
-edition = "2018"
-
-[dev-dependencies]
-chrono = { version = "0.4.11", features = ["serde"] }
-futures = "0.3.4"
-influxdb = { path = "../influxdb", features = ["derive"] }
-tokio = { version =  "0.2.22", features = ["macros", "rt-threaded", "sync"] }
-
-[[bench]]
-name = "client"
-path = "client.rs"
-harness = false
diff --git a/benches/client.rs b/benches/client.rs
deleted file mode 100644
index e07bd1b..0000000
--- a/benches/client.rs
+++ /dev/null
@@ -1,85 +0,0 @@
-use chrono::{DateTime, Utc};
-use influxdb::Error;
-use influxdb::InfluxDbWriteable;
-use influxdb::{Client, ReadQuery};
-use std::sync::Arc;
-use std::time::Instant;
-use tokio::sync::mpsc::unbounded_channel;
-use tokio::sync::Semaphore;
-
-#[derive(InfluxDbWriteable, Clone)]
-struct WeatherReading {
-    time: DateTime<Utc>,
-    humidity: i32,
-    #[influxdb(tag)]
-    wind_direction: String,
-}
-
-#[tokio::main]
-async fn main() {
-    let db_name = "bench";
-    let url = "http://localhost:8086";
-    let number_of_total_requests = 20000;
-    let concurrent_requests = 1000;
-
-    let client = Client::new(url, db_name);
-    let concurrency_limit = Arc::new(Semaphore::new(concurrent_requests));
-
-    prepare_influxdb(&client, db_name).await;
-    let measurements = generate_measurements(number_of_total_requests);
-    let (tx, mut rx) = unbounded_channel::<Result<String, Error>>();
-
-    let start = Instant::now();
-    for m in measurements {
-        let permit = concurrency_limit.clone().acquire_owned().await;
-        let client_task = client.clone();
-        let tx_task = tx.clone();
-        tokio::spawn(async move {
-            let res = client_task.query(&m.into_query("weather")).await;
-            let _ = tx_task.send(res);
-            drop(permit);
-        });
-    }
-    drop(tx);
-
-    let mut successful_count = 0;
-    let mut error_count = 0;
-    while let Some(res) = rx.recv().await {
-        if res.is_err() {
-            error_count += 1;
-        } else {
-            successful_count += 1;
-        }
-    }
-
-    let end = Instant::now();
-
-    println!(
-        "Throughput: {:.1} request/s",
-        1000000.0 * successful_count as f64 / (end - start).as_micros() as f64
-    );
-    println!(
-        "{} successful requests, {} errors",
-        successful_count, error_count
-    );
-}
-
-async fn prepare_influxdb(client: &Client, db_name: &str) {
-    let create_db_stmt = format!("CREATE DATABASE {}", db_name);
-    client
-        .query(&ReadQuery::new(create_db_stmt))
-        .await
-        .expect("failed to create database");
-}
-
-fn generate_measurements(n: u64) -> Vec<WeatherReading> {
-    (0..n)
-        .collect::<Vec<u64>>()
-        .iter_mut()
-        .map(|_| WeatherReading {
-            time: Utc::now(),
-            humidity: 30,
-            wind_direction: String::from("north"),
-        })
-        .collect()
-}
diff --git a/coverage.svg b/coverage.svg
new file mode 100644
index 0000000..ccd27ee
--- /dev/null
+++ b/coverage.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="114" height="20" role="img" aria-label="coverage: 66.88%"><title>coverage: 66.88%</title><linearGradient id="s" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="r"><rect width="114" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#r)"><rect width="61" height="20" fill="#555"/><rect x="61" width="53" height="20" fill="#dfb317"/><rect width="114" height="20" fill="url(#s)"/></g><g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110"><text aria-hidden="true" x="315" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="510">coverage</text><text x="315" y="140" transform="scale(.1)" fill="#fff" textLength="510">coverage</text><text aria-hidden="true" x="865" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="430">66.88%</text><text x="865" y="140" transform="scale(.1)" fill="#fff" textLength="430">66.88%</text></g></svg>
\ No newline at end of file
diff --git a/docker-compose.integrationtest.yaml b/docker-compose.integrationtest.yaml
deleted file mode 100644
index 1fd549d..0000000
--- a/docker-compose.integrationtest.yaml
+++ /dev/null
@@ -1,27 +0,0 @@
-version: '3'
-services:
-  influxdb:
-      image: influxdb:1.8
-      ports:
-        - 8086:8086
-  authed_influxdb:
-    image: influxdb:1.8
-    ports:
-      - 9086:8086
-    environment:
-      INFLUXDB_HTTP_AUTH_ENABLED: true
-      INFLUXDB_ADMIN_USER: admin
-      INFLUXDB_ADMIN_PASSWORD: password
-      INFLUXDB_USER: nopriv_user
-      INFLUXDB_USER_PASSWORD: password
-  influxdbv2:
-    image: influxdb:2.6
-    ports:
-      - 2086:8086
-    environment:
-      DOCKER_INFLUXDB_INIT_MODE: setup
-      DOCKER_INFLUXDB_INIT_USERNAME: admin
-      DOCKER_INFLUXDB_INIT_PASSWORD: password
-      DOCKER_INFLUXDB_INIT_ORG: testing
-      DOCKER_INFLUXDB_INIT_BUCKET: mydb
-      DOCKER_INFLUXDB_INIT_ADMIN_TOKEN: admintoken
diff --git a/influxdb/Cargo.toml b/influxdb/Cargo.toml
deleted file mode 100644
index c31729a..0000000
--- a/influxdb/Cargo.toml
+++ /dev/null
@@ -1,47 +0,0 @@
-# -*- eval: (cargo-minor-mode 1) -*-
-
-[package]
-name = "influxdb"
-version = "0.7.2"
-authors = ["Gero Gerke <11deutron11@gmail.com>"]
-edition = "2018"
-description = "InfluxDB Driver for Rust"
-keywords = ["influxdb", "database", "influx"]
-license = "MIT"
-readme = "README.md"
-include = ["src/**/*", "tests/**/*", "Cargo.toml", "LICENSE"]
-repository = "https://github.com/influxdb-rs/influxdb-rust"
-rust-version = "1.70"
-
-[dependencies]
-chrono = { version = "0.4.23", features = ["serde"], default-features = false }
-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 }
-thiserror = "1.0"
-
-[features]
-default = ["serde", "reqwest-client-rustls"]
-derive = ["dep:influxdb_derive"]
-serde = ["dep:serde", "dep:serde_derive", "dep:serde_json"]
-
-# http clients
-curl-client = ["surf", "surf/curl-client"]
-h1-client = ["surf", "surf/h1-client"]
-h1-client-rustls = ["surf", "surf/h1-client-rustls"]
-hyper-client = ["surf", "surf/hyper-client"]
-reqwest-client-rustls = ["reqwest", "reqwest/rustls-tls-webpki-roots"]
-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"]
-
-[dev-dependencies]
-async-std = { version = "1.6.5", features = ["attributes", "tokio02", "tokio1"] }
-indoc = "1.0"
-tokio = { version = "1.7", features = ["macros", "rt-multi-thread"] }
diff --git a/influxdb/README.md b/influxdb/README.md
deleted file mode 120000
index 32d46ee..0000000
--- a/influxdb/README.md
+++ /dev/null
@@ -1 +0,0 @@
-../README.md
\ No newline at end of file
diff --git a/influxdb/src/client/mod.rs b/influxdb/src/client/mod.rs
deleted file mode 100644
index 264cfde..0000000
--- a/influxdb/src/client/mod.rs
+++ /dev/null
@@ -1,357 +0,0 @@
-//! Client which can read and write data from InfluxDB.
-//!
-//! # Arguments
-//!
-//!  * `url`: The URL where InfluxDB is running (ex. `http://localhost:8086`).
-//!  * `database`: The Database against which queries and writes will be run.
-//!
-//! # Examples
-//!
-//! ```rust
-//! use influxdb::Client;
-//!
-//! let client = Client::new("http://localhost:8086", "test");
-//!
-//! assert_eq!(client.database_name(), "test");
-//! ```
-
-use futures_util::TryFutureExt;
-#[cfg(feature = "reqwest")]
-use reqwest::{Client as HttpClient, RequestBuilder, Response as HttpResponse};
-use std::collections::{BTreeMap, HashMap};
-use std::fmt::{self, Debug, Formatter};
-use std::sync::Arc;
-#[cfg(feature = "surf")]
-use surf::{Client as HttpClient, RequestBuilder, Response as HttpResponse};
-
-use crate::query::QueryType;
-use crate::Error;
-use crate::Query;
-
-#[derive(Clone)]
-/// Internal Representation of a Client
-pub struct Client {
-    pub(crate) url: Arc<String>,
-    pub(crate) parameters: Arc<HashMap<&'static str, String>>,
-    pub(crate) token: Option<String>,
-    pub(crate) client: HttpClient,
-}
-
-struct RedactPassword<'a>(&'a HashMap<&'static str, String>);
-
-impl<'a> Debug for RedactPassword<'a> {
-    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
-        let entries = self
-            .0
-            .iter()
-            .map(|(k, v)| match *k {
-                "p" => (*k, "<redacted>"),
-                _ => (*k, v.as_str()),
-            })
-            .collect::<BTreeMap<&'static str, &str>>();
-        f.debug_map().entries(entries).finish()
-    }
-}
-
-impl Debug for Client {
-    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
-        f.debug_struct("Client")
-            .field("url", &self.url)
-            .field("parameters", &RedactPassword(&self.parameters))
-            .finish_non_exhaustive()
-    }
-}
-
-impl Client {
-    /// Instantiates a new [`Client`](crate::Client)
-    ///
-    /// # Arguments
-    ///
-    ///  * `url`: The URL where InfluxDB is running (ex. `http://localhost:8086`).
-    ///  * `database`: The Database against which queries and writes will be run.
-    ///
-    /// # Examples
-    ///
-    /// ```rust
-    /// use influxdb::Client;
-    ///
-    /// let _client = Client::new("http://localhost:8086", "test");
-    /// ```
-    #[must_use = "Creating a client is pointless unless you use it"]
-    pub fn new<S1, S2>(url: S1, database: S2) -> Self
-    where
-        S1: Into<String>,
-        S2: Into<String>,
-    {
-        let mut parameters = HashMap::<&str, String>::new();
-        parameters.insert("db", database.into());
-        Client {
-            url: Arc::new(url.into()),
-            parameters: Arc::new(parameters),
-            client: HttpClient::new(),
-            token: None,
-        }
-    }
-
-    /// Add authentication/authorization information to [`Client`](crate::Client)
-    ///
-    /// # Arguments
-    ///
-    /// * username: The Username for InfluxDB.
-    /// * password: The Password for the user.
-    ///
-    /// # Examples
-    ///
-    /// ```rust
-    /// use influxdb::Client;
-    ///
-    /// let _client = Client::new("http://localhost:9086", "test").with_auth("admin", "password");
-    /// ```
-    #[must_use = "Creating a client is pointless unless you use it"]
-    pub fn with_auth<S1, S2>(mut self, username: S1, password: S2) -> Self
-    where
-        S1: Into<String>,
-        S2: Into<String>,
-    {
-        let mut with_auth = self.parameters.as_ref().clone();
-        with_auth.insert("u", username.into());
-        with_auth.insert("p", password.into());
-        self.parameters = Arc::new(with_auth);
-        self
-    }
-
-    /// Replaces the HTTP Client
-    #[must_use = "Creating a client is pointless unless you use it"]
-    pub fn with_http_client(mut self, http_client: HttpClient) -> Self {
-        self.client = http_client;
-        self
-    }
-
-    /// Add authorization token to [`Client`](crate::Client)
-    ///
-    /// This is designed for influxdb 2.0's backward-compatible API which
-    /// requires authorization by default. You can create such token from
-    /// console of influxdb 2.0 .
-    pub fn with_token<S>(mut self, token: S) -> Self
-    where
-        S: Into<String>,
-    {
-        self.token = Some(token.into());
-        self
-    }
-
-    /// Returns the name of the database the client is using
-    pub fn database_name(&self) -> &str {
-        // safe to unwrap: we always set the database name in `Self::new`
-        self.parameters.get("db").unwrap()
-    }
-
-    /// Returns the URL of the InfluxDB installation the client is using
-    pub fn database_url(&self) -> &str {
-        &self.url
-    }
-
-    /// Pings the InfluxDB Server
-    ///
-    /// Returns a tuple of build type and version number
-    pub async fn ping(&self) -> Result<(String, String), Error> {
-        let url = &format!("{}/ping", self.url);
-        let res = self
-            .client
-            .get(url)
-            .send()
-            .await
-            .map_err(|err| Error::ProtocolError {
-                error: format!("{}", err),
-            })?;
-
-        const BUILD_HEADER: &str = "X-Influxdb-Build";
-        const VERSION_HEADER: &str = "X-Influxdb-Version";
-
-        #[cfg(feature = "reqwest")]
-        let (build, version) = {
-            let hdrs = res.headers();
-            (
-                hdrs.get(BUILD_HEADER).and_then(|value| value.to_str().ok()),
-                hdrs.get(VERSION_HEADER)
-                    .and_then(|value| value.to_str().ok()),
-            )
-        };
-
-        #[cfg(feature = "surf")]
-        let build = res.header(BUILD_HEADER).map(|value| value.as_str());
-        #[cfg(feature = "surf")]
-        let version = res.header(VERSION_HEADER).map(|value| value.as_str());
-
-        Ok((build.unwrap().to_owned(), version.unwrap().to_owned()))
-    }
-
-    /// Sends a [`ReadQuery`](crate::ReadQuery) or [`WriteQuery`](crate::WriteQuery) to the InfluxDB Server.
-    ///
-    /// A version capable of parsing the returned string is available under the [serde_integration](crate::integrations::serde_integration)
-    ///
-    /// # Arguments
-    ///
-    ///  * `q`: Query of type [`ReadQuery`](crate::ReadQuery) or [`WriteQuery`](crate::WriteQuery)
-    ///
-    /// # Examples
-    ///
-    /// ```rust,no_run
-    /// use influxdb::{Client, Query, Timestamp};
-    /// use influxdb::InfluxDbWriteable;
-    /// use std::time::{SystemTime, UNIX_EPOCH};
-    ///
-    /// # #[async_std::main]
-    /// # async fn main() -> Result<(), influxdb::Error> {
-    /// let start = SystemTime::now();
-    /// let since_the_epoch = start
-    ///   .duration_since(UNIX_EPOCH)
-    ///   .expect("Time went backwards")
-    ///   .as_millis();
-    ///
-    /// let client = Client::new("http://localhost:8086", "test");
-    /// let query = Timestamp::Milliseconds(since_the_epoch)
-    ///     .into_query("weather")
-    ///     .add_field("temperature", 82);
-    /// let results = client.query(query).await?;
-    ///
-    /// # Ok(())
-    /// # }
-    /// ```
-    /// # Errors
-    ///
-    /// If the function can not finish the query,
-    /// a [`Error`] variant will be returned.
-    ///
-    /// [`Error`]: enum.Error.html
-    pub async fn query<Q>(&self, q: Q) -> Result<String, Error>
-    where
-        Q: Query,
-    {
-        let query = q.build().map_err(|err| Error::InvalidQueryError {
-            error: err.to_string(),
-        })?;
-
-        let mut parameters = self.parameters.as_ref().clone();
-        let request_builder = match q.get_type() {
-            QueryType::ReadQuery => {
-                let read_query = query.get();
-                let url = &format!("{}/query", &self.url);
-                parameters.insert("q", read_query.clone());
-
-                if read_query.contains("SELECT") || read_query.contains("SHOW") {
-                    self.client.get(url).query(&parameters)
-                } else {
-                    self.client.post(url).query(&parameters)
-                }
-            }
-            QueryType::WriteQuery(precision) => {
-                let url = &format!("{}/write", &self.url);
-                let mut parameters = self.parameters.as_ref().clone();
-                parameters.insert("precision", precision);
-
-                self.client.post(url).body(query.get()).query(&parameters)
-            }
-        };
-
-        #[cfg(feature = "surf")]
-        let request_builder = request_builder.map_err(|err| Error::UrlConstructionError {
-            error: err.to_string(),
-        })?;
-
-        let res = self
-            .auth_if_needed(request_builder)
-            .send()
-            .map_err(|err| Error::ConnectionError {
-                error: err.to_string(),
-            })
-            .await?;
-        check_status(&res)?;
-
-        #[cfg(feature = "reqwest")]
-        let body = res.text();
-        #[cfg(feature = "surf")]
-        let mut res = res;
-        #[cfg(feature = "surf")]
-        let body = res.body_string();
-
-        let s = body.await.map_err(|_| Error::DeserializationError {
-            error: "response could not be converted to UTF-8".to_string(),
-        })?;
-
-        // todo: improve error parsing without serde
-        if s.contains("\"error\"") || s.contains("\"Error\"") {
-            return Err(Error::DatabaseError {
-                error: format!("influxdb error: \"{}\"", s),
-            });
-        }
-
-        Ok(s)
-    }
-
-    fn auth_if_needed(&self, rb: RequestBuilder) -> RequestBuilder {
-        if let Some(ref token) = self.token {
-            rb.header("Authorization", format!("Token {}", token))
-        } else {
-            rb
-        }
-    }
-}
-
-pub(crate) fn check_status(res: &HttpResponse) -> Result<(), Error> {
-    let status = res.status();
-    if !status.is_success() {
-        return Err(Error::ApiError(status.into()));
-    }
-    Ok(())
-}
-
-#[cfg(test)]
-mod tests {
-    use super::Client;
-    use indoc::indoc;
-
-    #[test]
-    fn test_client_debug_redacted_password() {
-        let client = Client::new("https://localhost:8086", "db").with_auth("user", "pass");
-        let actual = format!("{:#?}", client);
-        let expected = indoc! { r#"
-            Client {
-                url: "https://localhost:8086",
-                parameters: {
-                    "db": "db",
-                    "p": "<redacted>",
-                    "u": "user",
-                },
-                ..
-            }
-        "# };
-        assert_eq!(actual.trim(), expected.trim());
-    }
-
-    #[test]
-    fn test_fn_database() {
-        let client = Client::new("http://localhost:8068", "database");
-        assert_eq!(client.database_name(), "database");
-        assert_eq!(client.database_url(), "http://localhost:8068");
-    }
-
-    #[test]
-    fn test_with_auth() {
-        let client = Client::new("http://localhost:8068", "database");
-        assert_eq!(client.parameters.len(), 1);
-        assert_eq!(client.parameters.get("db").unwrap(), "database");
-
-        let with_auth = client.with_auth("username", "password");
-        assert_eq!(with_auth.parameters.len(), 3);
-        assert_eq!(with_auth.parameters.get("db").unwrap(), "database");
-        assert_eq!(with_auth.parameters.get("u").unwrap(), "username");
-        assert_eq!(with_auth.parameters.get("p").unwrap(), "password");
-
-        let client = Client::new("http://localhost:8068", "database");
-        let with_auth = client.with_token("token");
-        assert_eq!(with_auth.parameters.len(), 1);
-        assert_eq!(with_auth.parameters.get("db").unwrap(), "database");
-        assert_eq!(with_auth.token.unwrap(), "token");
-    }
-}
diff --git a/influxdb/src/error.rs b/influxdb/src/error.rs
deleted file mode 100644
index 5f89e8f..0000000
--- a/influxdb/src/error.rs
+++ /dev/null
@@ -1,35 +0,0 @@
-//! Errors that might happen in the crate
-
-use thiserror::Error;
-
-#[derive(Debug, Eq, PartialEq, Error)]
-#[non_exhaustive]
-pub enum Error {
-    #[error("query is invalid: {error}")]
-    /// Error happens when a query is invalid
-    InvalidQueryError { error: String },
-
-    #[error("Failed to build URL: {error}")]
-    /// Error happens when a query is invalid
-    UrlConstructionError { error: String },
-
-    #[error("http protocol error: {error}")]
-    /// Error happens when a query is invalid
-    ProtocolError { error: String },
-
-    #[error("http protocol error: {error}")]
-    /// Error happens when Serde cannot deserialize the response
-    DeserializationError { error: String },
-
-    #[error("InfluxDB encountered the following error: {error}")]
-    /// Error which has happened inside InfluxDB
-    DatabaseError { error: String },
-
-    #[error("API error with a status code: {0}")]
-    /// Error happens when API returns non 2xx status code.
-    ApiError(u16),
-
-    #[error("connection error: {error}")]
-    /// Error happens when HTTP request fails
-    ConnectionError { error: String },
-}
diff --git a/influxdb/src/integrations/serde_integration/de.rs b/influxdb/src/integrations/serde_integration/de.rs
deleted file mode 100644
index a3e904d..0000000
--- a/influxdb/src/integrations/serde_integration/de.rs
+++ /dev/null
@@ -1,451 +0,0 @@
-use super::{Series, TaggedSeries};
-use serde::de::{
-    value, Deserialize, DeserializeSeed, Deserializer, Error, IntoDeserializer, MapAccess,
-    SeqAccess, Visitor,
-};
-use serde_derive::Deserialize;
-use std::fmt;
-use std::marker::PhantomData;
-
-// Based on https://serde.rs/deserialize-struct.html
-impl<'de, T> Deserialize<'de> for Series<T>
-where
-    T: Deserialize<'de>,
-{
-    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
-    where
-        D: Deserializer<'de>,
-    {
-        // Field name deserializer
-        #[derive(Deserialize)]
-        #[serde(field_identifier, rename_all = "lowercase")]
-        enum Field {
-            Name,
-            Columns,
-            Values,
-        }
-
-        struct SeriesVisitor<T> {
-            _inner_type: PhantomData<T>,
-        }
-
-        impl<'de, T> Visitor<'de> for SeriesVisitor<T>
-        where
-            T: Deserialize<'de>,
-        {
-            type Value = Series<T>;
-
-            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
-                formatter.write_str("struct Series")
-            }
-
-            fn visit_map<V>(self, mut map: V) -> Result<Series<T>, V::Error>
-            where
-                V: MapAccess<'de>,
-            {
-                let mut name = None;
-                let mut columns: Option<Vec<String>> = None;
-                let mut values: Option<Vec<T>> = None;
-                while let Some(key) = map.next_key()? {
-                    match key {
-                        Field::Name => {
-                            if name.is_some() {
-                                return Err(Error::duplicate_field("name"));
-                            }
-                            name = Some(map.next_value()?);
-                        }
-                        Field::Columns => {
-                            if columns.is_some() {
-                                return Err(Error::duplicate_field("columns"));
-                            }
-                            columns = Some(map.next_value()?);
-                        }
-                        Field::Values => {
-                            if values.is_some() {
-                                return Err(Error::duplicate_field("values"));
-                            }
-                            // Error out if "values" is encountered before "columns"
-                            // Hopefully, InfluxDB never does this.
-                            if columns.is_none() {
-                                return Err(Error::custom(
-                                    "series values encountered before columns",
-                                ));
-                            }
-                            // Deserialize using a HeaderVec deserializer
-                            // seeded with the headers from the "columns" field
-                            values = Some(map.next_value_seed(HeaderVec::<T> {
-                                header: columns.as_ref().unwrap(),
-                                _inner_type: PhantomData,
-                            })?);
-                        }
-                    }
-                }
-                let name = name.ok_or_else(|| Error::missing_field("name"))?;
-                let values = values.unwrap_or_default();
-
-                Ok(Series { name, values })
-            }
-        }
-
-        const FIELDS: &[&str] = &["name", "values"];
-        deserializer.deserialize_struct(
-            "Series",
-            FIELDS,
-            SeriesVisitor::<T> {
-                _inner_type: PhantomData,
-            },
-        )
-    }
-}
-
-// Based on https://serde.rs/deserialize-struct.html
-impl<'de, TAG, T> Deserialize<'de> for TaggedSeries<TAG, T>
-where
-    TAG: Deserialize<'de>,
-    T: Deserialize<'de>,
-{
-    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
-    where
-        D: Deserializer<'de>,
-    {
-        // Field name deserializer
-        #[derive(Deserialize)]
-        #[serde(field_identifier, rename_all = "lowercase")]
-        enum Field {
-            Name,
-            Tags,
-            Columns,
-            Values,
-        }
-
-        struct SeriesVisitor<TAG, T> {
-            _tag_type: PhantomData<TAG>,
-            _value_type: PhantomData<T>,
-        }
-
-        impl<'de, TAG, T> Visitor<'de> for SeriesVisitor<TAG, T>
-        where
-            TAG: Deserialize<'de>,
-            T: Deserialize<'de>,
-        {
-            type Value = TaggedSeries<TAG, T>;
-
-            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
-                formatter.write_str("struct TaggedSeries")
-            }
-
-            fn visit_map<V>(self, mut map: V) -> Result<TaggedSeries<TAG, T>, V::Error>
-            where
-                V: MapAccess<'de>,
-            {
-                let mut name = None;
-                let mut tags: Option<TAG> = None;
-                let mut columns: Option<Vec<String>> = None;
-                let mut values: Option<Vec<T>> = None;
-                while let Some(key) = map.next_key()? {
-                    match key {
-                        Field::Name => {
-                            if name.is_some() {
-                                return Err(Error::duplicate_field("name"));
-                            }
-                            name = Some(map.next_value()?);
-                        }
-                        Field::Tags => {
-                            if tags.is_some() {
-                                return Err(Error::duplicate_field("tags"));
-                            }
-                            tags = Some(map.next_value()?);
-                        }
-                        Field::Columns => {
-                            if columns.is_some() {
-                                return Err(Error::duplicate_field("columns"));
-                            }
-                            columns = Some(map.next_value()?);
-                        }
-                        Field::Values => {
-                            if values.is_some() {
-                                return Err(Error::duplicate_field("values"));
-                            }
-                            // Error out if "values" is encountered before "columns"
-                            // Hopefully, InfluxDB never does this.
-                            if columns.is_none() {
-                                return Err(Error::custom(
-                                    "series values encountered before columns",
-                                ));
-                            }
-                            // Deserialize using a HeaderVec deserializer
-                            // seeded with the headers from the "columns" field
-                            values = Some(map.next_value_seed(HeaderVec::<T> {
-                                header: columns.as_ref().unwrap(),
-                                _inner_type: PhantomData,
-                            })?);
-                        }
-                    }
-                }
-                let name = name.ok_or_else(|| Error::missing_field("name"))?;
-                let tags = tags.ok_or_else(|| Error::missing_field("tags"))?;
-                let values = values.ok_or_else(|| Error::missing_field("values"))?;
-                Ok(TaggedSeries { name, tags, values })
-            }
-        }
-
-        const FIELDS: &[&str] = &["name", "tags", "values"];
-        deserializer.deserialize_struct(
-            "TaggedSeries",
-            FIELDS,
-            SeriesVisitor::<TAG, T> {
-                _tag_type: PhantomData,
-                _value_type: PhantomData,
-            },
-        )
-    }
-}
-
-// Deserializer that takes a header as a seed
-// and deserializes an array of arrays into a
-// Vec of map-like values using the header as
-// keys and the values as values.
-struct HeaderVec<'h, T> {
-    header: &'h [String],
-    _inner_type: PhantomData<T>,
-}
-
-impl<'de, 'h, T> DeserializeSeed<'de> for HeaderVec<'h, T>
-where
-    T: Deserialize<'de>,
-{
-    type Value = Vec<T>;
-
-    fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
-    where
-        D: Deserializer<'de>,
-    {
-        struct HeaderVecVisitor<'h, T> {
-            header: &'h [String],
-            _inner_type: PhantomData<T>,
-        }
-        impl<'de, 'h, T> Visitor<'de> for HeaderVecVisitor<'h, T>
-        where
-            T: Deserialize<'de>,
-        {
-            type Value = Vec<T>;
-
-            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
-                write!(formatter, "an array of arrays")
-            }
-
-            fn visit_seq<A>(self, mut seq: A) -> Result<Vec<T>, A::Error>
-            where
-                A: SeqAccess<'de>,
-            {
-                let mut vec = Vec::new();
-
-                while let Some(v) = seq.next_element_seed(RowWithHeader {
-                    header: self.header,
-                    _inner_type: PhantomData,
-                })? {
-                    vec.push(v);
-                }
-
-                Ok(vec)
-            }
-        }
-        deserializer.deserialize_seq(HeaderVecVisitor {
-            header: self.header,
-            _inner_type: PhantomData,
-        })
-    }
-}
-
-// Deserializer that takes a header as a seed
-// and deserializes an array into a map-like
-// value using the header as keys and the values
-// as values.
-struct RowWithHeader<'h, T> {
-    header: &'h [String],
-    _inner_type: PhantomData<T>,
-}
-
-impl<'de, 'h, T> DeserializeSeed<'de> for RowWithHeader<'h, T>
-where
-    T: Deserialize<'de>,
-{
-    type Value = T;
-
-    fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
-    where
-        D: Deserializer<'de>,
-    {
-        struct RowWithHeaderVisitor<'h, T> {
-            header: &'h [String],
-            _inner: PhantomData<fn() -> T>,
-        }
-
-        impl<'de, 'h, T> Visitor<'de> for RowWithHeaderVisitor<'h, T>
-        where
-            T: Deserialize<'de>,
-        {
-            type Value = T;
-
-            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
-                formatter.write_str("array")
-            }
-
-            fn visit_seq<A>(self, seq: A) -> Result<T, A::Error>
-            where
-                A: SeqAccess<'de>,
-            {
-                // `MapAccessDeserializer` is a wrapper that turns a `MapAccess`
-                // into a `Deserializer`, allowing it to be used as the input to T's
-                // `Deserialize` implementation. T then deserializes itself using
-                // the entries from the map visitor.
-                Deserialize::deserialize(value::MapAccessDeserializer::new(HeaderMapAccess {
-                    header: self.header,
-                    field: 0,
-                    data: seq,
-                }))
-            }
-        }
-
-        deserializer.deserialize_seq(RowWithHeaderVisitor {
-            header: self.header,
-            _inner: PhantomData,
-        })
-    }
-}
-
-// MapAccess implementation that holds a reference to
-// the header for keys and a serde sequence for values.
-// When asked for a key, it returns the next header and
-// advances its header field index. When asked for a value,
-// it tries to deserialize the next element in the serde
-// sequence into the desired type, and returns an error
-// if no element is returned (the sequence is exhausted).
-struct HeaderMapAccess<'h, A> {
-    header: &'h [String],
-    field: usize,
-    data: A,
-}
-
-impl<'de, 'h, A> MapAccess<'de> for HeaderMapAccess<'h, A>
-where
-    A: SeqAccess<'de>,
-{
-    type Error = <A as SeqAccess<'de>>::Error;
-
-    fn next_key_seed<K: DeserializeSeed<'de>>(
-        &mut self,
-        seed: K,
-    ) -> Result<Option<K::Value>, Self::Error> {
-        let field = match self.header.get(self.field) {
-            None => return Ok(None),
-            Some(field) => field,
-        };
-        self.field += 1;
-        seed.deserialize(field.clone().into_deserializer())
-            .map(Some)
-    }
-
-    fn next_value_seed<K: DeserializeSeed<'de>>(
-        &mut self,
-        seed: K,
-    ) -> Result<K::Value, Self::Error> {
-        match self.data.next_element_seed(seed)? {
-            Some(value) => Ok(value),
-            None => Err(Error::custom("next_value_seed called but no value")),
-        }
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use super::Series;
-    use std::borrow::Cow;
-    use std::collections::HashMap;
-
-    const TEST_DATA: &str = r#"
-    {
-        "name": "series_name",
-        "columns": ["foo", "bar"],
-        "values": [
-            ["foo_a", "bar_a"],
-            ["foo_b", "bar_b"]
-        ]
-    }
-    "#;
-
-    // we can derive all the impls we want here
-    #[derive(Debug, PartialEq, Eq)]
-    struct EqSeries<T> {
-        pub name: String,
-        pub values: Vec<T>,
-    }
-
-    impl<T> From<Series<T>> for EqSeries<T> {
-        fn from(Series { name, values }: Series<T>) -> Self {
-            EqSeries { name, values }
-        }
-    }
-
-    #[test]
-    fn test_deserialize_cow() {
-        // Unfortunately, Cow is not automatically borrowed,
-        // so this is basically equivalent to String, String
-        let result = serde_json::from_str::<Series<HashMap<Cow<str>, Cow<str>>>>(TEST_DATA);
-        assert!(result.is_ok());
-        assert_eq!(
-            EqSeries::from(result.unwrap()),
-            EqSeries {
-                name: "series_name".into(),
-                values: vec![
-                    {
-                        let mut h = std::collections::HashMap::new();
-                        h.insert("foo".into(), "foo_a".into());
-                        h.insert("bar".into(), "bar_a".into());
-                        h
-                    },
-                    {
-                        let mut h = std::collections::HashMap::new();
-                        h.insert("foo".into(), "foo_b".into());
-                        h.insert("bar".into(), "bar_b".into());
-                        h
-                    },
-                ],
-            },
-        );
-    }
-
-    #[test]
-    fn test_deserialize_borrowed() {
-        use serde_derive::Deserialize;
-
-        // Deserializing a string that cannot be passed through
-        // without escaping will result in an error like this:
-        // `invalid type: string "\n", expected a borrowed string at line 6 column 43`
-        // but if it doesn't need escaping it's fine.
-        #[derive(Deserialize, Debug, PartialEq, Eq)]
-        struct BorrowingStruct<'a> {
-            foo: &'a str,
-            bar: &'a str,
-        }
-
-        let result = serde_json::from_str::<Series<BorrowingStruct>>(TEST_DATA);
-        assert!(result.is_ok(), "{}", result.unwrap_err());
-        assert_eq!(
-            EqSeries::from(result.unwrap()),
-            EqSeries {
-                name: "series_name".into(),
-                values: vec![
-                    BorrowingStruct {
-                        foo: "foo_a",
-                        bar: "bar_a",
-                    },
-                    BorrowingStruct {
-                        foo: "foo_b",
-                        bar: "bar_b",
-                    },
-                ],
-            },
-        );
-    }
-}
diff --git a/influxdb/src/integrations/serde_integration/mod.rs b/influxdb/src/integrations/serde_integration/mod.rs
deleted file mode 100644
index 75b678b..0000000
--- a/influxdb/src/integrations/serde_integration/mod.rs
+++ /dev/null
@@ -1,186 +0,0 @@
-//! Serde Integration for InfluxDB. Provides deserialization of query returns.
-//!
-//! When querying multiple series in the same query (e.g. with a regex query), it might be desirable to flat map
-//! the resulting series into a single `Vec` like so. The example assumes, that there are weather readings in multiple
-//! series named `weather_<city_name>` (e.g. `weather_berlin`, or `weather_london`). Since we're using a Regex query,
-//! we don't actually know which series will be returned. To assign the city name to the series, we can use the series
-//! `name`, InfluxDB provides alongside query results.
-//!
-//! ```rust,no_run
-//! use influxdb::{Client, Query};
-//! use serde_derive::Deserialize;
-//!
-//! #[derive(Deserialize)]
-//! struct WeatherWithoutCityName {
-//!     temperature: i32,
-//! }
-//!
-//! #[derive(Deserialize)]
-//! struct Weather {
-//!     city_name: String,
-//!     weather: WeatherWithoutCityName,
-//! }
-//!
-//! # #[async_std::main]
-//! # async fn main() -> Result<(), influxdb::Error> {
-//! let client = Client::new("http://localhost:8086", "test");
-//! let query = Query::raw_read_query(
-//!     "SELECT temperature FROM /weather_[a-z]*$/ WHERE time > now() - 1m ORDER BY DESC",
-//! );
-//! let mut db_result = client.json_query(query).await?;
-//! let _result = db_result
-//!     .deserialize_next::<WeatherWithoutCityName>()?
-//!     .series
-//!     .into_iter()
-//!     .map(|mut city_series| {
-//!         let city_name =
-//!             city_series.name.split("_").collect::<Vec<&str>>().remove(2);
-//!         Weather {
-//!             weather: city_series.values.remove(0),
-//!             city_name: city_name.to_string(),
-//!         }
-//!     })
-//!     .collect::<Vec<Weather>>();
-//! # Ok(())
-//! # }
-//! ```
-
-mod de;
-
-use serde::de::DeserializeOwned;
-use serde_derive::Deserialize;
-
-use crate::{client::check_status, Client, Error, Query, ReadQuery};
-
-#[derive(Deserialize)]
-#[doc(hidden)]
-struct _DatabaseError {
-    error: String,
-}
-
-#[derive(Deserialize, Debug)]
-#[doc(hidden)]
-pub struct DatabaseQueryResult {
-    pub results: Vec<serde_json::Value>,
-}
-
-impl DatabaseQueryResult {
-    pub fn deserialize_next<T: 'static>(&mut self) -> Result<Return<T>, Error>
-    where
-        T: DeserializeOwned + Send,
-    {
-        serde_json::from_value::<Return<T>>(self.results.remove(0)).map_err(|err| {
-            Error::DeserializationError {
-                error: format!("could not deserialize: {}", err),
-            }
-        })
-    }
-
-    pub fn deserialize_next_tagged<TAG, T: 'static>(
-        &mut self,
-    ) -> Result<TaggedReturn<TAG, T>, Error>
-    where
-        TAG: DeserializeOwned + Send,
-        T: DeserializeOwned + Send,
-    {
-        serde_json::from_value::<TaggedReturn<TAG, T>>(self.results.remove(0)).map_err(|err| {
-            Error::DeserializationError {
-                error: format!("could not deserialize: {}", err),
-            }
-        })
-    }
-}
-
-#[derive(Deserialize, Debug)]
-#[doc(hidden)]
-pub struct Return<T> {
-    #[serde(default = "Vec::new")]
-    pub series: Vec<Series<T>>,
-}
-
-#[derive(Debug)]
-/// Represents a returned series from InfluxDB
-pub struct Series<T> {
-    pub name: String,
-    pub values: Vec<T>,
-}
-
-#[derive(Deserialize, Debug)]
-#[doc(hidden)]
-pub struct TaggedReturn<TAG, T> {
-    #[serde(default = "Vec::new")]
-    pub series: Vec<TaggedSeries<TAG, T>>,
-}
-
-#[derive(Debug)]
-/// Represents a returned series from InfluxDB
-pub struct TaggedSeries<TAG, T> {
-    pub name: String,
-    pub tags: TAG,
-    pub values: Vec<T>,
-}
-
-impl Client {
-    pub async fn json_query(&self, q: ReadQuery) -> Result<DatabaseQueryResult, Error> {
-        let query = q.build().map_err(|err| Error::InvalidQueryError {
-            error: format!("{}", err),
-        })?;
-
-        let read_query = query.get();
-        let read_query_lower = read_query.to_lowercase();
-
-        if !read_query_lower.contains("select") && !read_query_lower.contains("show") {
-            let error = Error::InvalidQueryError {
-                error: String::from(
-                    "Only SELECT and SHOW queries supported with JSON deserialization",
-                ),
-            };
-            return Err(error);
-        }
-
-        let url = &format!("{}/query", &self.url);
-        let mut parameters = self.parameters.as_ref().clone();
-        parameters.insert("q", read_query);
-        let mut request_builder = self.client.get(url);
-        if let Some(ref token) = self.token {
-            request_builder = request_builder.header("Authorization", format!("Token {}", token))
-        }
-        let request_builder = request_builder.query(&parameters);
-
-        #[cfg(feature = "surf")]
-        let request_builder = request_builder.map_err(|err| Error::UrlConstructionError {
-            error: err.to_string(),
-        })?;
-
-        let res = request_builder
-            .send()
-            .await
-            .map_err(|err| Error::ConnectionError {
-                error: err.to_string(),
-            })?;
-        check_status(&res)?;
-
-        #[cfg(feature = "reqwest")]
-        let body = res.bytes();
-        #[cfg(feature = "surf")]
-        let mut res = res;
-        #[cfg(feature = "surf")]
-        let body = res.body_bytes();
-
-        let body = body.await.map_err(|err| Error::ProtocolError {
-            error: err.to_string(),
-        })?;
-
-        // Try parsing InfluxDBs { "error": "error message here" }
-        if let Ok(error) = serde_json::from_slice::<_DatabaseError>(&body) {
-            return Err(Error::DatabaseError { error: error.error });
-        }
-
-        // Json has another structure, let's try actually parsing it to the type we're deserializing
-        serde_json::from_slice::<DatabaseQueryResult>(&body).map_err(|err| {
-            Error::DeserializationError {
-                error: format!("serde error: {}", err),
-            }
-        })
-    }
-}
diff --git a/influxdb/src/lib.rs b/influxdb/src/lib.rs
deleted file mode 100644
index d062e25..0000000
--- a/influxdb/src/lib.rs
+++ /dev/null
@@ -1,155 +0,0 @@
-//! Pull requests are always welcome. See [Contributing](https://github.com/influxdb-rs/influxdb-rust/blob/main/CONTRIBUTING.md) and [Code of Conduct](https://github.com/influxdb-rs/influxdb-rust/blob/main/CODE_OF_CONDUCT.md). For a list of past changes, see [CHANGELOG.md](https://github.com/influxdb-rs/influxdb-rust/blob/main/CHANGELOG.md).
-//!
-//! ## Currently Supported Features
-//!
-//! -   Reading and writing to InfluxDB
-//! -   Optional Serde support for deserialization
-//! -   Running multiple queries in one request (e.g. `SELECT * FROM weather_berlin; SELECT * FROM weather_london`)
-//! -   Writing single or multiple measurements in one request (e.g. `WriteQuery` or `Vec<WriteQuery>` argument)
-//! -   Authenticated and unauthenticated connections
-//! -   `async`/`await` support
-//! -   `#[derive(InfluxDbWriteable)]` derive macro for writing / reading into structs
-//! -   `GROUP BY` support
-//! -   Tokio and async-std support (see example below) or [available backends](https://github.com/influxdb-rs/influxdb-rust/blob/main/influxdb/Cargo.toml)
-//! -   Swappable HTTP backends ([see below](#Choice-of-HTTP-backend))
-//!
-//! # Quickstart
-//!
-//! Add the following to your `Cargo.toml`
-//!
-#![doc = cargo_toml!(indent="", "derive")]
-//!
-//! For an example with using Serde deserialization, please refer to [serde_integration](crate::integrations::serde_integration)
-//!
-//! ```rust,no_run
-//! use chrono::{DateTime, Utc};
-//! use influxdb::{Client, Error, InfluxDbWriteable, ReadQuery, Timestamp};
-//!
-//! #[tokio::main]
-//! // or #[async_std::main] if you prefer
-//! async fn main() -> Result<(), Error> {
-//!     // Connect to db `test` on `http://localhost:8086`
-//!     let client = Client::new("http://localhost:8086", "test");
-//!
-//!     #[derive(InfluxDbWriteable)]
-//!     struct WeatherReading {
-//!         time: DateTime<Utc>,
-//!         humidity: i32,
-//!         #[influxdb(tag)]
-//!         wind_direction: String,
-//!     }
-//!
-//!     // Let's write some data into a measurement called `weather`
-//!     let weather_readings = vec![
-//!         WeatherReading {
-//!             time: Timestamp::Hours(1).into(),
-//!             humidity: 30,
-//!             wind_direction: String::from("north"),
-//!         }
-//!         .into_query("weather"),
-//!         WeatherReading {
-//!             time: Timestamp::Hours(2).into(),
-//!             humidity: 40,
-//!             wind_direction: String::from("west"),
-//!         }
-//!         .into_query("weather"),
-//!     ];
-//!
-//!     client.query(weather_readings).await?;
-//!
-//!     // Read back all records
-//!     let read_query = ReadQuery::new("SELECT * FROM weather");
-//!
-//!     let read_result = client.query(read_query).await?;
-//!     println!("{}", read_result);
-//!     Ok(())
-//! }
-//! ```
-//!
-//! For further examples, check out the integration tests in `tests/integration_tests.rs`
-//! in the repository.
-//!
-//! # Choice of HTTP backend
-//!
-//! To communicate with InfluxDB, you can choose the HTTP backend to be used configuring the appropriate feature. We recommend sticking with the default reqwest-based client, unless you really need async-std compatibility.
-//!
-//! - **[hyper](https://github.com/hyperium/hyper)** (through reqwest, used by default), with [rustls](https://github.com/ctz/rustls)
-#![doc = cargo_toml!(indent="\t", "derive")]
-//! - **[hyper](https://github.com/hyperium/hyper)** (through reqwest), with native TLS (OpenSSL)
-#![doc = cargo_toml!(indent="\t", default-features = false, "derive", "serde", "reqwest-client-native-tls")]
-//! - **[hyper](https://github.com/hyperium/hyper)** (through reqwest), with vendored native TLS (OpenSSL)
-#![doc = cargo_toml!(indent="\t", default-features = false, "derive", "serde", "reqwest-client-native-tls-vendored")]
-//! - **[hyper](https://github.com/hyperium/hyper)** (through surf), use this if you need tokio 0.2 compatibility
-#![doc = cargo_toml!(indent="\t", default-features = false, "derive", "serde", "hyper-client")]
-//! - **[curl](https://github.com/alexcrichton/curl-rust)**, using [libcurl](https://curl.se/libcurl/)
-#![doc = cargo_toml!(indent="\t", default-features = false, "derive", "serde", "curl-client")]
-//! - **[async-h1](https://github.com/http-rs/async-h1)** with native TLS (OpenSSL)
-#![doc = cargo_toml!(indent="\t", default-features = false, "derive", "serde", "h1-client")]
-//! - **[async-h1](https://github.com/http-rs/async-h1)** with [rustls](https://github.com/ctz/rustls)
-#![doc = cargo_toml!(indent="\t", default-features = false, "derive", "serde", "h1-client-rustls")]
-//! - WebAssembly's `window.fetch`, via `web-sys` and **[wasm-bindgen](https://github.com/rustwasm/wasm-bindgen)**
-#![doc = cargo_toml!(indent="\t", default-features = false, "derive", "serde", "wasm-client")]
-//!
-//! # License
-//!
-//! [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
-
-#![allow(clippy::needless_doctest_main)]
-#![allow(clippy::needless_lifetimes)] // False positive in client/mod.rs query fn
-#![forbid(bare_trait_objects)]
-
-macro_rules! cargo_toml {
-    (indent=$indent:literal, $firstfeat:literal $(, $feature:literal)*) => {
-        cargo_toml_private!($indent, "", $firstfeat $(, $feature)*)
-    };
-
-    (indent=$indent:literal, default-features = false, $firstfeat:literal $(, $feature:literal)*) => {
-        cargo_toml_private!($indent, "default-features = false, ", $firstfeat $(, $feature)*)
-    };
-}
-
-macro_rules! cargo_toml_private {
-    ($indent:literal, $deffeats:literal, $firstfeat:literal $(, $feature:literal)*) => {
-        concat!(
-            $indent,
-            "```toml\n",
-
-            $indent,
-            "influxdb = { version = \"",
-            env!("CARGO_PKG_VERSION"),
-            "\", ",
-            $deffeats,
-            "features = [",
-            "\"", $firstfeat, "\"",
-            $(", \"", $feature, "\"",)*
-            "] }\n",
-
-            $indent,
-            "```"
-        )
-    };
-}
-
-#[cfg(all(feature = "reqwest", feature = "surf"))]
-compile_error!("You need to choose between reqwest and surf; enabling both is not supported");
-
-#[cfg(not(any(feature = "reqwest", feature = "surf")))]
-compile_error!("You need to choose an http client; consider not disabling default features");
-
-mod client;
-mod error;
-mod query;
-
-pub use client::Client;
-pub use error::Error;
-pub use query::{
-    read_query::ReadQuery,
-    write_query::{Type, WriteQuery},
-    InfluxDbWriteable, Query, QueryType, Timestamp, ValidQuery,
-};
-
-#[cfg(feature = "serde")]
-pub mod integrations {
-    #[cfg(feature = "serde")]
-    pub mod serde_integration;
-}
diff --git a/influxdb/src/query/consts.rs b/influxdb/src/query/consts.rs
deleted file mode 100644
index 96c0b36..0000000
--- a/influxdb/src/query/consts.rs
+++ /dev/null
@@ -1,5 +0,0 @@
-pub const MINUTES_PER_HOUR: u128 = 60;
-pub const SECONDS_PER_MINUTE: u128 = 60;
-pub const MILLIS_PER_SECOND: u128 = 1000;
-pub const NANOS_PER_MILLI: u128 = 1_000_000;
-pub const NANOS_PER_MICRO: u128 = 1000;
diff --git a/influxdb/src/query/line_proto_term.rs b/influxdb/src/query/line_proto_term.rs
deleted file mode 100644
index d803c75..0000000
--- a/influxdb/src/query/line_proto_term.rs
+++ /dev/null
@@ -1,149 +0,0 @@
-/// InfluxDB Line Protocol escaping helper module.
-/// https://docs.influxdata.com/influxdb/v1.7/write_protocols/line_protocol_tutorial/
-use crate::Type;
-use lazy_regex::{lazy_regex, Lazy, Regex};
-
-pub static COMMAS_SPACES: Lazy<Regex> = lazy_regex!("[, ]");
-pub static COMMAS_SPACES_EQUALS: Lazy<Regex> = lazy_regex!("[, =]");
-pub static QUOTES_SLASHES: Lazy<Regex> = lazy_regex!(r#"["\\]"#);
-pub static SLASHES: Lazy<Regex> = lazy_regex!(r#"(\\|,| |=|")"#);
-
-pub enum LineProtoTerm<'a> {
-    Measurement(&'a str), // escape commas, spaces
-    TagKey(&'a str),      // escape commas, equals, spaces
-    TagValue(&'a Type),   // escape commas, equals, spaces
-    FieldKey(&'a str),    // escape commas, equals, spaces
-    FieldValue(&'a Type), // escape quotes, backslashes + quote
-}
-
-impl LineProtoTerm<'_> {
-    pub fn escape(self) -> String {
-        use LineProtoTerm::*;
-        match self {
-            Measurement(x) => Self::escape_any(x, &COMMAS_SPACES),
-            TagKey(x) | FieldKey(x) => Self::escape_any(x, &COMMAS_SPACES_EQUALS),
-            FieldValue(x) => Self::escape_field_value(x, false),
-            TagValue(x) => Self::escape_tag_value(x),
-        }
-    }
-
-    pub fn escape_v2(self) -> String {
-        use LineProtoTerm::*;
-        match self {
-            Measurement(x) => Self::escape_any(x, &COMMAS_SPACES),
-            TagKey(x) | FieldKey(x) => Self::escape_any(x, &COMMAS_SPACES_EQUALS),
-            FieldValue(x) => Self::escape_field_value(x, true),
-            TagValue(x) => Self::escape_tag_value(x),
-        }
-    }
-
-    fn escape_field_value(v: &Type, use_v2: bool) -> String {
-        use Type::*;
-        match v {
-            Boolean(v) => {
-                if *v {
-                    "true"
-                } else {
-                    "false"
-                }
-            }
-            .to_string(),
-            Float(v) => v.to_string(),
-            SignedInteger(v) => format!("{}i", v),
-            UnsignedInteger(v) => {
-                if use_v2 {
-                    format!("{}u", v)
-                } else {
-                    format!("{}i", v)
-                }
-            }
-            Text(v) => format!(r#""{}""#, Self::escape_any(v, &QUOTES_SLASHES)),
-        }
-    }
-
-    fn escape_tag_value(v: &Type) -> String {
-        use Type::*;
-        match v {
-            Boolean(v) => {
-                if *v {
-                    "true"
-                } else {
-                    "false"
-                }
-            }
-            .to_string(),
-            Float(v) => format!(r#"{}"#, v),
-            SignedInteger(v) => format!(r#"{}"#, v),
-            UnsignedInteger(v) => format!(r#"{}"#, v),
-            Text(v) => Self::escape_any(v, &SLASHES),
-        }
-    }
-
-    fn escape_any(s: &str, re: &Regex) -> String {
-        re.replace_all(s, r"\$0").to_string()
-    }
-}
-
-#[cfg(test)]
-mod test {
-    use crate::query::line_proto_term::LineProtoTerm::*;
-    use crate::Type;
-
-    #[test]
-    fn test() {
-        assert_eq!(TagValue(&Type::Boolean(true)).escape(), r#"true"#);
-        assert_eq!(TagValue(&Type::Float(1.8324f64)).escape(), r#"1.8324"#);
-        assert_eq!(TagValue(&Type::SignedInteger(-1i64)).escape(), r#"-1"#);
-        assert_eq!(TagValue(&Type::UnsignedInteger(1u64)).escape(), r#"1"#);
-
-        assert_eq!(
-            TagValue(&Type::Text("this is my special string".into())).escape(),
-            r"this\ is\ my\ special\ string"
-        );
-        assert_eq!(
-            TagValue(&Type::Text("a tag w=i th == tons of escapes".into())).escape(),
-            r"a\ tag\ w\=i\ th\ \=\=\ tons\ of\ escapes"
-        );
-        assert_eq!(
-            TagValue(&Type::Text("no_escapes".into())).escape(),
-            r#"no_escapes"#
-        );
-        assert_eq!(
-            TagValue(&Type::Text("some,commas,here".into())).escape(),
-            r"some\,commas\,here"
-        );
-
-        assert_eq!(Measurement(r#"wea", ther"#).escape(), r#"wea"\,\ ther"#);
-        assert_eq!(TagKey(r"locat\ ,=ion").escape(), r"locat\\ \,\=ion");
-
-        assert_eq!(FieldValue(&Type::Boolean(true)).escape(), r#"true"#);
-        assert_eq!(FieldValue(&Type::Boolean(false)).escape(), r#"false"#);
-
-        assert_eq!(FieldValue(&Type::Float(0.0)).escape(), r#"0"#);
-        assert_eq!(FieldValue(&Type::Float(-0.1)).escape(), r#"-0.1"#);
-
-        assert_eq!(FieldValue(&Type::SignedInteger(0)).escape(), r#"0i"#);
-        assert_eq!(FieldValue(&Type::SignedInteger(83)).escape(), r#"83i"#);
-
-        assert_eq!(FieldValue(&Type::UnsignedInteger(0)).escape(), r#"0i"#);
-        assert_eq!(FieldValue(&Type::UnsignedInteger(83)).escape(), r#"83i"#);
-
-        assert_eq!(FieldValue(&Type::UnsignedInteger(0)).escape_v2(), r#"0u"#);
-        assert_eq!(FieldValue(&Type::UnsignedInteger(83)).escape_v2(), r#"83u"#);
-
-        assert_eq!(FieldValue(&Type::Text("".into())).escape(), r#""""#);
-        assert_eq!(FieldValue(&Type::Text("0".into())).escape(), r#""0""#);
-        assert_eq!(FieldValue(&Type::Text("\"".into())).escape(), r#""\"""#);
-        assert_eq!(
-            FieldValue(&Type::Text(r#"locat"\ ,=ion"#.into())).escape(),
-            r#""locat\"\\ ,=ion""#
-        );
-    }
-
-    #[test]
-    fn test_empty_tag_value() {
-        // InfluxDB doesn't support empty tag values. But that's a job
-        // of a calling site to validate an entire write request.
-        assert_eq!(TagValue(&Type::Text("".into())).escape(), r#""#);
-    }
-}
diff --git a/influxdb/src/query/mod.rs b/influxdb/src/query/mod.rs
deleted file mode 100644
index 02163c7..0000000
--- a/influxdb/src/query/mod.rs
+++ /dev/null
@@ -1,324 +0,0 @@
-//! Used to create queries of type [`ReadQuery`](crate::query::read_query::ReadQuery) or
-//! [`WriteQuery`](crate::query::write_query::WriteQuery) which can be executed in InfluxDB
-//!
-//! # Examples
-//!
-//! ```rust
-//! use influxdb::{Query, Timestamp};
-//! use influxdb::InfluxDbWriteable;
-//!
-//! let write_query = Timestamp::Nanoseconds(0).into_query("measurement")
-//!     .add_field("field1", 5)
-//!     .add_tag("author", "Gero")
-//!     .build();
-//!
-//! assert!(write_query.is_ok());
-//!
-//! let read_query = Query::raw_read_query("SELECT * FROM weather")
-//!     .build();
-//!
-//! 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;
-pub mod write_query;
-use std::fmt;
-
-use crate::{Error, ReadQuery, WriteQuery};
-use consts::{
-    MILLIS_PER_SECOND, MINUTES_PER_HOUR, NANOS_PER_MICRO, NANOS_PER_MILLI, SECONDS_PER_MINUTE,
-};
-
-#[cfg(feature = "derive")]
-pub use influxdb_derive::InfluxDbWriteable;
-
-#[derive(PartialEq, Eq, Debug, Copy, Clone)]
-pub enum Timestamp {
-    Nanoseconds(u128),
-    Microseconds(u128),
-    Milliseconds(u128),
-    Seconds(u128),
-    Minutes(u128),
-    Hours(u128),
-}
-
-impl fmt::Display for Timestamp {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        use Timestamp::*;
-        match self {
-            Nanoseconds(ts) | Microseconds(ts) | Milliseconds(ts) | Seconds(ts) | Minutes(ts)
-            | Hours(ts) => write!(f, "{}", ts),
-        }
-    }
-}
-
-impl From<Timestamp> for DateTime<Utc> {
-    fn from(ts: Timestamp) -> DateTime<Utc> {
-        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())
-            }
-        }
-    }
-}
-
-impl<T> From<DateTime<T>> for Timestamp
-where
-    T: TimeZone,
-{
-    fn from(date_time: DateTime<T>) -> Self {
-        Timestamp::Nanoseconds(date_time.timestamp_nanos_opt().unwrap() 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,
-    /// as that is invalid InfluxSQL syntax.
-    ///
-    /// # Examples
-    ///
-    /// ```rust
-    /// use influxdb::{Query, Timestamp};
-    /// use influxdb::InfluxDbWriteable;
-    ///
-    /// let invalid_query = Timestamp::Nanoseconds(0).into_query("measurement").build();
-    /// assert!(invalid_query.is_err());
-    ///
-    /// let valid_query = Timestamp::Nanoseconds(0).into_query("measurement").add_field("myfield1", 11).build();
-    /// assert!(valid_query.is_ok());
-    /// ```
-    fn build(&self) -> Result<ValidQuery, Error>;
-
-    /// Like [build] but with additional support for unsigned integers in the line protocol.
-    /// Please note, this crate can only interact with InfluxDB 2.0 in compatibility mode
-    /// and does not natively support InfluxDB 2.0.
-    ///
-    /// # Examples
-    ///
-    /// ```rust
-    /// use influxdb::{Query, Timestamp};
-    /// use influxdb::InfluxDbWriteable;
-    ///
-    /// let use_v2 = true;
-    ///
-    /// let invalid_query = Timestamp::Nanoseconds(0).into_query("measurement").build_with_opts(use_v2);
-    /// assert!(invalid_query.is_err());
-    ///
-    /// let valid_query = Timestamp::Nanoseconds(0).into_query("measurement").add_field("myfield1", 11).build_with_opts(use_v2);
-    /// assert!(valid_query.is_ok());
-    /// ```
-    fn build_with_opts(&self, use_v2: bool) -> Result<ValidQuery, Error>;
-
-    fn get_type(&self) -> QueryType;
-}
-
-impl<Q: Query> Query for &Q {
-    fn build(&self) -> Result<ValidQuery, Error> {
-        Q::build_with_opts(self, false)
-    }
-
-    fn build_with_opts(&self, use_v2: bool) -> Result<ValidQuery, Error> {
-        Q::build_with_opts(self, use_v2)
-    }
-
-    fn get_type(&self) -> QueryType {
-        Q::get_type(self)
-    }
-}
-
-impl<Q: Query> Query for Box<Q> {
-    fn build(&self) -> Result<ValidQuery, Error> {
-        Q::build(self)
-    }
-
-    fn build_with_opts(&self, use_v2: bool) -> Result<ValidQuery, Error> {
-        Q::build_with_opts(self, use_v2)
-    }
-
-    fn get_type(&self) -> QueryType {
-        Q::get_type(self)
-    }
-}
-
-pub trait InfluxDbWriteable {
-    fn into_query<I: Into<String>>(self, name: I) -> WriteQuery;
-}
-
-impl InfluxDbWriteable for Timestamp {
-    fn into_query<I: Into<String>>(self, name: I) -> WriteQuery {
-        WriteQuery::new(self, name.into())
-    }
-}
-
-impl dyn Query {
-    /// Returns a [`ReadQuery`](crate::ReadQuery) builder.
-    ///
-    /// # Examples
-    ///
-    /// ```rust
-    /// use influxdb::Query;
-    ///
-    /// Query::raw_read_query("SELECT * FROM weather"); // Is of type [`ReadQuery`](crate::ReadQuery)
-    /// ```
-    #[deprecated(since = "0.5.0", note = "Use ReadQuery::new instead")]
-    pub fn raw_read_query<S>(read_query: S) -> ReadQuery
-    where
-        S: Into<String>,
-    {
-        ReadQuery::new(read_query)
-    }
-}
-
-#[derive(Debug)]
-#[doc(hidden)]
-pub struct ValidQuery(String);
-impl ValidQuery {
-    pub fn get(self) -> String {
-        self.0
-    }
-}
-impl<T> From<T> for ValidQuery
-where
-    T: Into<String>,
-{
-    fn from(string: T) -> Self {
-        Self(string.into())
-    }
-}
-impl PartialEq<String> for ValidQuery {
-    fn eq(&self, other: &String) -> bool {
-        &self.0 == other
-    }
-}
-impl PartialEq<&str> for ValidQuery {
-    fn eq(&self, other: &&str) -> bool {
-        &self.0 == other
-    }
-}
-
-/// Internal Enum used to decide if a `POST` or `GET` request should be sent to InfluxDB. See [InfluxDB Docs](https://docs.influxdata.com/influxdb/v1.7/tools/api/#query-http-endpoint).
-#[derive(PartialEq, Eq, Debug)]
-pub enum QueryType {
-    ReadQuery,
-    /// write query with precision
-    WriteQuery(String),
-}
-
-#[cfg(test)]
-mod tests {
-    use super::consts::{
-        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() {
-        assert_eq!(ValidQuery::from("hello"), "hello");
-    }
-    #[test]
-    fn test_equality_string() {
-        assert_eq!(
-            ValidQuery::from(String::from("hello")),
-            String::from("hello")
-        );
-    }
-    #[test]
-    fn test_format_for_timestamp_else() {
-        assert!(format!("{}", Timestamp::Nanoseconds(100)) == "100");
-    }
-    #[test]
-    fn test_chrono_datetime_from_timestamp_hours() {
-        let datetime_from_timestamp: DateTime<Utc> = Timestamp::Hours(2).into();
-        assert_eq!(
-            Utc.timestamp_nanos(
-                (2 * MINUTES_PER_HOUR * SECONDS_PER_MINUTE * MILLIS_PER_SECOND * NANOS_PER_MILLI)
-                    .try_into()
-                    .unwrap()
-            ),
-            datetime_from_timestamp
-        )
-    }
-    #[test]
-    fn test_chrono_datetime_from_timestamp_minutes() {
-        let datetime_from_timestamp: DateTime<Utc> = Timestamp::Minutes(2).into();
-        assert_eq!(
-            Utc.timestamp_nanos(
-                (2 * SECONDS_PER_MINUTE * MILLIS_PER_SECOND * NANOS_PER_MILLI)
-                    .try_into()
-                    .unwrap()
-            ),
-            datetime_from_timestamp
-        )
-    }
-    #[test]
-    fn test_chrono_datetime_from_timestamp_seconds() {
-        let datetime_from_timestamp: DateTime<Utc> = Timestamp::Seconds(2).into();
-        assert_eq!(
-            Utc.timestamp_nanos(
-                (2 * MILLIS_PER_SECOND * NANOS_PER_MILLI)
-                    .try_into()
-                    .unwrap()
-            ),
-            datetime_from_timestamp
-        )
-    }
-    #[test]
-    fn test_chrono_datetime_from_timestamp_millis() {
-        let datetime_from_timestamp: DateTime<Utc> = Timestamp::Milliseconds(2).into();
-        assert_eq!(
-            Utc.timestamp_nanos((2 * NANOS_PER_MILLI).try_into().unwrap()),
-            datetime_from_timestamp
-        )
-    }
-    #[test]
-    fn test_chrono_datetime_from_timestamp_nanos() {
-        let datetime_from_timestamp: DateTime<Utc> = Timestamp::Nanoseconds(1).into();
-        assert_eq!(Utc.timestamp_nanos(1), datetime_from_timestamp)
-    }
-    #[test]
-    fn test_chrono_datetime_from_timestamp_micros() {
-        let datetime_from_timestamp: DateTime<Utc> = Timestamp::Microseconds(2).into();
-        assert_eq!(
-            Utc.timestamp_nanos((2 * NANOS_PER_MICRO).try_into().unwrap()),
-            datetime_from_timestamp
-        )
-    }
-    #[test]
-    fn test_timestamp_from_chrono_date() {
-        let timestamp_from_datetime: Timestamp = Utc
-            .with_ymd_and_hms(1970, 1, 1, 0, 0, 1)
-            .single()
-            .unwrap()
-            .into();
-        assert_eq!(
-            Timestamp::Nanoseconds(MILLIS_PER_SECOND * NANOS_PER_MILLI),
-            timestamp_from_datetime
-        )
-    }
-}
diff --git a/influxdb/src/query/read_query.rs b/influxdb/src/query/read_query.rs
deleted file mode 100644
index a102146..0000000
--- a/influxdb/src/query/read_query.rs
+++ /dev/null
@@ -1,76 +0,0 @@
-//! Read Query Builder returned by Query::raw_read_query
-//!
-//! Can only be instantiated by using Query::raw_read_query
-
-use crate::query::{QueryType, ValidQuery};
-use crate::{Error, Query};
-
-#[derive(Debug, Clone)]
-pub struct ReadQuery {
-    queries: Vec<String>,
-}
-
-impl ReadQuery {
-    /// Creates a new [`ReadQuery`]
-    #[must_use = "Creating a query is pointless unless you execute it"]
-    pub fn new<S>(query: S) -> Self
-    where
-        S: Into<String>,
-    {
-        ReadQuery {
-            queries: vec![query.into()],
-        }
-    }
-
-    /// Adds a query to the [`ReadQuery`]
-    #[must_use = "Creating a query is pointless unless you execute it"]
-    pub fn add_query<S>(mut self, query: S) -> Self
-    where
-        S: Into<String>,
-    {
-        self.queries.push(query.into());
-        self
-    }
-}
-
-impl Query for ReadQuery {
-    fn build(&self) -> Result<ValidQuery, Error> {
-        Ok(ValidQuery(self.queries.join(";")))
-    }
-
-    fn build_with_opts(&self, _use_v2: bool) -> Result<ValidQuery, Error> {
-        Ok(ValidQuery(self.queries.join(";")))
-    }
-
-    fn get_type(&self) -> QueryType {
-        QueryType::ReadQuery
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use crate::query::{Query, QueryType, ReadQuery};
-
-    #[test]
-    fn test_read_builder_single_query() {
-        let query = ReadQuery::new("SELECT * FROM aachen").build();
-
-        assert_eq!(query.unwrap(), "SELECT * FROM aachen");
-    }
-
-    #[test]
-    fn test_read_builder_multi_query() {
-        let query = ReadQuery::new("SELECT * FROM aachen")
-            .add_query("SELECT * FROM cologne")
-            .build();
-
-        assert_eq!(query.unwrap(), "SELECT * FROM aachen;SELECT * FROM cologne");
-    }
-
-    #[test]
-    fn test_correct_query_type() {
-        let query = ReadQuery::new("SELECT * FROM aachen");
-
-        assert_eq!(query.get_type(), QueryType::ReadQuery);
-    }
-}
diff --git a/influxdb/src/query/write_query.rs b/influxdb/src/query/write_query.rs
deleted file mode 100644
index 75d8b02..0000000
--- a/influxdb/src/query/write_query.rs
+++ /dev/null
@@ -1,436 +0,0 @@
-//! Write Query Builder returned by Query::write_query
-//!
-//! Can only be instantiated by using Query::write_query
-
-use crate::query::line_proto_term::LineProtoTerm;
-use crate::query::{QueryType, ValidQuery};
-use crate::{Error, Query, Timestamp};
-use std::fmt::{Display, Formatter};
-
-pub trait WriteType {
-    fn add_to(self, tag: String, fields_or_tags: &mut Vec<(String, Type)>);
-}
-
-impl<T: Into<Type>> WriteType for T {
-    fn add_to(self, tag: String, fields_or_tags: &mut Vec<(String, Type)>) {
-        let val: Type = self.into();
-        fields_or_tags.push((tag, val));
-    }
-}
-
-impl<T: Into<Type>> WriteType for Option<T> {
-    fn add_to(self, tag: String, fields_or_tags: &mut Vec<(String, Type)>) {
-        if let Some(val) = self {
-            val.add_to(tag, fields_or_tags);
-        }
-    }
-}
-
-/// Internal Representation of a Write query that has not yet been built
-#[derive(Debug, Clone)]
-pub struct WriteQuery {
-    fields: Vec<(String, Type)>,
-    tags: Vec<(String, Type)>,
-    measurement: String,
-    timestamp: Timestamp,
-}
-
-impl WriteQuery {
-    /// Creates a new [`WriteQuery`](crate::query::write_query::WriteQuery)
-    #[must_use = "Creating a query is pointless unless you execute it"]
-    pub fn new<S>(timestamp: Timestamp, measurement: S) -> Self
-    where
-        S: Into<String>,
-    {
-        WriteQuery {
-            fields: vec![],
-            tags: vec![],
-            measurement: measurement.into(),
-            timestamp,
-        }
-    }
-
-    /// Adds a field to the [`WriteQuery`](crate::WriteQuery)
-    ///
-    /// # Examples
-    ///
-    /// ```rust
-    /// use influxdb::{Query, Timestamp};
-    /// use influxdb::InfluxDbWriteable;
-    ///
-    /// Timestamp::Nanoseconds(0).into_query("measurement").add_field("field1", 5).build();
-    /// ```
-    #[must_use = "Creating a query is pointless unless you execute it"]
-    pub fn add_field<S, F>(mut self, field: S, value: F) -> Self
-    where
-        S: Into<String>,
-        F: WriteType,
-    {
-        value.add_to(field.into(), &mut self.fields);
-        self
-    }
-
-    /// Adds a tag to the [`WriteQuery`](crate::WriteQuery)
-    ///
-    /// Please note that a [`WriteQuery`](crate::WriteQuery) requires at least one field. Composing a query with
-    /// only tags will result in a failure building the query.
-    ///
-    /// # Examples
-    ///
-    /// ```rust
-    /// use influxdb::{Query, Timestamp};
-    /// use influxdb::InfluxDbWriteable;
-    ///
-    /// Timestamp::Nanoseconds(0)
-    ///     .into_query("measurement")
-    ///     .add_tag("field1", 5); // calling `.build()` now would result in a `Err(Error::InvalidQueryError)`
-    /// ```
-    #[must_use = "Creating a query is pointless unless you execute it"]
-    pub fn add_tag<S, I>(mut self, tag: S, value: I) -> Self
-    where
-        S: Into<String>,
-        I: WriteType,
-    {
-        value.add_to(tag.into(), &mut self.tags);
-        self
-    }
-
-    pub fn get_precision(&self) -> String {
-        let modifier = match self.timestamp {
-            Timestamp::Nanoseconds(_) => "ns",
-            Timestamp::Microseconds(_) => "u",
-            Timestamp::Milliseconds(_) => "ms",
-            Timestamp::Seconds(_) => "s",
-            Timestamp::Minutes(_) => "m",
-            Timestamp::Hours(_) => "h",
-        };
-        modifier.to_string()
-    }
-}
-
-#[derive(Debug, Clone)]
-pub enum Type {
-    Boolean(bool),
-    Float(f64),
-    SignedInteger(i64),
-    UnsignedInteger(u64),
-    Text(String),
-}
-
-impl Display for Type {
-    fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
-        use Type::*;
-
-        match self {
-            Boolean(x) => write!(f, "{}", x),
-            Float(x) => write!(f, "{}", x),
-            SignedInteger(x) => write!(f, "{}", x),
-            UnsignedInteger(x) => write!(f, "{}", x),
-            Text(text) => write!(f, "{text}", text = text),
-        }
-    }
-}
-
-macro_rules! from_impl {
-        ( $variant:ident => $( $typ:ident ),+ ) => (
-                $(
-                    impl From<$typ> for Type {
-                        fn from(b: $typ) -> Self {
-                            Type::$variant(b.into())
-                        }
-                    }
-                )+
-        )
-}
-from_impl! {Boolean => bool}
-from_impl! {Float => f32, f64}
-from_impl! {SignedInteger => i8, i16, i32, i64}
-from_impl! {UnsignedInteger => u8, u16, u32, u64}
-from_impl! {Text => String}
-impl From<&str> for Type {
-    fn from(b: &str) -> Self {
-        Type::Text(b.into())
-    }
-}
-impl<T> From<&T> for Type
-where
-    T: Copy + Into<Type>,
-{
-    fn from(t: &T) -> Self {
-        (*t).into()
-    }
-}
-
-impl Query for WriteQuery {
-    fn build(&self) -> Result<ValidQuery, Error> {
-        self.build_with_opts(false)
-    }
-
-    fn build_with_opts(&self, use_v2: bool) -> Result<ValidQuery, Error> {
-        if self.fields.is_empty() {
-            return Err(Error::InvalidQueryError {
-                error: "fields cannot be empty".to_string(),
-            });
-        }
-
-        let mut tags = self
-            .tags
-            .iter()
-            .map(|(tag, value)| {
-                let escaped_tag_key = if use_v2 {
-                    LineProtoTerm::TagKey(tag).escape_v2()
-                } else {
-                    LineProtoTerm::TagKey(tag).escape()
-                };
-                let escaped_tag_value = if use_v2 {
-                    LineProtoTerm::TagValue(value).escape_v2()
-                } else {
-                    LineProtoTerm::TagValue(value).escape()
-                };
-                format!(
-                    "{tag}={value}",
-                    tag = escaped_tag_key,
-                    value = escaped_tag_value,
-                )
-            })
-            .collect::<Vec<String>>()
-            .join(",");
-
-        if !tags.is_empty() {
-            tags.insert(0, ',');
-        }
-        let fields = self
-            .fields
-            .iter()
-            .map(|(field, value)| {
-                let escaped_field_key = if use_v2 {
-                    LineProtoTerm::FieldKey(field).escape_v2()
-                } else {
-                    LineProtoTerm::FieldKey(field).escape()
-                };
-                let escaped_field_value = if use_v2 {
-                    LineProtoTerm::FieldValue(value).escape_v2()
-                } else {
-                    LineProtoTerm::FieldValue(value).escape()
-                };
-                format!(
-                    "{field}={value}",
-                    field = escaped_field_key,
-                    value = escaped_field_value,
-                )
-            })
-            .collect::<Vec<String>>()
-            .join(",");
-
-        let escaped_measurement = if use_v2 {
-            LineProtoTerm::Measurement(&self.measurement).escape_v2()
-        } else {
-            LineProtoTerm::Measurement(&self.measurement).escape()
-        };
-
-        Ok(ValidQuery(format!(
-            "{measurement}{tags} {fields} {time}",
-            measurement = escaped_measurement,
-            tags = tags,
-            fields = fields,
-            time = self.timestamp
-        )))
-    }
-
-    fn get_type(&self) -> QueryType {
-        QueryType::WriteQuery(self.get_precision())
-    }
-}
-
-impl Query for Vec<WriteQuery> {
-    fn build(&self) -> Result<ValidQuery, Error> {
-        let mut qlines = Vec::new();
-
-        for q in self {
-            let valid_query = q.build()?;
-            qlines.push(valid_query.0);
-        }
-
-        Ok(ValidQuery(qlines.join("\n")))
-    }
-
-    fn build_with_opts(&self, use_v2: bool) -> Result<ValidQuery, Error> {
-        let mut qlines = Vec::new();
-
-        for q in self {
-            let valid_query = q.build_with_opts(use_v2)?;
-            qlines.push(valid_query.0);
-        }
-
-        Ok(ValidQuery(qlines.join("\n")))
-    }
-
-    fn get_type(&self) -> QueryType {
-        QueryType::WriteQuery(
-            self.first()
-                .map(|q| q.get_precision())
-                // use "ms" as placeholder if query is empty
-                .unwrap_or_else(|| "ms".to_owned()),
-        )
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use crate::query::{InfluxDbWriteable, Query, Timestamp};
-
-    #[test]
-    fn test_write_builder_empty_query() {
-        let query = Timestamp::Hours(5)
-            .into_query("marina_3".to_string())
-            .build();
-
-        assert!(query.is_err(), "Query was not empty");
-    }
-
-    #[test]
-    fn test_write_builder_single_field() {
-        let query = Timestamp::Hours(11)
-            .into_query("weather".to_string())
-            .add_field("temperature", 82)
-            .build();
-
-        assert!(query.is_ok(), "Query was empty");
-        assert_eq!(query.unwrap(), "weather temperature=82i 11");
-    }
-
-    #[test]
-    fn test_write_builder_multiple_fields() {
-        let query = Timestamp::Hours(11)
-            .into_query("weather".to_string())
-            .add_field("temperature", 82)
-            .add_field("wind_strength", 3.7)
-            .add_field("temperature_unsigned", 82u64)
-            .build();
-
-        assert!(query.is_ok(), "Query was empty");
-        assert_eq!(
-            query.unwrap(),
-            "weather temperature=82i,wind_strength=3.7,temperature_unsigned=82i 11"
-        );
-    }
-
-    #[test]
-    fn test_write_builder_multiple_fields_with_v2() {
-        let query = Timestamp::Hours(11)
-            .into_query("weather".to_string())
-            .add_field("temperature", 82)
-            .add_field("wind_strength", 3.7)
-            .add_field("temperature_unsigned", 82u64)
-            .build_with_opts(true);
-
-        assert!(query.is_ok(), "Query was empty");
-        assert_eq!(
-            query.unwrap(),
-            "weather temperature=82i,wind_strength=3.7,temperature_unsigned=82u 11"
-        );
-    }
-
-    #[test]
-    fn test_write_builder_optional_fields() {
-        let query = Timestamp::Hours(11)
-            .into_query("weather".to_string())
-            .add_field("temperature", 82u64)
-            .add_tag("wind_strength", <Option<u64>>::None)
-            .build();
-
-        assert!(query.is_ok(), "Query was empty");
-        assert_eq!(query.unwrap(), "weather temperature=82i 11");
-    }
-
-    #[test]
-    fn test_write_builder_optional_fields_with_v2() {
-        let query = Timestamp::Hours(11)
-            .into_query("weather".to_string())
-            .add_field("temperature", 82u64)
-            .add_tag("wind_strength", <Option<u64>>::None)
-            .build_with_opts(true);
-
-        assert!(query.is_ok(), "Query was empty");
-        assert_eq!(query.unwrap(), "weather temperature=82u 11");
-    }
-
-    #[test]
-    fn test_write_builder_only_tags() {
-        let query = Timestamp::Hours(11)
-            .into_query("weather".to_string())
-            .add_tag("season", "summer")
-            .build();
-
-        assert!(query.is_err(), "Query missing one or more fields");
-    }
-
-    #[test]
-    fn test_write_builder_full_query() {
-        let query = Timestamp::Hours(11)
-            .into_query("weather".to_string())
-            .add_field("temperature", 82)
-            .add_tag("location", "us-midwest")
-            .add_tag("season", "summer")
-            .build();
-
-        assert!(query.is_ok(), "Query was empty");
-        assert_eq!(
-            query.unwrap(),
-            r#"weather,location=us-midwest,season=summer temperature=82i 11"#
-        );
-    }
-
-    #[test]
-    fn test_correct_query_type() {
-        use crate::query::QueryType;
-
-        let query = Timestamp::Hours(11)
-            .into_query("weather".to_string())
-            .add_field("temperature", 82)
-            .add_tag("location", "us-midwest")
-            .add_tag("season", "summer");
-
-        assert_eq!(query.get_type(), QueryType::WriteQuery("h".to_owned()));
-    }
-
-    #[test]
-    fn test_escaping() {
-        let query = Timestamp::Hours(11)
-            .into_query("wea, ther=")
-            .add_field("temperature", 82)
-            .add_field("\"temp=era,t ure\"", r#"too"\\hot"#)
-            .add_field("float", 82.0)
-            .add_tag("location", "us-midwest")
-            .add_tag("loc, =\"ation", r#"us, "mid=west"#)
-            .build();
-
-        assert!(query.is_ok(), "Query was empty");
-        let query_res = query.unwrap().get();
-        assert_eq!(
-            query_res,
-            r#"wea\,\ ther=,location=us-midwest,loc\,\ \="ation=us\,\ \"mid\=west temperature=82i,"temp\=era\,t\ ure"="too\"\\\\hot",float=82 11"#
-        );
-    }
-
-    #[test]
-    fn test_batch() {
-        let q0 = Timestamp::Hours(11)
-            .into_query("weather")
-            .add_field("temperature", 82)
-            .add_tag("location", "us-midwest");
-
-        let q1 = Timestamp::Hours(12)
-            .into_query("weather")
-            .add_field("temperature", 65)
-            .add_tag("location", "us-midwest");
-
-        let query = vec![q0, q1].build();
-
-        assert_eq!(
-            query.unwrap().get(),
-            r#"weather,location=us-midwest temperature=82i 11
-weather,location=us-midwest temperature=65i 12"#
-        );
-    }
-}
diff --git a/influxdb/tests/derive_integration_tests.rs b/influxdb/tests/derive_integration_tests.rs
deleted file mode 100644
index 1601ce7..0000000
--- a/influxdb/tests/derive_integration_tests.rs
+++ /dev/null
@@ -1,122 +0,0 @@
-#[path = "./utilities.rs"]
-mod utilities;
-
-#[cfg(feature = "derive")]
-use influxdb::InfluxDbWriteable;
-
-use chrono::{DateTime, Utc};
-use influxdb::{Query, ReadQuery, Timestamp};
-
-#[cfg(feature = "serde")]
-use serde_derive::Deserialize;
-
-use utilities::{assert_result_ok, create_client, create_db, delete_db, run_test};
-
-#[derive(Debug, PartialEq)]
-#[cfg_attr(feature = "derive", derive(InfluxDbWriteable))]
-struct WeatherReading {
-    time: DateTime<Utc>,
-    #[influxdb(ignore)]
-    humidity: i32,
-    pressure: i32,
-    #[influxdb(tag)]
-    wind_strength: Option<u64>,
-}
-
-#[derive(Debug)]
-#[cfg_attr(feature = "serde", derive(Deserialize))]
-struct WeatherReadingWithoutIgnored {
-    time: DateTime<Utc>,
-    pressure: i32,
-    wind_strength: Option<u64>,
-}
-
-#[test]
-fn test_build_query() {
-    let weather_reading = WeatherReading {
-        time: Timestamp::Hours(1).into(),
-        humidity: 30,
-        pressure: 100,
-        wind_strength: Some(5),
-    };
-    let query = weather_reading.into_query("weather_reading");
-    let query = query.build().unwrap();
-    assert_eq!(
-        query.get(),
-        "weather_reading,wind_strength=5 pressure=100i 3600000000000"
-    );
-}
-
-#[cfg(feature = "derive")]
-/// INTEGRATION TEST
-///
-/// This integration tests that writing data and retrieving the data again is working
-#[async_std::test]
-#[cfg(not(tarpaulin_include))]
-async fn test_derive_simple_write() {
-    const TEST_NAME: &str = "test_derive_simple_write";
-
-    run_test(
-        || async move {
-            create_db(TEST_NAME).await.expect("could not setup db");
-            let client = create_client(TEST_NAME);
-            let weather_reading = WeatherReading {
-                time: Timestamp::Nanoseconds(0).into(),
-                humidity: 30,
-                wind_strength: Some(5),
-                pressure: 100,
-            };
-            let query = weather_reading.into_query("weather_reading");
-            let result = client.query(&query).await;
-            assert!(result.is_ok(), "unable to insert into db");
-        },
-        || async move {
-            delete_db(TEST_NAME).await.expect("could not clean up db");
-        },
-    )
-    .await;
-}
-
-/// INTEGRATION TEST
-///
-/// This integration tests that writing data and retrieving the data again is working
-#[cfg(feature = "derive")]
-#[cfg(feature = "serde")]
-#[async_std::test]
-#[cfg(not(tarpaulin_include))]
-async fn test_write_and_read_option() {
-    const TEST_NAME: &str = "test_write_and_read_option";
-
-    run_test(
-        || async move {
-            create_db(TEST_NAME).await.expect("could not setup db");
-            let client = create_client(TEST_NAME);
-            let weather_reading = WeatherReading {
-                time: Timestamp::Hours(11).into(),
-                humidity: 30,
-                wind_strength: None,
-                pressure: 100,
-            };
-            let write_result = client
-                .query(&weather_reading.into_query("weather_reading".to_string()))
-                .await;
-            assert_result_ok(&write_result);
-
-            let query = ReadQuery::new("SELECT time, pressure, wind_strength FROM weather_reading");
-            let result = client.json_query(query).await.and_then(|mut db_result| {
-                println!("{:?}", db_result);
-                db_result.deserialize_next::<WeatherReadingWithoutIgnored>()
-            });
-            assert_result_ok(&result);
-            let result = result.unwrap();
-            let value = &result.series[0].values[0];
-            assert_eq!(value.time, Timestamp::Hours(11).into());
-            assert_eq!(value.pressure, 100);
-            assert_eq!(value.wind_strength, None);
-        },
-        || async move {
-            delete_db(TEST_NAME).await.expect("could not clean up db");
-        },
-    )
-    .await;
-}
diff --git a/influxdb/tests/integration_tests.rs b/influxdb/tests/integration_tests.rs
deleted file mode 100644
index 01b9fdf..0000000
--- a/influxdb/tests/integration_tests.rs
+++ /dev/null
@@ -1,676 +0,0 @@
-extern crate influxdb;
-
-#[path = "./utilities.rs"]
-mod utilities;
-
-use serde_derive::Deserialize;
-use utilities::{
-    assert_result_err, assert_result_ok, create_client, create_db, delete_db, run_test,
-};
-
-use influxdb::InfluxDbWriteable;
-use influxdb::{Client, Error, ReadQuery, Timestamp};
-
-/// INTEGRATION TEST
-///
-/// This test case tests whether the InfluxDB server can be connected to and gathers info about it - tested with async_std
-#[async_std::test]
-#[cfg(not(tarpaulin_include))]
-async fn test_ping_influx_db_async_std() {
-    let client = create_client("notusedhere");
-    let result = client.ping().await;
-    assert_result_ok(&result);
-
-    let (build, version) = result.unwrap();
-    assert!(!build.is_empty(), "Build should not be empty");
-    assert!(!version.is_empty(), "Build should not be empty");
-
-    println!("build: {} version: {}", build, version);
-}
-
-/// INTEGRATION TEST
-///
-/// This test case tests whether the InfluxDB server can be connected to and gathers info about it - tested with tokio 1.0
-#[tokio::test]
-#[cfg(not(any(tarpaulin_include, feature = "hyper-client")))]
-async fn test_ping_influx_db_tokio() {
-    let client = create_client("notusedhere");
-    let result = client.ping().await;
-    assert_result_ok(&result);
-
-    let (build, version) = result.unwrap();
-    assert!(!build.is_empty(), "Build should not be empty");
-    assert!(!version.is_empty(), "Build should not be empty");
-
-    println!("build: {} version: {}", build, version);
-}
-
-/// INTEGRATION TEST
-///
-/// This test case tests connection error
-#[async_std::test]
-#[cfg(not(tarpaulin_include))]
-async fn test_connection_error() {
-    let test_name = "test_connection_error";
-    let client =
-        Client::new("http://127.0.0.1:10086", test_name).with_auth("nopriv_user", "password");
-    let read_query = ReadQuery::new("SELECT * FROM weather");
-    let read_result = client.query(read_query).await;
-    assert_result_err(&read_result);
-    match read_result {
-        Err(Error::ConnectionError { .. }) => {}
-        _ => panic!(
-            "Should cause a ConnectionError: {}",
-            read_result.unwrap_err()
-        ),
-    }
-}
-
-/// INTEGRATION TEST
-///
-/// This test case tests the Authentication
-#[async_std::test]
-#[cfg(not(tarpaulin_include))]
-async fn test_authed_write_and_read() {
-    const TEST_NAME: &str = "test_authed_write_and_read";
-
-    run_test(
-        || async move {
-            let client =
-                Client::new("http://127.0.0.1:9086", TEST_NAME).with_auth("admin", "password");
-            let query = format!("CREATE DATABASE {}", TEST_NAME);
-            client
-                .query(ReadQuery::new(query))
-                .await
-                .expect("could not setup db");
-
-            let client =
-                Client::new("http://127.0.0.1:9086", TEST_NAME).with_auth("admin", "password");
-            let write_query = Timestamp::Hours(11)
-                .into_query("weather")
-                .add_field("temperature", 82);
-            let write_result = client.query(write_query).await;
-            assert_result_ok(&write_result);
-
-            let read_query = ReadQuery::new("SELECT * FROM weather");
-            let read_result = client.query(read_query).await;
-            assert_result_ok(&read_result);
-            assert!(
-                !read_result.unwrap().contains("error"),
-                "Data contained a database error"
-            );
-        },
-        || async move {
-            let client =
-                Client::new("http://127.0.0.1:9086", TEST_NAME).with_auth("admin", "password");
-            let query = format!("DROP DATABASE {}", TEST_NAME);
-
-            client
-                .query(ReadQuery::new(query))
-                .await
-                .expect("could not clean up db");
-        },
-    )
-    .await;
-}
-
-/// INTEGRATION TEST
-///
-/// This test case tests the Authentication
-#[async_std::test]
-#[cfg(not(tarpaulin_include))]
-async fn test_wrong_authed_write_and_read() {
-    use http::StatusCode;
-
-    const TEST_NAME: &str = "test_wrong_authed_write_and_read";
-
-    run_test(
-        || async move {
-            let client =
-                Client::new("http://127.0.0.1:9086", TEST_NAME).with_auth("admin", "password");
-            let query = format!("CREATE DATABASE {}", TEST_NAME);
-            client
-                .query(ReadQuery::new(query))
-                .await
-                .expect("could not setup db");
-
-            let client =
-                Client::new("http://127.0.0.1:9086", TEST_NAME).with_auth("wrong_user", "password");
-            let write_query = Timestamp::Hours(11)
-                .into_query("weather")
-                .add_field("temperature", 82);
-            let write_result = client.query(write_query).await;
-            assert_result_err(&write_result);
-            match write_result {
-                Err(Error::ApiError(code)) if code == StatusCode::UNAUTHORIZED.as_u16() => {}
-                _ => panic!(
-                    "Should be an ApiError(UNAUTHORIZED): {}",
-                    write_result.unwrap_err()
-                ),
-            }
-
-            let read_query = ReadQuery::new("SELECT * FROM weather");
-            let read_result = client.query(read_query).await;
-            assert_result_err(&read_result);
-            match read_result {
-                Err(Error::ApiError(code)) if code == StatusCode::UNAUTHORIZED.as_u16() => {}
-                _ => panic!(
-                    "Should be an ApiError(UNAUTHORIZED): {}",
-                    read_result.unwrap_err()
-                ),
-            }
-
-            let client = Client::new("http://127.0.0.1:9086", TEST_NAME)
-                .with_auth("nopriv_user", "password");
-            let read_query = ReadQuery::new("SELECT * FROM weather");
-            let read_result = client.query(read_query).await;
-            assert_result_err(&read_result);
-            match read_result {
-                Err(Error::ApiError(code)) if code == StatusCode::FORBIDDEN.as_u16() => {}
-                _ => panic!(
-                    "Should be an ApiError(UNAUTHENTICATED): {}",
-                    read_result.unwrap_err()
-                ),
-            }
-        },
-        || async move {
-            let client =
-                Client::new("http://127.0.0.1:9086", TEST_NAME).with_auth("admin", "password");
-            let query = format!("DROP DATABASE {}", TEST_NAME);
-            client
-                .query(ReadQuery::new(query))
-                .await
-                .expect("could not clean up db");
-        },
-    )
-    .await;
-}
-
-/// INTEGRATION TEST
-///
-/// This test case tests the Authentication
-#[async_std::test]
-#[cfg(not(tarpaulin_include))]
-async fn test_non_authed_write_and_read() {
-    use http::StatusCode;
-
-    const TEST_NAME: &str = "test_non_authed_write_and_read";
-
-    run_test(
-        || async move {
-            let client =
-                Client::new("http://127.0.0.1:9086", TEST_NAME).with_auth("admin", "password");
-            let query = format!("CREATE DATABASE {}", TEST_NAME);
-            client
-                .query(ReadQuery::new(query))
-                .await
-                .expect("could not setup db");
-            let non_authed_client = Client::new("http://127.0.0.1:9086", TEST_NAME);
-            let write_query = Timestamp::Hours(11)
-                .into_query("weather")
-                .add_field("temperature", 82);
-            let write_result = non_authed_client.query(write_query).await;
-            assert_result_err(&write_result);
-            match write_result {
-                Err(Error::ApiError(code)) if code == StatusCode::UNAUTHORIZED.as_u16() => {}
-                _ => panic!(
-                    "Should be an ApiError(UNAUTHORIZED): {}",
-                    write_result.unwrap_err()
-                ),
-            }
-
-            let read_query = ReadQuery::new("SELECT * FROM weather");
-            let read_result = non_authed_client.query(read_query).await;
-
-            assert_result_err(&read_result);
-            match read_result {
-                Err(Error::ApiError(code)) if code == StatusCode::UNAUTHORIZED.as_u16() => {}
-                _ => panic!(
-                    "Should be an ApiError(UNAUTHORIZED): {}",
-                    read_result.unwrap_err()
-                ),
-            }
-        },
-        || async move {
-            let client =
-                Client::new("http://127.0.0.1:9086", TEST_NAME).with_auth("admin", "password");
-            let query = format!("DROP DATABASE {}", TEST_NAME);
-            client
-                .query(ReadQuery::new(query))
-                .await
-                .expect("could not clean up db");
-        },
-    )
-    .await;
-}
-
-/// INTEGRATION TEST
-///
-/// This integration tests that writing data and retrieving the data again is working
-#[async_std::test]
-#[cfg(not(tarpaulin_include))]
-async fn test_write_and_read_field() {
-    const TEST_NAME: &str = "test_write_field";
-
-    run_test(
-        || async move {
-            create_db(TEST_NAME).await.expect("could not setup db");
-            let client = create_client(TEST_NAME);
-            let write_query = Timestamp::Hours(11)
-                .into_query("weather")
-                .add_field("temperature", 82);
-            let write_result = client.query(write_query).await;
-            assert_result_ok(&write_result);
-
-            let read_query = ReadQuery::new("SELECT * FROM weather");
-            let read_result = client.query(read_query).await;
-            assert_result_ok(&read_result);
-            assert!(
-                !read_result.unwrap().contains("error"),
-                "Data contained a database error"
-            );
-        },
-        || async move {
-            delete_db(TEST_NAME).await.expect("could not clean up db");
-        },
-    )
-    .await;
-}
-
-/// INTEGRATION TEST
-///
-/// This test case tests the authentication on json reads
-#[async_std::test]
-#[cfg(feature = "serde")]
-#[cfg(not(tarpaulin_include))]
-async fn test_json_non_authed_read() {
-    use http::StatusCode;
-
-    const TEST_NAME: &str = "test_json_non_authed_read";
-
-    run_test(
-        || async move {
-            let client =
-                Client::new("http://127.0.0.1:9086", TEST_NAME).with_auth("admin", "password");
-            let query = format!("CREATE DATABASE {}", TEST_NAME);
-            client
-                .query(ReadQuery::new(query))
-                .await
-                .expect("could not setup db");
-            let non_authed_client = Client::new("http://127.0.0.1:9086", TEST_NAME);
-
-            let read_query = ReadQuery::new("SELECT * FROM weather");
-            let read_result = non_authed_client.json_query(read_query).await;
-            assert_result_err(&read_result);
-            match read_result {
-                Err(Error::ApiError(code)) if code == StatusCode::UNAUTHORIZED.as_u16() => {}
-                _ => panic!(
-                    "Should be an ApiError(UNAUTHORIZED): {}",
-                    read_result.unwrap_err()
-                ),
-            }
-        },
-        || async move {
-            let client =
-                Client::new("http://127.0.0.1:9086", TEST_NAME).with_auth("admin", "password");
-            let query = format!("DROP DATABASE {}", TEST_NAME);
-
-            client
-                .query(ReadQuery::new(query))
-                .await
-                .expect("could not clean up db");
-        },
-    )
-    .await
-}
-
-/// INTEGRATION TEST
-///
-/// This test case tests the authentication on json reads
-#[async_std::test]
-#[cfg(feature = "serde")]
-#[cfg(not(tarpaulin_include))]
-async fn test_json_authed_read() {
-    const TEST_NAME: &str = "test_json_authed_read";
-
-    run_test(
-        || async move {
-            let client =
-                Client::new("http://127.0.0.1:9086", TEST_NAME).with_auth("admin", "password");
-            let query = format!("CREATE DATABASE {}", TEST_NAME);
-            client
-                .query(ReadQuery::new(query))
-                .await
-                .expect("could not setup db");
-
-            let read_query = ReadQuery::new("SELECT * FROM weather");
-            let read_result = client.json_query(read_query).await;
-            assert_result_ok(&read_result);
-        },
-        || async move {
-            let client =
-                Client::new("http://127.0.0.1:9086", TEST_NAME).with_auth("admin", "password");
-            let query = format!("DROP DATABASE {}", TEST_NAME);
-
-            client
-                .query(ReadQuery::new(query))
-                .await
-                .expect("could not clean up db");
-        },
-    )
-    .await
-}
-
-/// INTEGRATION TEST
-///
-/// This integration tests that writing data and retrieving the data again is working
-#[async_std::test]
-#[cfg(feature = "serde")]
-#[cfg(not(tarpaulin_include))]
-async fn test_write_and_read_option() {
-    const TEST_NAME: &str = "test_write_and_read_option";
-
-    run_test(
-        || {
-            async move {
-                create_db(TEST_NAME).await.expect("could not setup db");
-
-                let client = create_client(TEST_NAME);
-                // Todo: Convert this to derive based insert for easier comparison of structs
-                let write_query = Timestamp::Hours(11)
-                    .into_query("weather")
-                    .add_field("temperature", 82)
-                    .add_field("wind_strength", <Option<u64>>::None);
-                let write_result = client.query(write_query).await;
-                assert_result_ok(&write_result);
-
-                #[derive(Deserialize, Debug, PartialEq)]
-                struct Weather {
-                    time: String,
-                    // different order to verify field names
-                    // are being used instead of just order
-                    wind_strength: Option<u64>,
-                    temperature: i32,
-                }
-
-                let query = ReadQuery::new("SELECT time, temperature, wind_strength FROM weather");
-                let result = client
-                    .json_query(query)
-                    .await
-                    .and_then(|mut db_result| db_result.deserialize_next::<Weather>());
-                assert_result_ok(&result);
-
-                assert_eq!(
-                    result.unwrap().series[0].values[0],
-                    Weather {
-                        time: "1970-01-01T11:00:00Z".to_string(),
-                        temperature: 82,
-                        wind_strength: None,
-                    }
-                );
-            }
-        },
-        || async move {
-            delete_db("test_write_and_read_option")
-                .await
-                .expect("could not clean up db");
-        },
-    )
-    .await;
-}
-
-/// INTEGRATION TEST
-///
-/// This test case tests whether JSON can be decoded from a InfluxDB response and whether that JSON
-/// is equal to the data which was written to the database
-#[async_std::test]
-#[cfg(feature = "serde")]
-#[cfg(not(tarpaulin_include))]
-async fn test_json_query() {
-    const TEST_NAME: &str = "test_json_query";
-
-    run_test(
-        || async move {
-            create_db(TEST_NAME).await.expect("could not setup db");
-
-            let client = create_client(TEST_NAME);
-
-            let write_query = Timestamp::Hours(11)
-                .into_query("weather")
-                .add_field("temperature", 82);
-            let write_result = client.query(write_query).await;
-            assert_result_ok(&write_result);
-
-            #[derive(Deserialize, Debug, PartialEq)]
-            struct Weather {
-                time: String,
-                temperature: i32,
-            }
-
-            let query = ReadQuery::new("SELECT * FROM weather");
-            let result = client
-                .json_query(query)
-                .await
-                .and_then(|mut db_result| db_result.deserialize_next::<Weather>());
-            assert_result_ok(&result);
-
-            assert_eq!(
-                result.unwrap().series[0].values[0],
-                Weather {
-                    time: "1970-01-01T11:00:00Z".to_string(),
-                    temperature: 82
-                }
-            );
-        },
-        || async move {
-            delete_db(TEST_NAME).await.expect("could not clean up db");
-        },
-    )
-    .await;
-}
-
-/// INTEGRATION TEST
-///
-/// This test case tests whether the response to a GROUP BY can be parsed by
-/// deserialize_next_tagged into a tags struct
-#[async_std::test]
-#[cfg(feature = "serde")]
-#[cfg(not(tarpaulin_include))]
-async fn test_json_query_tagged() {
-    const TEST_NAME: &str = "test_json_query_tagged";
-
-    run_test(
-        || async move {
-            create_db(TEST_NAME).await.expect("could not setup db");
-
-            let client = create_client(TEST_NAME);
-
-            let write_query = Timestamp::Hours(11)
-                .into_query("weather")
-                .add_tag("location", "London")
-                .add_field("temperature", 82);
-            let write_result = client.query(write_query).await;
-            assert_result_ok(&write_result);
-
-            #[derive(Deserialize, Debug, PartialEq)]
-            struct WeatherMeta {
-                location: String,
-            }
-
-            #[derive(Deserialize, Debug, PartialEq)]
-            struct Weather {
-                time: String,
-                temperature: i32,
-            }
-
-            let query = ReadQuery::new("SELECT * FROM weather GROUP BY location");
-            let result = client.json_query(query).await.and_then(|mut db_result| {
-                db_result.deserialize_next_tagged::<WeatherMeta, Weather>()
-            });
-            assert_result_ok(&result);
-            let result = result.unwrap();
-
-            assert_eq!(
-                result.series[0].tags,
-                WeatherMeta {
-                    location: "London".to_string(),
-                }
-            );
-            assert_eq!(
-                result.series[0].values[0],
-                Weather {
-                    time: "1970-01-01T11:00:00Z".to_string(),
-                    temperature: 82
-                }
-            );
-        },
-        || async move {
-            delete_db(TEST_NAME).await.expect("could not clean up db");
-        },
-    )
-    .await;
-}
-
-/// INTEGRATION TEST
-///
-/// This test case tests whether JSON can be decoded from a InfluxDB response and whether that JSON
-/// is equal to the data which was written to the database
-/// (tested with tokio)
-#[tokio::test]
-#[cfg(all(
-    feature = "serde",
-    not(any(tarpaulin_include, feature = "hyper-client"))
-))]
-async fn test_json_query_vec() {
-    const TEST_NAME: &str = "test_json_query_vec";
-
-    run_test(
-        || async move {
-            create_db(TEST_NAME).await.expect("could not setup db");
-
-            let client = create_client(TEST_NAME);
-            let write_query1 = Timestamp::Hours(11)
-                .into_query("temperature_vec")
-                .add_field("temperature", 16);
-            let write_query2 = Timestamp::Hours(12)
-                .into_query("temperature_vec")
-                .add_field("temperature", 17);
-            let write_query3 = Timestamp::Hours(13)
-                .into_query("temperature_vec")
-                .add_field("temperature", 18);
-
-            let _write_result = client.query(write_query1).await;
-            let _write_result2 = client.query(write_query2).await;
-            let _write_result2 = client.query(write_query3).await;
-
-            #[derive(Deserialize, Debug, PartialEq)]
-            struct Weather {
-                time: String,
-                temperature: i32,
-            }
-
-            let query = ReadQuery::new("SELECT * FROM temperature_vec");
-            let result = client
-                .json_query(query)
-                .await
-                .and_then(|mut db_result| db_result.deserialize_next::<Weather>());
-            assert_result_ok(&result);
-            assert_eq!(result.unwrap().series[0].values.len(), 3);
-        },
-        || async move {
-            delete_db(TEST_NAME).await.expect("could not clean up db");
-        },
-    )
-    .await;
-}
-
-/// INTEGRATION TEST
-///
-/// This integration test tests whether using the wrong query method fails building the query
-#[async_std::test]
-#[cfg(feature = "serde")]
-#[cfg(not(tarpaulin_include))]
-async fn test_serde_multi_query() {
-    const TEST_NAME: &str = "test_serde_multi_query";
-
-    run_test(
-        || async move {
-            create_db(TEST_NAME).await.expect("could not setup db");
-
-            #[derive(Deserialize, Debug, PartialEq)]
-            struct Temperature {
-                time: String,
-                temperature: i32,
-            }
-
-            #[derive(Deserialize, Debug, PartialEq)]
-            struct Humidity {
-                time: String,
-                humidity: i32,
-            }
-
-            let client = create_client(TEST_NAME);
-            let write_query = Timestamp::Hours(11)
-                .into_query("temperature")
-                .add_field("temperature", 16);
-            let write_query2 = Timestamp::Hours(11)
-                .into_query("humidity")
-                .add_field("humidity", 69);
-
-            let write_result = client.query(write_query).await;
-            let write_result2 = client.query(write_query2).await;
-            assert_result_ok(&write_result);
-            assert_result_ok(&write_result2);
-
-            let result = client
-                .json_query(
-                    ReadQuery::new("SELECT * FROM temperature").add_query("SELECT * FROM humidity"),
-                )
-                .await
-                .and_then(|mut db_result| {
-                    let temp = db_result.deserialize_next::<Temperature>()?;
-                    let humidity = db_result.deserialize_next::<Humidity>()?;
-
-                    Ok((temp, humidity))
-                });
-            assert_result_ok(&result);
-
-            let (temp, humidity) = result.unwrap();
-            assert_eq!(
-                temp.series[0].values[0],
-                Temperature {
-                    time: "1970-01-01T11:00:00Z".to_string(),
-                    temperature: 16
-                },
-            );
-            assert_eq!(
-                humidity.series[0].values[0],
-                Humidity {
-                    time: "1970-01-01T11:00:00Z".to_string(),
-                    humidity: 69
-                }
-            );
-        },
-        || async move {
-            delete_db(TEST_NAME).await.expect("could not clean up db");
-        },
-    )
-    .await;
-}
-
-/// INTEGRATION TEST
-///
-/// This integration test tests whether using the wrong query method fails building the query
-#[async_std::test]
-#[cfg(feature = "serde")]
-#[cfg(not(tarpaulin_include))]
-async fn test_wrong_query_errors() {
-    let client = create_client("test_name");
-    let result = client
-        .json_query(ReadQuery::new("CREATE DATABASE this_should_fail"))
-        .await;
-    assert!(
-        result.is_err(),
-        "Should only build SELECT and SHOW queries."
-    );
-}
diff --git a/influxdb/tests/integration_tests_v2.rs b/influxdb/tests/integration_tests_v2.rs
deleted file mode 100644
index 8c47e2a..0000000
--- a/influxdb/tests/integration_tests_v2.rs
+++ /dev/null
@@ -1,123 +0,0 @@
-extern crate influxdb;
-
-#[path = "./utilities.rs"]
-mod utilities;
-use utilities::{assert_result_err, assert_result_ok, run_test};
-
-use influxdb::InfluxDbWriteable;
-use influxdb::{Client, Error, ReadQuery, Timestamp};
-
-/// INTEGRATION TEST
-///
-
-/// This test case tests the Authentication
-#[async_std::test]
-#[cfg(not(tarpaulin))]
-async fn test_authed_write_and_read() {
-    run_test(
-        || async move {
-            let client = Client::new("http://127.0.0.1:2086", "mydb").with_token("admintoken");
-            let write_query = Timestamp::Hours(11)
-                .into_query("weather")
-                .add_field("temperature", 82);
-            let write_result = client.query(&write_query).await;
-            assert_result_ok(&write_result);
-
-            let read_query = ReadQuery::new("SELECT * FROM weather");
-            let read_result = client.query(read_query).await;
-            assert_result_ok(&read_result);
-            assert!(
-                !read_result.unwrap().contains("error"),
-                "Data contained a database error"
-            );
-        },
-        || async move {
-            let client = Client::new("http://127.0.0.1:2086", "mydb").with_token("admintoken");
-            let read_query = ReadQuery::new("DROP MEASUREMENT \"weather\"");
-            let read_result = client.query(read_query).await;
-            assert_result_ok(&read_result);
-            assert!(!read_result.unwrap().contains("error"), "Teardown failed");
-        },
-    )
-    .await;
-}
-
-/// INTEGRATION TEST
-///
-/// This test case tests the Authentication
-#[async_std::test]
-#[cfg(not(tarpaulin))]
-async fn test_wrong_authed_write_and_read() {
-    use http::StatusCode;
-
-    run_test(
-        || async move {
-            let client = Client::new("http://127.0.0.1:2086", "mydb").with_token("falsetoken");
-            let write_query = Timestamp::Hours(11)
-                .into_query("weather")
-                .add_field("temperature", 82);
-            let write_result = client.query(&write_query).await;
-            assert_result_err(&write_result);
-            match write_result {
-                Err(Error::ApiError(code)) if code == StatusCode::UNAUTHORIZED.as_u16() => {}
-                _ => panic!(
-                    "Should be an ApiError(UNAUTHORIZED): {}",
-                    write_result.unwrap_err()
-                ),
-            }
-
-            let read_query = ReadQuery::new("SELECT * FROM weather");
-            let read_result = client.query(&read_query).await;
-            assert_result_err(&read_result);
-            match read_result {
-                Err(Error::ApiError(code)) if code == StatusCode::UNAUTHORIZED.as_u16() => {}
-                _ => panic!(
-                    "Should be an ApiError(UNAUTHORIZED): {}",
-                    read_result.unwrap_err()
-                ),
-            }
-        },
-        || async move {},
-    )
-    .await;
-}
-
-/// INTEGRATION TEST
-///
-/// This test case tests the Authentication
-#[async_std::test]
-#[cfg(not(tarpaulin))]
-async fn test_non_authed_write_and_read() {
-    use http::StatusCode;
-
-    run_test(
-        || async move {
-            let non_authed_client = Client::new("http://127.0.0.1:2086", "mydb");
-            let write_query = Timestamp::Hours(11)
-                .into_query("weather")
-                .add_field("temperature", 82);
-            let write_result = non_authed_client.query(&write_query).await;
-            assert_result_err(&write_result);
-            match write_result {
-                Err(Error::ApiError(code)) if code == StatusCode::UNAUTHORIZED.as_u16() => {}
-                _ => panic!(
-                    "Should be an ApiError(UNAUTHORIZED): {}",
-                    write_result.unwrap_err()
-                ),
-            }
-
-            let read_query = ReadQuery::new("SELECT * FROM weather");
-            let read_result = non_authed_client.query(&read_query).await;
-            assert_result_err(&read_result);
-            match read_result {
-                Err(Error::ApiError(code)) if code == StatusCode::UNAUTHORIZED.as_u16() => {}
-                _ => panic!(
-                    "Should be an ApiError(UNAUTHORIZED): {}",
-                    read_result.unwrap_err()
-                ),
-            }
-        },
-        || async move {},
-    )
-    .await;
-}
diff --git a/influxdb/tests/utilities.rs b/influxdb/tests/utilities.rs
deleted file mode 100644
index 8b3d5a7..0000000
--- a/influxdb/tests/utilities.rs
+++ /dev/null
@@ -1,62 +0,0 @@
-use futures_util::FutureExt;
-use influxdb::{Client, Error, ReadQuery};
-use std::future::Future;
-use std::panic::{AssertUnwindSafe, UnwindSafe};
-
-#[allow(dead_code)]
-#[cfg(not(tarpaulin_include))]
-pub fn assert_result_err<A: std::fmt::Debug, B: std::fmt::Debug>(result: &Result<A, B>) {
-    result.as_ref().expect_err("assert_result_err failed");
-}
-
-#[cfg(not(tarpaulin_include))]
-pub fn assert_result_ok<A: std::fmt::Debug, B: std::fmt::Debug>(result: &Result<A, B>) {
-    result.as_ref().expect("assert_result_ok failed");
-}
-
-#[allow(dead_code)]
-#[cfg(not(tarpaulin_include))]
-pub fn create_client<T>(db_name: T) -> Client
-where
-    T: Into<String>,
-{
-    Client::new("http://127.0.0.1:8086", db_name)
-}
-
-#[allow(dead_code)]
-#[cfg(not(tarpaulin_include))]
-pub async fn create_db<T>(name: T) -> Result<String, Error>
-where
-    T: Into<String>,
-{
-    let test_name = name.into();
-    let query = format!("CREATE DATABASE {}", test_name);
-    create_client(test_name).query(ReadQuery::new(query)).await
-}
-
-#[allow(dead_code)]
-#[cfg(not(tarpaulin_include))]
-pub async fn delete_db<T>(name: T) -> Result<String, Error>
-where
-    T: Into<String>,
-{
-    let test_name = name.into();
-    let query = format!("DROP DATABASE {}", test_name);
-    create_client(test_name).query(ReadQuery::new(query)).await
-}
-
-#[cfg(not(tarpaulin_include))]
-pub async fn run_test<F, T, Fut1, Fut2>(test_fn: F, teardown: T)
-where
-    F: FnOnce() -> Fut1 + UnwindSafe,
-    T: FnOnce() -> Fut2,
-    Fut1: Future,
-    Fut2: Future,
-{
-    let test_result = AssertUnwindSafe(test_fn()).catch_unwind().await;
-    AssertUnwindSafe(teardown())
-        .catch_unwind()
-        .await
-        .expect("failed teardown");
-    test_result.expect("failed test");
-}
diff --git a/influxdb_derive/Cargo.toml b/influxdb_derive/Cargo.toml
deleted file mode 100644
index 6e4b377..0000000
--- a/influxdb_derive/Cargo.toml
+++ /dev/null
@@ -1,22 +0,0 @@
-# -*- eval: (cargo-minor-mode 1) -*-
-
-[package]
-name = "influxdb_derive"
-version = "0.5.1"
-authors = ["Gero Gerke <11deutron11@gmail.com>"]
-edition = "2018"
-description = "Private implementation detail of the influxdb crate"
-keywords = ["influxdb", "database", "influx", "derive"]
-license = "MIT"
-readme = "README.md"
-include = ["src/**/*", "tests/**/*", "Cargo.toml", "LICENSE"]
-repository = "https://github.com/influxdb-rs/influxdb-rust"
-rust-version = "1.70"
-
-[lib]
-proc-macro = true
-
-[dependencies]
-proc-macro2 = "1.0"
-quote = "1.0"
-syn = { version = "2.0", features = ["extra-traits", "full"] }
diff --git a/influxdb_derive/README.md b/influxdb_derive/README.md
deleted file mode 100644
index 4d51211..0000000
--- a/influxdb_derive/README.md
+++ /dev/null
@@ -1,25 +0,0 @@
-<div align="center">
-    <br/>
-    <img
-        alt="rust-influxdb"
-        src="https://i.imgur.com/4k7l8XJ.png"
-        width=250px />
-    <br/>
-    <br/>
-    <strong>Derive Crate for <a href="https://crates.io/crates/influxdb">influxdb</a></strong>
-</div>
-<br/>
-<p align="center">
-    <a href="https://crates.io/crates/influxdb_derive">
-        <img src="https://img.shields.io/crates/v/influxdb_derive.svg"/>
-    </a>
-    <a href="https://github.com/influxdb-rs/influxdb-rust/actions/workflows/rust.yml">
-        <img src="https://github.com/influxdb-rs/influxdb-rust/actions/workflows/rust.yml/badge.svg" alt='Build Status' />
-    </a>
-    <a href="https://docs.rs/influxdb_derive">
-        <img src="https://docs.rs/influxdb_derive/badge.svg" alt='Documentation Status' />
-    </a>
-    <a href="https://www.rust-lang.org/en-US/">
-        <img src="https://img.shields.io/badge/Made%20with-Rust-orange.svg" alt='Build with Rust' />
-    </a>
-</p>
diff --git a/influxdb_derive/src/lib.rs b/influxdb_derive/src/lib.rs
deleted file mode 100644
index 5025b33..0000000
--- a/influxdb_derive/src/lib.rs
+++ /dev/null
@@ -1,12 +0,0 @@
-use proc_macro::TokenStream;
-
-mod writeable;
-use syn::parse_macro_input;
-use writeable::expand_writeable;
-
-#[proc_macro_derive(InfluxDbWriteable, attributes(influxdb))]
-pub fn derive_writeable(input: TokenStream) -> TokenStream {
-    expand_writeable(parse_macro_input!(input))
-        .unwrap_or_else(syn::Error::into_compile_error)
-        .into()
-}
diff --git a/influxdb_derive/src/writeable.rs b/influxdb_derive/src/writeable.rs
deleted file mode 100644
index 870f947..0000000
--- a/influxdb_derive/src/writeable.rs
+++ /dev/null
@@ -1,138 +0,0 @@
-use proc_macro2::TokenStream;
-use quote::{format_ident, quote};
-use std::convert::TryFrom;
-use syn::{
-    parse::{Parse, ParseStream},
-    punctuated::Punctuated,
-    Data, DeriveInput, Field, Fields, Ident, Meta, Token,
-};
-
-#[derive(Debug)]
-struct WriteableField {
-    ident: Ident,
-    is_tag: bool,
-    is_ignore: bool,
-}
-
-mod kw {
-    use syn::custom_keyword;
-
-    custom_keyword!(tag);
-    custom_keyword!(ignore);
-}
-
-enum FieldAttr {
-    Tag(kw::tag),
-    Ignore(kw::ignore),
-}
-
-impl Parse for FieldAttr {
-    fn parse(input: ParseStream<'_>) -> syn::Result<Self> {
-        let lookahead = input.lookahead1();
-        if lookahead.peek(kw::tag) {
-            Ok(Self::Tag(input.parse()?))
-        } else if lookahead.peek(kw::ignore) {
-            Ok(Self::Ignore(input.parse()?))
-        } else {
-            Err(lookahead.error())
-        }
-    }
-}
-
-struct FieldAttrs(Punctuated<FieldAttr, Token![,]>);
-
-impl Parse for FieldAttrs {
-    fn parse(input: ParseStream<'_>) -> syn::Result<Self> {
-        Ok(Self(Punctuated::parse_terminated(input)?))
-    }
-}
-
-impl TryFrom<Field> for WriteableField {
-    type Error = syn::Error;
-
-    fn try_from(field: Field) -> syn::Result<WriteableField> {
-        let ident = field.ident.expect("fields without ident are not supported");
-        let mut is_tag = false;
-        let mut is_ignore = false;
-
-        for attr in field.attrs {
-            match attr.meta {
-                Meta::List(list) if list.path.is_ident("influxdb") => {
-                    for attr in syn::parse2::<FieldAttrs>(list.tokens)?.0 {
-                        match attr {
-                            FieldAttr::Tag(_) => is_tag = true,
-                            FieldAttr::Ignore(_) => is_ignore = true,
-                        }
-                    }
-                }
-                _ => {}
-            }
-        }
-
-        Ok(WriteableField {
-            ident,
-            is_tag,
-            is_ignore,
-        })
-    }
-}
-
-pub fn expand_writeable(input: DeriveInput) -> syn::Result<TokenStream> {
-    let ident = input.ident;
-    let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
-
-    let fields = match input.data {
-        Data::Struct(strukt) => strukt.fields,
-        Data::Enum(inum) => {
-            return Err(syn::Error::new(
-                inum.enum_token.span,
-                "#[derive(InfluxDbWriteable)] can only be used on structs",
-            ))
-        }
-        Data::Union(cdu) => {
-            return Err(syn::Error::new(
-                cdu.union_token.span,
-                "#[derive(InfluxDbWriteable)] can only be used on structs",
-            ))
-        }
-    };
-
-    let time_field = format_ident!("time");
-    let time_field_str = time_field.to_string();
-    #[allow(clippy::cmp_owned)] // that's not how idents work clippy
-    let fields = match fields {
-        Fields::Named(fields) => fields
-            .named
-            .into_iter()
-            .filter_map(|f| {
-                WriteableField::try_from(f)
-                    .map(|wf| {
-                        if !wf.is_ignore && wf.ident.to_string() != time_field_str {
-                            let ident = wf.ident;
-                            Some(match wf.is_tag {
-                                true => quote!(query.add_tag(stringify!(#ident), self.#ident)),
-                                false => quote!(query.add_field(stringify!(#ident), self.#ident)),
-                            })
-                        } else {
-                            None
-                        }
-                    })
-                    .transpose()
-            })
-            .collect::<syn::Result<Vec<_>>>()?,
-        _ => panic!("a struct without named fields is not supported"),
-    };
-
-    Ok(quote! {
-        impl #impl_generics ::influxdb::InfluxDbWriteable for #ident #ty_generics #where_clause {
-            fn into_query<I: Into<String>>(self, name: I) -> ::influxdb::WriteQuery {
-                let timestamp: ::influxdb::Timestamp = self.#time_field.into();
-                let mut query = timestamp.into_query(name);
-                #(
-                    query = #fields;
-                )*
-                query
-            }
-        }
-    })
-}
diff --git a/tarpaulin-report.html b/tarpaulin-report.html
new file mode 100644
index 0000000..5eba8d4
--- /dev/null
+++ b/tarpaulin-report.html
@@ -0,0 +1,671 @@
+<!doctype html>
+<html>
+<head>
+    <meta charset="utf-8">
+    <style>html, body {
+  margin: 0;
+  padding: 0;
+}
+
+.app {
+  margin: 10px;
+  padding: 0;
+}
+
+.files-list {
+  margin: 10px 0 0;
+  width: 100%;
+  border-collapse: collapse;
+}
+.files-list__head {
+  border: 1px solid #999;
+}
+.files-list__head > tr > th {
+  padding: 10px;
+  border: 1px solid #999;
+  text-align: left;
+  font-weight: normal;
+  background: #ddd;
+}
+.files-list__body {
+}
+.files-list__file {
+  cursor: pointer;
+}
+.files-list__file:hover {
+  background: #ccf;
+}
+.files-list__file > td {
+  padding: 10px;
+  border: 1px solid #999;
+}
+.files-list__file > td:first-child::before {
+  content: '\01F4C4';
+  margin-right: 1em;
+}
+.files-list__file_low {
+  background: #fcc;
+}
+.files-list__file_medium {
+  background: #ffc;
+}
+.files-list__file_high {
+  background: #cfc;
+}
+.files-list__file_folder > td:first-child::before {
+  content: '\01F4C1';
+  margin-right: 1em;
+}
+
+.file-header {
+  border: 1px solid #999;
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  position: sticky;
+  top: 0;
+  background: white;
+}
+
+.file-header__back {
+  margin: 10px;
+  cursor: pointer;
+  flex-shrink: 0;
+  flex-grow: 0;
+  text-decoration: underline;
+  color: #338;
+}
+
+.file-header__name {
+  margin: 10px;
+  flex-shrink: 2;
+  flex-grow: 2;
+}
+
+.file-header__stat {
+  margin: 10px;
+  flex-shrink: 0;
+  flex-grow: 0;
+}
+
+.file-content {
+  margin: 10px 0 0;
+  border: 1px solid #999;
+  padding: 10px;
+  counter-reset: line;
+  display: flex;
+  flex-direction: column;
+}
+
+.code-line::before {
+    content: counter(line);
+    margin-right: 10px;
+}
+.code-line {
+  margin: 0;
+  padding: 0.3em;
+  height: 1em;
+  counter-increment: line;
+}
+.code-line_covered {
+  background: #cfc;
+}
+.code-line_uncovered {
+  background: #fcc;
+}
+</style>
+</head>
+<body>
+    <div id="root"></div>
+    <script>
+        var data = {"files":[{"path":["/","home","runner","work","influxdb-rust","influxdb-rust","benches","client.rs"],"content":"use chrono::{DateTime, Utc};\nuse influxdb::Error;\nuse influxdb::InfluxDbWriteable;\nuse influxdb::{Client, ReadQuery};\nuse std::sync::Arc;\nuse std::time::Instant;\nuse tokio::sync::mpsc::unbounded_channel;\nuse tokio::sync::Semaphore;\n\n#[derive(InfluxDbWriteable, Clone)]\nstruct WeatherReading {\n    time: DateTime\u003cUtc\u003e,\n    humidity: i32,\n    #[influxdb(tag)]\n    wind_direction: String,\n}\n\n#[tokio::main]\nasync fn main() {\n    let db_name = \"bench\";\n    let url = \"http://localhost:8086\";\n    let number_of_total_requests = 20000;\n    let concurrent_requests = 1000;\n\n    let client = Client::new(url, db_name);\n    let concurrency_limit = Arc::new(Semaphore::new(concurrent_requests));\n\n    prepare_influxdb(\u0026client, db_name).await;\n    let measurements = generate_measurements(number_of_total_requests);\n    let (tx, mut rx) = unbounded_channel::\u003cResult\u003cString, Error\u003e\u003e();\n\n    let start = Instant::now();\n    for m in measurements {\n        let permit = concurrency_limit.clone().acquire_owned().await;\n        let client_task = client.clone();\n        let tx_task = tx.clone();\n        tokio::spawn(async move {\n            let res = client_task.query(\u0026m.into_query(\"weather\")).await;\n            let _ = tx_task.send(res);\n            drop(permit);\n        });\n    }\n    drop(tx);\n\n    let mut successful_count = 0;\n    let mut error_count = 0;\n    while let Some(res) = rx.recv().await {\n        if res.is_err() {\n            error_count += 1;\n        } else {\n            successful_count += 1;\n        }\n    }\n\n    let end = Instant::now();\n\n    println!(\n        \"Throughput: {:.1} request/s\",\n        1000000.0 * successful_count as f64 / (end - start).as_micros() as f64\n    );\n    println!(\n        \"{} successful requests, {} errors\",\n        successful_count, error_count\n    );\n}\n\nasync fn prepare_influxdb(client: \u0026Client, db_name: \u0026str) {\n    let create_db_stmt = format!(\"CREATE DATABASE {}\", db_name);\n    client\n        .query(\u0026ReadQuery::new(create_db_stmt))\n        .await\n        .expect(\"failed to create database\");\n}\n\nfn generate_measurements(n: u64) -\u003e Vec\u003cWeatherReading\u003e {\n    (0..n)\n        .collect::\u003cVec\u003cu64\u003e\u003e()\n        .iter_mut()\n        .map(|_| WeatherReading {\n            time: Utc::now(),\n            humidity: 30,\n            wind_direction: String::from(\"north\"),\n        })\n        .collect()\n}\n","traces":[],"covered":0,"coverable":0},{"path":["/","home","runner","work","influxdb-rust","influxdb-rust","influxdb","src","client","mod.rs"],"content":"//! Client which can read and write data from InfluxDB.\n//!\n//! # Arguments\n//!\n//!  * `url`: The URL where InfluxDB is running (ex. `http://localhost:8086`).\n//!  * `database`: The Database against which queries and writes will be run.\n//!\n//! # Examples\n//!\n//! ```rust\n//! use influxdb::Client;\n//!\n//! let client = Client::new(\"http://localhost:8086\", \"test\");\n//!\n//! assert_eq!(client.database_name(), \"test\");\n//! ```\n\nuse futures_util::TryFutureExt;\n#[cfg(feature = \"reqwest\")]\nuse reqwest::{Client as HttpClient, RequestBuilder, Response as HttpResponse};\nuse std::collections::{BTreeMap, HashMap};\nuse std::fmt::{self, Debug, Formatter};\nuse std::sync::Arc;\n#[cfg(feature = \"surf\")]\nuse surf::{Client as HttpClient, RequestBuilder, Response as HttpResponse};\n\nuse crate::query::QueryType;\nuse crate::Error;\nuse crate::Query;\n\n#[derive(Clone)]\n/// Internal Representation of a Client\npub struct Client {\n    pub(crate) url: Arc\u003cString\u003e,\n    pub(crate) parameters: Arc\u003cHashMap\u003c\u0026'static str, String\u003e\u003e,\n    pub(crate) token: Option\u003cString\u003e,\n    pub(crate) client: HttpClient,\n}\n\nstruct RedactPassword\u003c'a\u003e(\u0026'a HashMap\u003c\u0026'static str, String\u003e);\n\nimpl\u003c'a\u003e Debug for RedactPassword\u003c'a\u003e {\n    fn fmt(\u0026self, f: \u0026mut Formatter\u003c'_\u003e) -\u003e fmt::Result {\n        let entries = self\n            .0\n            .iter()\n            .map(|(k, v)| match *k {\n                \"p\" =\u003e (*k, \"\u003credacted\u003e\"),\n                _ =\u003e (*k, v.as_str()),\n            })\n            .collect::\u003cBTreeMap\u003c\u0026'static str, \u0026str\u003e\u003e();\n        f.debug_map().entries(entries).finish()\n    }\n}\n\nimpl Debug for Client {\n    fn fmt(\u0026self, f: \u0026mut Formatter\u003c'_\u003e) -\u003e fmt::Result {\n        f.debug_struct(\"Client\")\n            .field(\"url\", \u0026self.url)\n            .field(\"parameters\", \u0026RedactPassword(\u0026self.parameters))\n            .finish_non_exhaustive()\n    }\n}\n\nimpl Client {\n    /// Instantiates a new [`Client`](crate::Client)\n    ///\n    /// # Arguments\n    ///\n    ///  * `url`: The URL where InfluxDB is running (ex. `http://localhost:8086`).\n    ///  * `database`: The Database against which queries and writes will be run.\n    ///\n    /// # Examples\n    ///\n    /// ```rust\n    /// use influxdb::Client;\n    ///\n    /// let _client = Client::new(\"http://localhost:8086\", \"test\");\n    /// ```\n    #[must_use = \"Creating a client is pointless unless you use it\"]\n    pub fn new\u003cS1, S2\u003e(url: S1, database: S2) -\u003e Self\n    where\n        S1: Into\u003cString\u003e,\n        S2: Into\u003cString\u003e,\n    {\n        let mut parameters = HashMap::\u003c\u0026str, String\u003e::new();\n        parameters.insert(\"db\", database.into());\n        Client {\n            url: Arc::new(url.into()),\n            parameters: Arc::new(parameters),\n            client: HttpClient::new(),\n            token: None,\n        }\n    }\n\n    /// Add authentication/authorization information to [`Client`](crate::Client)\n    ///\n    /// # Arguments\n    ///\n    /// * username: The Username for InfluxDB.\n    /// * password: The Password for the user.\n    ///\n    /// # Examples\n    ///\n    /// ```rust\n    /// use influxdb::Client;\n    ///\n    /// let _client = Client::new(\"http://localhost:9086\", \"test\").with_auth(\"admin\", \"password\");\n    /// ```\n    #[must_use = \"Creating a client is pointless unless you use it\"]\n    pub fn with_auth\u003cS1, S2\u003e(mut self, username: S1, password: S2) -\u003e Self\n    where\n        S1: Into\u003cString\u003e,\n        S2: Into\u003cString\u003e,\n    {\n        let mut with_auth = self.parameters.as_ref().clone();\n        with_auth.insert(\"u\", username.into());\n        with_auth.insert(\"p\", password.into());\n        self.parameters = Arc::new(with_auth);\n        self\n    }\n\n    /// Replaces the HTTP Client\n    #[must_use = \"Creating a client is pointless unless you use it\"]\n    pub fn with_http_client(mut self, http_client: HttpClient) -\u003e Self {\n        self.client = http_client;\n        self\n    }\n\n    /// Add authorization token to [`Client`](crate::Client)\n    ///\n    /// This is designed for influxdb 2.0's backward-compatible API which\n    /// requires authorization by default. You can create such token from\n    /// console of influxdb 2.0 .\n    pub fn with_token\u003cS\u003e(mut self, token: S) -\u003e Self\n    where\n        S: Into\u003cString\u003e,\n    {\n        self.token = Some(token.into());\n        self\n    }\n\n    /// Returns the name of the database the client is using\n    pub fn database_name(\u0026self) -\u003e \u0026str {\n        // safe to unwrap: we always set the database name in `Self::new`\n        self.parameters.get(\"db\").unwrap()\n    }\n\n    /// Returns the URL of the InfluxDB installation the client is using\n    pub fn database_url(\u0026self) -\u003e \u0026str {\n        \u0026self.url\n    }\n\n    /// Pings the InfluxDB Server\n    ///\n    /// Returns a tuple of build type and version number\n    pub async fn ping(\u0026self) -\u003e Result\u003c(String, String), Error\u003e {\n        let url = \u0026format!(\"{}/ping\", self.url);\n        let res = self\n            .client\n            .get(url)\n            .send()\n            .await\n            .map_err(|err| Error::ProtocolError {\n                error: format!(\"{}\", err),\n            })?;\n\n        const BUILD_HEADER: \u0026str = \"X-Influxdb-Build\";\n        const VERSION_HEADER: \u0026str = \"X-Influxdb-Version\";\n\n        #[cfg(feature = \"reqwest\")]\n        let (build, version) = {\n            let hdrs = res.headers();\n            (\n                hdrs.get(BUILD_HEADER).and_then(|value| value.to_str().ok()),\n                hdrs.get(VERSION_HEADER)\n                    .and_then(|value| value.to_str().ok()),\n            )\n        };\n\n        #[cfg(feature = \"surf\")]\n        let build = res.header(BUILD_HEADER).map(|value| value.as_str());\n        #[cfg(feature = \"surf\")]\n        let version = res.header(VERSION_HEADER).map(|value| value.as_str());\n\n        Ok((build.unwrap().to_owned(), version.unwrap().to_owned()))\n    }\n\n    /// Sends a [`ReadQuery`](crate::ReadQuery) or [`WriteQuery`](crate::WriteQuery) to the InfluxDB Server.\n    ///\n    /// A version capable of parsing the returned string is available under the [serde_integration](crate::integrations::serde_integration)\n    ///\n    /// # Arguments\n    ///\n    ///  * `q`: Query of type [`ReadQuery`](crate::ReadQuery) or [`WriteQuery`](crate::WriteQuery)\n    ///\n    /// # Examples\n    ///\n    /// ```rust,no_run\n    /// use influxdb::{Client, Query, Timestamp};\n    /// use influxdb::InfluxDbWriteable;\n    /// use std::time::{SystemTime, UNIX_EPOCH};\n    ///\n    /// # #[async_std::main]\n    /// # async fn main() -\u003e Result\u003c(), influxdb::Error\u003e {\n    /// let start = SystemTime::now();\n    /// let since_the_epoch = start\n    ///   .duration_since(UNIX_EPOCH)\n    ///   .expect(\"Time went backwards\")\n    ///   .as_millis();\n    ///\n    /// let client = Client::new(\"http://localhost:8086\", \"test\");\n    /// let query = Timestamp::Milliseconds(since_the_epoch)\n    ///     .into_query(\"weather\")\n    ///     .add_field(\"temperature\", 82);\n    /// let results = client.query(query).await?;\n    ///\n    /// # Ok(())\n    /// # }\n    /// ```\n    /// # Errors\n    ///\n    /// If the function can not finish the query,\n    /// a [`Error`] variant will be returned.\n    ///\n    /// [`Error`]: enum.Error.html\n    pub async fn query\u003cQ\u003e(\u0026self, q: Q) -\u003e Result\u003cString, Error\u003e\n    where\n        Q: Query,\n    {\n        let query = q.build().map_err(|err| Error::InvalidQueryError {\n            error: err.to_string(),\n        })?;\n\n        let mut parameters = self.parameters.as_ref().clone();\n        let request_builder = match q.get_type() {\n            QueryType::ReadQuery =\u003e {\n                let read_query = query.get();\n                let url = \u0026format!(\"{}/query\", \u0026self.url);\n                parameters.insert(\"q\", read_query.clone());\n\n                if read_query.contains(\"SELECT\") || read_query.contains(\"SHOW\") {\n                    self.client.get(url).query(\u0026parameters)\n                } else {\n                    self.client.post(url).query(\u0026parameters)\n                }\n            }\n            QueryType::WriteQuery(precision) =\u003e {\n                let url = \u0026format!(\"{}/write\", \u0026self.url);\n                let mut parameters = self.parameters.as_ref().clone();\n                parameters.insert(\"precision\", precision);\n\n                self.client.post(url).body(query.get()).query(\u0026parameters)\n            }\n        };\n\n        #[cfg(feature = \"surf\")]\n        let request_builder = request_builder.map_err(|err| Error::UrlConstructionError {\n            error: err.to_string(),\n        })?;\n\n        let res = self\n            .auth_if_needed(request_builder)\n            .send()\n            .map_err(|err| Error::ConnectionError {\n                error: err.to_string(),\n            })\n            .await?;\n        check_status(\u0026res)?;\n\n        #[cfg(feature = \"reqwest\")]\n        let body = res.text();\n        #[cfg(feature = \"surf\")]\n        let mut res = res;\n        #[cfg(feature = \"surf\")]\n        let body = res.body_string();\n\n        let s = body.await.map_err(|_| Error::DeserializationError {\n            error: \"response could not be converted to UTF-8\".to_string(),\n        })?;\n\n        // todo: improve error parsing without serde\n        if s.contains(\"\\\"error\\\"\") || s.contains(\"\\\"Error\\\"\") {\n            return Err(Error::DatabaseError {\n                error: format!(\"influxdb error: \\\"{}\\\"\", s),\n            });\n        }\n\n        Ok(s)\n    }\n\n    fn auth_if_needed(\u0026self, rb: RequestBuilder) -\u003e RequestBuilder {\n        if let Some(ref token) = self.token {\n            rb.header(\"Authorization\", format!(\"Token {}\", token))\n        } else {\n            rb\n        }\n    }\n}\n\npub(crate) fn check_status(res: \u0026HttpResponse) -\u003e Result\u003c(), Error\u003e {\n    let status = res.status();\n    if !status.is_success() {\n        return Err(Error::ApiError(status.into()));\n    }\n    Ok(())\n}\n\n#[cfg(test)]\nmod tests {\n    use super::Client;\n    use indoc::indoc;\n\n    #[test]\n    fn test_client_debug_redacted_password() {\n        let client = Client::new(\"https://localhost:8086\", \"db\").with_auth(\"user\", \"pass\");\n        let actual = format!(\"{:#?}\", client);\n        let expected = indoc! { r#\"\n            Client {\n                url: \"https://localhost:8086\",\n                parameters: {\n                    \"db\": \"db\",\n                    \"p\": \"\u003credacted\u003e\",\n                    \"u\": \"user\",\n                },\n                ..\n            }\n        \"# };\n        assert_eq!(actual.trim(), expected.trim());\n    }\n\n    #[test]\n    fn test_fn_database() {\n        let client = Client::new(\"http://localhost:8068\", \"database\");\n        assert_eq!(client.database_name(), \"database\");\n        assert_eq!(client.database_url(), \"http://localhost:8068\");\n    }\n\n    #[test]\n    fn test_with_auth() {\n        let client = Client::new(\"http://localhost:8068\", \"database\");\n        assert_eq!(client.parameters.len(), 1);\n        assert_eq!(client.parameters.get(\"db\").unwrap(), \"database\");\n\n        let with_auth = client.with_auth(\"username\", \"password\");\n        assert_eq!(with_auth.parameters.len(), 3);\n        assert_eq!(with_auth.parameters.get(\"db\").unwrap(), \"database\");\n        assert_eq!(with_auth.parameters.get(\"u\").unwrap(), \"username\");\n        assert_eq!(with_auth.parameters.get(\"p\").unwrap(), \"password\");\n\n        let client = Client::new(\"http://localhost:8068\", \"database\");\n        let with_auth = client.with_token(\"token\");\n        assert_eq!(with_auth.parameters.len(), 1);\n        assert_eq!(with_auth.parameters.get(\"db\").unwrap(), \"database\");\n        assert_eq!(with_auth.token.unwrap(), \"token\");\n    }\n}\n","traces":[{"line":43,"address":[],"length":0,"stats":{"Line":1}},{"line":44,"address":[2155260],"length":1,"stats":{"Line":1}},{"line":45,"address":[],"length":0,"stats":{"Line":0}},{"line":47,"address":[],"length":0,"stats":{"Line":2}},{"line":48,"address":[6948104,6948001],"length":1,"stats":{"Line":2}},{"line":49,"address":[2155623],"length":1,"stats":{"Line":1}},{"line":52,"address":[6947806,6947746],"length":1,"stats":{"Line":2}},{"line":57,"address":[6948160],"length":1,"stats":{"Line":1}},{"line":58,"address":[6948178,6948209,6948268],"length":1,"stats":{"Line":3}},{"line":59,"address":[2155789],"length":1,"stats":{"Line":1}},{"line":60,"address":[6948248],"length":1,"stats":{"Line":1}},{"line":81,"address":[2155904,2156569,2156607],"length":1,"stats":{"Line":11}},{"line":86,"address":[2354816,2355605],"length":1,"stats":{"Line":11}},{"line":87,"address":[2156156,2156076],"length":1,"stats":{"Line":22}},{"line":89,"address":[2355855,2355095],"length":1,"stats":{"Line":12}},{"line":90,"address":[2355166,2356042,2355282,2355926],"length":1,"stats":{"Line":24}},{"line":91,"address":[2355290,2356050],"length":1,"stats":{"Line":12}},{"line":111,"address":[2157298,2156624,2157261],"length":1,"stats":{"Line":6}},{"line":116,"address":[2156813,2156706],"length":1,"stats":{"Line":10}},{"line":117,"address":[2156838,2156910],"length":1,"stats":{"Line":11}},{"line":118,"address":[2724770],"length":1,"stats":{"Line":5}},{"line":119,"address":[2157072],"length":1,"stats":{"Line":6}},{"line":120,"address":[2157215],"length":1,"stats":{"Line":6}},{"line":125,"address":[6948320,6948449],"length":1,"stats":{"Line":0}},{"line":126,"address":[6948356,6948425],"length":1,"stats":{"Line":0}},{"line":127,"address":[6948429],"length":1,"stats":{"Line":0}},{"line":135,"address":[2157718,2157456],"length":1,"stats":{"Line":1}},{"line":139,"address":[],"length":0,"stats":{"Line":2}},{"line":140,"address":[],"length":0,"stats":{"Line":1}},{"line":144,"address":[7487936],"length":1,"stats":{"Line":1}},{"line":146,"address":[7487941],"length":1,"stats":{"Line":1}},{"line":150,"address":[6948560],"length":1,"stats":{"Line":1}},{"line":151,"address":[2157813],"length":1,"stats":{"Line":1}},{"line":157,"address":[6948829,6948786,6948624,6950489,6949196,6948671,6948592,6948600],"length":1,"stats":{"Line":4}},{"line":158,"address":[6948879,6948763],"length":1,"stats":{"Line":2}},{"line":159,"address":[6949082,6949442,6949136,6949011,6949365,6949667],"length":1,"stats":{"Line":5}},{"line":163,"address":[2158402,2158600,2158060,2158365,2158461],"length":1,"stats":{"Line":4}},{"line":164,"address":[2159965,2159792,2160021],"length":1,"stats":{"Line":0}},{"line":165,"address":[2159875,2159827],"length":1,"stats":{"Line":0}},{"line":172,"address":[2159157],"length":1,"stats":{"Line":1}},{"line":173,"address":[6949620,6949756],"length":1,"stats":{"Line":2}},{"line":175,"address":[2158985,2160048,2160057],"length":1,"stats":{"Line":3}},{"line":176,"address":[6949846],"length":1,"stats":{"Line":1}},{"line":177,"address":[2160096,2160105],"length":1,"stats":{"Line":2}},{"line":186,"address":[7489482,7489572],"length":1,"stats":{"Line":2}},{"line":227,"address":[2356288,2356492,2356320,2361484],"length":1,"stats":{"Line":15}},{"line":231,"address":[2364197,2361580,2356965,2361925,2366704,2366774,2366822,2359261,2367008,2367078,2361726,2367126,2356595,2356766],"length":1,"stats":{"Line":16}},{"line":232,"address":[],"length":0,"stats":{"Line":0}},{"line":235,"address":[2361870,2362011,2357051,2356910],"length":1,"stats":{"Line":14}},{"line":236,"address":[],"length":0,"stats":{"Line":14}},{"line":237,"address":[],"length":0,"stats":{"Line":0}},{"line":238,"address":[2719312,2714195],"length":1,"stats":{"Line":5}},{"line":239,"address":[2362400,2357369,2362317,2357452],"length":1,"stats":{"Line":10}},{"line":240,"address":[2357568,2362611,2362516,2357667],"length":1,"stats":{"Line":10}},{"line":242,"address":[2362842,2363027,2362677,2358091,2357898,2357733],"length":1,"stats":{"Line":10}},{"line":243,"address":[],"length":0,"stats":{"Line":2}},{"line":245,"address":[2714949,2720055],"length":1,"stats":{"Line":4}},{"line":248,"address":[],"length":0,"stats":{"Line":2}},{"line":249,"address":[2714317,2715265,2719431,2720356],"length":1,"stats":{"Line":4}},{"line":250,"address":[],"length":0,"stats":{"Line":4}},{"line":251,"address":[2715608,2720568,2720699,2715477],"length":1,"stats":{"Line":4}},{"line":253,"address":[],"length":0,"stats":{"Line":4}},{"line":258,"address":[],"length":0,"stats":{"Line":0}},{"line":259,"address":[],"length":0,"stats":{"Line":0}},{"line":262,"address":[2364013,2359077,2364638,2364374,2365011,2364436,2358172,2359723,2359521,2359150,2360096,2359459,2363108,2364086],"length":1,"stats":{"Line":29}},{"line":263,"address":[2715130,2720224],"length":1,"stats":{"Line":7}},{"line":265,"address":[2723472,2723547,2723851,2723904,2723600,2723776],"length":1,"stats":{"Line":2}},{"line":266,"address":[],"length":0,"stats":{"Line":1}},{"line":268,"address":[2716754,2721255,2721573,2718768,2721292,2713633,2716509,2721445,2721803,2716378,2716179,2716219],"length":1,"stats":{"Line":23}},{"line":269,"address":[],"length":0,"stats":{"Line":12}},{"line":272,"address":[],"length":0,"stats":{"Line":4}},{"line":274,"address":[],"length":0,"stats":{"Line":0}},{"line":276,"address":[],"length":0,"stats":{"Line":0}},{"line":278,"address":[2366095,2366306,2366384,2360148,2361658,2365059,2360007,2356677,2365461,2366466,2361258,2360550,2364922,2366519,2366224,2366359],"length":1,"stats":{"Line":6}},{"line":279,"address":[],"length":0,"stats":{"Line":0}},{"line":283,"address":[2360637,2365650,2365412,2360739,2365548,2360501],"length":1,"stats":{"Line":13}},{"line":284,"address":[],"length":0,"stats":{"Line":0}},{"line":285,"address":[],"length":0,"stats":{"Line":0}},{"line":289,"address":[],"length":0,"stats":{"Line":5}},{"line":292,"address":[6950928,6951300,6951329],"length":1,"stats":{"Line":6}},{"line":293,"address":[2160300,2160178],"length":1,"stats":{"Line":11}},{"line":294,"address":[2160305,2160525,2160230],"length":1,"stats":{"Line":0}},{"line":296,"address":[2160290],"length":1,"stats":{"Line":5}},{"line":301,"address":[6951344],"length":1,"stats":{"Line":2}},{"line":302,"address":[2160590],"length":1,"stats":{"Line":2}},{"line":303,"address":[2160600],"length":1,"stats":{"Line":2}},{"line":304,"address":[2160614],"length":1,"stats":{"Line":1}},{"line":306,"address":[2160694],"length":1,"stats":{"Line":2}}],"covered":72,"coverable":88},{"path":["/","home","runner","work","influxdb-rust","influxdb-rust","influxdb","src","error.rs"],"content":"//! Errors that might happen in the crate\n\nuse thiserror::Error;\n\n#[derive(Debug, Eq, PartialEq, Error)]\n#[non_exhaustive]\npub enum Error {\n    #[error(\"query is invalid: {error}\")]\n    /// Error happens when a query is invalid\n    InvalidQueryError { error: String },\n\n    #[error(\"Failed to build URL: {error}\")]\n    /// Error happens when a query is invalid\n    UrlConstructionError { error: String },\n\n    #[error(\"http protocol error: {error}\")]\n    /// Error happens when a query is invalid\n    ProtocolError { error: String },\n\n    #[error(\"http protocol error: {error}\")]\n    /// Error happens when Serde cannot deserialize the response\n    DeserializationError { error: String },\n\n    #[error(\"InfluxDB encountered the following error: {error}\")]\n    /// Error which has happened inside InfluxDB\n    DatabaseError { error: String },\n\n    #[error(\"API error with a status code: {0}\")]\n    /// Error happens when API returns non 2xx status code.\n    ApiError(u16),\n\n    #[error(\"connection error: {error}\")]\n    /// Error happens when HTTP request fails\n    ConnectionError { error: String },\n}\n","traces":[],"covered":0,"coverable":0},{"path":["/","home","runner","work","influxdb-rust","influxdb-rust","influxdb","src","integrations","serde_integration","de.rs"],"content":"use super::{Series, TaggedSeries};\nuse serde::de::{\n    value, Deserialize, DeserializeSeed, Deserializer, Error, IntoDeserializer, MapAccess,\n    SeqAccess, Visitor,\n};\nuse serde_derive::Deserialize;\nuse std::fmt;\nuse std::marker::PhantomData;\n\n// Based on https://serde.rs/deserialize-struct.html\nimpl\u003c'de, T\u003e Deserialize\u003c'de\u003e for Series\u003cT\u003e\nwhere\n    T: Deserialize\u003c'de\u003e,\n{\n    fn deserialize\u003cD\u003e(deserializer: D) -\u003e Result\u003cSelf, D::Error\u003e\n    where\n        D: Deserializer\u003c'de\u003e,\n    {\n        // Field name deserializer\n        #[derive(Deserialize)]\n        #[serde(field_identifier, rename_all = \"lowercase\")]\n        enum Field {\n            Name,\n            Columns,\n            Values,\n        }\n\n        struct SeriesVisitor\u003cT\u003e {\n            _inner_type: PhantomData\u003cT\u003e,\n        }\n\n        impl\u003c'de, T\u003e Visitor\u003c'de\u003e for SeriesVisitor\u003cT\u003e\n        where\n            T: Deserialize\u003c'de\u003e,\n        {\n            type Value = Series\u003cT\u003e;\n\n            fn expecting(\u0026self, formatter: \u0026mut fmt::Formatter) -\u003e fmt::Result {\n                formatter.write_str(\"struct Series\")\n            }\n\n            fn visit_map\u003cV\u003e(self, mut map: V) -\u003e Result\u003cSeries\u003cT\u003e, V::Error\u003e\n            where\n                V: MapAccess\u003c'de\u003e,\n            {\n                let mut name = None;\n                let mut columns: Option\u003cVec\u003cString\u003e\u003e = None;\n                let mut values: Option\u003cVec\u003cT\u003e\u003e = None;\n                while let Some(key) = map.next_key()? {\n                    match key {\n                        Field::Name =\u003e {\n                            if name.is_some() {\n                                return Err(Error::duplicate_field(\"name\"));\n                            }\n                            name = Some(map.next_value()?);\n                        }\n                        Field::Columns =\u003e {\n                            if columns.is_some() {\n                                return Err(Error::duplicate_field(\"columns\"));\n                            }\n                            columns = Some(map.next_value()?);\n                        }\n                        Field::Values =\u003e {\n                            if values.is_some() {\n                                return Err(Error::duplicate_field(\"values\"));\n                            }\n                            // Error out if \"values\" is encountered before \"columns\"\n                            // Hopefully, InfluxDB never does this.\n                            if columns.is_none() {\n                                return Err(Error::custom(\n                                    \"series values encountered before columns\",\n                                ));\n                            }\n                            // Deserialize using a HeaderVec deserializer\n                            // seeded with the headers from the \"columns\" field\n                            values = Some(map.next_value_seed(HeaderVec::\u003cT\u003e {\n                                header: columns.as_ref().unwrap(),\n                                _inner_type: PhantomData,\n                            })?);\n                        }\n                    }\n                }\n                let name = name.ok_or_else(|| Error::missing_field(\"name\"))?;\n                let values = values.unwrap_or_default();\n\n                Ok(Series { name, values })\n            }\n        }\n\n        const FIELDS: \u0026[\u0026str] = \u0026[\"name\", \"values\"];\n        deserializer.deserialize_struct(\n            \"Series\",\n            FIELDS,\n            SeriesVisitor::\u003cT\u003e {\n                _inner_type: PhantomData,\n            },\n        )\n    }\n}\n\n// Based on https://serde.rs/deserialize-struct.html\nimpl\u003c'de, TAG, T\u003e Deserialize\u003c'de\u003e for TaggedSeries\u003cTAG, T\u003e\nwhere\n    TAG: Deserialize\u003c'de\u003e,\n    T: Deserialize\u003c'de\u003e,\n{\n    fn deserialize\u003cD\u003e(deserializer: D) -\u003e Result\u003cSelf, D::Error\u003e\n    where\n        D: Deserializer\u003c'de\u003e,\n    {\n        // Field name deserializer\n        #[derive(Deserialize)]\n        #[serde(field_identifier, rename_all = \"lowercase\")]\n        enum Field {\n            Name,\n            Tags,\n            Columns,\n            Values,\n        }\n\n        struct SeriesVisitor\u003cTAG, T\u003e {\n            _tag_type: PhantomData\u003cTAG\u003e,\n            _value_type: PhantomData\u003cT\u003e,\n        }\n\n        impl\u003c'de, TAG, T\u003e Visitor\u003c'de\u003e for SeriesVisitor\u003cTAG, T\u003e\n        where\n            TAG: Deserialize\u003c'de\u003e,\n            T: Deserialize\u003c'de\u003e,\n        {\n            type Value = TaggedSeries\u003cTAG, T\u003e;\n\n            fn expecting(\u0026self, formatter: \u0026mut fmt::Formatter) -\u003e fmt::Result {\n                formatter.write_str(\"struct TaggedSeries\")\n            }\n\n            fn visit_map\u003cV\u003e(self, mut map: V) -\u003e Result\u003cTaggedSeries\u003cTAG, T\u003e, V::Error\u003e\n            where\n                V: MapAccess\u003c'de\u003e,\n            {\n                let mut name = None;\n                let mut tags: Option\u003cTAG\u003e = None;\n                let mut columns: Option\u003cVec\u003cString\u003e\u003e = None;\n                let mut values: Option\u003cVec\u003cT\u003e\u003e = None;\n                while let Some(key) = map.next_key()? {\n                    match key {\n                        Field::Name =\u003e {\n                            if name.is_some() {\n                                return Err(Error::duplicate_field(\"name\"));\n                            }\n                            name = Some(map.next_value()?);\n                        }\n                        Field::Tags =\u003e {\n                            if tags.is_some() {\n                                return Err(Error::duplicate_field(\"tags\"));\n                            }\n                            tags = Some(map.next_value()?);\n                        }\n                        Field::Columns =\u003e {\n                            if columns.is_some() {\n                                return Err(Error::duplicate_field(\"columns\"));\n                            }\n                            columns = Some(map.next_value()?);\n                        }\n                        Field::Values =\u003e {\n                            if values.is_some() {\n                                return Err(Error::duplicate_field(\"values\"));\n                            }\n                            // Error out if \"values\" is encountered before \"columns\"\n                            // Hopefully, InfluxDB never does this.\n                            if columns.is_none() {\n                                return Err(Error::custom(\n                                    \"series values encountered before columns\",\n                                ));\n                            }\n                            // Deserialize using a HeaderVec deserializer\n                            // seeded with the headers from the \"columns\" field\n                            values = Some(map.next_value_seed(HeaderVec::\u003cT\u003e {\n                                header: columns.as_ref().unwrap(),\n                                _inner_type: PhantomData,\n                            })?);\n                        }\n                    }\n                }\n                let name = name.ok_or_else(|| Error::missing_field(\"name\"))?;\n                let tags = tags.ok_or_else(|| Error::missing_field(\"tags\"))?;\n                let values = values.ok_or_else(|| Error::missing_field(\"values\"))?;\n                Ok(TaggedSeries { name, tags, values })\n            }\n        }\n\n        const FIELDS: \u0026[\u0026str] = \u0026[\"name\", \"tags\", \"values\"];\n        deserializer.deserialize_struct(\n            \"TaggedSeries\",\n            FIELDS,\n            SeriesVisitor::\u003cTAG, T\u003e {\n                _tag_type: PhantomData,\n                _value_type: PhantomData,\n            },\n        )\n    }\n}\n\n// Deserializer that takes a header as a seed\n// and deserializes an array of arrays into a\n// Vec of map-like values using the header as\n// keys and the values as values.\nstruct HeaderVec\u003c'h, T\u003e {\n    header: \u0026'h [String],\n    _inner_type: PhantomData\u003cT\u003e,\n}\n\nimpl\u003c'de, 'h, T\u003e DeserializeSeed\u003c'de\u003e for HeaderVec\u003c'h, T\u003e\nwhere\n    T: Deserialize\u003c'de\u003e,\n{\n    type Value = Vec\u003cT\u003e;\n\n    fn deserialize\u003cD\u003e(self, deserializer: D) -\u003e Result\u003cSelf::Value, D::Error\u003e\n    where\n        D: Deserializer\u003c'de\u003e,\n    {\n        struct HeaderVecVisitor\u003c'h, T\u003e {\n            header: \u0026'h [String],\n            _inner_type: PhantomData\u003cT\u003e,\n        }\n        impl\u003c'de, 'h, T\u003e Visitor\u003c'de\u003e for HeaderVecVisitor\u003c'h, T\u003e\n        where\n            T: Deserialize\u003c'de\u003e,\n        {\n            type Value = Vec\u003cT\u003e;\n\n            fn expecting(\u0026self, formatter: \u0026mut fmt::Formatter) -\u003e fmt::Result {\n                write!(formatter, \"an array of arrays\")\n            }\n\n            fn visit_seq\u003cA\u003e(self, mut seq: A) -\u003e Result\u003cVec\u003cT\u003e, A::Error\u003e\n            where\n                A: SeqAccess\u003c'de\u003e,\n            {\n                let mut vec = Vec::new();\n\n                while let Some(v) = seq.next_element_seed(RowWithHeader {\n                    header: self.header,\n                    _inner_type: PhantomData,\n                })? {\n                    vec.push(v);\n                }\n\n                Ok(vec)\n            }\n        }\n        deserializer.deserialize_seq(HeaderVecVisitor {\n            header: self.header,\n            _inner_type: PhantomData,\n        })\n    }\n}\n\n// Deserializer that takes a header as a seed\n// and deserializes an array into a map-like\n// value using the header as keys and the values\n// as values.\nstruct RowWithHeader\u003c'h, T\u003e {\n    header: \u0026'h [String],\n    _inner_type: PhantomData\u003cT\u003e,\n}\n\nimpl\u003c'de, 'h, T\u003e DeserializeSeed\u003c'de\u003e for RowWithHeader\u003c'h, T\u003e\nwhere\n    T: Deserialize\u003c'de\u003e,\n{\n    type Value = T;\n\n    fn deserialize\u003cD\u003e(self, deserializer: D) -\u003e Result\u003cSelf::Value, D::Error\u003e\n    where\n        D: Deserializer\u003c'de\u003e,\n    {\n        struct RowWithHeaderVisitor\u003c'h, T\u003e {\n            header: \u0026'h [String],\n            _inner: PhantomData\u003cfn() -\u003e T\u003e,\n        }\n\n        impl\u003c'de, 'h, T\u003e Visitor\u003c'de\u003e for RowWithHeaderVisitor\u003c'h, T\u003e\n        where\n            T: Deserialize\u003c'de\u003e,\n        {\n            type Value = T;\n\n            fn expecting(\u0026self, formatter: \u0026mut fmt::Formatter) -\u003e fmt::Result {\n                formatter.write_str(\"array\")\n            }\n\n            fn visit_seq\u003cA\u003e(self, seq: A) -\u003e Result\u003cT, A::Error\u003e\n            where\n                A: SeqAccess\u003c'de\u003e,\n            {\n                // `MapAccessDeserializer` is a wrapper that turns a `MapAccess`\n                // into a `Deserializer`, allowing it to be used as the input to T's\n                // `Deserialize` implementation. T then deserializes itself using\n                // the entries from the map visitor.\n                Deserialize::deserialize(value::MapAccessDeserializer::new(HeaderMapAccess {\n                    header: self.header,\n                    field: 0,\n                    data: seq,\n                }))\n            }\n        }\n\n        deserializer.deserialize_seq(RowWithHeaderVisitor {\n            header: self.header,\n            _inner: PhantomData,\n        })\n    }\n}\n\n// MapAccess implementation that holds a reference to\n// the header for keys and a serde sequence for values.\n// When asked for a key, it returns the next header and\n// advances its header field index. When asked for a value,\n// it tries to deserialize the next element in the serde\n// sequence into the desired type, and returns an error\n// if no element is returned (the sequence is exhausted).\nstruct HeaderMapAccess\u003c'h, A\u003e {\n    header: \u0026'h [String],\n    field: usize,\n    data: A,\n}\n\nimpl\u003c'de, 'h, A\u003e MapAccess\u003c'de\u003e for HeaderMapAccess\u003c'h, A\u003e\nwhere\n    A: SeqAccess\u003c'de\u003e,\n{\n    type Error = \u003cA as SeqAccess\u003c'de\u003e\u003e::Error;\n\n    fn next_key_seed\u003cK: DeserializeSeed\u003c'de\u003e\u003e(\n        \u0026mut self,\n        seed: K,\n    ) -\u003e Result\u003cOption\u003cK::Value\u003e, Self::Error\u003e {\n        let field = match self.header.get(self.field) {\n            None =\u003e return Ok(None),\n            Some(field) =\u003e field,\n        };\n        self.field += 1;\n        seed.deserialize(field.clone().into_deserializer())\n            .map(Some)\n    }\n\n    fn next_value_seed\u003cK: DeserializeSeed\u003c'de\u003e\u003e(\n        \u0026mut self,\n        seed: K,\n    ) -\u003e Result\u003cK::Value, Self::Error\u003e {\n        match self.data.next_element_seed(seed)? {\n            Some(value) =\u003e Ok(value),\n            None =\u003e Err(Error::custom(\"next_value_seed called but no value\")),\n        }\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::Series;\n    use std::borrow::Cow;\n    use std::collections::HashMap;\n\n    const TEST_DATA: \u0026str = r#\"\n    {\n        \"name\": \"series_name\",\n        \"columns\": [\"foo\", \"bar\"],\n        \"values\": [\n            [\"foo_a\", \"bar_a\"],\n            [\"foo_b\", \"bar_b\"]\n        ]\n    }\n    \"#;\n\n    // we can derive all the impls we want here\n    #[derive(Debug, PartialEq, Eq)]\n    struct EqSeries\u003cT\u003e {\n        pub name: String,\n        pub values: Vec\u003cT\u003e,\n    }\n\n    impl\u003cT\u003e From\u003cSeries\u003cT\u003e\u003e for EqSeries\u003cT\u003e {\n        fn from(Series { name, values }: Series\u003cT\u003e) -\u003e Self {\n            EqSeries { name, values }\n        }\n    }\n\n    #[test]\n    fn test_deserialize_cow() {\n        // Unfortunately, Cow is not automatically borrowed,\n        // so this is basically equivalent to String, String\n        let result = serde_json::from_str::\u003cSeries\u003cHashMap\u003cCow\u003cstr\u003e, Cow\u003cstr\u003e\u003e\u003e\u003e(TEST_DATA);\n        assert!(result.is_ok());\n        assert_eq!(\n            EqSeries::from(result.unwrap()),\n            EqSeries {\n                name: \"series_name\".into(),\n                values: vec![\n                    {\n                        let mut h = std::collections::HashMap::new();\n                        h.insert(\"foo\".into(), \"foo_a\".into());\n                        h.insert(\"bar\".into(), \"bar_a\".into());\n                        h\n                    },\n                    {\n                        let mut h = std::collections::HashMap::new();\n                        h.insert(\"foo\".into(), \"foo_b\".into());\n                        h.insert(\"bar\".into(), \"bar_b\".into());\n                        h\n                    },\n                ],\n            },\n        );\n    }\n\n    #[test]\n    fn test_deserialize_borrowed() {\n        use serde_derive::Deserialize;\n\n        // Deserializing a string that cannot be passed through\n        // without escaping will result in an error like this:\n        // `invalid type: string \"\\n\", expected a borrowed string at line 6 column 43`\n        // but if it doesn't need escaping it's fine.\n        #[derive(Deserialize, Debug, PartialEq, Eq)]\n        struct BorrowingStruct\u003c'a\u003e {\n            foo: \u0026'a str,\n            bar: \u0026'a str,\n        }\n\n        let result = serde_json::from_str::\u003cSeries\u003cBorrowingStruct\u003e\u003e(TEST_DATA);\n        assert!(result.is_ok(), \"{}\", result.unwrap_err());\n        assert_eq!(\n            EqSeries::from(result.unwrap()),\n            EqSeries {\n                name: \"series_name\".into(),\n                values: vec![\n                    BorrowingStruct {\n                        foo: \"foo_a\",\n                        bar: \"bar_a\",\n                    },\n                    BorrowingStruct {\n                        foo: \"foo_b\",\n                        bar: \"bar_b\",\n                    },\n                ],\n            },\n        );\n    }\n}\n","traces":[{"line":15,"address":[2771984,2772128,2772032,2772080,2772176],"length":1,"stats":{"Line":8}},{"line":32,"address":[],"length":0,"stats":{"Line":0}},{"line":38,"address":[2375248],"length":1,"stats":{"Line":0}},{"line":39,"address":[2102409,2102345],"length":1,"stats":{"Line":0}},{"line":42,"address":[],"length":0,"stats":{"Line":8}},{"line":46,"address":[2375334],"length":1,"stats":{"Line":8}},{"line":47,"address":[2375373],"length":1,"stats":{"Line":8}},{"line":48,"address":[2934687,2939807,2942367,2932127,2937247],"length":1,"stats":{"Line":8}},{"line":49,"address":[2939544,2942406,2934424,2937286,2942470,2937350,2944664,2942104,2936984,2939846,2934790,2932166,2934726,2932230,2939910],"length":1,"stats":{"Line":16}},{"line":50,"address":[],"length":0,"stats":{"Line":8}},{"line":51,"address":[],"length":0,"stats":{"Line":8}},{"line":52,"address":[2375780,2375712],"length":1,"stats":{"Line":16}},{"line":53,"address":[2935102,2940222,2940595,2938035,2943155,2935475,2937662,2942782,2932542,2932915],"length":1,"stats":{"Line":0}},{"line":55,"address":[],"length":0,"stats":{"Line":16}},{"line":57,"address":[2103721,2106361],"length":1,"stats":{"Line":8}},{"line":58,"address":[2940618,2943178,2935036,2937596,2938058,2940156,2932476,2932938,2935498,2942716],"length":1,"stats":{"Line":16}},{"line":59,"address":[2376228,2376577],"length":1,"stats":{"Line":0}},{"line":61,"address":[2940637,2943538,2943197,2935858,2943251,2940978,2935517,2932957,2938131,2935571,2938418,2940691,2933298,2933011,2938077],"length":1,"stats":{"Line":16}},{"line":63,"address":[],"length":0,"stats":{"Line":8}},{"line":64,"address":[2941019,2935899,2938459,2943579,2932498,2940178,2942738,2935058,2933339,2937618],"length":1,"stats":{"Line":16}},{"line":65,"address":[2377160,2376628],"length":1,"stats":{"Line":0}},{"line":69,"address":[2103827,2103781,2106467,2106421],"length":1,"stats":{"Line":16}},{"line":70,"address":[],"length":0,"stats":{"Line":0}},{"line":71,"address":[],"length":0,"stats":{"Line":0}},{"line":76,"address":[],"length":0,"stats":{"Line":8}},{"line":77,"address":[],"length":0,"stats":{"Line":16}},{"line":78,"address":[],"length":0,"stats":{"Line":0}},{"line":83,"address":[2105434,2107728,2107055,2104589,2104415,2107229,2104896,2107536,2102794,2107760,2107761,2107729],"length":1,"stats":{"Line":16}},{"line":84,"address":[2107161,2104521],"length":1,"stats":{"Line":8}},{"line":86,"address":[2104671,2107311],"length":1,"stats":{"Line":8}},{"line":91,"address":[2772040,2772088,2772184,2771992,2772136],"length":1,"stats":{"Line":8}},{"line":93,"address":[],"length":0,"stats":{"Line":0}},{"line":94,"address":[],"length":0,"stats":{"Line":0}},{"line":95,"address":[],"length":0,"stats":{"Line":0}},{"line":107,"address":[2772224],"length":1,"stats":{"Line":1}},{"line":126,"address":[],"length":0,"stats":{"Line":0}},{"line":133,"address":[],"length":0,"stats":{"Line":0}},{"line":134,"address":[],"length":0,"stats":{"Line":0}},{"line":137,"address":[2945072,2948645,2948438],"length":1,"stats":{"Line":1}},{"line":141,"address":[],"length":0,"stats":{"Line":1}},{"line":142,"address":[2945141],"length":1,"stats":{"Line":1}},{"line":143,"address":[],"length":0,"stats":{"Line":1}},{"line":144,"address":[],"length":0,"stats":{"Line":1}},{"line":145,"address":[],"length":0,"stats":{"Line":2}},{"line":146,"address":[],"length":0,"stats":{"Line":1}},{"line":147,"address":[],"length":0,"stats":{"Line":1}},{"line":148,"address":[],"length":0,"stats":{"Line":2}},{"line":149,"address":[2946001,2945621],"length":1,"stats":{"Line":0}},{"line":151,"address":[],"length":0,"stats":{"Line":2}},{"line":153,"address":[],"length":0,"stats":{"Line":1}},{"line":154,"address":[2946024,2945533],"length":1,"stats":{"Line":2}},{"line":155,"address":[],"length":0,"stats":{"Line":0}},{"line":157,"address":[],"length":0,"stats":{"Line":2}},{"line":159,"address":[],"length":0,"stats":{"Line":1}},{"line":160,"address":[2945555,2946441],"length":1,"stats":{"Line":2}},{"line":161,"address":[],"length":0,"stats":{"Line":0}},{"line":163,"address":[],"length":0,"stats":{"Line":2}},{"line":165,"address":[],"length":0,"stats":{"Line":1}},{"line":166,"address":[],"length":0,"stats":{"Line":2}},{"line":167,"address":[],"length":0,"stats":{"Line":0}},{"line":171,"address":[2946902,2946856],"length":1,"stats":{"Line":2}},{"line":172,"address":[2946928,2947367],"length":1,"stats":{"Line":0}},{"line":173,"address":[],"length":0,"stats":{"Line":0}},{"line":178,"address":[],"length":0,"stats":{"Line":1}},{"line":179,"address":[],"length":0,"stats":{"Line":2}},{"line":180,"address":[],"length":0,"stats":{"Line":0}},{"line":185,"address":[2948449,2947615,2948737,2948736,2945440,2947421],"length":1,"stats":{"Line":2}},{"line":186,"address":[],"length":0,"stats":{"Line":2}},{"line":187,"address":[],"length":0,"stats":{"Line":2}},{"line":188,"address":[],"length":0,"stats":{"Line":1}},{"line":193,"address":[2772232],"length":1,"stats":{"Line":1}},{"line":195,"address":[],"length":0,"stats":{"Line":0}},{"line":196,"address":[],"length":0,"stats":{"Line":0}},{"line":197,"address":[],"length":0,"stats":{"Line":0}},{"line":198,"address":[],"length":0,"stats":{"Line":0}},{"line":219,"address":[2925984,2926112,2926304,2926048,2926176,2926240],"length":1,"stats":{"Line":9}},{"line":227,"address":[],"length":0,"stats":{"Line":0}},{"line":233,"address":[2107920,2107984],"length":1,"stats":{"Line":0}},{"line":234,"address":[2107938,2108002],"length":1,"stats":{"Line":0}},{"line":237,"address":[2109088,2108645,2108576,2108048,2108592,2108101],"length":1,"stats":{"Line":9}},{"line":241,"address":[2108638,2108680,2108136,2108094],"length":1,"stats":{"Line":18}},{"line":243,"address":[2108705,2108161,2108762,2108215,2108393,2108882],"length":1,"stats":{"Line":18}},{"line":244,"address":[],"length":0,"stats":{"Line":9}},{"line":245,"address":[],"length":0,"stats":{"Line":0}},{"line":247,"address":[2108436,2108465,2108938,2108977],"length":1,"stats":{"Line":18}},{"line":250,"address":[2927755,2930558,2928878,2929998,2928318,2929438],"length":1,"stats":{"Line":9}},{"line":253,"address":[],"length":0,"stats":{"Line":9}},{"line":254,"address":[2107830,2107894],"length":1,"stats":{"Line":9}},{"line":255,"address":[],"length":0,"stats":{"Line":0}},{"line":275,"address":[2109168,2109104],"length":1,"stats":{"Line":9}},{"line":284,"address":[],"length":0,"stats":{"Line":0}},{"line":290,"address":[2930800,2930672,2930736,2930992,2930864,2930928],"length":1,"stats":{"Line":0}},{"line":291,"address":[2109321,2109257],"length":1,"stats":{"Line":0}},{"line":294,"address":[],"length":0,"stats":{"Line":9}},{"line":302,"address":[2931318,2931430,2931094,2931542,2931206,2931654],"length":1,"stats":{"Line":9}},{"line":303,"address":[2109551,2109407],"length":1,"stats":{"Line":9}},{"line":304,"address":[],"length":0,"stats":{"Line":0}},{"line":305,"address":[],"length":0,"stats":{"Line":0}},{"line":310,"address":[2109152,2109216],"length":1,"stats":{"Line":9}},{"line":311,"address":[],"length":0,"stats":{"Line":9}},{"line":312,"address":[],"length":0,"stats":{"Line":0}},{"line":336,"address":[2371712,2372132],"length":1,"stats":{"Line":9}},{"line":340,"address":[2924782,2923345,2923438,2924689,2924241,2922897,2923793,2922542,2923886,2924334,2922449,2922990],"length":1,"stats":{"Line":18}},{"line":341,"address":[],"length":0,"stats":{"Line":9}},{"line":342,"address":[],"length":0,"stats":{"Line":9}},{"line":344,"address":[2371962,2371998,2371914],"length":1,"stats":{"Line":18}},{"line":345,"address":[2372018,2371966],"length":1,"stats":{"Line":9}},{"line":346,"address":[],"length":0,"stats":{"Line":0}},{"line":349,"address":[2110576,2110960,2110736],"length":1,"stats":{"Line":8}},{"line":353,"address":[2110754,2110981,2110588],"length":1,"stats":{"Line":8}},{"line":354,"address":[],"length":0,"stats":{"Line":8}},{"line":355,"address":[],"length":0,"stats":{"Line":0}}],"covered":73,"coverable":112},{"path":["/","home","runner","work","influxdb-rust","influxdb-rust","influxdb","src","integrations","serde_integration","mod.rs"],"content":"//! Serde Integration for InfluxDB. Provides deserialization of query returns.\n//!\n//! When querying multiple series in the same query (e.g. with a regex query), it might be desirable to flat map\n//! the resulting series into a single `Vec` like so. The example assumes, that there are weather readings in multiple\n//! series named `weather_\u003ccity_name\u003e` (e.g. `weather_berlin`, or `weather_london`). Since we're using a Regex query,\n//! we don't actually know which series will be returned. To assign the city name to the series, we can use the series\n//! `name`, InfluxDB provides alongside query results.\n//!\n//! ```rust,no_run\n//! use influxdb::{Client, Query};\n//! use serde_derive::Deserialize;\n//!\n//! #[derive(Deserialize)]\n//! struct WeatherWithoutCityName {\n//!     temperature: i32,\n//! }\n//!\n//! #[derive(Deserialize)]\n//! struct Weather {\n//!     city_name: String,\n//!     weather: WeatherWithoutCityName,\n//! }\n//!\n//! # #[async_std::main]\n//! # async fn main() -\u003e Result\u003c(), influxdb::Error\u003e {\n//! let client = Client::new(\"http://localhost:8086\", \"test\");\n//! let query = Query::raw_read_query(\n//!     \"SELECT temperature FROM /weather_[a-z]*$/ WHERE time \u003e now() - 1m ORDER BY DESC\",\n//! );\n//! let mut db_result = client.json_query(query).await?;\n//! let _result = db_result\n//!     .deserialize_next::\u003cWeatherWithoutCityName\u003e()?\n//!     .series\n//!     .into_iter()\n//!     .map(|mut city_series| {\n//!         let city_name =\n//!             city_series.name.split(\"_\").collect::\u003cVec\u003c\u0026str\u003e\u003e().remove(2);\n//!         Weather {\n//!             weather: city_series.values.remove(0),\n//!             city_name: city_name.to_string(),\n//!         }\n//!     })\n//!     .collect::\u003cVec\u003cWeather\u003e\u003e();\n//! # Ok(())\n//! # }\n//! ```\n\nmod de;\n\nuse serde::de::DeserializeOwned;\nuse serde_derive::Deserialize;\n\nuse crate::{client::check_status, Client, Error, Query, ReadQuery};\n\n#[derive(Deserialize)]\n#[doc(hidden)]\nstruct _DatabaseError {\n    error: String,\n}\n\n#[derive(Deserialize, Debug)]\n#[doc(hidden)]\npub struct DatabaseQueryResult {\n    pub results: Vec\u003cserde_json::Value\u003e,\n}\n\nimpl DatabaseQueryResult {\n    pub fn deserialize_next\u003cT: 'static\u003e(\u0026mut self) -\u003e Result\u003cReturn\u003cT\u003e, Error\u003e\n    where\n        T: DeserializeOwned + Send,\n    {\n        serde_json::from_value::\u003cReturn\u003cT\u003e\u003e(self.results.remove(0)).map_err(|err| {\n            Error::DeserializationError {\n                error: format!(\"could not deserialize: {}\", err),\n            }\n        })\n    }\n\n    pub fn deserialize_next_tagged\u003cTAG, T: 'static\u003e(\n        \u0026mut self,\n    ) -\u003e Result\u003cTaggedReturn\u003cTAG, T\u003e, Error\u003e\n    where\n        TAG: DeserializeOwned + Send,\n        T: DeserializeOwned + Send,\n    {\n        serde_json::from_value::\u003cTaggedReturn\u003cTAG, T\u003e\u003e(self.results.remove(0)).map_err(|err| {\n            Error::DeserializationError {\n                error: format!(\"could not deserialize: {}\", err),\n            }\n        })\n    }\n}\n\n#[derive(Deserialize, Debug)]\n#[doc(hidden)]\npub struct Return\u003cT\u003e {\n    #[serde(default = \"Vec::new\")]\n    pub series: Vec\u003cSeries\u003cT\u003e\u003e,\n}\n\n#[derive(Debug)]\n/// Represents a returned series from InfluxDB\npub struct Series\u003cT\u003e {\n    pub name: String,\n    pub values: Vec\u003cT\u003e,\n}\n\n#[derive(Deserialize, Debug)]\n#[doc(hidden)]\npub struct TaggedReturn\u003cTAG, T\u003e {\n    #[serde(default = \"Vec::new\")]\n    pub series: Vec\u003cTaggedSeries\u003cTAG, T\u003e\u003e,\n}\n\n#[derive(Debug)]\n/// Represents a returned series from InfluxDB\npub struct TaggedSeries\u003cTAG, T\u003e {\n    pub name: String,\n    pub tags: TAG,\n    pub values: Vec\u003cT\u003e,\n}\n\nimpl Client {\n    pub async fn json_query(\u0026self, q: ReadQuery) -\u003e Result\u003cDatabaseQueryResult, Error\u003e {\n        let query = q.build().map_err(|err| Error::InvalidQueryError {\n            error: format!(\"{}\", err),\n        })?;\n\n        let read_query = query.get();\n        let read_query_lower = read_query.to_lowercase();\n\n        if !read_query_lower.contains(\"select\") \u0026\u0026 !read_query_lower.contains(\"show\") {\n            let error = Error::InvalidQueryError {\n                error: String::from(\n                    \"Only SELECT and SHOW queries supported with JSON deserialization\",\n                ),\n            };\n            return Err(error);\n        }\n\n        let url = \u0026format!(\"{}/query\", \u0026self.url);\n        let mut parameters = self.parameters.as_ref().clone();\n        parameters.insert(\"q\", read_query);\n        let mut request_builder = self.client.get(url);\n        if let Some(ref token) = self.token {\n            request_builder = request_builder.header(\"Authorization\", format!(\"Token {}\", token))\n        }\n        let request_builder = request_builder.query(\u0026parameters);\n\n        #[cfg(feature = \"surf\")]\n        let request_builder = request_builder.map_err(|err| Error::UrlConstructionError {\n            error: err.to_string(),\n        })?;\n\n        let res = request_builder\n            .send()\n            .await\n            .map_err(|err| Error::ConnectionError {\n                error: err.to_string(),\n            })?;\n        check_status(\u0026res)?;\n\n        #[cfg(feature = \"reqwest\")]\n        let body = res.bytes();\n        #[cfg(feature = \"surf\")]\n        let mut res = res;\n        #[cfg(feature = \"surf\")]\n        let body = res.body_bytes();\n\n        let body = body.await.map_err(|err| Error::ProtocolError {\n            error: err.to_string(),\n        })?;\n\n        // Try parsing InfluxDBs { \"error\": \"error message here\" }\n        if let Ok(error) = serde_json::from_slice::\u003c_DatabaseError\u003e(\u0026body) {\n            return Err(Error::DatabaseError { error: error.error });\n        }\n\n        // Json has another structure, let's try actually parsing it to the type we're deserializing\n        serde_json::from_slice::\u003cDatabaseQueryResult\u003e(\u0026body).map_err(|err| {\n            Error::DeserializationError {\n                error: format!(\"serde error: {}\", err),\n            }\n        })\n    }\n}\n","traces":[{"line":68,"address":[2769760,2769840,2769920,2770000,2769680],"length":1,"stats":{"Line":6}},{"line":72,"address":[2770825,2769699,2771104,2770080,2770569,2770592,2770848,2771337,2769939,2770336,2770313,2770019,2769859,2769779,2771081],"length":1,"stats":{"Line":6}},{"line":73,"address":[],"length":0,"stats":{"Line":0}},{"line":74,"address":[],"length":0,"stats":{"Line":0}},{"line":79,"address":[2771360],"length":1,"stats":{"Line":1}},{"line":86,"address":[],"length":0,"stats":{"Line":1}},{"line":87,"address":[],"length":0,"stats":{"Line":0}},{"line":88,"address":[2771462,2771527],"length":1,"stats":{"Line":0}},{"line":124,"address":[1966623,1969005,1964722,1966823,1964526,1964464],"length":1,"stats":{"Line":8}},{"line":125,"address":[1969579,1965092,1969360,1964844,1966784,1969529,1964695],"length":1,"stats":{"Line":4}},{"line":126,"address":[1969434,1969390],"length":1,"stats":{"Line":0}},{"line":129,"address":[1964983,1965188],"length":1,"stats":{"Line":4}},{"line":130,"address":[6956215,6956314],"length":1,"stats":{"Line":4}},{"line":132,"address":[6956337,6956436,6956574],"length":1,"stats":{"Line":5}},{"line":134,"address":[6956611],"length":1,"stats":{"Line":1}},{"line":138,"address":[6956696],"length":1,"stats":{"Line":1}},{"line":141,"address":[1965762,1965503],"length":1,"stats":{"Line":4}},{"line":142,"address":[6956996,6956923],"length":1,"stats":{"Line":4}},{"line":143,"address":[6957160,6957019],"length":1,"stats":{"Line":4}},{"line":144,"address":[1966152],"length":1,"stats":{"Line":2}},{"line":145,"address":[6957223,6957638],"length":1,"stats":{"Line":2}},{"line":146,"address":[7496864,7497099,7497112,7496725],"length":1,"stats":{"Line":0}},{"line":148,"address":[7496823],"length":1,"stats":{"Line":2}},{"line":155,"address":[1967290,1966992,1966632,1966724,1967679,1967080],"length":1,"stats":{"Line":8}},{"line":157,"address":[2384703],"length":1,"stats":{"Line":8}},{"line":158,"address":[1969616,1969740,1969687],"length":1,"stats":{"Line":0}},{"line":159,"address":[6960786],"length":1,"stats":{"Line":0}},{"line":161,"address":[6958298,6958449,6958740,6958583],"length":1,"stats":{"Line":6}},{"line":164,"address":[1967420],"length":1,"stats":{"Line":2}},{"line":170,"address":[2384726],"length":1,"stats":{"Line":5}},{"line":171,"address":[7500402],"length":1,"stats":{"Line":0}},{"line":175,"address":[6959141,6959281],"length":1,"stats":{"Line":4}},{"line":176,"address":[1968281],"length":1,"stats":{"Line":0}},{"line":180,"address":[1968624,1968548,1970133,1969904],"length":1,"stats":{"Line":4}},{"line":181,"address":[1970077],"length":1,"stats":{"Line":0}},{"line":182,"address":[1969987,1969939],"length":1,"stats":{"Line":0}}],"covered":24,"coverable":36},{"path":["/","home","runner","work","influxdb-rust","influxdb-rust","influxdb","src","lib.rs"],"content":"//! Pull requests are always welcome. See [Contributing](https://github.com/influxdb-rs/influxdb-rust/blob/main/CONTRIBUTING.md) and [Code of Conduct](https://github.com/influxdb-rs/influxdb-rust/blob/main/CODE_OF_CONDUCT.md). For a list of past changes, see [CHANGELOG.md](https://github.com/influxdb-rs/influxdb-rust/blob/main/CHANGELOG.md).\n//!\n//! ## Currently Supported Features\n//!\n//! -   Reading and writing to InfluxDB\n//! -   Optional Serde support for deserialization\n//! -   Running multiple queries in one request (e.g. `SELECT * FROM weather_berlin; SELECT * FROM weather_london`)\n//! -   Writing single or multiple measurements in one request (e.g. `WriteQuery` or `Vec\u003cWriteQuery\u003e` argument)\n//! -   Authenticated and unauthenticated connections\n//! -   `async`/`await` support\n//! -   `#[derive(InfluxDbWriteable)]` derive macro for writing / reading into structs\n//! -   `GROUP BY` support\n//! -   Tokio and async-std support (see example below) or [available backends](https://github.com/influxdb-rs/influxdb-rust/blob/main/influxdb/Cargo.toml)\n//! -   Swappable HTTP backends ([see below](#Choice-of-HTTP-backend))\n//!\n//! # Quickstart\n//!\n//! Add the following to your `Cargo.toml`\n//!\n#![doc = cargo_toml!(indent=\"\", \"derive\")]\n//!\n//! For an example with using Serde deserialization, please refer to [serde_integration](crate::integrations::serde_integration)\n//!\n//! ```rust,no_run\n//! use chrono::{DateTime, Utc};\n//! use influxdb::{Client, Error, InfluxDbWriteable, ReadQuery, Timestamp};\n//!\n//! #[tokio::main]\n//! // or #[async_std::main] if you prefer\n//! async fn main() -\u003e Result\u003c(), Error\u003e {\n//!     // Connect to db `test` on `http://localhost:8086`\n//!     let client = Client::new(\"http://localhost:8086\", \"test\");\n//!\n//!     #[derive(InfluxDbWriteable)]\n//!     struct WeatherReading {\n//!         time: DateTime\u003cUtc\u003e,\n//!         humidity: i32,\n//!         #[influxdb(tag)]\n//!         wind_direction: String,\n//!     }\n//!\n//!     // Let's write some data into a measurement called `weather`\n//!     let weather_readings = vec![\n//!         WeatherReading {\n//!             time: Timestamp::Hours(1).into(),\n//!             humidity: 30,\n//!             wind_direction: String::from(\"north\"),\n//!         }\n//!         .into_query(\"weather\"),\n//!         WeatherReading {\n//!             time: Timestamp::Hours(2).into(),\n//!             humidity: 40,\n//!             wind_direction: String::from(\"west\"),\n//!         }\n//!         .into_query(\"weather\"),\n//!     ];\n//!\n//!     client.query(weather_readings).await?;\n//!\n//!     // Read back all records\n//!     let read_query = ReadQuery::new(\"SELECT * FROM weather\");\n//!\n//!     let read_result = client.query(read_query).await?;\n//!     println!(\"{}\", read_result);\n//!     Ok(())\n//! }\n//! ```\n//!\n//! For further examples, check out the integration tests in `tests/integration_tests.rs`\n//! in the repository.\n//!\n//! # Choice of HTTP backend\n//!\n//! To communicate with InfluxDB, you can choose the HTTP backend to be used configuring the appropriate feature. We recommend sticking with the default reqwest-based client, unless you really need async-std compatibility.\n//!\n//! - **[hyper](https://github.com/hyperium/hyper)** (through reqwest, used by default), with [rustls](https://github.com/ctz/rustls)\n#![doc = cargo_toml!(indent=\"\\t\", \"derive\")]\n//! - **[hyper](https://github.com/hyperium/hyper)** (through reqwest), with native TLS (OpenSSL)\n#![doc = cargo_toml!(indent=\"\\t\", default-features = false, \"derive\", \"serde\", \"reqwest-client-native-tls\")]\n//! - **[hyper](https://github.com/hyperium/hyper)** (through reqwest), with vendored native TLS (OpenSSL)\n#![doc = cargo_toml!(indent=\"\\t\", default-features = false, \"derive\", \"serde\", \"reqwest-client-native-tls-vendored\")]\n//! - **[hyper](https://github.com/hyperium/hyper)** (through surf), use this if you need tokio 0.2 compatibility\n#![doc = cargo_toml!(indent=\"\\t\", default-features = false, \"derive\", \"serde\", \"hyper-client\")]\n//! - **[curl](https://github.com/alexcrichton/curl-rust)**, using [libcurl](https://curl.se/libcurl/)\n#![doc = cargo_toml!(indent=\"\\t\", default-features = false, \"derive\", \"serde\", \"curl-client\")]\n//! - **[async-h1](https://github.com/http-rs/async-h1)** with native TLS (OpenSSL)\n#![doc = cargo_toml!(indent=\"\\t\", default-features = false, \"derive\", \"serde\", \"h1-client\")]\n//! - **[async-h1](https://github.com/http-rs/async-h1)** with [rustls](https://github.com/ctz/rustls)\n#![doc = cargo_toml!(indent=\"\\t\", default-features = false, \"derive\", \"serde\", \"h1-client-rustls\")]\n//! - WebAssembly's `window.fetch`, via `web-sys` and **[wasm-bindgen](https://github.com/rustwasm/wasm-bindgen)**\n#![doc = cargo_toml!(indent=\"\\t\", default-features = false, \"derive\", \"serde\", \"wasm-client\")]\n//!\n//! # License\n//!\n//! [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n\n#![allow(clippy::needless_doctest_main)]\n#![allow(clippy::needless_lifetimes)] // False positive in client/mod.rs query fn\n#![forbid(bare_trait_objects)]\n\nmacro_rules! cargo_toml {\n    (indent=$indent:literal, $firstfeat:literal $(, $feature:literal)*) =\u003e {\n        cargo_toml_private!($indent, \"\", $firstfeat $(, $feature)*)\n    };\n\n    (indent=$indent:literal, default-features = false, $firstfeat:literal $(, $feature:literal)*) =\u003e {\n        cargo_toml_private!($indent, \"default-features = false, \", $firstfeat $(, $feature)*)\n    };\n}\n\nmacro_rules! cargo_toml_private {\n    ($indent:literal, $deffeats:literal, $firstfeat:literal $(, $feature:literal)*) =\u003e {\n        concat!(\n            $indent,\n            \"```toml\\n\",\n\n            $indent,\n            \"influxdb = { version = \\\"\",\n            env!(\"CARGO_PKG_VERSION\"),\n            \"\\\", \",\n            $deffeats,\n            \"features = [\",\n            \"\\\"\", $firstfeat, \"\\\"\",\n            $(\", \\\"\", $feature, \"\\\"\",)*\n            \"] }\\n\",\n\n            $indent,\n            \"```\"\n        )\n    };\n}\n\n#[cfg(all(feature = \"reqwest\", feature = \"surf\"))]\ncompile_error!(\"You need to choose between reqwest and surf; enabling both is not supported\");\n\n#[cfg(not(any(feature = \"reqwest\", feature = \"surf\")))]\ncompile_error!(\"You need to choose an http client; consider not disabling default features\");\n\nmod client;\nmod error;\nmod query;\n\npub use client::Client;\npub use error::Error;\npub use query::{\n    read_query::ReadQuery,\n    write_query::{Type, WriteQuery},\n    InfluxDbWriteable, Query, QueryType, Timestamp, ValidQuery,\n};\n\n#[cfg(feature = \"serde\")]\npub mod integrations {\n    #[cfg(feature = \"serde\")]\n    pub mod serde_integration;\n}\n","traces":[],"covered":0,"coverable":0},{"path":["/","home","runner","work","influxdb-rust","influxdb-rust","influxdb","src","query","consts.rs"],"content":"pub const MINUTES_PER_HOUR: u128 = 60;\npub const SECONDS_PER_MINUTE: u128 = 60;\npub const MILLIS_PER_SECOND: u128 = 1000;\npub const NANOS_PER_MILLI: u128 = 1_000_000;\npub const NANOS_PER_MICRO: u128 = 1000;\n","traces":[],"covered":0,"coverable":0},{"path":["/","home","runner","work","influxdb-rust","influxdb-rust","influxdb","src","query","line_proto_term.rs"],"content":"/// InfluxDB Line Protocol escaping helper module.\n/// https://docs.influxdata.com/influxdb/v1.7/write_protocols/line_protocol_tutorial/\nuse crate::Type;\nuse lazy_regex::{lazy_regex, Lazy, Regex};\n\npub static COMMAS_SPACES: Lazy\u003cRegex\u003e = lazy_regex!(\"[, ]\");\npub static COMMAS_SPACES_EQUALS: Lazy\u003cRegex\u003e = lazy_regex!(\"[, =]\");\npub static QUOTES_SLASHES: Lazy\u003cRegex\u003e = lazy_regex!(r#\"[\"\\\\]\"#);\npub static SLASHES: Lazy\u003cRegex\u003e = lazy_regex!(r#\"(\\\\|,| |=|\")\"#);\n\npub enum LineProtoTerm\u003c'a\u003e {\n    Measurement(\u0026'a str), // escape commas, spaces\n    TagKey(\u0026'a str),      // escape commas, equals, spaces\n    TagValue(\u0026'a Type),   // escape commas, equals, spaces\n    FieldKey(\u0026'a str),    // escape commas, equals, spaces\n    FieldValue(\u0026'a Type), // escape quotes, backslashes + quote\n}\n\nimpl LineProtoTerm\u003c'_\u003e {\n    pub fn escape(self) -\u003e String {\n        use LineProtoTerm::*;\n        match self {\n            Measurement(x) =\u003e Self::escape_any(x, \u0026COMMAS_SPACES),\n            TagKey(x) | FieldKey(x) =\u003e Self::escape_any(x, \u0026COMMAS_SPACES_EQUALS),\n            FieldValue(x) =\u003e Self::escape_field_value(x, false),\n            TagValue(x) =\u003e Self::escape_tag_value(x),\n        }\n    }\n\n    pub fn escape_v2(self) -\u003e String {\n        use LineProtoTerm::*;\n        match self {\n            Measurement(x) =\u003e Self::escape_any(x, \u0026COMMAS_SPACES),\n            TagKey(x) | FieldKey(x) =\u003e Self::escape_any(x, \u0026COMMAS_SPACES_EQUALS),\n            FieldValue(x) =\u003e Self::escape_field_value(x, true),\n            TagValue(x) =\u003e Self::escape_tag_value(x),\n        }\n    }\n\n    fn escape_field_value(v: \u0026Type, use_v2: bool) -\u003e String {\n        use Type::*;\n        match v {\n            Boolean(v) =\u003e {\n                if *v {\n                    \"true\"\n                } else {\n                    \"false\"\n                }\n            }\n            .to_string(),\n            Float(v) =\u003e v.to_string(),\n            SignedInteger(v) =\u003e format!(\"{}i\", v),\n            UnsignedInteger(v) =\u003e {\n                if use_v2 {\n                    format!(\"{}u\", v)\n                } else {\n                    format!(\"{}i\", v)\n                }\n            }\n            Text(v) =\u003e format!(r#\"\"{}\"\"#, Self::escape_any(v, \u0026QUOTES_SLASHES)),\n        }\n    }\n\n    fn escape_tag_value(v: \u0026Type) -\u003e String {\n        use Type::*;\n        match v {\n            Boolean(v) =\u003e {\n                if *v {\n                    \"true\"\n                } else {\n                    \"false\"\n                }\n            }\n            .to_string(),\n            Float(v) =\u003e format!(r#\"{}\"#, v),\n            SignedInteger(v) =\u003e format!(r#\"{}\"#, v),\n            UnsignedInteger(v) =\u003e format!(r#\"{}\"#, v),\n            Text(v) =\u003e Self::escape_any(v, \u0026SLASHES),\n        }\n    }\n\n    fn escape_any(s: \u0026str, re: \u0026Regex) -\u003e String {\n        re.replace_all(s, r\"\\$0\").to_string()\n    }\n}\n\n#[cfg(test)]\nmod test {\n    use crate::query::line_proto_term::LineProtoTerm::*;\n    use crate::Type;\n\n    #[test]\n    fn test() {\n        assert_eq!(TagValue(\u0026Type::Boolean(true)).escape(), r#\"true\"#);\n        assert_eq!(TagValue(\u0026Type::Float(1.8324f64)).escape(), r#\"1.8324\"#);\n        assert_eq!(TagValue(\u0026Type::SignedInteger(-1i64)).escape(), r#\"-1\"#);\n        assert_eq!(TagValue(\u0026Type::UnsignedInteger(1u64)).escape(), r#\"1\"#);\n\n        assert_eq!(\n            TagValue(\u0026Type::Text(\"this is my special string\".into())).escape(),\n            r\"this\\ is\\ my\\ special\\ string\"\n        );\n        assert_eq!(\n            TagValue(\u0026Type::Text(\"a tag w=i th == tons of escapes\".into())).escape(),\n            r\"a\\ tag\\ w\\=i\\ th\\ \\=\\=\\ tons\\ of\\ escapes\"\n        );\n        assert_eq!(\n            TagValue(\u0026Type::Text(\"no_escapes\".into())).escape(),\n            r#\"no_escapes\"#\n        );\n        assert_eq!(\n            TagValue(\u0026Type::Text(\"some,commas,here\".into())).escape(),\n            r\"some\\,commas\\,here\"\n        );\n\n        assert_eq!(Measurement(r#\"wea\", ther\"#).escape(), r#\"wea\"\\,\\ ther\"#);\n        assert_eq!(TagKey(r\"locat\\ ,=ion\").escape(), r\"locat\\\\ \\,\\=ion\");\n\n        assert_eq!(FieldValue(\u0026Type::Boolean(true)).escape(), r#\"true\"#);\n        assert_eq!(FieldValue(\u0026Type::Boolean(false)).escape(), r#\"false\"#);\n\n        assert_eq!(FieldValue(\u0026Type::Float(0.0)).escape(), r#\"0\"#);\n        assert_eq!(FieldValue(\u0026Type::Float(-0.1)).escape(), r#\"-0.1\"#);\n\n        assert_eq!(FieldValue(\u0026Type::SignedInteger(0)).escape(), r#\"0i\"#);\n        assert_eq!(FieldValue(\u0026Type::SignedInteger(83)).escape(), r#\"83i\"#);\n\n        assert_eq!(FieldValue(\u0026Type::UnsignedInteger(0)).escape(), r#\"0i\"#);\n        assert_eq!(FieldValue(\u0026Type::UnsignedInteger(83)).escape(), r#\"83i\"#);\n\n        assert_eq!(FieldValue(\u0026Type::UnsignedInteger(0)).escape_v2(), r#\"0u\"#);\n        assert_eq!(FieldValue(\u0026Type::UnsignedInteger(83)).escape_v2(), r#\"83u\"#);\n\n        assert_eq!(FieldValue(\u0026Type::Text(\"\".into())).escape(), r#\"\"\"\"#);\n        assert_eq!(FieldValue(\u0026Type::Text(\"0\".into())).escape(), r#\"\"0\"\"#);\n        assert_eq!(FieldValue(\u0026Type::Text(\"\\\"\".into())).escape(), r#\"\"\\\"\"\"#);\n        assert_eq!(\n            FieldValue(\u0026Type::Text(r#\"locat\"\\ ,=ion\"#.into())).escape(),\n            r#\"\"locat\\\"\\\\ ,=ion\"\"#\n        );\n    }\n\n    #[test]\n    fn test_empty_tag_value() {\n        // InfluxDB doesn't support empty tag values. But that's a job\n        // of a calling site to validate an entire write request.\n        assert_eq!(TagValue(\u0026Type::Text(\"\".into())).escape(), r#\"\"#);\n    }\n}\n","traces":[{"line":6,"address":[7552032,7552057],"length":1,"stats":{"Line":6}},{"line":7,"address":[7012921,7012896],"length":1,"stats":{"Line":6}},{"line":8,"address":[2165904,2165929],"length":1,"stats":{"Line":2}},{"line":9,"address":[2166208,2166233],"length":1,"stats":{"Line":4}},{"line":20,"address":[7547680],"length":1,"stats":{"Line":3}},{"line":22,"address":[2160739,2160863,2160914],"length":1,"stats":{"Line":11}},{"line":23,"address":[7008279],"length":1,"stats":{"Line":3}},{"line":24,"address":[2160845,2160896,2160952],"length":1,"stats":{"Line":12}},{"line":25,"address":[7547887],"length":1,"stats":{"Line":3}},{"line":26,"address":[7008380],"length":1,"stats":{"Line":3}},{"line":30,"address":[7547984],"length":1,"stats":{"Line":1}},{"line":32,"address":[2161043,2161167,2161218],"length":1,"stats":{"Line":2}},{"line":33,"address":[2161079],"length":1,"stats":{"Line":2}},{"line":34,"address":[2161149,2161200,2161259],"length":1,"stats":{"Line":2}},{"line":35,"address":[2161230],"length":1,"stats":{"Line":1}},{"line":36,"address":[7548140],"length":1,"stats":{"Line":0}},{"line":40,"address":[2161328,2162341],"length":1,"stats":{"Line":3}},{"line":42,"address":[7008877],"length":1,"stats":{"Line":3}},{"line":43,"address":[2161817,2161438],"length":1,"stats":{"Line":2}},{"line":44,"address":[2161779,2161807,2161453],"length":1,"stats":{"Line":3}},{"line":45,"address":[2161781],"length":1,"stats":{"Line":1}},{"line":47,"address":[7548724],"length":1,"stats":{"Line":1}},{"line":51,"address":[7548438],"length":1,"stats":{"Line":1}},{"line":52,"address":[7548466],"length":1,"stats":{"Line":3}},{"line":53,"address":[2161635],"length":1,"stats":{"Line":1}},{"line":54,"address":[7009153],"length":1,"stats":{"Line":1}},{"line":55,"address":[2161964],"length":1,"stats":{"Line":1}},{"line":57,"address":[7548802],"length":1,"stats":{"Line":1}},{"line":60,"address":[7549058,7548627],"length":1,"stats":{"Line":1}},{"line":64,"address":[7009888],"length":1,"stats":{"Line":3}},{"line":66,"address":[7009918],"length":1,"stats":{"Line":3}},{"line":67,"address":[2162463,2163030],"length":1,"stats":{"Line":2}},{"line":68,"address":[7009998,7010515,7010543],"length":1,"stats":{"Line":2}},{"line":69,"address":[7010517],"length":1,"stats":{"Line":1}},{"line":71,"address":[2162971],"length":1,"stats":{"Line":0}},{"line":75,"address":[2162498],"length":1,"stats":{"Line":1}},{"line":76,"address":[2162624],"length":1,"stats":{"Line":1}},{"line":77,"address":[2162768],"length":1,"stats":{"Line":2}},{"line":78,"address":[2162913],"length":1,"stats":{"Line":2}},{"line":82,"address":[2163203,2163056],"length":1,"stats":{"Line":4}},{"line":83,"address":[2163101],"length":1,"stats":{"Line":4}}],"covered":39,"coverable":41},{"path":["/","home","runner","work","influxdb-rust","influxdb-rust","influxdb","src","query","mod.rs"],"content":"//! Used to create queries of type [`ReadQuery`](crate::query::read_query::ReadQuery) or\n//! [`WriteQuery`](crate::query::write_query::WriteQuery) which can be executed in InfluxDB\n//!\n//! # Examples\n//!\n//! ```rust\n//! use influxdb::{Query, Timestamp};\n//! use influxdb::InfluxDbWriteable;\n//!\n//! let write_query = Timestamp::Nanoseconds(0).into_query(\"measurement\")\n//!     .add_field(\"field1\", 5)\n//!     .add_tag(\"author\", \"Gero\")\n//!     .build();\n//!\n//! assert!(write_query.is_ok());\n//!\n//! let read_query = Query::raw_read_query(\"SELECT * FROM weather\")\n//!     .build();\n//!\n//! assert!(read_query.is_ok());\n//! ```\n\nuse chrono::prelude::{DateTime, TimeZone, Utc};\nuse std::convert::TryInto;\n\npub mod consts;\nmod line_proto_term;\npub mod read_query;\npub mod write_query;\nuse std::fmt;\n\nuse crate::{Error, ReadQuery, WriteQuery};\nuse consts::{\n    MILLIS_PER_SECOND, MINUTES_PER_HOUR, NANOS_PER_MICRO, NANOS_PER_MILLI, SECONDS_PER_MINUTE,\n};\n\n#[cfg(feature = \"derive\")]\npub use influxdb_derive::InfluxDbWriteable;\n\n#[derive(PartialEq, Eq, Debug, Copy, Clone)]\npub enum Timestamp {\n    Nanoseconds(u128),\n    Microseconds(u128),\n    Milliseconds(u128),\n    Seconds(u128),\n    Minutes(u128),\n    Hours(u128),\n}\n\nimpl fmt::Display for Timestamp {\n    fn fmt(\u0026self, f: \u0026mut fmt::Formatter\u003c'_\u003e) -\u003e fmt::Result {\n        use Timestamp::*;\n        match self {\n            Nanoseconds(ts) | Microseconds(ts) | Milliseconds(ts) | Seconds(ts) | Minutes(ts)\n            | Hours(ts) =\u003e write!(f, \"{}\", ts),\n        }\n    }\n}\n\nimpl From\u003cTimestamp\u003e for DateTime\u003cUtc\u003e {\n    fn from(ts: Timestamp) -\u003e DateTime\u003cUtc\u003e {\n        match ts {\n            Timestamp::Hours(h) =\u003e {\n                let nanos =\n                    h * MINUTES_PER_HOUR * SECONDS_PER_MINUTE * MILLIS_PER_SECOND * NANOS_PER_MILLI;\n                Utc.timestamp_nanos(nanos.try_into().unwrap())\n            }\n            Timestamp::Minutes(m) =\u003e {\n                let nanos = m * SECONDS_PER_MINUTE * MILLIS_PER_SECOND * NANOS_PER_MILLI;\n                Utc.timestamp_nanos(nanos.try_into().unwrap())\n            }\n            Timestamp::Seconds(s) =\u003e {\n                let nanos = s * MILLIS_PER_SECOND * NANOS_PER_MILLI;\n                Utc.timestamp_nanos(nanos.try_into().unwrap())\n            }\n            Timestamp::Milliseconds(millis) =\u003e {\n                let nanos = millis * NANOS_PER_MILLI;\n                Utc.timestamp_nanos(nanos.try_into().unwrap())\n            }\n            Timestamp::Nanoseconds(nanos) =\u003e Utc.timestamp_nanos(nanos.try_into().unwrap()),\n            Timestamp::Microseconds(micros) =\u003e {\n                let nanos = micros * NANOS_PER_MICRO;\n                Utc.timestamp_nanos(nanos.try_into().unwrap())\n            }\n        }\n    }\n}\n\nimpl\u003cT\u003e From\u003cDateTime\u003cT\u003e\u003e for Timestamp\nwhere\n    T: TimeZone,\n{\n    fn from(date_time: DateTime\u003cT\u003e) -\u003e Self {\n        Timestamp::Nanoseconds(date_time.timestamp_nanos_opt().unwrap() as u128)\n    }\n}\n\npub trait Query {\n    /// Builds valid InfluxSQL which can be run against the Database.\n    /// In case no fields have been specified, it will return an error,\n    /// as that is invalid InfluxSQL syntax.\n    ///\n    /// # Examples\n    ///\n    /// ```rust\n    /// use influxdb::{Query, Timestamp};\n    /// use influxdb::InfluxDbWriteable;\n    ///\n    /// let invalid_query = Timestamp::Nanoseconds(0).into_query(\"measurement\").build();\n    /// assert!(invalid_query.is_err());\n    ///\n    /// let valid_query = Timestamp::Nanoseconds(0).into_query(\"measurement\").add_field(\"myfield1\", 11).build();\n    /// assert!(valid_query.is_ok());\n    /// ```\n    fn build(\u0026self) -\u003e Result\u003cValidQuery, Error\u003e;\n\n    /// Like [build] but with additional support for unsigned integers in the line protocol.\n    /// Please note, this crate can only interact with InfluxDB 2.0 in compatibility mode\n    /// and does not natively support InfluxDB 2.0.\n    ///\n    /// # Examples\n    ///\n    /// ```rust\n    /// use influxdb::{Query, Timestamp};\n    /// use influxdb::InfluxDbWriteable;\n    ///\n    /// let use_v2 = true;\n    ///\n    /// let invalid_query = Timestamp::Nanoseconds(0).into_query(\"measurement\").build_with_opts(use_v2);\n    /// assert!(invalid_query.is_err());\n    ///\n    /// let valid_query = Timestamp::Nanoseconds(0).into_query(\"measurement\").add_field(\"myfield1\", 11).build_with_opts(use_v2);\n    /// assert!(valid_query.is_ok());\n    /// ```\n    fn build_with_opts(\u0026self, use_v2: bool) -\u003e Result\u003cValidQuery, Error\u003e;\n\n    fn get_type(\u0026self) -\u003e QueryType;\n}\n\nimpl\u003cQ: Query\u003e Query for \u0026Q {\n    fn build(\u0026self) -\u003e Result\u003cValidQuery, Error\u003e {\n        Q::build_with_opts(self, false)\n    }\n\n    fn build_with_opts(\u0026self, use_v2: bool) -\u003e Result\u003cValidQuery, Error\u003e {\n        Q::build_with_opts(self, use_v2)\n    }\n\n    fn get_type(\u0026self) -\u003e QueryType {\n        Q::get_type(self)\n    }\n}\n\nimpl\u003cQ: Query\u003e Query for Box\u003cQ\u003e {\n    fn build(\u0026self) -\u003e Result\u003cValidQuery, Error\u003e {\n        Q::build(self)\n    }\n\n    fn build_with_opts(\u0026self, use_v2: bool) -\u003e Result\u003cValidQuery, Error\u003e {\n        Q::build_with_opts(self, use_v2)\n    }\n\n    fn get_type(\u0026self) -\u003e QueryType {\n        Q::get_type(self)\n    }\n}\n\npub trait InfluxDbWriteable {\n    fn into_query\u003cI: Into\u003cString\u003e\u003e(self, name: I) -\u003e WriteQuery;\n}\n\nimpl InfluxDbWriteable for Timestamp {\n    fn into_query\u003cI: Into\u003cString\u003e\u003e(self, name: I) -\u003e WriteQuery {\n        WriteQuery::new(self, name.into())\n    }\n}\n\nimpl dyn Query {\n    /// Returns a [`ReadQuery`](crate::ReadQuery) builder.\n    ///\n    /// # Examples\n    ///\n    /// ```rust\n    /// use influxdb::Query;\n    ///\n    /// Query::raw_read_query(\"SELECT * FROM weather\"); // Is of type [`ReadQuery`](crate::ReadQuery)\n    /// ```\n    #[deprecated(since = \"0.5.0\", note = \"Use ReadQuery::new instead\")]\n    pub fn raw_read_query\u003cS\u003e(read_query: S) -\u003e ReadQuery\n    where\n        S: Into\u003cString\u003e,\n    {\n        ReadQuery::new(read_query)\n    }\n}\n\n#[derive(Debug)]\n#[doc(hidden)]\npub struct ValidQuery(String);\nimpl ValidQuery {\n    pub fn get(self) -\u003e String {\n        self.0\n    }\n}\nimpl\u003cT\u003e From\u003cT\u003e for ValidQuery\nwhere\n    T: Into\u003cString\u003e,\n{\n    fn from(string: T) -\u003e Self {\n        Self(string.into())\n    }\n}\nimpl PartialEq\u003cString\u003e for ValidQuery {\n    fn eq(\u0026self, other: \u0026String) -\u003e bool {\n        \u0026self.0 == other\n    }\n}\nimpl PartialEq\u003c\u0026str\u003e for ValidQuery {\n    fn eq(\u0026self, other: \u0026\u0026str) -\u003e bool {\n        \u0026self.0 == other\n    }\n}\n\n/// Internal Enum used to decide if a `POST` or `GET` request should be sent to InfluxDB. See [InfluxDB Docs](https://docs.influxdata.com/influxdb/v1.7/tools/api/#query-http-endpoint).\n#[derive(PartialEq, Eq, Debug)]\npub enum QueryType {\n    ReadQuery,\n    /// write query with precision\n    WriteQuery(String),\n}\n\n#[cfg(test)]\nmod tests {\n    use super::consts::{\n        MILLIS_PER_SECOND, MINUTES_PER_HOUR, NANOS_PER_MICRO, NANOS_PER_MILLI, SECONDS_PER_MINUTE,\n    };\n    use crate::query::{Timestamp, ValidQuery};\n    use chrono::prelude::{DateTime, TimeZone, Utc};\n    use std::convert::TryInto;\n    #[test]\n    fn test_equality_str() {\n        assert_eq!(ValidQuery::from(\"hello\"), \"hello\");\n    }\n    #[test]\n    fn test_equality_string() {\n        assert_eq!(\n            ValidQuery::from(String::from(\"hello\")),\n            String::from(\"hello\")\n        );\n    }\n    #[test]\n    fn test_format_for_timestamp_else() {\n        assert!(format!(\"{}\", Timestamp::Nanoseconds(100)) == \"100\");\n    }\n    #[test]\n    fn test_chrono_datetime_from_timestamp_hours() {\n        let datetime_from_timestamp: DateTime\u003cUtc\u003e = Timestamp::Hours(2).into();\n        assert_eq!(\n            Utc.timestamp_nanos(\n                (2 * MINUTES_PER_HOUR * SECONDS_PER_MINUTE * MILLIS_PER_SECOND * NANOS_PER_MILLI)\n                    .try_into()\n                    .unwrap()\n            ),\n            datetime_from_timestamp\n        )\n    }\n    #[test]\n    fn test_chrono_datetime_from_timestamp_minutes() {\n        let datetime_from_timestamp: DateTime\u003cUtc\u003e = Timestamp::Minutes(2).into();\n        assert_eq!(\n            Utc.timestamp_nanos(\n                (2 * SECONDS_PER_MINUTE * MILLIS_PER_SECOND * NANOS_PER_MILLI)\n                    .try_into()\n                    .unwrap()\n            ),\n            datetime_from_timestamp\n        )\n    }\n    #[test]\n    fn test_chrono_datetime_from_timestamp_seconds() {\n        let datetime_from_timestamp: DateTime\u003cUtc\u003e = Timestamp::Seconds(2).into();\n        assert_eq!(\n            Utc.timestamp_nanos(\n                (2 * MILLIS_PER_SECOND * NANOS_PER_MILLI)\n                    .try_into()\n                    .unwrap()\n            ),\n            datetime_from_timestamp\n        )\n    }\n    #[test]\n    fn test_chrono_datetime_from_timestamp_millis() {\n        let datetime_from_timestamp: DateTime\u003cUtc\u003e = Timestamp::Milliseconds(2).into();\n        assert_eq!(\n            Utc.timestamp_nanos((2 * NANOS_PER_MILLI).try_into().unwrap()),\n            datetime_from_timestamp\n        )\n    }\n    #[test]\n    fn test_chrono_datetime_from_timestamp_nanos() {\n        let datetime_from_timestamp: DateTime\u003cUtc\u003e = Timestamp::Nanoseconds(1).into();\n        assert_eq!(Utc.timestamp_nanos(1), datetime_from_timestamp)\n    }\n    #[test]\n    fn test_chrono_datetime_from_timestamp_micros() {\n        let datetime_from_timestamp: DateTime\u003cUtc\u003e = Timestamp::Microseconds(2).into();\n        assert_eq!(\n            Utc.timestamp_nanos((2 * NANOS_PER_MICRO).try_into().unwrap()),\n            datetime_from_timestamp\n        )\n    }\n    #[test]\n    fn test_timestamp_from_chrono_date() {\n        let timestamp_from_datetime: Timestamp = Utc\n            .with_ymd_and_hms(1970, 1, 1, 0, 0, 1)\n            .single()\n            .unwrap()\n            .into();\n        assert_eq!(\n            Timestamp::Nanoseconds(MILLIS_PER_SECOND * NANOS_PER_MILLI),\n            timestamp_from_datetime\n        )\n    }\n}\n","traces":[{"line":51,"address":[7530592],"length":1,"stats":{"Line":3}},{"line":53,"address":[2070219,2070267,2070235,2070203,2070158,2070251],"length":1,"stats":{"Line":6}},{"line":54,"address":[2070274],"length":1,"stats":{"Line":1}},{"line":61,"address":[7010752],"length":1,"stats":{"Line":2}},{"line":62,"address":[7550263],"length":1,"stats":{"Line":2}},{"line":63,"address":[7011420],"length":1,"stats":{"Line":2}},{"line":64,"address":[7011465,7012237,7012551],"length":1,"stats":{"Line":4}},{"line":66,"address":[2072107],"length":1,"stats":{"Line":2}},{"line":68,"address":[2070914],"length":1,"stats":{"Line":1}},{"line":69,"address":[7550800,7551430,7551664],"length":1,"stats":{"Line":2}},{"line":70,"address":[2071765],"length":1,"stats":{"Line":1}},{"line":72,"address":[2070793],"length":1,"stats":{"Line":1}},{"line":73,"address":[2070838,2071557,2071386],"length":1,"stats":{"Line":2}},{"line":74,"address":[2071503],"length":1,"stats":{"Line":1}},{"line":76,"address":[7011057],"length":1,"stats":{"Line":1}},{"line":77,"address":[7550558,7551129,7551200],"length":1,"stats":{"Line":2}},{"line":78,"address":[7011689],"length":1,"stats":{"Line":1}},{"line":80,"address":[2070465],"length":1,"stats":{"Line":2}},{"line":81,"address":[2070551],"length":1,"stats":{"Line":1}},{"line":82,"address":[7011573,7010981,7011641],"length":1,"stats":{"Line":2}},{"line":83,"address":[2071204],"length":1,"stats":{"Line":1}},{"line":93,"address":[],"length":0,"stats":{"Line":2}},{"line":94,"address":[2072219,2072276],"length":1,"stats":{"Line":4}},{"line":141,"address":[],"length":0,"stats":{"Line":1}},{"line":142,"address":[],"length":0,"stats":{"Line":1}},{"line":145,"address":[],"length":0,"stats":{"Line":0}},{"line":146,"address":[],"length":0,"stats":{"Line":0}},{"line":149,"address":[],"length":0,"stats":{"Line":1}},{"line":150,"address":[],"length":0,"stats":{"Line":1}},{"line":155,"address":[],"length":0,"stats":{"Line":0}},{"line":156,"address":[],"length":0,"stats":{"Line":0}},{"line":159,"address":[],"length":0,"stats":{"Line":0}},{"line":160,"address":[],"length":0,"stats":{"Line":0}},{"line":163,"address":[],"length":0,"stats":{"Line":0}},{"line":164,"address":[],"length":0,"stats":{"Line":0}},{"line":173,"address":[],"length":0,"stats":{"Line":5}},{"line":174,"address":[],"length":0,"stats":{"Line":5}},{"line":193,"address":[],"length":0,"stats":{"Line":0}},{"line":201,"address":[6991376],"length":1,"stats":{"Line":5}},{"line":202,"address":[2072659],"length":1,"stats":{"Line":6}},{"line":209,"address":[],"length":0,"stats":{"Line":2}},{"line":210,"address":[],"length":0,"stats":{"Line":2}},{"line":214,"address":[7530864],"length":1,"stats":{"Line":1}},{"line":215,"address":[2072877],"length":1,"stats":{"Line":1}},{"line":219,"address":[2072912],"length":1,"stats":{"Line":1}},{"line":220,"address":[2072925],"length":1,"stats":{"Line":1}}],"covered":37,"coverable":46},{"path":["/","home","runner","work","influxdb-rust","influxdb-rust","influxdb","src","query","read_query.rs"],"content":"//! Read Query Builder returned by Query::raw_read_query\n//!\n//! Can only be instantiated by using Query::raw_read_query\n\nuse crate::query::{QueryType, ValidQuery};\nuse crate::{Error, Query};\n\n#[derive(Debug, Clone)]\npub struct ReadQuery {\n    queries: Vec\u003cString\u003e,\n}\n\nimpl ReadQuery {\n    /// Creates a new [`ReadQuery`]\n    #[must_use = \"Creating a query is pointless unless you execute it\"]\n    pub fn new\u003cS\u003e(query: S) -\u003e Self\n    where\n        S: Into\u003cString\u003e,\n    {\n        ReadQuery {\n            queries: vec![query.into()],\n        }\n    }\n\n    /// Adds a query to the [`ReadQuery`]\n    #[must_use = \"Creating a query is pointless unless you execute it\"]\n    pub fn add_query\u003cS\u003e(mut self, query: S) -\u003e Self\n    where\n        S: Into\u003cString\u003e,\n    {\n        self.queries.push(query.into());\n        self\n    }\n}\n\nimpl Query for ReadQuery {\n    fn build(\u0026self) -\u003e Result\u003cValidQuery, Error\u003e {\n        Ok(ValidQuery(self.queries.join(\";\")))\n    }\n\n    fn build_with_opts(\u0026self, _use_v2: bool) -\u003e Result\u003cValidQuery, Error\u003e {\n        Ok(ValidQuery(self.queries.join(\";\")))\n    }\n\n    fn get_type(\u0026self) -\u003e QueryType {\n        QueryType::ReadQuery\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use crate::query::{Query, QueryType, ReadQuery};\n\n    #[test]\n    fn test_read_builder_single_query() {\n        let query = ReadQuery::new(\"SELECT * FROM aachen\").build();\n\n        assert_eq!(query.unwrap(), \"SELECT * FROM aachen\");\n    }\n\n    #[test]\n    fn test_read_builder_multi_query() {\n        let query = ReadQuery::new(\"SELECT * FROM aachen\")\n            .add_query(\"SELECT * FROM cologne\")\n            .build();\n\n        assert_eq!(query.unwrap(), \"SELECT * FROM aachen;SELECT * FROM cologne\");\n    }\n\n    #[test]\n    fn test_correct_query_type() {\n        let query = ReadQuery::new(\"SELECT * FROM aachen\");\n\n        assert_eq!(query.get_type(), QueryType::ReadQuery);\n    }\n}\n","traces":[{"line":16,"address":[2031872,2032253,2032239],"length":1,"stats":{"Line":8}},{"line":21,"address":[],"length":0,"stats":{"Line":14}},{"line":27,"address":[2032448,2032272],"length":1,"stats":{"Line":2}},{"line":31,"address":[],"length":0,"stats":{"Line":4}},{"line":32,"address":[2032421],"length":1,"stats":{"Line":2}},{"line":37,"address":[2032480],"length":1,"stats":{"Line":7}},{"line":38,"address":[2032512],"length":1,"stats":{"Line":7}},{"line":41,"address":[2032624],"length":1,"stats":{"Line":0}},{"line":42,"address":[2032662],"length":1,"stats":{"Line":0}},{"line":45,"address":[2032784],"length":1,"stats":{"Line":6}},{"line":46,"address":[2032792],"length":1,"stats":{"Line":6}}],"covered":9,"coverable":11},{"path":["/","home","runner","work","influxdb-rust","influxdb-rust","influxdb","src","query","write_query.rs"],"content":"//! Write Query Builder returned by Query::write_query\n//!\n//! Can only be instantiated by using Query::write_query\n\nuse crate::query::line_proto_term::LineProtoTerm;\nuse crate::query::{QueryType, ValidQuery};\nuse crate::{Error, Query, Timestamp};\nuse std::fmt::{Display, Formatter};\n\npub trait WriteType {\n    fn add_to(self, tag: String, fields_or_tags: \u0026mut Vec\u003c(String, Type)\u003e);\n}\n\nimpl\u003cT: Into\u003cType\u003e\u003e WriteType for T {\n    fn add_to(self, tag: String, fields_or_tags: \u0026mut Vec\u003c(String, Type)\u003e) {\n        let val: Type = self.into();\n        fields_or_tags.push((tag, val));\n    }\n}\n\nimpl\u003cT: Into\u003cType\u003e\u003e WriteType for Option\u003cT\u003e {\n    fn add_to(self, tag: String, fields_or_tags: \u0026mut Vec\u003c(String, Type)\u003e) {\n        if let Some(val) = self {\n            val.add_to(tag, fields_or_tags);\n        }\n    }\n}\n\n/// Internal Representation of a Write query that has not yet been built\n#[derive(Debug, Clone)]\npub struct WriteQuery {\n    fields: Vec\u003c(String, Type)\u003e,\n    tags: Vec\u003c(String, Type)\u003e,\n    measurement: String,\n    timestamp: Timestamp,\n}\n\nimpl WriteQuery {\n    /// Creates a new [`WriteQuery`](crate::query::write_query::WriteQuery)\n    #[must_use = \"Creating a query is pointless unless you execute it\"]\n    pub fn new\u003cS\u003e(timestamp: Timestamp, measurement: S) -\u003e Self\n    where\n        S: Into\u003cString\u003e,\n    {\n        WriteQuery {\n            fields: vec![],\n            tags: vec![],\n            measurement: measurement.into(),\n            timestamp,\n        }\n    }\n\n    /// Adds a field to the [`WriteQuery`](crate::WriteQuery)\n    ///\n    /// # Examples\n    ///\n    /// ```rust\n    /// use influxdb::{Query, Timestamp};\n    /// use influxdb::InfluxDbWriteable;\n    ///\n    /// Timestamp::Nanoseconds(0).into_query(\"measurement\").add_field(\"field1\", 5).build();\n    /// ```\n    #[must_use = \"Creating a query is pointless unless you execute it\"]\n    pub fn add_field\u003cS, F\u003e(mut self, field: S, value: F) -\u003e Self\n    where\n        S: Into\u003cString\u003e,\n        F: WriteType,\n    {\n        value.add_to(field.into(), \u0026mut self.fields);\n        self\n    }\n\n    /// Adds a tag to the [`WriteQuery`](crate::WriteQuery)\n    ///\n    /// Please note that a [`WriteQuery`](crate::WriteQuery) requires at least one field. Composing a query with\n    /// only tags will result in a failure building the query.\n    ///\n    /// # Examples\n    ///\n    /// ```rust\n    /// use influxdb::{Query, Timestamp};\n    /// use influxdb::InfluxDbWriteable;\n    ///\n    /// Timestamp::Nanoseconds(0)\n    ///     .into_query(\"measurement\")\n    ///     .add_tag(\"field1\", 5); // calling `.build()` now would result in a `Err(Error::InvalidQueryError)`\n    /// ```\n    #[must_use = \"Creating a query is pointless unless you execute it\"]\n    pub fn add_tag\u003cS, I\u003e(mut self, tag: S, value: I) -\u003e Self\n    where\n        S: Into\u003cString\u003e,\n        I: WriteType,\n    {\n        value.add_to(tag.into(), \u0026mut self.tags);\n        self\n    }\n\n    pub fn get_precision(\u0026self) -\u003e String {\n        let modifier = match self.timestamp {\n            Timestamp::Nanoseconds(_) =\u003e \"ns\",\n            Timestamp::Microseconds(_) =\u003e \"u\",\n            Timestamp::Milliseconds(_) =\u003e \"ms\",\n            Timestamp::Seconds(_) =\u003e \"s\",\n            Timestamp::Minutes(_) =\u003e \"m\",\n            Timestamp::Hours(_) =\u003e \"h\",\n        };\n        modifier.to_string()\n    }\n}\n\n#[derive(Debug, Clone)]\npub enum Type {\n    Boolean(bool),\n    Float(f64),\n    SignedInteger(i64),\n    UnsignedInteger(u64),\n    Text(String),\n}\n\nimpl Display for Type {\n    fn fmt(\u0026self, f: \u0026mut Formatter) -\u003e std::fmt::Result {\n        use Type::*;\n\n        match self {\n            Boolean(x) =\u003e write!(f, \"{}\", x),\n            Float(x) =\u003e write!(f, \"{}\", x),\n            SignedInteger(x) =\u003e write!(f, \"{}\", x),\n            UnsignedInteger(x) =\u003e write!(f, \"{}\", x),\n            Text(text) =\u003e write!(f, \"{text}\", text = text),\n        }\n    }\n}\n\nmacro_rules! from_impl {\n        ( $variant:ident =\u003e $( $typ:ident ),+ ) =\u003e (\n                $(\n                    impl From\u003c$typ\u003e for Type {\n                        fn from(b: $typ) -\u003e Self {\n                            Type::$variant(b.into())\n                        }\n                    }\n                )+\n        )\n}\nfrom_impl! {Boolean =\u003e bool}\nfrom_impl! {Float =\u003e f32, f64}\nfrom_impl! {SignedInteger =\u003e i8, i16, i32, i64}\nfrom_impl! {UnsignedInteger =\u003e u8, u16, u32, u64}\nfrom_impl! {Text =\u003e String}\nimpl From\u003c\u0026str\u003e for Type {\n    fn from(b: \u0026str) -\u003e Self {\n        Type::Text(b.into())\n    }\n}\nimpl\u003cT\u003e From\u003c\u0026T\u003e for Type\nwhere\n    T: Copy + Into\u003cType\u003e,\n{\n    fn from(t: \u0026T) -\u003e Self {\n        (*t).into()\n    }\n}\n\nimpl Query for WriteQuery {\n    fn build(\u0026self) -\u003e Result\u003cValidQuery, Error\u003e {\n        self.build_with_opts(false)\n    }\n\n    fn build_with_opts(\u0026self, use_v2: bool) -\u003e Result\u003cValidQuery, Error\u003e {\n        if self.fields.is_empty() {\n            return Err(Error::InvalidQueryError {\n                error: \"fields cannot be empty\".to_string(),\n            });\n        }\n\n        let mut tags = self\n            .tags\n            .iter()\n            .map(|(tag, value)| {\n                let escaped_tag_key = if use_v2 {\n                    LineProtoTerm::TagKey(tag).escape_v2()\n                } else {\n                    LineProtoTerm::TagKey(tag).escape()\n                };\n                let escaped_tag_value = if use_v2 {\n                    LineProtoTerm::TagValue(value).escape_v2()\n                } else {\n                    LineProtoTerm::TagValue(value).escape()\n                };\n                format!(\n                    \"{tag}={value}\",\n                    tag = escaped_tag_key,\n                    value = escaped_tag_value,\n                )\n            })\n            .collect::\u003cVec\u003cString\u003e\u003e()\n            .join(\",\");\n\n        if !tags.is_empty() {\n            tags.insert(0, ',');\n        }\n        let fields = self\n            .fields\n            .iter()\n            .map(|(field, value)| {\n                let escaped_field_key = if use_v2 {\n                    LineProtoTerm::FieldKey(field).escape_v2()\n                } else {\n                    LineProtoTerm::FieldKey(field).escape()\n                };\n                let escaped_field_value = if use_v2 {\n                    LineProtoTerm::FieldValue(value).escape_v2()\n                } else {\n                    LineProtoTerm::FieldValue(value).escape()\n                };\n                format!(\n                    \"{field}={value}\",\n                    field = escaped_field_key,\n                    value = escaped_field_value,\n                )\n            })\n            .collect::\u003cVec\u003cString\u003e\u003e()\n            .join(\",\");\n\n        let escaped_measurement = if use_v2 {\n            LineProtoTerm::Measurement(\u0026self.measurement).escape_v2()\n        } else {\n            LineProtoTerm::Measurement(\u0026self.measurement).escape()\n        };\n\n        Ok(ValidQuery(format!(\n            \"{measurement}{tags} {fields} {time}\",\n            measurement = escaped_measurement,\n            tags = tags,\n            fields = fields,\n            time = self.timestamp\n        )))\n    }\n\n    fn get_type(\u0026self) -\u003e QueryType {\n        QueryType::WriteQuery(self.get_precision())\n    }\n}\n\nimpl Query for Vec\u003cWriteQuery\u003e {\n    fn build(\u0026self) -\u003e Result\u003cValidQuery, Error\u003e {\n        let mut qlines = Vec::new();\n\n        for q in self {\n            let valid_query = q.build()?;\n            qlines.push(valid_query.0);\n        }\n\n        Ok(ValidQuery(qlines.join(\"\\n\")))\n    }\n\n    fn build_with_opts(\u0026self, use_v2: bool) -\u003e Result\u003cValidQuery, Error\u003e {\n        let mut qlines = Vec::new();\n\n        for q in self {\n            let valid_query = q.build_with_opts(use_v2)?;\n            qlines.push(valid_query.0);\n        }\n\n        Ok(ValidQuery(qlines.join(\"\\n\")))\n    }\n\n    fn get_type(\u0026self) -\u003e QueryType {\n        QueryType::WriteQuery(\n            self.first()\n                .map(|q| q.get_precision())\n                // use \"ms\" as placeholder if query is empty\n                .unwrap_or_else(|| \"ms\".to_owned()),\n        )\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use crate::query::{InfluxDbWriteable, Query, Timestamp};\n\n    #[test]\n    fn test_write_builder_empty_query() {\n        let query = Timestamp::Hours(5)\n            .into_query(\"marina_3\".to_string())\n            .build();\n\n        assert!(query.is_err(), \"Query was not empty\");\n    }\n\n    #[test]\n    fn test_write_builder_single_field() {\n        let query = Timestamp::Hours(11)\n            .into_query(\"weather\".to_string())\n            .add_field(\"temperature\", 82)\n            .build();\n\n        assert!(query.is_ok(), \"Query was empty\");\n        assert_eq!(query.unwrap(), \"weather temperature=82i 11\");\n    }\n\n    #[test]\n    fn test_write_builder_multiple_fields() {\n        let query = Timestamp::Hours(11)\n            .into_query(\"weather\".to_string())\n            .add_field(\"temperature\", 82)\n            .add_field(\"wind_strength\", 3.7)\n            .add_field(\"temperature_unsigned\", 82u64)\n            .build();\n\n        assert!(query.is_ok(), \"Query was empty\");\n        assert_eq!(\n            query.unwrap(),\n            \"weather temperature=82i,wind_strength=3.7,temperature_unsigned=82i 11\"\n        );\n    }\n\n    #[test]\n    fn test_write_builder_multiple_fields_with_v2() {\n        let query = Timestamp::Hours(11)\n            .into_query(\"weather\".to_string())\n            .add_field(\"temperature\", 82)\n            .add_field(\"wind_strength\", 3.7)\n            .add_field(\"temperature_unsigned\", 82u64)\n            .build_with_opts(true);\n\n        assert!(query.is_ok(), \"Query was empty\");\n        assert_eq!(\n            query.unwrap(),\n            \"weather temperature=82i,wind_strength=3.7,temperature_unsigned=82u 11\"\n        );\n    }\n\n    #[test]\n    fn test_write_builder_optional_fields() {\n        let query = Timestamp::Hours(11)\n            .into_query(\"weather\".to_string())\n            .add_field(\"temperature\", 82u64)\n            .add_tag(\"wind_strength\", \u003cOption\u003cu64\u003e\u003e::None)\n            .build();\n\n        assert!(query.is_ok(), \"Query was empty\");\n        assert_eq!(query.unwrap(), \"weather temperature=82i 11\");\n    }\n\n    #[test]\n    fn test_write_builder_optional_fields_with_v2() {\n        let query = Timestamp::Hours(11)\n            .into_query(\"weather\".to_string())\n            .add_field(\"temperature\", 82u64)\n            .add_tag(\"wind_strength\", \u003cOption\u003cu64\u003e\u003e::None)\n            .build_with_opts(true);\n\n        assert!(query.is_ok(), \"Query was empty\");\n        assert_eq!(query.unwrap(), \"weather temperature=82u 11\");\n    }\n\n    #[test]\n    fn test_write_builder_only_tags() {\n        let query = Timestamp::Hours(11)\n            .into_query(\"weather\".to_string())\n            .add_tag(\"season\", \"summer\")\n            .build();\n\n        assert!(query.is_err(), \"Query missing one or more fields\");\n    }\n\n    #[test]\n    fn test_write_builder_full_query() {\n        let query = Timestamp::Hours(11)\n            .into_query(\"weather\".to_string())\n            .add_field(\"temperature\", 82)\n            .add_tag(\"location\", \"us-midwest\")\n            .add_tag(\"season\", \"summer\")\n            .build();\n\n        assert!(query.is_ok(), \"Query was empty\");\n        assert_eq!(\n            query.unwrap(),\n            r#\"weather,location=us-midwest,season=summer temperature=82i 11\"#\n        );\n    }\n\n    #[test]\n    fn test_correct_query_type() {\n        use crate::query::QueryType;\n\n        let query = Timestamp::Hours(11)\n            .into_query(\"weather\".to_string())\n            .add_field(\"temperature\", 82)\n            .add_tag(\"location\", \"us-midwest\")\n            .add_tag(\"season\", \"summer\");\n\n        assert_eq!(query.get_type(), QueryType::WriteQuery(\"h\".to_owned()));\n    }\n\n    #[test]\n    fn test_escaping() {\n        let query = Timestamp::Hours(11)\n            .into_query(\"wea, ther=\")\n            .add_field(\"temperature\", 82)\n            .add_field(\"\\\"temp=era,t ure\\\"\", r#\"too\"\\\\hot\"#)\n            .add_field(\"float\", 82.0)\n            .add_tag(\"location\", \"us-midwest\")\n            .add_tag(\"loc, =\\\"ation\", r#\"us, \"mid=west\"#)\n            .build();\n\n        assert!(query.is_ok(), \"Query was empty\");\n        let query_res = query.unwrap().get();\n        assert_eq!(\n            query_res,\n            r#\"wea\\,\\ ther=,location=us-midwest,loc\\,\\ \\=\"ation=us\\,\\ \\\"mid\\=west temperature=82i,\"temp\\=era\\,t\\ ure\"=\"too\\\"\\\\\\\\hot\",float=82 11\"#\n        );\n    }\n\n    #[test]\n    fn test_batch() {\n        let q0 = Timestamp::Hours(11)\n            .into_query(\"weather\")\n            .add_field(\"temperature\", 82)\n            .add_tag(\"location\", \"us-midwest\");\n\n        let q1 = Timestamp::Hours(12)\n            .into_query(\"weather\")\n            .add_field(\"temperature\", 65)\n            .add_tag(\"location\", \"us-midwest\");\n\n        let query = vec![q0, q1].build();\n\n        assert_eq!(\n            query.unwrap().get(),\n            r#\"weather,location=us-midwest temperature=82i 11\nweather,location=us-midwest temperature=65i 12\"#\n        );\n    }\n}\n","traces":[{"line":15,"address":[2033072,2033315,2033525,2033554,2033328,2033568,2033025,2033810,2033054,2033286,2032816,2033781],"length":1,"stats":{"Line":8}},{"line":16,"address":[2351826,2351575],"length":1,"stats":{"Line":10}},{"line":17,"address":[],"length":0,"stats":{"Line":8}},{"line":22,"address":[],"length":0,"stats":{"Line":3}},{"line":23,"address":[2769484],"length":1,"stats":{"Line":3}},{"line":24,"address":[2769605,2769536],"length":1,"stats":{"Line":2}},{"line":41,"address":[2959427,2959024],"length":1,"stats":{"Line":3}},{"line":46,"address":[2353897],"length":1,"stats":{"Line":4}},{"line":47,"address":[2033971],"length":1,"stats":{"Line":3}},{"line":48,"address":[2354020],"length":1,"stats":{"Line":4}},{"line":64,"address":[2034940,2034713,2034960,2035162,2034256,2034512,2034736,2034481],"length":1,"stats":{"Line":7}},{"line":69,"address":[2959793,2960195,2959932,2960045],"length":1,"stats":{"Line":8}},{"line":70,"address":[2034906,2034444,2034679,2035128],"length":1,"stats":{"Line":8}},{"line":89,"address":[2035409,2035665,2035184,2035440],"length":1,"stats":{"Line":5}},{"line":94,"address":[2035407,2035261,2035517,2035663],"length":1,"stats":{"Line":5}},{"line":95,"address":[2354460],"length":1,"stats":{"Line":5}},{"line":98,"address":[2035696],"length":1,"stats":{"Line":3}},{"line":99,"address":[2035715],"length":1,"stats":{"Line":3}},{"line":100,"address":[7491010],"length":1,"stats":{"Line":1}},{"line":101,"address":[6951577],"length":1,"stats":{"Line":0}},{"line":102,"address":[7491056],"length":1,"stats":{"Line":0}},{"line":103,"address":[6951623],"length":1,"stats":{"Line":0}},{"line":104,"address":[7491102],"length":1,"stats":{"Line":0}},{"line":105,"address":[7491125],"length":1,"stats":{"Line":2}},{"line":107,"address":[6951695],"length":1,"stats":{"Line":3}},{"line":121,"address":[7491184],"length":1,"stats":{"Line":0}},{"line":124,"address":[2035952],"length":1,"stats":{"Line":0}},{"line":125,"address":[6951824],"length":1,"stats":{"Line":0}},{"line":126,"address":[2036114],"length":1,"stats":{"Line":0}},{"line":127,"address":[2036235],"length":1,"stats":{"Line":0}},{"line":128,"address":[7491628],"length":1,"stats":{"Line":0}},{"line":129,"address":[6952297],"length":1,"stats":{"Line":0}},{"line":138,"address":[2045344,2045664,2045904,2045200,2045824,2045264,2045040,2045136,2045424,2045504,2045584,2045744],"length":1,"stats":{"Line":6}},{"line":139,"address":[6963155,6963773,6963685,6963284,6963365,6963536,6963219,6963065,6963917,6963856,6963604,6963453],"length":1,"stats":{"Line":7}},{"line":151,"address":[7491888],"length":1,"stats":{"Line":2}},{"line":152,"address":[7491911],"length":1,"stats":{"Line":3}},{"line":159,"address":[],"length":0,"stats":{"Line":0}},{"line":160,"address":[],"length":0,"stats":{"Line":0}},{"line":165,"address":[2036720],"length":1,"stats":{"Line":3}},{"line":166,"address":[2036737],"length":1,"stats":{"Line":3}},{"line":169,"address":[7492032,7493517],"length":1,"stats":{"Line":3}},{"line":170,"address":[2036829],"length":1,"stats":{"Line":3}},{"line":171,"address":[2036985],"length":1,"stats":{"Line":1}},{"line":172,"address":[7492232],"length":1,"stats":{"Line":1}},{"line":176,"address":[6952974,6952659],"length":1,"stats":{"Line":6}},{"line":179,"address":[2038240,2038282,2038790],"length":1,"stats":{"Line":6}},{"line":180,"address":[7493619],"length":1,"stats":{"Line":3}},{"line":181,"address":[6954220],"length":1,"stats":{"Line":0}},{"line":183,"address":[2038319],"length":1,"stats":{"Line":3}},{"line":185,"address":[2038408],"length":1,"stats":{"Line":3}},{"line":186,"address":[6954322,6954429],"length":1,"stats":{"Line":0}},{"line":188,"address":[2038421,2038547],"length":1,"stats":{"Line":7}},{"line":190,"address":[6954405,6954469],"length":1,"stats":{"Line":7}},{"line":199,"address":[7492533],"length":1,"stats":{"Line":4}},{"line":200,"address":[2037326,2037290],"length":1,"stats":{"Line":7}},{"line":202,"address":[2037338,2037494,2037305],"length":1,"stats":{"Line":14}},{"line":205,"address":[7494170,7494678,7494128],"length":1,"stats":{"Line":7}},{"line":206,"address":[6954739],"length":1,"stats":{"Line":5}},{"line":207,"address":[2038940],"length":1,"stats":{"Line":1}},{"line":209,"address":[2038895],"length":1,"stats":{"Line":5}},{"line":211,"address":[6954840],"length":1,"stats":{"Line":3}},{"line":212,"address":[6954898,6955005],"length":1,"stats":{"Line":2}},{"line":214,"address":[2038997,2039123],"length":1,"stats":{"Line":8}},{"line":216,"address":[6955045,6954981],"length":1,"stats":{"Line":8}},{"line":225,"address":[6953430],"length":1,"stats":{"Line":6}},{"line":226,"address":[2037757,2037636],"length":1,"stats":{"Line":3}},{"line":228,"address":[7492964,7492904],"length":1,"stats":{"Line":9}},{"line":231,"address":[2037854,2037720],"length":1,"stats":{"Line":8}},{"line":240,"address":[2039392],"length":1,"stats":{"Line":3}},{"line":241,"address":[2039411],"length":1,"stats":{"Line":3}},{"line":246,"address":[2163986,2163232,2163953],"length":1,"stats":{"Line":1}},{"line":247,"address":[2163262],"length":1,"stats":{"Line":1}},{"line":249,"address":[2163445,2163289,2163357,2163929],"length":1,"stats":{"Line":4}},{"line":250,"address":[6937247,6937446,6937066],"length":1,"stats":{"Line":2}},{"line":251,"address":[6937373],"length":1,"stats":{"Line":1}},{"line":254,"address":[6937028,6937097],"length":1,"stats":{"Line":2}},{"line":257,"address":[2164790,2164757,2164000],"length":1,"stats":{"Line":0}},{"line":258,"address":[6937677],"length":1,"stats":{"Line":0}},{"line":260,"address":[6937776,6937873,6937704,6938382],"length":1,"stats":{"Line":0}},{"line":261,"address":[2164631,2164446,2164246],"length":1,"stats":{"Line":0}},{"line":262,"address":[2164555],"length":1,"stats":{"Line":0}},{"line":265,"address":[2164203,2164280],"length":1,"stats":{"Line":0}},{"line":268,"address":[2164816],"length":1,"stats":{"Line":0}},{"line":270,"address":[2164848],"length":1,"stats":{"Line":0}},{"line":271,"address":[2039488,2039472],"length":1,"stats":{"Line":0}},{"line":273,"address":[2039504,2039516],"length":1,"stats":{"Line":0}}],"covered":61,"coverable":86},{"path":["/","home","runner","work","influxdb-rust","influxdb-rust","influxdb","tests","derive_integration_tests.rs"],"content":"#[path = \"./utilities.rs\"]\nmod utilities;\n\n#[cfg(feature = \"derive\")]\nuse influxdb::InfluxDbWriteable;\n\nuse chrono::{DateTime, Utc};\nuse influxdb::{Query, ReadQuery, Timestamp};\n\n#[cfg(feature = \"serde\")]\nuse serde_derive::Deserialize;\n\nuse utilities::{assert_result_ok, create_client, create_db, delete_db, run_test};\n\n#[derive(Debug, PartialEq)]\n#[cfg_attr(feature = \"derive\", derive(InfluxDbWriteable))]\nstruct WeatherReading {\n    time: DateTime\u003cUtc\u003e,\n    #[influxdb(ignore)]\n    humidity: i32,\n    pressure: i32,\n    #[influxdb(tag)]\n    wind_strength: Option\u003cu64\u003e,\n}\n\n#[derive(Debug)]\n#[cfg_attr(feature = \"serde\", derive(Deserialize))]\nstruct WeatherReadingWithoutIgnored {\n    time: DateTime\u003cUtc\u003e,\n    pressure: i32,\n    wind_strength: Option\u003cu64\u003e,\n}\n\n#[test]\nfn test_build_query() {\n    let weather_reading = WeatherReading {\n        time: Timestamp::Hours(1).into(),\n        humidity: 30,\n        pressure: 100,\n        wind_strength: Some(5),\n    };\n    let query = weather_reading.into_query(\"weather_reading\");\n    let query = query.build().unwrap();\n    assert_eq!(\n        query.get(),\n        \"weather_reading,wind_strength=5 pressure=100i 3600000000000\"\n    );\n}\n\n#[cfg(feature = \"derive\")]\n/// INTEGRATION TEST\n///\n/// This integration tests that writing data and retrieving the data again is working\n#[async_std::test]\n#[cfg(not(tarpaulin_include))]\nasync fn test_derive_simple_write() {\n    const TEST_NAME: \u0026str = \"test_derive_simple_write\";\n\n    run_test(\n        || async move {\n            create_db(TEST_NAME).await.expect(\"could not setup db\");\n            let client = create_client(TEST_NAME);\n            let weather_reading = WeatherReading {\n                time: Timestamp::Nanoseconds(0).into(),\n                humidity: 30,\n                wind_strength: Some(5),\n                pressure: 100,\n            };\n            let query = weather_reading.into_query(\"weather_reading\");\n            let result = client.query(\u0026query).await;\n            assert!(result.is_ok(), \"unable to insert into db\");\n        },\n        || async move {\n            delete_db(TEST_NAME).await.expect(\"could not clean up db\");\n        },\n    )\n    .await;\n}\n\n/// INTEGRATION TEST\n///\n/// This integration tests that writing data and retrieving the data again is working\n#[cfg(feature = \"derive\")]\n#[cfg(feature = \"serde\")]\n#[async_std::test]\n#[cfg(not(tarpaulin_include))]\nasync fn test_write_and_read_option() {\n    const TEST_NAME: \u0026str = \"test_write_and_read_option\";\n\n    run_test(\n        || async move {\n            create_db(TEST_NAME).await.expect(\"could not setup db\");\n            let client = create_client(TEST_NAME);\n            let weather_reading = WeatherReading {\n                time: Timestamp::Hours(11).into(),\n                humidity: 30,\n                wind_strength: None,\n                pressure: 100,\n            };\n            let write_result = client\n                .query(\u0026weather_reading.into_query(\"weather_reading\".to_string()))\n                .await;\n            assert_result_ok(\u0026write_result);\n\n            let query = ReadQuery::new(\"SELECT time, pressure, wind_strength FROM weather_reading\");\n            let result = client.json_query(query).await.and_then(|mut db_result| {\n                println!(\"{:?}\", db_result);\n                db_result.deserialize_next::\u003cWeatherReadingWithoutIgnored\u003e()\n            });\n            assert_result_ok(\u0026result);\n            let result = result.unwrap();\n            let value = \u0026result.series[0].values[0];\n            assert_eq!(value.time, Timestamp::Hours(11).into());\n            assert_eq!(value.pressure, 100);\n            assert_eq!(value.wind_strength, None);\n        },\n        || async move {\n            delete_db(TEST_NAME).await.expect(\"could not clean up db\");\n        },\n    )\n    .await;\n}\n","traces":[],"covered":0,"coverable":0},{"path":["/","home","runner","work","influxdb-rust","influxdb-rust","influxdb","tests","integration_tests.rs"],"content":"extern crate influxdb;\n\n#[path = \"./utilities.rs\"]\nmod utilities;\n\nuse serde_derive::Deserialize;\nuse utilities::{\n    assert_result_err, assert_result_ok, create_client, create_db, delete_db, run_test,\n};\n\nuse influxdb::InfluxDbWriteable;\nuse influxdb::{Client, Error, ReadQuery, Timestamp};\n\n/// INTEGRATION TEST\n///\n/// This test case tests whether the InfluxDB server can be connected to and gathers info about it - tested with async_std\n#[async_std::test]\n#[cfg(not(tarpaulin_include))]\nasync fn test_ping_influx_db_async_std() {\n    let client = create_client(\"notusedhere\");\n    let result = client.ping().await;\n    assert_result_ok(\u0026result);\n\n    let (build, version) = result.unwrap();\n    assert!(!build.is_empty(), \"Build should not be empty\");\n    assert!(!version.is_empty(), \"Build should not be empty\");\n\n    println!(\"build: {} version: {}\", build, version);\n}\n\n/// INTEGRATION TEST\n///\n/// This test case tests whether the InfluxDB server can be connected to and gathers info about it - tested with tokio 1.0\n#[tokio::test]\n#[cfg(not(any(tarpaulin_include, feature = \"hyper-client\")))]\nasync fn test_ping_influx_db_tokio() {\n    let client = create_client(\"notusedhere\");\n    let result = client.ping().await;\n    assert_result_ok(\u0026result);\n\n    let (build, version) = result.unwrap();\n    assert!(!build.is_empty(), \"Build should not be empty\");\n    assert!(!version.is_empty(), \"Build should not be empty\");\n\n    println!(\"build: {} version: {}\", build, version);\n}\n\n/// INTEGRATION TEST\n///\n/// This test case tests connection error\n#[async_std::test]\n#[cfg(not(tarpaulin_include))]\nasync fn test_connection_error() {\n    let test_name = \"test_connection_error\";\n    let client =\n        Client::new(\"http://127.0.0.1:10086\", test_name).with_auth(\"nopriv_user\", \"password\");\n    let read_query = ReadQuery::new(\"SELECT * FROM weather\");\n    let read_result = client.query(read_query).await;\n    assert_result_err(\u0026read_result);\n    match read_result {\n        Err(Error::ConnectionError { .. }) =\u003e {}\n        _ =\u003e panic!(\n            \"Should cause a ConnectionError: {}\",\n            read_result.unwrap_err()\n        ),\n    }\n}\n\n/// INTEGRATION TEST\n///\n/// This test case tests the Authentication\n#[async_std::test]\n#[cfg(not(tarpaulin_include))]\nasync fn test_authed_write_and_read() {\n    const TEST_NAME: \u0026str = \"test_authed_write_and_read\";\n\n    run_test(\n        || async move {\n            let client =\n                Client::new(\"http://127.0.0.1:9086\", TEST_NAME).with_auth(\"admin\", \"password\");\n            let query = format!(\"CREATE DATABASE {}\", TEST_NAME);\n            client\n                .query(ReadQuery::new(query))\n                .await\n                .expect(\"could not setup db\");\n\n            let client =\n                Client::new(\"http://127.0.0.1:9086\", TEST_NAME).with_auth(\"admin\", \"password\");\n            let write_query = Timestamp::Hours(11)\n                .into_query(\"weather\")\n                .add_field(\"temperature\", 82);\n            let write_result = client.query(write_query).await;\n            assert_result_ok(\u0026write_result);\n\n            let read_query = ReadQuery::new(\"SELECT * FROM weather\");\n            let read_result = client.query(read_query).await;\n            assert_result_ok(\u0026read_result);\n            assert!(\n                !read_result.unwrap().contains(\"error\"),\n                \"Data contained a database error\"\n            );\n        },\n        || async move {\n            let client =\n                Client::new(\"http://127.0.0.1:9086\", TEST_NAME).with_auth(\"admin\", \"password\");\n            let query = format!(\"DROP DATABASE {}\", TEST_NAME);\n\n            client\n                .query(ReadQuery::new(query))\n                .await\n                .expect(\"could not clean up db\");\n        },\n    )\n    .await;\n}\n\n/// INTEGRATION TEST\n///\n/// This test case tests the Authentication\n#[async_std::test]\n#[cfg(not(tarpaulin_include))]\nasync fn test_wrong_authed_write_and_read() {\n    use http::StatusCode;\n\n    const TEST_NAME: \u0026str = \"test_wrong_authed_write_and_read\";\n\n    run_test(\n        || async move {\n            let client =\n                Client::new(\"http://127.0.0.1:9086\", TEST_NAME).with_auth(\"admin\", \"password\");\n            let query = format!(\"CREATE DATABASE {}\", TEST_NAME);\n            client\n                .query(ReadQuery::new(query))\n                .await\n                .expect(\"could not setup db\");\n\n            let client =\n                Client::new(\"http://127.0.0.1:9086\", TEST_NAME).with_auth(\"wrong_user\", \"password\");\n            let write_query = Timestamp::Hours(11)\n                .into_query(\"weather\")\n                .add_field(\"temperature\", 82);\n            let write_result = client.query(write_query).await;\n            assert_result_err(\u0026write_result);\n            match write_result {\n                Err(Error::ApiError(code)) if code == StatusCode::UNAUTHORIZED.as_u16() =\u003e {}\n                _ =\u003e panic!(\n                    \"Should be an ApiError(UNAUTHORIZED): {}\",\n                    write_result.unwrap_err()\n                ),\n            }\n\n            let read_query = ReadQuery::new(\"SELECT * FROM weather\");\n            let read_result = client.query(read_query).await;\n            assert_result_err(\u0026read_result);\n            match read_result {\n                Err(Error::ApiError(code)) if code == StatusCode::UNAUTHORIZED.as_u16() =\u003e {}\n                _ =\u003e panic!(\n                    \"Should be an ApiError(UNAUTHORIZED): {}\",\n                    read_result.unwrap_err()\n                ),\n            }\n\n            let client = Client::new(\"http://127.0.0.1:9086\", TEST_NAME)\n                .with_auth(\"nopriv_user\", \"password\");\n            let read_query = ReadQuery::new(\"SELECT * FROM weather\");\n            let read_result = client.query(read_query).await;\n            assert_result_err(\u0026read_result);\n            match read_result {\n                Err(Error::ApiError(code)) if code == StatusCode::FORBIDDEN.as_u16() =\u003e {}\n                _ =\u003e panic!(\n                    \"Should be an ApiError(UNAUTHENTICATED): {}\",\n                    read_result.unwrap_err()\n                ),\n            }\n        },\n        || async move {\n            let client =\n                Client::new(\"http://127.0.0.1:9086\", TEST_NAME).with_auth(\"admin\", \"password\");\n            let query = format!(\"DROP DATABASE {}\", TEST_NAME);\n            client\n                .query(ReadQuery::new(query))\n                .await\n                .expect(\"could not clean up db\");\n        },\n    )\n    .await;\n}\n\n/// INTEGRATION TEST\n///\n/// This test case tests the Authentication\n#[async_std::test]\n#[cfg(not(tarpaulin_include))]\nasync fn test_non_authed_write_and_read() {\n    use http::StatusCode;\n\n    const TEST_NAME: \u0026str = \"test_non_authed_write_and_read\";\n\n    run_test(\n        || async move {\n            let client =\n                Client::new(\"http://127.0.0.1:9086\", TEST_NAME).with_auth(\"admin\", \"password\");\n            let query = format!(\"CREATE DATABASE {}\", TEST_NAME);\n            client\n                .query(ReadQuery::new(query))\n                .await\n                .expect(\"could not setup db\");\n            let non_authed_client = Client::new(\"http://127.0.0.1:9086\", TEST_NAME);\n            let write_query = Timestamp::Hours(11)\n                .into_query(\"weather\")\n                .add_field(\"temperature\", 82);\n            let write_result = non_authed_client.query(write_query).await;\n            assert_result_err(\u0026write_result);\n            match write_result {\n                Err(Error::ApiError(code)) if code == StatusCode::UNAUTHORIZED.as_u16() =\u003e {}\n                _ =\u003e panic!(\n                    \"Should be an ApiError(UNAUTHORIZED): {}\",\n                    write_result.unwrap_err()\n                ),\n            }\n\n            let read_query = ReadQuery::new(\"SELECT * FROM weather\");\n            let read_result = non_authed_client.query(read_query).await;\n\n            assert_result_err(\u0026read_result);\n            match read_result {\n                Err(Error::ApiError(code)) if code == StatusCode::UNAUTHORIZED.as_u16() =\u003e {}\n                _ =\u003e panic!(\n                    \"Should be an ApiError(UNAUTHORIZED): {}\",\n                    read_result.unwrap_err()\n                ),\n            }\n        },\n        || async move {\n            let client =\n                Client::new(\"http://127.0.0.1:9086\", TEST_NAME).with_auth(\"admin\", \"password\");\n            let query = format!(\"DROP DATABASE {}\", TEST_NAME);\n            client\n                .query(ReadQuery::new(query))\n                .await\n                .expect(\"could not clean up db\");\n        },\n    )\n    .await;\n}\n\n/// INTEGRATION TEST\n///\n/// This integration tests that writing data and retrieving the data again is working\n#[async_std::test]\n#[cfg(not(tarpaulin_include))]\nasync fn test_write_and_read_field() {\n    const TEST_NAME: \u0026str = \"test_write_field\";\n\n    run_test(\n        || async move {\n            create_db(TEST_NAME).await.expect(\"could not setup db\");\n            let client = create_client(TEST_NAME);\n            let write_query = Timestamp::Hours(11)\n                .into_query(\"weather\")\n                .add_field(\"temperature\", 82);\n            let write_result = client.query(write_query).await;\n            assert_result_ok(\u0026write_result);\n\n            let read_query = ReadQuery::new(\"SELECT * FROM weather\");\n            let read_result = client.query(read_query).await;\n            assert_result_ok(\u0026read_result);\n            assert!(\n                !read_result.unwrap().contains(\"error\"),\n                \"Data contained a database error\"\n            );\n        },\n        || async move {\n            delete_db(TEST_NAME).await.expect(\"could not clean up db\");\n        },\n    )\n    .await;\n}\n\n/// INTEGRATION TEST\n///\n/// This test case tests the authentication on json reads\n#[async_std::test]\n#[cfg(feature = \"serde\")]\n#[cfg(not(tarpaulin_include))]\nasync fn test_json_non_authed_read() {\n    use http::StatusCode;\n\n    const TEST_NAME: \u0026str = \"test_json_non_authed_read\";\n\n    run_test(\n        || async move {\n            let client =\n                Client::new(\"http://127.0.0.1:9086\", TEST_NAME).with_auth(\"admin\", \"password\");\n            let query = format!(\"CREATE DATABASE {}\", TEST_NAME);\n            client\n                .query(ReadQuery::new(query))\n                .await\n                .expect(\"could not setup db\");\n            let non_authed_client = Client::new(\"http://127.0.0.1:9086\", TEST_NAME);\n\n            let read_query = ReadQuery::new(\"SELECT * FROM weather\");\n            let read_result = non_authed_client.json_query(read_query).await;\n            assert_result_err(\u0026read_result);\n            match read_result {\n                Err(Error::ApiError(code)) if code == StatusCode::UNAUTHORIZED.as_u16() =\u003e {}\n                _ =\u003e panic!(\n                    \"Should be an ApiError(UNAUTHORIZED): {}\",\n                    read_result.unwrap_err()\n                ),\n            }\n        },\n        || async move {\n            let client =\n                Client::new(\"http://127.0.0.1:9086\", TEST_NAME).with_auth(\"admin\", \"password\");\n            let query = format!(\"DROP DATABASE {}\", TEST_NAME);\n\n            client\n                .query(ReadQuery::new(query))\n                .await\n                .expect(\"could not clean up db\");\n        },\n    )\n    .await\n}\n\n/// INTEGRATION TEST\n///\n/// This test case tests the authentication on json reads\n#[async_std::test]\n#[cfg(feature = \"serde\")]\n#[cfg(not(tarpaulin_include))]\nasync fn test_json_authed_read() {\n    const TEST_NAME: \u0026str = \"test_json_authed_read\";\n\n    run_test(\n        || async move {\n            let client =\n                Client::new(\"http://127.0.0.1:9086\", TEST_NAME).with_auth(\"admin\", \"password\");\n            let query = format!(\"CREATE DATABASE {}\", TEST_NAME);\n            client\n                .query(ReadQuery::new(query))\n                .await\n                .expect(\"could not setup db\");\n\n            let read_query = ReadQuery::new(\"SELECT * FROM weather\");\n            let read_result = client.json_query(read_query).await;\n            assert_result_ok(\u0026read_result);\n        },\n        || async move {\n            let client =\n                Client::new(\"http://127.0.0.1:9086\", TEST_NAME).with_auth(\"admin\", \"password\");\n            let query = format!(\"DROP DATABASE {}\", TEST_NAME);\n\n            client\n                .query(ReadQuery::new(query))\n                .await\n                .expect(\"could not clean up db\");\n        },\n    )\n    .await\n}\n\n/// INTEGRATION TEST\n///\n/// This integration tests that writing data and retrieving the data again is working\n#[async_std::test]\n#[cfg(feature = \"serde\")]\n#[cfg(not(tarpaulin_include))]\nasync fn test_write_and_read_option() {\n    const TEST_NAME: \u0026str = \"test_write_and_read_option\";\n\n    run_test(\n        || {\n            async move {\n                create_db(TEST_NAME).await.expect(\"could not setup db\");\n\n                let client = create_client(TEST_NAME);\n                // Todo: Convert this to derive based insert for easier comparison of structs\n                let write_query = Timestamp::Hours(11)\n                    .into_query(\"weather\")\n                    .add_field(\"temperature\", 82)\n                    .add_field(\"wind_strength\", \u003cOption\u003cu64\u003e\u003e::None);\n                let write_result = client.query(write_query).await;\n                assert_result_ok(\u0026write_result);\n\n                #[derive(Deserialize, Debug, PartialEq)]\n                struct Weather {\n                    time: String,\n                    // different order to verify field names\n                    // are being used instead of just order\n                    wind_strength: Option\u003cu64\u003e,\n                    temperature: i32,\n                }\n\n                let query = ReadQuery::new(\"SELECT time, temperature, wind_strength FROM weather\");\n                let result = client\n                    .json_query(query)\n                    .await\n                    .and_then(|mut db_result| db_result.deserialize_next::\u003cWeather\u003e());\n                assert_result_ok(\u0026result);\n\n                assert_eq!(\n                    result.unwrap().series[0].values[0],\n                    Weather {\n                        time: \"1970-01-01T11:00:00Z\".to_string(),\n                        temperature: 82,\n                        wind_strength: None,\n                    }\n                );\n            }\n        },\n        || async move {\n            delete_db(\"test_write_and_read_option\")\n                .await\n                .expect(\"could not clean up db\");\n        },\n    )\n    .await;\n}\n\n/// INTEGRATION TEST\n///\n/// This test case tests whether JSON can be decoded from a InfluxDB response and whether that JSON\n/// is equal to the data which was written to the database\n#[async_std::test]\n#[cfg(feature = \"serde\")]\n#[cfg(not(tarpaulin_include))]\nasync fn test_json_query() {\n    const TEST_NAME: \u0026str = \"test_json_query\";\n\n    run_test(\n        || async move {\n            create_db(TEST_NAME).await.expect(\"could not setup db\");\n\n            let client = create_client(TEST_NAME);\n\n            let write_query = Timestamp::Hours(11)\n                .into_query(\"weather\")\n                .add_field(\"temperature\", 82);\n            let write_result = client.query(write_query).await;\n            assert_result_ok(\u0026write_result);\n\n            #[derive(Deserialize, Debug, PartialEq)]\n            struct Weather {\n                time: String,\n                temperature: i32,\n            }\n\n            let query = ReadQuery::new(\"SELECT * FROM weather\");\n            let result = client\n                .json_query(query)\n                .await\n                .and_then(|mut db_result| db_result.deserialize_next::\u003cWeather\u003e());\n            assert_result_ok(\u0026result);\n\n            assert_eq!(\n                result.unwrap().series[0].values[0],\n                Weather {\n                    time: \"1970-01-01T11:00:00Z\".to_string(),\n                    temperature: 82\n                }\n            );\n        },\n        || async move {\n            delete_db(TEST_NAME).await.expect(\"could not clean up db\");\n        },\n    )\n    .await;\n}\n\n/// INTEGRATION TEST\n///\n/// This test case tests whether the response to a GROUP BY can be parsed by\n/// deserialize_next_tagged into a tags struct\n#[async_std::test]\n#[cfg(feature = \"serde\")]\n#[cfg(not(tarpaulin_include))]\nasync fn test_json_query_tagged() {\n    const TEST_NAME: \u0026str = \"test_json_query_tagged\";\n\n    run_test(\n        || async move {\n            create_db(TEST_NAME).await.expect(\"could not setup db\");\n\n            let client = create_client(TEST_NAME);\n\n            let write_query = Timestamp::Hours(11)\n                .into_query(\"weather\")\n                .add_tag(\"location\", \"London\")\n                .add_field(\"temperature\", 82);\n            let write_result = client.query(write_query).await;\n            assert_result_ok(\u0026write_result);\n\n            #[derive(Deserialize, Debug, PartialEq)]\n            struct WeatherMeta {\n                location: String,\n            }\n\n            #[derive(Deserialize, Debug, PartialEq)]\n            struct Weather {\n                time: String,\n                temperature: i32,\n            }\n\n            let query = ReadQuery::new(\"SELECT * FROM weather GROUP BY location\");\n            let result = client.json_query(query).await.and_then(|mut db_result| {\n                db_result.deserialize_next_tagged::\u003cWeatherMeta, Weather\u003e()\n            });\n            assert_result_ok(\u0026result);\n            let result = result.unwrap();\n\n            assert_eq!(\n                result.series[0].tags,\n                WeatherMeta {\n                    location: \"London\".to_string(),\n                }\n            );\n            assert_eq!(\n                result.series[0].values[0],\n                Weather {\n                    time: \"1970-01-01T11:00:00Z\".to_string(),\n                    temperature: 82\n                }\n            );\n        },\n        || async move {\n            delete_db(TEST_NAME).await.expect(\"could not clean up db\");\n        },\n    )\n    .await;\n}\n\n/// INTEGRATION TEST\n///\n/// This test case tests whether JSON can be decoded from a InfluxDB response and whether that JSON\n/// is equal to the data which was written to the database\n/// (tested with tokio)\n#[tokio::test]\n#[cfg(all(\n    feature = \"serde\",\n    not(any(tarpaulin_include, feature = \"hyper-client\"))\n))]\nasync fn test_json_query_vec() {\n    const TEST_NAME: \u0026str = \"test_json_query_vec\";\n\n    run_test(\n        || async move {\n            create_db(TEST_NAME).await.expect(\"could not setup db\");\n\n            let client = create_client(TEST_NAME);\n            let write_query1 = Timestamp::Hours(11)\n                .into_query(\"temperature_vec\")\n                .add_field(\"temperature\", 16);\n            let write_query2 = Timestamp::Hours(12)\n                .into_query(\"temperature_vec\")\n                .add_field(\"temperature\", 17);\n            let write_query3 = Timestamp::Hours(13)\n                .into_query(\"temperature_vec\")\n                .add_field(\"temperature\", 18);\n\n            let _write_result = client.query(write_query1).await;\n            let _write_result2 = client.query(write_query2).await;\n            let _write_result2 = client.query(write_query3).await;\n\n            #[derive(Deserialize, Debug, PartialEq)]\n            struct Weather {\n                time: String,\n                temperature: i32,\n            }\n\n            let query = ReadQuery::new(\"SELECT * FROM temperature_vec\");\n            let result = client\n                .json_query(query)\n                .await\n                .and_then(|mut db_result| db_result.deserialize_next::\u003cWeather\u003e());\n            assert_result_ok(\u0026result);\n            assert_eq!(result.unwrap().series[0].values.len(), 3);\n        },\n        || async move {\n            delete_db(TEST_NAME).await.expect(\"could not clean up db\");\n        },\n    )\n    .await;\n}\n\n/// INTEGRATION TEST\n///\n/// This integration test tests whether using the wrong query method fails building the query\n#[async_std::test]\n#[cfg(feature = \"serde\")]\n#[cfg(not(tarpaulin_include))]\nasync fn test_serde_multi_query() {\n    const TEST_NAME: \u0026str = \"test_serde_multi_query\";\n\n    run_test(\n        || async move {\n            create_db(TEST_NAME).await.expect(\"could not setup db\");\n\n            #[derive(Deserialize, Debug, PartialEq)]\n            struct Temperature {\n                time: String,\n                temperature: i32,\n            }\n\n            #[derive(Deserialize, Debug, PartialEq)]\n            struct Humidity {\n                time: String,\n                humidity: i32,\n            }\n\n            let client = create_client(TEST_NAME);\n            let write_query = Timestamp::Hours(11)\n                .into_query(\"temperature\")\n                .add_field(\"temperature\", 16);\n            let write_query2 = Timestamp::Hours(11)\n                .into_query(\"humidity\")\n                .add_field(\"humidity\", 69);\n\n            let write_result = client.query(write_query).await;\n            let write_result2 = client.query(write_query2).await;\n            assert_result_ok(\u0026write_result);\n            assert_result_ok(\u0026write_result2);\n\n            let result = client\n                .json_query(\n                    ReadQuery::new(\"SELECT * FROM temperature\").add_query(\"SELECT * FROM humidity\"),\n                )\n                .await\n                .and_then(|mut db_result| {\n                    let temp = db_result.deserialize_next::\u003cTemperature\u003e()?;\n                    let humidity = db_result.deserialize_next::\u003cHumidity\u003e()?;\n\n                    Ok((temp, humidity))\n                });\n            assert_result_ok(\u0026result);\n\n            let (temp, humidity) = result.unwrap();\n            assert_eq!(\n                temp.series[0].values[0],\n                Temperature {\n                    time: \"1970-01-01T11:00:00Z\".to_string(),\n                    temperature: 16\n                },\n            );\n            assert_eq!(\n                humidity.series[0].values[0],\n                Humidity {\n                    time: \"1970-01-01T11:00:00Z\".to_string(),\n                    humidity: 69\n                }\n            );\n        },\n        || async move {\n            delete_db(TEST_NAME).await.expect(\"could not clean up db\");\n        },\n    )\n    .await;\n}\n\n/// INTEGRATION TEST\n///\n/// This integration test tests whether using the wrong query method fails building the query\n#[async_std::test]\n#[cfg(feature = \"serde\")]\n#[cfg(not(tarpaulin_include))]\nasync fn test_wrong_query_errors() {\n    let client = create_client(\"test_name\");\n    let result = client\n        .json_query(ReadQuery::new(\"CREATE DATABASE this_should_fail\"))\n        .await;\n    assert!(\n        result.is_err(),\n        \"Should only build SELECT and SHOW queries.\"\n    );\n}\n","traces":[],"covered":0,"coverable":0},{"path":["/","home","runner","work","influxdb-rust","influxdb-rust","influxdb","tests","integration_tests_v2.rs"],"content":"extern crate influxdb;\n\n#[path = \"./utilities.rs\"]\nmod utilities;\nuse utilities::{assert_result_err, assert_result_ok, run_test};\n\nuse influxdb::InfluxDbWriteable;\nuse influxdb::{Client, Error, ReadQuery, Timestamp};\n\n/// INTEGRATION TEST\n///\n\n/// This test case tests the Authentication\n#[async_std::test]\n#[cfg(not(tarpaulin))]\nasync fn test_authed_write_and_read() {\n    run_test(\n        || async move {\n            let client = Client::new(\"http://127.0.0.1:2086\", \"mydb\").with_token(\"admintoken\");\n            let write_query = Timestamp::Hours(11)\n                .into_query(\"weather\")\n                .add_field(\"temperature\", 82);\n            let write_result = client.query(\u0026write_query).await;\n            assert_result_ok(\u0026write_result);\n\n            let read_query = ReadQuery::new(\"SELECT * FROM weather\");\n            let read_result = client.query(read_query).await;\n            assert_result_ok(\u0026read_result);\n            assert!(\n                !read_result.unwrap().contains(\"error\"),\n                \"Data contained a database error\"\n            );\n        },\n        || async move {\n            let client = Client::new(\"http://127.0.0.1:2086\", \"mydb\").with_token(\"admintoken\");\n            let read_query = ReadQuery::new(\"DROP MEASUREMENT \\\"weather\\\"\");\n            let read_result = client.query(read_query).await;\n            assert_result_ok(\u0026read_result);\n            assert!(!read_result.unwrap().contains(\"error\"), \"Teardown failed\");\n        },\n    )\n    .await;\n}\n\n/// INTEGRATION TEST\n///\n/// This test case tests the Authentication\n#[async_std::test]\n#[cfg(not(tarpaulin))]\nasync fn test_wrong_authed_write_and_read() {\n    use http::StatusCode;\n\n    run_test(\n        || async move {\n            let client = Client::new(\"http://127.0.0.1:2086\", \"mydb\").with_token(\"falsetoken\");\n            let write_query = Timestamp::Hours(11)\n                .into_query(\"weather\")\n                .add_field(\"temperature\", 82);\n            let write_result = client.query(\u0026write_query).await;\n            assert_result_err(\u0026write_result);\n            match write_result {\n                Err(Error::ApiError(code)) if code == StatusCode::UNAUTHORIZED.as_u16() =\u003e {}\n                _ =\u003e panic!(\n                    \"Should be an ApiError(UNAUTHORIZED): {}\",\n                    write_result.unwrap_err()\n                ),\n            }\n\n            let read_query = ReadQuery::new(\"SELECT * FROM weather\");\n            let read_result = client.query(\u0026read_query).await;\n            assert_result_err(\u0026read_result);\n            match read_result {\n                Err(Error::ApiError(code)) if code == StatusCode::UNAUTHORIZED.as_u16() =\u003e {}\n                _ =\u003e panic!(\n                    \"Should be an ApiError(UNAUTHORIZED): {}\",\n                    read_result.unwrap_err()\n                ),\n            }\n        },\n        || async move {},\n    )\n    .await;\n}\n\n/// INTEGRATION TEST\n///\n/// This test case tests the Authentication\n#[async_std::test]\n#[cfg(not(tarpaulin))]\nasync fn test_non_authed_write_and_read() {\n    use http::StatusCode;\n\n    run_test(\n        || async move {\n            let non_authed_client = Client::new(\"http://127.0.0.1:2086\", \"mydb\");\n            let write_query = Timestamp::Hours(11)\n                .into_query(\"weather\")\n                .add_field(\"temperature\", 82);\n            let write_result = non_authed_client.query(\u0026write_query).await;\n            assert_result_err(\u0026write_result);\n            match write_result {\n                Err(Error::ApiError(code)) if code == StatusCode::UNAUTHORIZED.as_u16() =\u003e {}\n                _ =\u003e panic!(\n                    \"Should be an ApiError(UNAUTHORIZED): {}\",\n                    write_result.unwrap_err()\n                ),\n            }\n\n            let read_query = ReadQuery::new(\"SELECT * FROM weather\");\n            let read_result = non_authed_client.query(\u0026read_query).await;\n            assert_result_err(\u0026read_result);\n            match read_result {\n                Err(Error::ApiError(code)) if code == StatusCode::UNAUTHORIZED.as_u16() =\u003e {}\n                _ =\u003e panic!(\n                    \"Should be an ApiError(UNAUTHORIZED): {}\",\n                    read_result.unwrap_err()\n                ),\n            }\n        },\n        || async move {},\n    )\n    .await;\n}\n","traces":[],"covered":0,"coverable":0},{"path":["/","home","runner","work","influxdb-rust","influxdb-rust","influxdb","tests","utilities.rs"],"content":"use futures_util::FutureExt;\nuse influxdb::{Client, Error, ReadQuery};\nuse std::future::Future;\nuse std::panic::{AssertUnwindSafe, UnwindSafe};\n\n#[allow(dead_code)]\n#[cfg(not(tarpaulin_include))]\npub fn assert_result_err\u003cA: std::fmt::Debug, B: std::fmt::Debug\u003e(result: \u0026Result\u003cA, B\u003e) {\n    result.as_ref().expect_err(\"assert_result_err failed\");\n}\n\n#[cfg(not(tarpaulin_include))]\npub fn assert_result_ok\u003cA: std::fmt::Debug, B: std::fmt::Debug\u003e(result: \u0026Result\u003cA, B\u003e) {\n    result.as_ref().expect(\"assert_result_ok failed\");\n}\n\n#[allow(dead_code)]\n#[cfg(not(tarpaulin_include))]\npub fn create_client\u003cT\u003e(db_name: T) -\u003e Client\nwhere\n    T: Into\u003cString\u003e,\n{\n    Client::new(\"http://127.0.0.1:8086\", db_name)\n}\n\n#[allow(dead_code)]\n#[cfg(not(tarpaulin_include))]\npub async fn create_db\u003cT\u003e(name: T) -\u003e Result\u003cString, Error\u003e\nwhere\n    T: Into\u003cString\u003e,\n{\n    let test_name = name.into();\n    let query = format!(\"CREATE DATABASE {}\", test_name);\n    create_client(test_name).query(ReadQuery::new(query)).await\n}\n\n#[allow(dead_code)]\n#[cfg(not(tarpaulin_include))]\npub async fn delete_db\u003cT\u003e(name: T) -\u003e Result\u003cString, Error\u003e\nwhere\n    T: Into\u003cString\u003e,\n{\n    let test_name = name.into();\n    let query = format!(\"DROP DATABASE {}\", test_name);\n    create_client(test_name).query(ReadQuery::new(query)).await\n}\n\n#[cfg(not(tarpaulin_include))]\npub async fn run_test\u003cF, T, Fut1, Fut2\u003e(test_fn: F, teardown: T)\nwhere\n    F: FnOnce() -\u003e Fut1 + UnwindSafe,\n    T: FnOnce() -\u003e Fut2,\n    Fut1: Future,\n    Fut2: Future,\n{\n    let test_result = AssertUnwindSafe(test_fn()).catch_unwind().await;\n    AssertUnwindSafe(teardown())\n        .catch_unwind()\n        .await\n        .expect(\"failed teardown\");\n    test_result.expect(\"failed test\");\n}\n","traces":[],"covered":0,"coverable":0},{"path":["/","home","runner","work","influxdb-rust","influxdb-rust","influxdb_derive","src","lib.rs"],"content":"use proc_macro::TokenStream;\n\nmod writeable;\nuse syn::parse_macro_input;\nuse writeable::expand_writeable;\n\n#[proc_macro_derive(InfluxDbWriteable, attributes(influxdb))]\npub fn derive_writeable(input: TokenStream) -\u003e TokenStream {\n    expand_writeable(parse_macro_input!(input))\n        .unwrap_or_else(syn::Error::into_compile_error)\n        .into()\n}\n","traces":[{"line":8,"address":[299840,300128],"length":1,"stats":{"Line":0}},{"line":9,"address":[300040,299856],"length":1,"stats":{"Line":0}}],"covered":0,"coverable":2},{"path":["/","home","runner","work","influxdb-rust","influxdb-rust","influxdb_derive","src","writeable.rs"],"content":"use proc_macro2::TokenStream;\nuse quote::{format_ident, quote};\nuse std::convert::TryFrom;\nuse syn::{\n    parse::{Parse, ParseStream},\n    punctuated::Punctuated,\n    Data, DeriveInput, Field, Fields, Ident, Meta, Token,\n};\n\n#[derive(Debug)]\nstruct WriteableField {\n    ident: Ident,\n    is_tag: bool,\n    is_ignore: bool,\n}\n\nmod kw {\n    use syn::custom_keyword;\n\n    custom_keyword!(tag);\n    custom_keyword!(ignore);\n}\n\nenum FieldAttr {\n    Tag(kw::tag),\n    Ignore(kw::ignore),\n}\n\nimpl Parse for FieldAttr {\n    fn parse(input: ParseStream\u003c'_\u003e) -\u003e syn::Result\u003cSelf\u003e {\n        let lookahead = input.lookahead1();\n        if lookahead.peek(kw::tag) {\n            Ok(Self::Tag(input.parse()?))\n        } else if lookahead.peek(kw::ignore) {\n            Ok(Self::Ignore(input.parse()?))\n        } else {\n            Err(lookahead.error())\n        }\n    }\n}\n\nstruct FieldAttrs(Punctuated\u003cFieldAttr, Token![,]\u003e);\n\nimpl Parse for FieldAttrs {\n    fn parse(input: ParseStream\u003c'_\u003e) -\u003e syn::Result\u003cSelf\u003e {\n        Ok(Self(Punctuated::parse_terminated(input)?))\n    }\n}\n\nimpl TryFrom\u003cField\u003e for WriteableField {\n    type Error = syn::Error;\n\n    fn try_from(field: Field) -\u003e syn::Result\u003cWriteableField\u003e {\n        let ident = field.ident.expect(\"fields without ident are not supported\");\n        let mut is_tag = false;\n        let mut is_ignore = false;\n\n        for attr in field.attrs {\n            match attr.meta {\n                Meta::List(list) if list.path.is_ident(\"influxdb\") =\u003e {\n                    for attr in syn::parse2::\u003cFieldAttrs\u003e(list.tokens)?.0 {\n                        match attr {\n                            FieldAttr::Tag(_) =\u003e is_tag = true,\n                            FieldAttr::Ignore(_) =\u003e is_ignore = true,\n                        }\n                    }\n                }\n                _ =\u003e {}\n            }\n        }\n\n        Ok(WriteableField {\n            ident,\n            is_tag,\n            is_ignore,\n        })\n    }\n}\n\npub fn expand_writeable(input: DeriveInput) -\u003e syn::Result\u003cTokenStream\u003e {\n    let ident = input.ident;\n    let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();\n\n    let fields = match input.data {\n        Data::Struct(strukt) =\u003e strukt.fields,\n        Data::Enum(inum) =\u003e {\n            return Err(syn::Error::new(\n                inum.enum_token.span,\n                \"#[derive(InfluxDbWriteable)] can only be used on structs\",\n            ))\n        }\n        Data::Union(cdu) =\u003e {\n            return Err(syn::Error::new(\n                cdu.union_token.span,\n                \"#[derive(InfluxDbWriteable)] can only be used on structs\",\n            ))\n        }\n    };\n\n    let time_field = format_ident!(\"time\");\n    let time_field_str = time_field.to_string();\n    #[allow(clippy::cmp_owned)] // that's not how idents work clippy\n    let fields = match fields {\n        Fields::Named(fields) =\u003e fields\n            .named\n            .into_iter()\n            .filter_map(|f| {\n                WriteableField::try_from(f)\n                    .map(|wf| {\n                        if !wf.is_ignore \u0026\u0026 wf.ident.to_string() != time_field_str {\n                            let ident = wf.ident;\n                            Some(match wf.is_tag {\n                                true =\u003e quote!(query.add_tag(stringify!(#ident), self.#ident)),\n                                false =\u003e quote!(query.add_field(stringify!(#ident), self.#ident)),\n                            })\n                        } else {\n                            None\n                        }\n                    })\n                    .transpose()\n            })\n            .collect::\u003csyn::Result\u003cVec\u003c_\u003e\u003e\u003e()?,\n        _ =\u003e panic!(\"a struct without named fields is not supported\"),\n    };\n\n    Ok(quote! {\n        impl #impl_generics ::influxdb::InfluxDbWriteable for #ident #ty_generics #where_clause {\n            fn into_query\u003cI: Into\u003cString\u003e\u003e(self, name: I) -\u003e ::influxdb::WriteQuery {\n                let timestamp: ::influxdb::Timestamp = self.#time_field.into();\n                let mut query = timestamp.into_query(name);\n                #(\n                    query = #fields;\n                )*\n                query\n            }\n        }\n    })\n}\n","traces":[{"line":30,"address":[290144,290918,290947],"length":1,"stats":{"Line":0}},{"line":31,"address":[290174],"length":1,"stats":{"Line":0}},{"line":32,"address":[290214,290270,290816],"length":1,"stats":{"Line":0}},{"line":33,"address":[290913,290722,290826,290305],"length":1,"stats":{"Line":0}},{"line":34,"address":[290619,290281,290319],"length":1,"stats":{"Line":0}},{"line":35,"address":[290629,290425,290507],"length":1,"stats":{"Line":0}},{"line":37,"address":[290325,290437],"length":1,"stats":{"Line":0}},{"line":45,"address":[290960],"length":1,"stats":{"Line":0}},{"line":46,"address":[290985,291197],"length":1,"stats":{"Line":0}},{"line":53,"address":[291966,291264],"length":1,"stats":{"Line":0}},{"line":54,"address":[291286],"length":1,"stats":{"Line":0}},{"line":55,"address":[291416],"length":1,"stats":{"Line":0}},{"line":56,"address":[291421],"length":1,"stats":{"Line":0}},{"line":58,"address":[291693,291648,293117,291426,291529],"length":1,"stats":{"Line":0}},{"line":59,"address":[291727],"length":1,"stats":{"Line":0}},{"line":60,"address":[291988,292137],"length":1,"stats":{"Line":0}},{"line":61,"address":[292247,292362,292688,292742],"length":1,"stats":{"Line":0}},{"line":62,"address":[292770],"length":1,"stats":{"Line":0}},{"line":63,"address":[292807],"length":1,"stats":{"Line":0}},{"line":64,"address":[292817],"length":1,"stats":{"Line":0}},{"line":72,"address":[291811],"length":1,"stats":{"Line":0}},{"line":73,"address":[291777],"length":1,"stats":{"Line":0}},{"line":74,"address":[291803],"length":1,"stats":{"Line":0}},{"line":75,"address":[291807],"length":1,"stats":{"Line":0}},{"line":80,"address":[293216,297207],"length":1,"stats":{"Line":0}},{"line":81,"address":[293238],"length":1,"stats":{"Line":0}},{"line":82,"address":[293318,293387],"length":1,"stats":{"Line":0}},{"line":84,"address":[293429],"length":1,"stats":{"Line":0}},{"line":85,"address":[293494],"length":1,"stats":{"Line":0}},{"line":86,"address":[293667],"length":1,"stats":{"Line":0}},{"line":87,"address":[297500,293718],"length":1,"stats":{"Line":0}},{"line":88,"address":[293711],"length":1,"stats":{"Line":0}},{"line":92,"address":[293757],"length":1,"stats":{"Line":0}},{"line":93,"address":[293820,297608],"length":1,"stats":{"Line":0}},{"line":94,"address":[293813],"length":1,"stats":{"Line":0}},{"line":100,"address":[293633,293912],"length":1,"stats":{"Line":0}},{"line":101,"address":[294133],"length":1,"stats":{"Line":0}},{"line":103,"address":[294160],"length":1,"stats":{"Line":0}},{"line":104,"address":[294571,294171,294387],"length":1,"stats":{"Line":0}},{"line":107,"address":[298032],"length":1,"stats":{"Line":0}},{"line":108,"address":[298067,298085],"length":1,"stats":{"Line":0}},{"line":109,"address":[299776,298082,299148,298128],"length":1,"stats":{"Line":0}},{"line":110,"address":[298216,298262,298155],"length":1,"stats":{"Line":0}},{"line":111,"address":[298371],"length":1,"stats":{"Line":0}},{"line":112,"address":[298405,299112],"length":1,"stats":{"Line":0}},{"line":113,"address":[299157,298430],"length":1,"stats":{"Line":0}},{"line":114,"address":[298490,298411],"length":1,"stats":{"Line":0}},{"line":117,"address":[298203],"length":1,"stats":{"Line":0}},{"line":126,"address":[294515,294640,297229],"length":1,"stats":{"Line":0}}],"covered":0,"coverable":49}]};
+        var previousData = null;
+    </script>
+    <script crossorigin>/** @license React v16.13.1
+ * react.production.min.js
+ *
+ * Copyright (c) Facebook, Inc. and its affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+'use strict';(function(d,r){"object"===typeof exports&&"undefined"!==typeof module?r(exports):"function"===typeof define&&define.amd?define(["exports"],r):(d=d||self,r(d.React={}))})(this,function(d){function r(a){for(var b="https://reactjs.org/docs/error-decoder.html?invariant="+a,c=1;c<arguments.length;c++)b+="&args[]="+encodeURIComponent(arguments[c]);return"Minified React error #"+a+"; visit "+b+" for the full message or use the non-minified dev environment for full errors and additional helpful warnings."}
+function w(a,b,c){this.props=a;this.context=b;this.refs=ba;this.updater=c||ca}function da(){}function L(a,b,c){this.props=a;this.context=b;this.refs=ba;this.updater=c||ca}function ea(a,b,c){var g,e={},fa=null,d=null;if(null!=b)for(g in void 0!==b.ref&&(d=b.ref),void 0!==b.key&&(fa=""+b.key),b)ha.call(b,g)&&!ia.hasOwnProperty(g)&&(e[g]=b[g]);var h=arguments.length-2;if(1===h)e.children=c;else if(1<h){for(var k=Array(h),f=0;f<h;f++)k[f]=arguments[f+2];e.children=k}if(a&&a.defaultProps)for(g in h=a.defaultProps,
+h)void 0===e[g]&&(e[g]=h[g]);return{$$typeof:x,type:a,key:fa,ref:d,props:e,_owner:M.current}}function va(a,b){return{$$typeof:x,type:a.type,key:b,ref:a.ref,props:a.props,_owner:a._owner}}function N(a){return"object"===typeof a&&null!==a&&a.$$typeof===x}function wa(a){var b={"=":"=0",":":"=2"};return"$"+(""+a).replace(/[=:]/g,function(a){return b[a]})}function ja(a,b,c,g){if(C.length){var e=C.pop();e.result=a;e.keyPrefix=b;e.func=c;e.context=g;e.count=0;return e}return{result:a,keyPrefix:b,func:c,
+context:g,count:0}}function ka(a){a.result=null;a.keyPrefix=null;a.func=null;a.context=null;a.count=0;10>C.length&&C.push(a)}function O(a,b,c,g){var e=typeof a;if("undefined"===e||"boolean"===e)a=null;var d=!1;if(null===a)d=!0;else switch(e){case "string":case "number":d=!0;break;case "object":switch(a.$$typeof){case x:case xa:d=!0}}if(d)return c(g,a,""===b?"."+P(a,0):b),1;d=0;b=""===b?".":b+":";if(Array.isArray(a))for(var f=0;f<a.length;f++){e=a[f];var h=b+P(e,f);d+=O(e,h,c,g)}else if(null===a||
+"object"!==typeof a?h=null:(h=la&&a[la]||a["@@iterator"],h="function"===typeof h?h:null),"function"===typeof h)for(a=h.call(a),f=0;!(e=a.next()).done;)e=e.value,h=b+P(e,f++),d+=O(e,h,c,g);else if("object"===e)throw c=""+a,Error(r(31,"[object Object]"===c?"object with keys {"+Object.keys(a).join(", ")+"}":c,""));return d}function Q(a,b,c){return null==a?0:O(a,"",b,c)}function P(a,b){return"object"===typeof a&&null!==a&&null!=a.key?wa(a.key):b.toString(36)}function ya(a,b,c){a.func.call(a.context,b,
+a.count++)}function za(a,b,c){var g=a.result,e=a.keyPrefix;a=a.func.call(a.context,b,a.count++);Array.isArray(a)?R(a,g,c,function(a){return a}):null!=a&&(N(a)&&(a=va(a,e+(!a.key||b&&b.key===a.key?"":(""+a.key).replace(ma,"$&/")+"/")+c)),g.push(a))}function R(a,b,c,g,e){var d="";null!=c&&(d=(""+c).replace(ma,"$&/")+"/");b=ja(b,d,g,e);Q(a,za,b);ka(b)}function t(){var a=na.current;if(null===a)throw Error(r(321));return a}function S(a,b){var c=a.length;a.push(b);a:for(;;){var g=c-1>>>1,e=a[g];if(void 0!==
+e&&0<D(e,b))a[g]=b,a[c]=e,c=g;else break a}}function n(a){a=a[0];return void 0===a?null:a}function E(a){var b=a[0];if(void 0!==b){var c=a.pop();if(c!==b){a[0]=c;a:for(var g=0,e=a.length;g<e;){var d=2*(g+1)-1,f=a[d],h=d+1,k=a[h];if(void 0!==f&&0>D(f,c))void 0!==k&&0>D(k,f)?(a[g]=k,a[h]=c,g=h):(a[g]=f,a[d]=c,g=d);else if(void 0!==k&&0>D(k,c))a[g]=k,a[h]=c,g=h;else break a}}return b}return null}function D(a,b){var c=a.sortIndex-b.sortIndex;return 0!==c?c:a.id-b.id}function F(a){for(var b=n(u);null!==
+b;){if(null===b.callback)E(u);else if(b.startTime<=a)E(u),b.sortIndex=b.expirationTime,S(p,b);else break;b=n(u)}}function T(a){y=!1;F(a);if(!v)if(null!==n(p))v=!0,z(U);else{var b=n(u);null!==b&&G(T,b.startTime-a)}}function U(a,b){v=!1;y&&(y=!1,V());H=!0;var c=m;try{F(b);for(l=n(p);null!==l&&(!(l.expirationTime>b)||a&&!W());){var g=l.callback;if(null!==g){l.callback=null;m=l.priorityLevel;var e=g(l.expirationTime<=b);b=q();"function"===typeof e?l.callback=e:l===n(p)&&E(p);F(b)}else E(p);l=n(p)}if(null!==
+l)var d=!0;else{var f=n(u);null!==f&&G(T,f.startTime-b);d=!1}return d}finally{l=null,m=c,H=!1}}function oa(a){switch(a){case 1:return-1;case 2:return 250;case 5:return 1073741823;case 4:return 1E4;default:return 5E3}}var f="function"===typeof Symbol&&Symbol.for,x=f?Symbol.for("react.element"):60103,xa=f?Symbol.for("react.portal"):60106,Aa=f?Symbol.for("react.fragment"):60107,Ba=f?Symbol.for("react.strict_mode"):60108,Ca=f?Symbol.for("react.profiler"):60114,Da=f?Symbol.for("react.provider"):60109,
+Ea=f?Symbol.for("react.context"):60110,Fa=f?Symbol.for("react.forward_ref"):60112,Ga=f?Symbol.for("react.suspense"):60113,Ha=f?Symbol.for("react.memo"):60115,Ia=f?Symbol.for("react.lazy"):60116,la="function"===typeof Symbol&&Symbol.iterator,pa=Object.getOwnPropertySymbols,Ja=Object.prototype.hasOwnProperty,Ka=Object.prototype.propertyIsEnumerable,I=function(){try{if(!Object.assign)return!1;var a=new String("abc");a[5]="de";if("5"===Object.getOwnPropertyNames(a)[0])return!1;var b={};for(a=0;10>a;a++)b["_"+
+String.fromCharCode(a)]=a;if("0123456789"!==Object.getOwnPropertyNames(b).map(function(a){return b[a]}).join(""))return!1;var c={};"abcdefghijklmnopqrst".split("").forEach(function(a){c[a]=a});return"abcdefghijklmnopqrst"!==Object.keys(Object.assign({},c)).join("")?!1:!0}catch(g){return!1}}()?Object.assign:function(a,b){if(null===a||void 0===a)throw new TypeError("Object.assign cannot be called with null or undefined");var c=Object(a);for(var g,e=1;e<arguments.length;e++){var d=Object(arguments[e]);
+for(var f in d)Ja.call(d,f)&&(c[f]=d[f]);if(pa){g=pa(d);for(var h=0;h<g.length;h++)Ka.call(d,g[h])&&(c[g[h]]=d[g[h]])}}return c},ca={isMounted:function(a){return!1},enqueueForceUpdate:function(a,b,c){},enqueueReplaceState:function(a,b,c,d){},enqueueSetState:function(a,b,c,d){}},ba={};w.prototype.isReactComponent={};w.prototype.setState=function(a,b){if("object"!==typeof a&&"function"!==typeof a&&null!=a)throw Error(r(85));this.updater.enqueueSetState(this,a,b,"setState")};w.prototype.forceUpdate=
+function(a){this.updater.enqueueForceUpdate(this,a,"forceUpdate")};da.prototype=w.prototype;f=L.prototype=new da;f.constructor=L;I(f,w.prototype);f.isPureReactComponent=!0;var M={current:null},ha=Object.prototype.hasOwnProperty,ia={key:!0,ref:!0,__self:!0,__source:!0},ma=/\/+/g,C=[],na={current:null},X;if("undefined"===typeof window||"function"!==typeof MessageChannel){var A=null,qa=null,ra=function(){if(null!==A)try{var a=q();A(!0,a);A=null}catch(b){throw setTimeout(ra,0),b;}},La=Date.now();var q=
+function(){return Date.now()-La};var z=function(a){null!==A?setTimeout(z,0,a):(A=a,setTimeout(ra,0))};var G=function(a,b){qa=setTimeout(a,b)};var V=function(){clearTimeout(qa)};var W=function(){return!1};f=X=function(){}}else{var Y=window.performance,sa=window.Date,Ma=window.setTimeout,Na=window.clearTimeout;"undefined"!==typeof console&&(f=window.cancelAnimationFrame,"function"!==typeof window.requestAnimationFrame&&console.error("This browser doesn't support requestAnimationFrame. Make sure that you load a polyfill in older browsers. https://fb.me/react-polyfills"),
+"function"!==typeof f&&console.error("This browser doesn't support cancelAnimationFrame. Make sure that you load a polyfill in older browsers. https://fb.me/react-polyfills"));if("object"===typeof Y&&"function"===typeof Y.now)q=function(){return Y.now()};else{var Oa=sa.now();q=function(){return sa.now()-Oa}}var J=!1,K=null,Z=-1,ta=5,ua=0;W=function(){return q()>=ua};f=function(){};X=function(a){0>a||125<a?console.error("forceFrameRate takes a positive int between 0 and 125, forcing framerates higher than 125 fps is not unsupported"):
+ta=0<a?Math.floor(1E3/a):5};var B=new MessageChannel,aa=B.port2;B.port1.onmessage=function(){if(null!==K){var a=q();ua=a+ta;try{K(!0,a)?aa.postMessage(null):(J=!1,K=null)}catch(b){throw aa.postMessage(null),b;}}else J=!1};z=function(a){K=a;J||(J=!0,aa.postMessage(null))};G=function(a,b){Z=Ma(function(){a(q())},b)};V=function(){Na(Z);Z=-1}}var p=[],u=[],Pa=1,l=null,m=3,H=!1,v=!1,y=!1,Qa=0;B={ReactCurrentDispatcher:na,ReactCurrentOwner:M,IsSomeRendererActing:{current:!1},assign:I};I(B,{Scheduler:{__proto__:null,
+unstable_ImmediatePriority:1,unstable_UserBlockingPriority:2,unstable_NormalPriority:3,unstable_IdlePriority:5,unstable_LowPriority:4,unstable_runWithPriority:function(a,b){switch(a){case 1:case 2:case 3:case 4:case 5:break;default:a=3}var c=m;m=a;try{return b()}finally{m=c}},unstable_next:function(a){switch(m){case 1:case 2:case 3:var b=3;break;default:b=m}var c=m;m=b;try{return a()}finally{m=c}},unstable_scheduleCallback:function(a,b,c){var d=q();if("object"===typeof c&&null!==c){var e=c.delay;
+e="number"===typeof e&&0<e?d+e:d;c="number"===typeof c.timeout?c.timeout:oa(a)}else c=oa(a),e=d;c=e+c;a={id:Pa++,callback:b,priorityLevel:a,startTime:e,expirationTime:c,sortIndex:-1};e>d?(a.sortIndex=e,S(u,a),null===n(p)&&a===n(u)&&(y?V():y=!0,G(T,e-d))):(a.sortIndex=c,S(p,a),v||H||(v=!0,z(U)));return a},unstable_cancelCallback:function(a){a.callback=null},unstable_wrapCallback:function(a){var b=m;return function(){var c=m;m=b;try{return a.apply(this,arguments)}finally{m=c}}},unstable_getCurrentPriorityLevel:function(){return m},
+unstable_shouldYield:function(){var a=q();F(a);var b=n(p);return b!==l&&null!==l&&null!==b&&null!==b.callback&&b.startTime<=a&&b.expirationTime<l.expirationTime||W()},unstable_requestPaint:f,unstable_continueExecution:function(){v||H||(v=!0,z(U))},unstable_pauseExecution:function(){},unstable_getFirstCallbackNode:function(){return n(p)},get unstable_now(){return q},get unstable_forceFrameRate(){return X},unstable_Profiling:null},SchedulerTracing:{__proto__:null,__interactionsRef:null,__subscriberRef:null,
+unstable_clear:function(a){return a()},unstable_getCurrent:function(){return null},unstable_getThreadID:function(){return++Qa},unstable_trace:function(a,b,c){return c()},unstable_wrap:function(a){return a},unstable_subscribe:function(a){},unstable_unsubscribe:function(a){}}});d.Children={map:function(a,b,c){if(null==a)return a;var d=[];R(a,d,null,b,c);return d},forEach:function(a,b,c){if(null==a)return a;b=ja(null,null,b,c);Q(a,ya,b);ka(b)},count:function(a){return Q(a,function(){return null},null)},
+toArray:function(a){var b=[];R(a,b,null,function(a){return a});return b},only:function(a){if(!N(a))throw Error(r(143));return a}};d.Component=w;d.Fragment=Aa;d.Profiler=Ca;d.PureComponent=L;d.StrictMode=Ba;d.Suspense=Ga;d.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=B;d.cloneElement=function(a,b,c){if(null===a||void 0===a)throw Error(r(267,a));var d=I({},a.props),e=a.key,f=a.ref,m=a._owner;if(null!=b){void 0!==b.ref&&(f=b.ref,m=M.current);void 0!==b.key&&(e=""+b.key);if(a.type&&a.type.defaultProps)var h=
+a.type.defaultProps;for(k in b)ha.call(b,k)&&!ia.hasOwnProperty(k)&&(d[k]=void 0===b[k]&&void 0!==h?h[k]:b[k])}var k=arguments.length-2;if(1===k)d.children=c;else if(1<k){h=Array(k);for(var l=0;l<k;l++)h[l]=arguments[l+2];d.children=h}return{$$typeof:x,type:a.type,key:e,ref:f,props:d,_owner:m}};d.createContext=function(a,b){void 0===b&&(b=null);a={$$typeof:Ea,_calculateChangedBits:b,_currentValue:a,_currentValue2:a,_threadCount:0,Provider:null,Consumer:null};a.Provider={$$typeof:Da,_context:a};return a.Consumer=
+a};d.createElement=ea;d.createFactory=function(a){var b=ea.bind(null,a);b.type=a;return b};d.createRef=function(){return{current:null}};d.forwardRef=function(a){return{$$typeof:Fa,render:a}};d.isValidElement=N;d.lazy=function(a){return{$$typeof:Ia,_ctor:a,_status:-1,_result:null}};d.memo=function(a,b){return{$$typeof:Ha,type:a,compare:void 0===b?null:b}};d.useCallback=function(a,b){return t().useCallback(a,b)};d.useContext=function(a,b){return t().useContext(a,b)};d.useDebugValue=function(a,b){};
+d.useEffect=function(a,b){return t().useEffect(a,b)};d.useImperativeHandle=function(a,b,c){return t().useImperativeHandle(a,b,c)};d.useLayoutEffect=function(a,b){return t().useLayoutEffect(a,b)};d.useMemo=function(a,b){return t().useMemo(a,b)};d.useReducer=function(a,b,c){return t().useReducer(a,b,c)};d.useRef=function(a){return t().useRef(a)};d.useState=function(a){return t().useState(a)};d.version="16.13.1"});
+</script>
+    <script crossorigin>/** @license React v16.13.1
+ * react-dom.production.min.js
+ *
+ * Copyright (c) Facebook, Inc. and its affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+/*
+ Modernizr 3.0.0pre (Custom Build) | MIT
+*/
+'use strict';(function(I,ea){"object"===typeof exports&&"undefined"!==typeof module?ea(exports,require("react")):"function"===typeof define&&define.amd?define(["exports","react"],ea):(I=I||self,ea(I.ReactDOM={},I.React))})(this,function(I,ea){function k(a){for(var b="https://reactjs.org/docs/error-decoder.html?invariant="+a,c=1;c<arguments.length;c++)b+="&args[]="+encodeURIComponent(arguments[c]);return"Minified React error #"+a+"; visit "+b+" for the full message or use the non-minified dev environment for full errors and additional helpful warnings."}
+function ji(a,b,c,d,e,f,g,h,m){yb=!1;gc=null;ki.apply(li,arguments)}function mi(a,b,c,d,e,f,g,h,m){ji.apply(this,arguments);if(yb){if(yb){var n=gc;yb=!1;gc=null}else throw Error(k(198));hc||(hc=!0,pd=n)}}function lf(a,b,c){var d=a.type||"unknown-event";a.currentTarget=mf(c);mi(d,b,void 0,a);a.currentTarget=null}function nf(){if(ic)for(var a in cb){var b=cb[a],c=ic.indexOf(a);if(!(-1<c))throw Error(k(96,a));if(!jc[c]){if(!b.extractEvents)throw Error(k(97,a));jc[c]=b;c=b.eventTypes;for(var d in c){var e=
+void 0;var f=c[d],g=b,h=d;if(qd.hasOwnProperty(h))throw Error(k(99,h));qd[h]=f;var m=f.phasedRegistrationNames;if(m){for(e in m)m.hasOwnProperty(e)&&of(m[e],g,h);e=!0}else f.registrationName?(of(f.registrationName,g,h),e=!0):e=!1;if(!e)throw Error(k(98,d,a));}}}}function of(a,b,c){if(db[a])throw Error(k(100,a));db[a]=b;rd[a]=b.eventTypes[c].dependencies}function pf(a){var b=!1,c;for(c in a)if(a.hasOwnProperty(c)){var d=a[c];if(!cb.hasOwnProperty(c)||cb[c]!==d){if(cb[c])throw Error(k(102,c));cb[c]=
+d;b=!0}}b&&nf()}function qf(a){if(a=rf(a)){if("function"!==typeof sd)throw Error(k(280));var b=a.stateNode;b&&(b=td(b),sd(a.stateNode,a.type,b))}}function sf(a){eb?fb?fb.push(a):fb=[a]:eb=a}function tf(){if(eb){var a=eb,b=fb;fb=eb=null;qf(a);if(b)for(a=0;a<b.length;a++)qf(b[a])}}function ud(){if(null!==eb||null!==fb)vd(),tf()}function uf(a,b,c){if(wd)return a(b,c);wd=!0;try{return vf(a,b,c)}finally{wd=!1,ud()}}function ni(a){if(wf.call(xf,a))return!0;if(wf.call(yf,a))return!1;if(oi.test(a))return xf[a]=
+!0;yf[a]=!0;return!1}function pi(a,b,c,d){if(null!==c&&0===c.type)return!1;switch(typeof b){case "function":case "symbol":return!0;case "boolean":if(d)return!1;if(null!==c)return!c.acceptsBooleans;a=a.toLowerCase().slice(0,5);return"data-"!==a&&"aria-"!==a;default:return!1}}function qi(a,b,c,d){if(null===b||"undefined"===typeof b||pi(a,b,c,d))return!0;if(d)return!1;if(null!==c)switch(c.type){case 3:return!b;case 4:return!1===b;case 5:return isNaN(b);case 6:return isNaN(b)||1>b}return!1}function L(a,
+b,c,d,e,f){this.acceptsBooleans=2===b||3===b||4===b;this.attributeName=d;this.attributeNamespace=e;this.mustUseProperty=c;this.propertyName=a;this.type=b;this.sanitizeURL=f}function xd(a,b,c,d){var e=E.hasOwnProperty(b)?E[b]:null;var f=null!==e?0===e.type:d?!1:!(2<b.length)||"o"!==b[0]&&"O"!==b[0]||"n"!==b[1]&&"N"!==b[1]?!1:!0;f||(qi(b,c,e,d)&&(c=null),d||null===e?ni(b)&&(null===c?a.removeAttribute(b):a.setAttribute(b,""+c)):e.mustUseProperty?a[e.propertyName]=null===c?3===e.type?!1:"":c:(b=e.attributeName,
+d=e.attributeNamespace,null===c?a.removeAttribute(b):(e=e.type,c=3===e||4===e&&!0===c?"":""+c,d?a.setAttributeNS(d,b,c):a.setAttribute(b,c))))}function zb(a){if(null===a||"object"!==typeof a)return null;a=zf&&a[zf]||a["@@iterator"];return"function"===typeof a?a:null}function ri(a){if(-1===a._status){a._status=0;var b=a._ctor;b=b();a._result=b;b.then(function(b){0===a._status&&(b=b.default,a._status=1,a._result=b)},function(b){0===a._status&&(a._status=2,a._result=b)})}}function na(a){if(null==a)return null;
+if("function"===typeof a)return a.displayName||a.name||null;if("string"===typeof a)return a;switch(a){case Ma:return"Fragment";case gb:return"Portal";case kc:return"Profiler";case Af:return"StrictMode";case lc:return"Suspense";case yd:return"SuspenseList"}if("object"===typeof a)switch(a.$$typeof){case Bf:return"Context.Consumer";case Cf:return"Context.Provider";case zd:var b=a.render;b=b.displayName||b.name||"";return a.displayName||(""!==b?"ForwardRef("+b+")":"ForwardRef");case Ad:return na(a.type);
+case Df:return na(a.render);case Ef:if(a=1===a._status?a._result:null)return na(a)}return null}function Bd(a){var b="";do{a:switch(a.tag){case 3:case 4:case 6:case 7:case 10:case 9:var c="";break a;default:var d=a._debugOwner,e=a._debugSource,f=na(a.type);c=null;d&&(c=na(d.type));d=f;f="";e?f=" (at "+e.fileName.replace(si,"")+":"+e.lineNumber+")":c&&(f=" (created by "+c+")");c="\n    in "+(d||"Unknown")+f}b+=c;a=a.return}while(a);return b}function va(a){switch(typeof a){case "boolean":case "number":case "object":case "string":case "undefined":return a;
+default:return""}}function Ff(a){var b=a.type;return(a=a.nodeName)&&"input"===a.toLowerCase()&&("checkbox"===b||"radio"===b)}function ti(a){var b=Ff(a)?"checked":"value",c=Object.getOwnPropertyDescriptor(a.constructor.prototype,b),d=""+a[b];if(!a.hasOwnProperty(b)&&"undefined"!==typeof c&&"function"===typeof c.get&&"function"===typeof c.set){var e=c.get,f=c.set;Object.defineProperty(a,b,{configurable:!0,get:function(){return e.call(this)},set:function(a){d=""+a;f.call(this,a)}});Object.defineProperty(a,
+b,{enumerable:c.enumerable});return{getValue:function(){return d},setValue:function(a){d=""+a},stopTracking:function(){a._valueTracker=null;delete a[b]}}}}function mc(a){a._valueTracker||(a._valueTracker=ti(a))}function Gf(a){if(!a)return!1;var b=a._valueTracker;if(!b)return!0;var c=b.getValue();var d="";a&&(d=Ff(a)?a.checked?"true":"false":a.value);a=d;return a!==c?(b.setValue(a),!0):!1}function Cd(a,b){var c=b.checked;return M({},b,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:null!=
+c?c:a._wrapperState.initialChecked})}function Hf(a,b){var c=null==b.defaultValue?"":b.defaultValue,d=null!=b.checked?b.checked:b.defaultChecked;c=va(null!=b.value?b.value:c);a._wrapperState={initialChecked:d,initialValue:c,controlled:"checkbox"===b.type||"radio"===b.type?null!=b.checked:null!=b.value}}function If(a,b){b=b.checked;null!=b&&xd(a,"checked",b,!1)}function Dd(a,b){If(a,b);var c=va(b.value),d=b.type;if(null!=c)if("number"===d){if(0===c&&""===a.value||a.value!=c)a.value=""+c}else a.value!==
+""+c&&(a.value=""+c);else if("submit"===d||"reset"===d){a.removeAttribute("value");return}b.hasOwnProperty("value")?Ed(a,b.type,c):b.hasOwnProperty("defaultValue")&&Ed(a,b.type,va(b.defaultValue));null==b.checked&&null!=b.defaultChecked&&(a.defaultChecked=!!b.defaultChecked)}function Jf(a,b,c){if(b.hasOwnProperty("value")||b.hasOwnProperty("defaultValue")){var d=b.type;if(!("submit"!==d&&"reset"!==d||void 0!==b.value&&null!==b.value))return;b=""+a._wrapperState.initialValue;c||b===a.value||(a.value=
+b);a.defaultValue=b}c=a.name;""!==c&&(a.name="");a.defaultChecked=!!a._wrapperState.initialChecked;""!==c&&(a.name=c)}function Ed(a,b,c){if("number"!==b||a.ownerDocument.activeElement!==a)null==c?a.defaultValue=""+a._wrapperState.initialValue:a.defaultValue!==""+c&&(a.defaultValue=""+c)}function ui(a){var b="";ea.Children.forEach(a,function(a){null!=a&&(b+=a)});return b}function Fd(a,b){a=M({children:void 0},b);if(b=ui(b.children))a.children=b;return a}function hb(a,b,c,d){a=a.options;if(b){b={};
+for(var e=0;e<c.length;e++)b["$"+c[e]]=!0;for(c=0;c<a.length;c++)e=b.hasOwnProperty("$"+a[c].value),a[c].selected!==e&&(a[c].selected=e),e&&d&&(a[c].defaultSelected=!0)}else{c=""+va(c);b=null;for(e=0;e<a.length;e++){if(a[e].value===c){a[e].selected=!0;d&&(a[e].defaultSelected=!0);return}null!==b||a[e].disabled||(b=a[e])}null!==b&&(b.selected=!0)}}function Gd(a,b){if(null!=b.dangerouslySetInnerHTML)throw Error(k(91));return M({},b,{value:void 0,defaultValue:void 0,children:""+a._wrapperState.initialValue})}
+function Kf(a,b){var c=b.value;if(null==c){c=b.children;b=b.defaultValue;if(null!=c){if(null!=b)throw Error(k(92));if(Array.isArray(c)){if(!(1>=c.length))throw Error(k(93));c=c[0]}b=c}null==b&&(b="");c=b}a._wrapperState={initialValue:va(c)}}function Lf(a,b){var c=va(b.value),d=va(b.defaultValue);null!=c&&(c=""+c,c!==a.value&&(a.value=c),null==b.defaultValue&&a.defaultValue!==c&&(a.defaultValue=c));null!=d&&(a.defaultValue=""+d)}function Mf(a,b){b=a.textContent;b===a._wrapperState.initialValue&&""!==
+b&&null!==b&&(a.value=b)}function Nf(a){switch(a){case "svg":return"http://www.w3.org/2000/svg";case "math":return"http://www.w3.org/1998/Math/MathML";default:return"http://www.w3.org/1999/xhtml"}}function Hd(a,b){return null==a||"http://www.w3.org/1999/xhtml"===a?Nf(b):"http://www.w3.org/2000/svg"===a&&"foreignObject"===b?"http://www.w3.org/1999/xhtml":a}function nc(a,b){var c={};c[a.toLowerCase()]=b.toLowerCase();c["Webkit"+a]="webkit"+b;c["Moz"+a]="moz"+b;return c}function oc(a){if(Id[a])return Id[a];
+if(!ib[a])return a;var b=ib[a],c;for(c in b)if(b.hasOwnProperty(c)&&c in Of)return Id[a]=b[c];return a}function Jd(a){var b=Pf.get(a);void 0===b&&(b=new Map,Pf.set(a,b));return b}function Na(a){var b=a,c=a;if(a.alternate)for(;b.return;)b=b.return;else{a=b;do b=a,0!==(b.effectTag&1026)&&(c=b.return),a=b.return;while(a)}return 3===b.tag?c:null}function Qf(a){if(13===a.tag){var b=a.memoizedState;null===b&&(a=a.alternate,null!==a&&(b=a.memoizedState));if(null!==b)return b.dehydrated}return null}function Rf(a){if(Na(a)!==
+a)throw Error(k(188));}function vi(a){var b=a.alternate;if(!b){b=Na(a);if(null===b)throw Error(k(188));return b!==a?null:a}for(var c=a,d=b;;){var e=c.return;if(null===e)break;var f=e.alternate;if(null===f){d=e.return;if(null!==d){c=d;continue}break}if(e.child===f.child){for(f=e.child;f;){if(f===c)return Rf(e),a;if(f===d)return Rf(e),b;f=f.sibling}throw Error(k(188));}if(c.return!==d.return)c=e,d=f;else{for(var g=!1,h=e.child;h;){if(h===c){g=!0;c=e;d=f;break}if(h===d){g=!0;d=e;c=f;break}h=h.sibling}if(!g){for(h=
+f.child;h;){if(h===c){g=!0;c=f;d=e;break}if(h===d){g=!0;d=f;c=e;break}h=h.sibling}if(!g)throw Error(k(189));}}if(c.alternate!==d)throw Error(k(190));}if(3!==c.tag)throw Error(k(188));return c.stateNode.current===c?a:b}function Sf(a){a=vi(a);if(!a)return null;for(var b=a;;){if(5===b.tag||6===b.tag)return b;if(b.child)b.child.return=b,b=b.child;else{if(b===a)break;for(;!b.sibling;){if(!b.return||b.return===a)return null;b=b.return}b.sibling.return=b.return;b=b.sibling}}return null}function jb(a,b){if(null==
+b)throw Error(k(30));if(null==a)return b;if(Array.isArray(a)){if(Array.isArray(b))return a.push.apply(a,b),a;a.push(b);return a}return Array.isArray(b)?[a].concat(b):[a,b]}function Kd(a,b,c){Array.isArray(a)?a.forEach(b,c):a&&b.call(c,a)}function pc(a){null!==a&&(Ab=jb(Ab,a));a=Ab;Ab=null;if(a){Kd(a,wi);if(Ab)throw Error(k(95));if(hc)throw a=pd,hc=!1,pd=null,a;}}function Ld(a){a=a.target||a.srcElement||window;a.correspondingUseElement&&(a=a.correspondingUseElement);return 3===a.nodeType?a.parentNode:
+a}function Tf(a){if(!wa)return!1;a="on"+a;var b=a in document;b||(b=document.createElement("div"),b.setAttribute(a,"return;"),b="function"===typeof b[a]);return b}function Uf(a){a.topLevelType=null;a.nativeEvent=null;a.targetInst=null;a.ancestors.length=0;10>qc.length&&qc.push(a)}function Vf(a,b,c,d){if(qc.length){var e=qc.pop();e.topLevelType=a;e.eventSystemFlags=d;e.nativeEvent=b;e.targetInst=c;return e}return{topLevelType:a,eventSystemFlags:d,nativeEvent:b,targetInst:c,ancestors:[]}}function Wf(a){var b=
+a.targetInst,c=b;do{if(!c){a.ancestors.push(c);break}var d=c;if(3===d.tag)d=d.stateNode.containerInfo;else{for(;d.return;)d=d.return;d=3!==d.tag?null:d.stateNode.containerInfo}if(!d)break;b=c.tag;5!==b&&6!==b||a.ancestors.push(c);c=Bb(d)}while(c);for(c=0;c<a.ancestors.length;c++){b=a.ancestors[c];var e=Ld(a.nativeEvent);d=a.topLevelType;var f=a.nativeEvent,g=a.eventSystemFlags;0===c&&(g|=64);for(var h=null,m=0;m<jc.length;m++){var n=jc[m];n&&(n=n.extractEvents(d,b,f,e,g))&&(h=jb(h,n))}pc(h)}}function Md(a,
+b,c){if(!c.has(a)){switch(a){case "scroll":Cb(b,"scroll",!0);break;case "focus":case "blur":Cb(b,"focus",!0);Cb(b,"blur",!0);c.set("blur",null);c.set("focus",null);break;case "cancel":case "close":Tf(a)&&Cb(b,a,!0);break;case "invalid":case "submit":case "reset":break;default:-1===Db.indexOf(a)&&w(a,b)}c.set(a,null)}}function xi(a,b){var c=Jd(b);Nd.forEach(function(a){Md(a,b,c)});yi.forEach(function(a){Md(a,b,c)})}function Od(a,b,c,d,e){return{blockedOn:a,topLevelType:b,eventSystemFlags:c|32,nativeEvent:e,
+container:d}}function Xf(a,b){switch(a){case "focus":case "blur":xa=null;break;case "dragenter":case "dragleave":ya=null;break;case "mouseover":case "mouseout":za=null;break;case "pointerover":case "pointerout":Eb.delete(b.pointerId);break;case "gotpointercapture":case "lostpointercapture":Fb.delete(b.pointerId)}}function Gb(a,b,c,d,e,f){if(null===a||a.nativeEvent!==f)return a=Od(b,c,d,e,f),null!==b&&(b=Hb(b),null!==b&&Yf(b)),a;a.eventSystemFlags|=d;return a}function zi(a,b,c,d,e){switch(b){case "focus":return xa=
+Gb(xa,a,b,c,d,e),!0;case "dragenter":return ya=Gb(ya,a,b,c,d,e),!0;case "mouseover":return za=Gb(za,a,b,c,d,e),!0;case "pointerover":var f=e.pointerId;Eb.set(f,Gb(Eb.get(f)||null,a,b,c,d,e));return!0;case "gotpointercapture":return f=e.pointerId,Fb.set(f,Gb(Fb.get(f)||null,a,b,c,d,e)),!0}return!1}function Ai(a){var b=Bb(a.target);if(null!==b){var c=Na(b);if(null!==c)if(b=c.tag,13===b){if(b=Qf(c),null!==b){a.blockedOn=b;Pd(a.priority,function(){Bi(c)});return}}else if(3===b&&c.stateNode.hydrate){a.blockedOn=
+3===c.tag?c.stateNode.containerInfo:null;return}}a.blockedOn=null}function rc(a){if(null!==a.blockedOn)return!1;var b=Qd(a.topLevelType,a.eventSystemFlags,a.container,a.nativeEvent);if(null!==b){var c=Hb(b);null!==c&&Yf(c);a.blockedOn=b;return!1}return!0}function Zf(a,b,c){rc(a)&&c.delete(b)}function Ci(){for(Rd=!1;0<fa.length;){var a=fa[0];if(null!==a.blockedOn){a=Hb(a.blockedOn);null!==a&&Di(a);break}var b=Qd(a.topLevelType,a.eventSystemFlags,a.container,a.nativeEvent);null!==b?a.blockedOn=b:fa.shift()}null!==
+xa&&rc(xa)&&(xa=null);null!==ya&&rc(ya)&&(ya=null);null!==za&&rc(za)&&(za=null);Eb.forEach(Zf);Fb.forEach(Zf)}function Ib(a,b){a.blockedOn===b&&(a.blockedOn=null,Rd||(Rd=!0,$f(ag,Ci)))}function bg(a){if(0<fa.length){Ib(fa[0],a);for(var b=1;b<fa.length;b++){var c=fa[b];c.blockedOn===a&&(c.blockedOn=null)}}null!==xa&&Ib(xa,a);null!==ya&&Ib(ya,a);null!==za&&Ib(za,a);b=function(b){return Ib(b,a)};Eb.forEach(b);Fb.forEach(b);for(b=0;b<Jb.length;b++)c=Jb[b],c.blockedOn===a&&(c.blockedOn=null);for(;0<Jb.length&&
+(b=Jb[0],null===b.blockedOn);)Ai(b),null===b.blockedOn&&Jb.shift()}function Sd(a,b){for(var c=0;c<a.length;c+=2){var d=a[c],e=a[c+1],f="on"+(e[0].toUpperCase()+e.slice(1));f={phasedRegistrationNames:{bubbled:f,captured:f+"Capture"},dependencies:[d],eventPriority:b};Td.set(d,b);cg.set(d,f);dg[e]=f}}function w(a,b){Cb(b,a,!1)}function Cb(a,b,c){var d=Td.get(b);switch(void 0===d?2:d){case 0:d=Ei.bind(null,b,1,a);break;case 1:d=Fi.bind(null,b,1,a);break;default:d=sc.bind(null,b,1,a)}c?a.addEventListener(b,
+d,!0):a.addEventListener(b,d,!1)}function Ei(a,b,c,d){Oa||vd();var e=sc,f=Oa;Oa=!0;try{eg(e,a,b,c,d)}finally{(Oa=f)||ud()}}function Fi(a,b,c,d){Gi(Hi,sc.bind(null,a,b,c,d))}function sc(a,b,c,d){if(tc)if(0<fa.length&&-1<Nd.indexOf(a))a=Od(null,a,b,c,d),fa.push(a);else{var e=Qd(a,b,c,d);if(null===e)Xf(a,d);else if(-1<Nd.indexOf(a))a=Od(e,a,b,c,d),fa.push(a);else if(!zi(e,a,b,c,d)){Xf(a,d);a=Vf(a,d,null,b);try{uf(Wf,a)}finally{Uf(a)}}}}function Qd(a,b,c,d){c=Ld(d);c=Bb(c);if(null!==c){var e=Na(c);if(null===
+e)c=null;else{var f=e.tag;if(13===f){c=Qf(e);if(null!==c)return c;c=null}else if(3===f){if(e.stateNode.hydrate)return 3===e.tag?e.stateNode.containerInfo:null;c=null}else e!==c&&(c=null)}}a=Vf(a,d,c,b);try{uf(Wf,a)}finally{Uf(a)}return null}function fg(a,b,c){return null==b||"boolean"===typeof b||""===b?"":c||"number"!==typeof b||0===b||Kb.hasOwnProperty(a)&&Kb[a]?(""+b).trim():b+"px"}function gg(a,b){a=a.style;for(var c in b)if(b.hasOwnProperty(c)){var d=0===c.indexOf("--"),e=fg(c,b[c],d);"float"===
+c&&(c="cssFloat");d?a.setProperty(c,e):a[c]=e}}function Ud(a,b){if(b){if(Ii[a]&&(null!=b.children||null!=b.dangerouslySetInnerHTML))throw Error(k(137,a,""));if(null!=b.dangerouslySetInnerHTML){if(null!=b.children)throw Error(k(60));if(!("object"===typeof b.dangerouslySetInnerHTML&&"__html"in b.dangerouslySetInnerHTML))throw Error(k(61));}if(null!=b.style&&"object"!==typeof b.style)throw Error(k(62,""));}}function Vd(a,b){if(-1===a.indexOf("-"))return"string"===typeof b.is;switch(a){case "annotation-xml":case "color-profile":case "font-face":case "font-face-src":case "font-face-uri":case "font-face-format":case "font-face-name":case "missing-glyph":return!1;
+default:return!0}}function oa(a,b){a=9===a.nodeType||11===a.nodeType?a:a.ownerDocument;var c=Jd(a);b=rd[b];for(var d=0;d<b.length;d++)Md(b[d],a,c)}function uc(){}function Wd(a){a=a||("undefined"!==typeof document?document:void 0);if("undefined"===typeof a)return null;try{return a.activeElement||a.body}catch(b){return a.body}}function hg(a){for(;a&&a.firstChild;)a=a.firstChild;return a}function ig(a,b){var c=hg(a);a=0;for(var d;c;){if(3===c.nodeType){d=a+c.textContent.length;if(a<=b&&d>=b)return{node:c,
+offset:b-a};a=d}a:{for(;c;){if(c.nextSibling){c=c.nextSibling;break a}c=c.parentNode}c=void 0}c=hg(c)}}function jg(a,b){return a&&b?a===b?!0:a&&3===a.nodeType?!1:b&&3===b.nodeType?jg(a,b.parentNode):"contains"in a?a.contains(b):a.compareDocumentPosition?!!(a.compareDocumentPosition(b)&16):!1:!1}function kg(){for(var a=window,b=Wd();b instanceof a.HTMLIFrameElement;){try{var c="string"===typeof b.contentWindow.location.href}catch(d){c=!1}if(c)a=b.contentWindow;else break;b=Wd(a.document)}return b}
+function Xd(a){var b=a&&a.nodeName&&a.nodeName.toLowerCase();return b&&("input"===b&&("text"===a.type||"search"===a.type||"tel"===a.type||"url"===a.type||"password"===a.type)||"textarea"===b||"true"===a.contentEditable)}function lg(a,b){switch(a){case "button":case "input":case "select":case "textarea":return!!b.autoFocus}return!1}function Yd(a,b){return"textarea"===a||"option"===a||"noscript"===a||"string"===typeof b.children||"number"===typeof b.children||"object"===typeof b.dangerouslySetInnerHTML&&
+null!==b.dangerouslySetInnerHTML&&null!=b.dangerouslySetInnerHTML.__html}function kb(a){for(;null!=a;a=a.nextSibling){var b=a.nodeType;if(1===b||3===b)break}return a}function mg(a){a=a.previousSibling;for(var b=0;a;){if(8===a.nodeType){var c=a.data;if(c===ng||c===Zd||c===$d){if(0===b)return a;b--}else c===og&&b++}a=a.previousSibling}return null}function Bb(a){var b=a[Aa];if(b)return b;for(var c=a.parentNode;c;){if(b=c[Lb]||c[Aa]){c=b.alternate;if(null!==b.child||null!==c&&null!==c.child)for(a=mg(a);null!==
+a;){if(c=a[Aa])return c;a=mg(a)}return b}a=c;c=a.parentNode}return null}function Hb(a){a=a[Aa]||a[Lb];return!a||5!==a.tag&&6!==a.tag&&13!==a.tag&&3!==a.tag?null:a}function Pa(a){if(5===a.tag||6===a.tag)return a.stateNode;throw Error(k(33));}function ae(a){return a[vc]||null}function pa(a){do a=a.return;while(a&&5!==a.tag);return a?a:null}function pg(a,b){var c=a.stateNode;if(!c)return null;var d=td(c);if(!d)return null;c=d[b];a:switch(b){case "onClick":case "onClickCapture":case "onDoubleClick":case "onDoubleClickCapture":case "onMouseDown":case "onMouseDownCapture":case "onMouseMove":case "onMouseMoveCapture":case "onMouseUp":case "onMouseUpCapture":case "onMouseEnter":(d=
+!d.disabled)||(a=a.type,d=!("button"===a||"input"===a||"select"===a||"textarea"===a));a=!d;break a;default:a=!1}if(a)return null;if(c&&"function"!==typeof c)throw Error(k(231,b,typeof c));return c}function qg(a,b,c){if(b=pg(a,c.dispatchConfig.phasedRegistrationNames[b]))c._dispatchListeners=jb(c._dispatchListeners,b),c._dispatchInstances=jb(c._dispatchInstances,a)}function Ji(a){if(a&&a.dispatchConfig.phasedRegistrationNames){for(var b=a._targetInst,c=[];b;)c.push(b),b=pa(b);for(b=c.length;0<b--;)qg(c[b],
+"captured",a);for(b=0;b<c.length;b++)qg(c[b],"bubbled",a)}}function be(a,b,c){a&&c&&c.dispatchConfig.registrationName&&(b=pg(a,c.dispatchConfig.registrationName))&&(c._dispatchListeners=jb(c._dispatchListeners,b),c._dispatchInstances=jb(c._dispatchInstances,a))}function Ki(a){a&&a.dispatchConfig.registrationName&&be(a._targetInst,null,a)}function lb(a){Kd(a,Ji)}function rg(){if(wc)return wc;var a,b=ce,c=b.length,d,e="value"in Ba?Ba.value:Ba.textContent,f=e.length;for(a=0;a<c&&b[a]===e[a];a++);var g=
+c-a;for(d=1;d<=g&&b[c-d]===e[f-d];d++);return wc=e.slice(a,1<d?1-d:void 0)}function xc(){return!0}function yc(){return!1}function R(a,b,c,d){this.dispatchConfig=a;this._targetInst=b;this.nativeEvent=c;a=this.constructor.Interface;for(var e in a)a.hasOwnProperty(e)&&((b=a[e])?this[e]=b(c):"target"===e?this.target=d:this[e]=c[e]);this.isDefaultPrevented=(null!=c.defaultPrevented?c.defaultPrevented:!1===c.returnValue)?xc:yc;this.isPropagationStopped=yc;return this}function Li(a,b,c,d){if(this.eventPool.length){var e=
+this.eventPool.pop();this.call(e,a,b,c,d);return e}return new this(a,b,c,d)}function Mi(a){if(!(a instanceof this))throw Error(k(279));a.destructor();10>this.eventPool.length&&this.eventPool.push(a)}function sg(a){a.eventPool=[];a.getPooled=Li;a.release=Mi}function tg(a,b){switch(a){case "keyup":return-1!==Ni.indexOf(b.keyCode);case "keydown":return 229!==b.keyCode;case "keypress":case "mousedown":case "blur":return!0;default:return!1}}function ug(a){a=a.detail;return"object"===typeof a&&"data"in
+a?a.data:null}function Oi(a,b){switch(a){case "compositionend":return ug(b);case "keypress":if(32!==b.which)return null;vg=!0;return wg;case "textInput":return a=b.data,a===wg&&vg?null:a;default:return null}}function Pi(a,b){if(mb)return"compositionend"===a||!de&&tg(a,b)?(a=rg(),wc=ce=Ba=null,mb=!1,a):null;switch(a){case "paste":return null;case "keypress":if(!(b.ctrlKey||b.altKey||b.metaKey)||b.ctrlKey&&b.altKey){if(b.char&&1<b.char.length)return b.char;if(b.which)return String.fromCharCode(b.which)}return null;
+case "compositionend":return xg&&"ko"!==b.locale?null:b.data;default:return null}}function yg(a){var b=a&&a.nodeName&&a.nodeName.toLowerCase();return"input"===b?!!Qi[a.type]:"textarea"===b?!0:!1}function zg(a,b,c){a=R.getPooled(Ag.change,a,b,c);a.type="change";sf(c);lb(a);return a}function Ri(a){pc(a)}function zc(a){var b=Pa(a);if(Gf(b))return a}function Si(a,b){if("change"===a)return b}function Bg(){Mb&&(Mb.detachEvent("onpropertychange",Cg),Nb=Mb=null)}function Cg(a){if("value"===a.propertyName&&
+zc(Nb))if(a=zg(Nb,a,Ld(a)),Oa)pc(a);else{Oa=!0;try{ee(Ri,a)}finally{Oa=!1,ud()}}}function Ti(a,b,c){"focus"===a?(Bg(),Mb=b,Nb=c,Mb.attachEvent("onpropertychange",Cg)):"blur"===a&&Bg()}function Ui(a,b){if("selectionchange"===a||"keyup"===a||"keydown"===a)return zc(Nb)}function Vi(a,b){if("click"===a)return zc(b)}function Wi(a,b){if("input"===a||"change"===a)return zc(b)}function Xi(a){var b=this.nativeEvent;return b.getModifierState?b.getModifierState(a):(a=Yi[a])?!!b[a]:!1}function fe(a){return Xi}
+function Zi(a,b){return a===b&&(0!==a||1/a===1/b)||a!==a&&b!==b}function Ob(a,b){if(Qa(a,b))return!0;if("object"!==typeof a||null===a||"object"!==typeof b||null===b)return!1;var c=Object.keys(a),d=Object.keys(b);if(c.length!==d.length)return!1;for(d=0;d<c.length;d++)if(!$i.call(b,c[d])||!Qa(a[c[d]],b[c[d]]))return!1;return!0}function Dg(a,b){var c=b.window===b?b.document:9===b.nodeType?b:b.ownerDocument;if(ge||null==nb||nb!==Wd(c))return null;c=nb;"selectionStart"in c&&Xd(c)?c={start:c.selectionStart,
+end:c.selectionEnd}:(c=(c.ownerDocument&&c.ownerDocument.defaultView||window).getSelection(),c={anchorNode:c.anchorNode,anchorOffset:c.anchorOffset,focusNode:c.focusNode,focusOffset:c.focusOffset});return Pb&&Ob(Pb,c)?null:(Pb=c,a=R.getPooled(Eg.select,he,a,b),a.type="select",a.target=nb,lb(a),a)}function Ac(a){var b=a.keyCode;"charCode"in a?(a=a.charCode,0===a&&13===b&&(a=13)):a=b;10===a&&(a=13);return 32<=a||13===a?a:0}function q(a,b){0>ob||(a.current=ie[ob],ie[ob]=null,ob--)}function y(a,b,c){ob++;
+ie[ob]=a.current;a.current=b}function pb(a,b){var c=a.type.contextTypes;if(!c)return Ca;var d=a.stateNode;if(d&&d.__reactInternalMemoizedUnmaskedChildContext===b)return d.__reactInternalMemoizedMaskedChildContext;var e={},f;for(f in c)e[f]=b[f];d&&(a=a.stateNode,a.__reactInternalMemoizedUnmaskedChildContext=b,a.__reactInternalMemoizedMaskedChildContext=e);return e}function N(a){a=a.childContextTypes;return null!==a&&void 0!==a}function Fg(a,b,c){if(B.current!==Ca)throw Error(k(168));y(B,b);y(G,c)}
+function Gg(a,b,c){var d=a.stateNode;a=b.childContextTypes;if("function"!==typeof d.getChildContext)return c;d=d.getChildContext();for(var e in d)if(!(e in a))throw Error(k(108,na(b)||"Unknown",e));return M({},c,{},d)}function Bc(a){a=(a=a.stateNode)&&a.__reactInternalMemoizedMergedChildContext||Ca;Ra=B.current;y(B,a);y(G,G.current);return!0}function Hg(a,b,c){var d=a.stateNode;if(!d)throw Error(k(169));c?(a=Gg(a,b,Ra),d.__reactInternalMemoizedMergedChildContext=a,q(G),q(B),y(B,a)):q(G);y(G,c)}function Cc(){switch(aj()){case Dc:return 99;
+case Ig:return 98;case Jg:return 97;case Kg:return 96;case Lg:return 95;default:throw Error(k(332));}}function Mg(a){switch(a){case 99:return Dc;case 98:return Ig;case 97:return Jg;case 96:return Kg;case 95:return Lg;default:throw Error(k(332));}}function Da(a,b){a=Mg(a);return bj(a,b)}function Ng(a,b,c){a=Mg(a);return je(a,b,c)}function Og(a){null===qa?(qa=[a],Ec=je(Dc,Pg)):qa.push(a);return Qg}function ha(){if(null!==Ec){var a=Ec;Ec=null;Rg(a)}Pg()}function Pg(){if(!ke&&null!==qa){ke=!0;var a=0;
+try{var b=qa;Da(99,function(){for(;a<b.length;a++){var c=b[a];do c=c(!0);while(null!==c)}});qa=null}catch(c){throw null!==qa&&(qa=qa.slice(a+1)),je(Dc,ha),c;}finally{ke=!1}}}function Fc(a,b,c){c/=10;return 1073741821-(((1073741821-a+b/10)/c|0)+1)*c}function aa(a,b){if(a&&a.defaultProps){b=M({},b);a=a.defaultProps;for(var c in a)void 0===b[c]&&(b[c]=a[c])}return b}function le(){Gc=qb=Hc=null}function me(a){var b=Ic.current;q(Ic);a.type._context._currentValue=b}function Sg(a,b){for(;null!==a;){var c=
+a.alternate;if(a.childExpirationTime<b)a.childExpirationTime=b,null!==c&&c.childExpirationTime<b&&(c.childExpirationTime=b);else if(null!==c&&c.childExpirationTime<b)c.childExpirationTime=b;else break;a=a.return}}function rb(a,b){Hc=a;Gc=qb=null;a=a.dependencies;null!==a&&null!==a.firstContext&&(a.expirationTime>=b&&(ia=!0),a.firstContext=null)}function W(a,b){if(Gc!==a&&!1!==b&&0!==b){if("number"!==typeof b||1073741823===b)Gc=a,b=1073741823;b={context:a,observedBits:b,next:null};if(null===qb){if(null===
+Hc)throw Error(k(308));qb=b;Hc.dependencies={expirationTime:0,firstContext:b,responders:null}}else qb=qb.next=b}return a._currentValue}function ne(a){a.updateQueue={baseState:a.memoizedState,baseQueue:null,shared:{pending:null},effects:null}}function oe(a,b){a=a.updateQueue;b.updateQueue===a&&(b.updateQueue={baseState:a.baseState,baseQueue:a.baseQueue,shared:a.shared,effects:a.effects})}function Ea(a,b){a={expirationTime:a,suspenseConfig:b,tag:Tg,payload:null,callback:null,next:null};return a.next=
+a}function Fa(a,b){a=a.updateQueue;if(null!==a){a=a.shared;var c=a.pending;null===c?b.next=b:(b.next=c.next,c.next=b);a.pending=b}}function Ug(a,b){var c=a.alternate;null!==c&&oe(c,a);a=a.updateQueue;c=a.baseQueue;null===c?(a.baseQueue=b.next=b,b.next=b):(b.next=c.next,c.next=b)}function Qb(a,b,c,d){var e=a.updateQueue;Ga=!1;var f=e.baseQueue,g=e.shared.pending;if(null!==g){if(null!==f){var h=f.next;f.next=g.next;g.next=h}f=g;e.shared.pending=null;h=a.alternate;null!==h&&(h=h.updateQueue,null!==h&&
+(h.baseQueue=g))}if(null!==f){h=f.next;var m=e.baseState,n=0,k=null,ba=null,l=null;if(null!==h){var p=h;do{g=p.expirationTime;if(g<d){var t={expirationTime:p.expirationTime,suspenseConfig:p.suspenseConfig,tag:p.tag,payload:p.payload,callback:p.callback,next:null};null===l?(ba=l=t,k=m):l=l.next=t;g>n&&(n=g)}else{null!==l&&(l=l.next={expirationTime:1073741823,suspenseConfig:p.suspenseConfig,tag:p.tag,payload:p.payload,callback:p.callback,next:null});Vg(g,p.suspenseConfig);a:{var q=a,r=p;g=b;t=c;switch(r.tag){case 1:q=
+r.payload;if("function"===typeof q){m=q.call(t,m,g);break a}m=q;break a;case 3:q.effectTag=q.effectTag&-4097|64;case Tg:q=r.payload;g="function"===typeof q?q.call(t,m,g):q;if(null===g||void 0===g)break a;m=M({},m,g);break a;case Jc:Ga=!0}}null!==p.callback&&(a.effectTag|=32,g=e.effects,null===g?e.effects=[p]:g.push(p))}p=p.next;if(null===p||p===h)if(g=e.shared.pending,null===g)break;else p=f.next=g.next,g.next=h,e.baseQueue=f=g,e.shared.pending=null}while(1)}null===l?k=m:l.next=ba;e.baseState=k;e.baseQueue=
+l;Kc(n);a.expirationTime=n;a.memoizedState=m}}function Wg(a,b,c){a=b.effects;b.effects=null;if(null!==a)for(b=0;b<a.length;b++){var d=a[b],e=d.callback;if(null!==e){d.callback=null;d=e;e=c;if("function"!==typeof d)throw Error(k(191,d));d.call(e)}}}function Lc(a,b,c,d){b=a.memoizedState;c=c(d,b);c=null===c||void 0===c?b:M({},b,c);a.memoizedState=c;0===a.expirationTime&&(a.updateQueue.baseState=c)}function Xg(a,b,c,d,e,f,g){a=a.stateNode;return"function"===typeof a.shouldComponentUpdate?a.shouldComponentUpdate(d,
+f,g):b.prototype&&b.prototype.isPureReactComponent?!Ob(c,d)||!Ob(e,f):!0}function Yg(a,b,c){var d=!1,e=Ca;var f=b.contextType;"object"===typeof f&&null!==f?f=W(f):(e=N(b)?Ra:B.current,d=b.contextTypes,f=(d=null!==d&&void 0!==d)?pb(a,e):Ca);b=new b(c,f);a.memoizedState=null!==b.state&&void 0!==b.state?b.state:null;b.updater=Mc;a.stateNode=b;b._reactInternalFiber=a;d&&(a=a.stateNode,a.__reactInternalMemoizedUnmaskedChildContext=e,a.__reactInternalMemoizedMaskedChildContext=f);return b}function Zg(a,
+b,c,d){a=b.state;"function"===typeof b.componentWillReceiveProps&&b.componentWillReceiveProps(c,d);"function"===typeof b.UNSAFE_componentWillReceiveProps&&b.UNSAFE_componentWillReceiveProps(c,d);b.state!==a&&Mc.enqueueReplaceState(b,b.state,null)}function pe(a,b,c,d){var e=a.stateNode;e.props=c;e.state=a.memoizedState;e.refs=$g;ne(a);var f=b.contextType;"object"===typeof f&&null!==f?e.context=W(f):(f=N(b)?Ra:B.current,e.context=pb(a,f));Qb(a,c,e,d);e.state=a.memoizedState;f=b.getDerivedStateFromProps;
+"function"===typeof f&&(Lc(a,b,f,c),e.state=a.memoizedState);"function"===typeof b.getDerivedStateFromProps||"function"===typeof e.getSnapshotBeforeUpdate||"function"!==typeof e.UNSAFE_componentWillMount&&"function"!==typeof e.componentWillMount||(b=e.state,"function"===typeof e.componentWillMount&&e.componentWillMount(),"function"===typeof e.UNSAFE_componentWillMount&&e.UNSAFE_componentWillMount(),b!==e.state&&Mc.enqueueReplaceState(e,e.state,null),Qb(a,c,e,d),e.state=a.memoizedState);"function"===
+typeof e.componentDidMount&&(a.effectTag|=4)}function Rb(a,b,c){a=c.ref;if(null!==a&&"function"!==typeof a&&"object"!==typeof a){if(c._owner){c=c._owner;if(c){if(1!==c.tag)throw Error(k(309));var d=c.stateNode}if(!d)throw Error(k(147,a));var e=""+a;if(null!==b&&null!==b.ref&&"function"===typeof b.ref&&b.ref._stringRef===e)return b.ref;b=function(a){var b=d.refs;b===$g&&(b=d.refs={});null===a?delete b[e]:b[e]=a};b._stringRef=e;return b}if("string"!==typeof a)throw Error(k(284));if(!c._owner)throw Error(k(290,
+a));}return a}function Nc(a,b){if("textarea"!==a.type)throw Error(k(31,"[object Object]"===Object.prototype.toString.call(b)?"object with keys {"+Object.keys(b).join(", ")+"}":b,""));}function ah(a){function b(b,c){if(a){var d=b.lastEffect;null!==d?(d.nextEffect=c,b.lastEffect=c):b.firstEffect=b.lastEffect=c;c.nextEffect=null;c.effectTag=8}}function c(c,d){if(!a)return null;for(;null!==d;)b(c,d),d=d.sibling;return null}function d(a,b){for(a=new Map;null!==b;)null!==b.key?a.set(b.key,b):a.set(b.index,
+b),b=b.sibling;return a}function e(a,b){a=Sa(a,b);a.index=0;a.sibling=null;return a}function f(b,c,d){b.index=d;if(!a)return c;d=b.alternate;if(null!==d)return d=d.index,d<c?(b.effectTag=2,c):d;b.effectTag=2;return c}function g(b){a&&null===b.alternate&&(b.effectTag=2);return b}function h(a,b,c,d){if(null===b||6!==b.tag)return b=qe(c,a.mode,d),b.return=a,b;b=e(b,c);b.return=a;return b}function m(a,b,c,d){if(null!==b&&b.elementType===c.type)return d=e(b,c.props),d.ref=Rb(a,b,c),d.return=a,d;d=Oc(c.type,
+c.key,c.props,null,a.mode,d);d.ref=Rb(a,b,c);d.return=a;return d}function n(a,b,c,d){if(null===b||4!==b.tag||b.stateNode.containerInfo!==c.containerInfo||b.stateNode.implementation!==c.implementation)return b=re(c,a.mode,d),b.return=a,b;b=e(b,c.children||[]);b.return=a;return b}function l(a,b,c,d,f){if(null===b||7!==b.tag)return b=Ha(c,a.mode,d,f),b.return=a,b;b=e(b,c);b.return=a;return b}function ba(a,b,c){if("string"===typeof b||"number"===typeof b)return b=qe(""+b,a.mode,c),b.return=a,b;if("object"===
+typeof b&&null!==b){switch(b.$$typeof){case Pc:return c=Oc(b.type,b.key,b.props,null,a.mode,c),c.ref=Rb(a,null,b),c.return=a,c;case gb:return b=re(b,a.mode,c),b.return=a,b}if(Qc(b)||zb(b))return b=Ha(b,a.mode,c,null),b.return=a,b;Nc(a,b)}return null}function p(a,b,c,d){var e=null!==b?b.key:null;if("string"===typeof c||"number"===typeof c)return null!==e?null:h(a,b,""+c,d);if("object"===typeof c&&null!==c){switch(c.$$typeof){case Pc:return c.key===e?c.type===Ma?l(a,b,c.props.children,d,e):m(a,b,c,
+d):null;case gb:return c.key===e?n(a,b,c,d):null}if(Qc(c)||zb(c))return null!==e?null:l(a,b,c,d,null);Nc(a,c)}return null}function t(a,b,c,d,e){if("string"===typeof d||"number"===typeof d)return a=a.get(c)||null,h(b,a,""+d,e);if("object"===typeof d&&null!==d){switch(d.$$typeof){case Pc:return a=a.get(null===d.key?c:d.key)||null,d.type===Ma?l(b,a,d.props.children,e,d.key):m(b,a,d,e);case gb:return a=a.get(null===d.key?c:d.key)||null,n(b,a,d,e)}if(Qc(d)||zb(d))return a=a.get(c)||null,l(b,a,d,e,null);
+Nc(b,d)}return null}function q(e,g,h,m){for(var n=null,k=null,l=g,r=g=0,C=null;null!==l&&r<h.length;r++){l.index>r?(C=l,l=null):C=l.sibling;var O=p(e,l,h[r],m);if(null===O){null===l&&(l=C);break}a&&l&&null===O.alternate&&b(e,l);g=f(O,g,r);null===k?n=O:k.sibling=O;k=O;l=C}if(r===h.length)return c(e,l),n;if(null===l){for(;r<h.length;r++)l=ba(e,h[r],m),null!==l&&(g=f(l,g,r),null===k?n=l:k.sibling=l,k=l);return n}for(l=d(e,l);r<h.length;r++)C=t(l,e,r,h[r],m),null!==C&&(a&&null!==C.alternate&&l.delete(null===
+C.key?r:C.key),g=f(C,g,r),null===k?n=C:k.sibling=C,k=C);a&&l.forEach(function(a){return b(e,a)});return n}function w(e,g,h,n){var m=zb(h);if("function"!==typeof m)throw Error(k(150));h=m.call(h);if(null==h)throw Error(k(151));for(var l=m=null,r=g,C=g=0,O=null,v=h.next();null!==r&&!v.done;C++,v=h.next()){r.index>C?(O=r,r=null):O=r.sibling;var q=p(e,r,v.value,n);if(null===q){null===r&&(r=O);break}a&&r&&null===q.alternate&&b(e,r);g=f(q,g,C);null===l?m=q:l.sibling=q;l=q;r=O}if(v.done)return c(e,r),m;
+if(null===r){for(;!v.done;C++,v=h.next())v=ba(e,v.value,n),null!==v&&(g=f(v,g,C),null===l?m=v:l.sibling=v,l=v);return m}for(r=d(e,r);!v.done;C++,v=h.next())v=t(r,e,C,v.value,n),null!==v&&(a&&null!==v.alternate&&r.delete(null===v.key?C:v.key),g=f(v,g,C),null===l?m=v:l.sibling=v,l=v);a&&r.forEach(function(a){return b(e,a)});return m}return function(a,d,f,h){var m="object"===typeof f&&null!==f&&f.type===Ma&&null===f.key;m&&(f=f.props.children);var n="object"===typeof f&&null!==f;if(n)switch(f.$$typeof){case Pc:a:{n=
+f.key;for(m=d;null!==m;){if(m.key===n){switch(m.tag){case 7:if(f.type===Ma){c(a,m.sibling);d=e(m,f.props.children);d.return=a;a=d;break a}break;default:if(m.elementType===f.type){c(a,m.sibling);d=e(m,f.props);d.ref=Rb(a,m,f);d.return=a;a=d;break a}}c(a,m);break}else b(a,m);m=m.sibling}f.type===Ma?(d=Ha(f.props.children,a.mode,h,f.key),d.return=a,a=d):(h=Oc(f.type,f.key,f.props,null,a.mode,h),h.ref=Rb(a,d,f),h.return=a,a=h)}return g(a);case gb:a:{for(m=f.key;null!==d;){if(d.key===m)if(4===d.tag&&d.stateNode.containerInfo===
+f.containerInfo&&d.stateNode.implementation===f.implementation){c(a,d.sibling);d=e(d,f.children||[]);d.return=a;a=d;break a}else{c(a,d);break}else b(a,d);d=d.sibling}d=re(f,a.mode,h);d.return=a;a=d}return g(a)}if("string"===typeof f||"number"===typeof f)return f=""+f,null!==d&&6===d.tag?(c(a,d.sibling),d=e(d,f),d.return=a,a=d):(c(a,d),d=qe(f,a.mode,h),d.return=a,a=d),g(a);if(Qc(f))return q(a,d,f,h);if(zb(f))return w(a,d,f,h);n&&Nc(a,f);if("undefined"===typeof f&&!m)switch(a.tag){case 1:case 0:throw a=
+a.type,Error(k(152,a.displayName||a.name||"Component"));}return c(a,d)}}function Ta(a){if(a===Sb)throw Error(k(174));return a}function se(a,b){y(Tb,b);y(Ub,a);y(ja,Sb);a=b.nodeType;switch(a){case 9:case 11:b=(b=b.documentElement)?b.namespaceURI:Hd(null,"");break;default:a=8===a?b.parentNode:b,b=a.namespaceURI||null,a=a.tagName,b=Hd(b,a)}q(ja);y(ja,b)}function tb(a){q(ja);q(Ub);q(Tb)}function bh(a){Ta(Tb.current);var b=Ta(ja.current);var c=Hd(b,a.type);b!==c&&(y(Ub,a),y(ja,c))}function te(a){Ub.current===
+a&&(q(ja),q(Ub))}function Rc(a){for(var b=a;null!==b;){if(13===b.tag){var c=b.memoizedState;if(null!==c&&(c=c.dehydrated,null===c||c.data===$d||c.data===Zd))return b}else if(19===b.tag&&void 0!==b.memoizedProps.revealOrder){if(0!==(b.effectTag&64))return b}else if(null!==b.child){b.child.return=b;b=b.child;continue}if(b===a)break;for(;null===b.sibling;){if(null===b.return||b.return===a)return null;b=b.return}b.sibling.return=b.return;b=b.sibling}return null}function ue(a,b){return{responder:a,props:b}}
+function S(){throw Error(k(321));}function ve(a,b){if(null===b)return!1;for(var c=0;c<b.length&&c<a.length;c++)if(!Qa(a[c],b[c]))return!1;return!0}function we(a,b,c,d,e,f){Ia=f;z=b;b.memoizedState=null;b.updateQueue=null;b.expirationTime=0;Sc.current=null===a||null===a.memoizedState?dj:ej;a=c(d,e);if(b.expirationTime===Ia){f=0;do{b.expirationTime=0;if(!(25>f))throw Error(k(301));f+=1;J=K=null;b.updateQueue=null;Sc.current=fj;a=c(d,e)}while(b.expirationTime===Ia)}Sc.current=Tc;b=null!==K&&null!==K.next;
+Ia=0;J=K=z=null;Uc=!1;if(b)throw Error(k(300));return a}function ub(){var a={memoizedState:null,baseState:null,baseQueue:null,queue:null,next:null};null===J?z.memoizedState=J=a:J=J.next=a;return J}function vb(){if(null===K){var a=z.alternate;a=null!==a?a.memoizedState:null}else a=K.next;var b=null===J?z.memoizedState:J.next;if(null!==b)J=b,K=a;else{if(null===a)throw Error(k(310));K=a;a={memoizedState:K.memoizedState,baseState:K.baseState,baseQueue:K.baseQueue,queue:K.queue,next:null};null===J?z.memoizedState=
+J=a:J=J.next=a}return J}function Ua(a,b){return"function"===typeof b?b(a):b}function Vc(a,b,c){b=vb();c=b.queue;if(null===c)throw Error(k(311));c.lastRenderedReducer=a;var d=K,e=d.baseQueue,f=c.pending;if(null!==f){if(null!==e){var g=e.next;e.next=f.next;f.next=g}d.baseQueue=e=f;c.pending=null}if(null!==e){e=e.next;d=d.baseState;var h=g=f=null,m=e;do{var n=m.expirationTime;if(n<Ia){var l={expirationTime:m.expirationTime,suspenseConfig:m.suspenseConfig,action:m.action,eagerReducer:m.eagerReducer,eagerState:m.eagerState,
+next:null};null===h?(g=h=l,f=d):h=h.next=l;n>z.expirationTime&&(z.expirationTime=n,Kc(n))}else null!==h&&(h=h.next={expirationTime:1073741823,suspenseConfig:m.suspenseConfig,action:m.action,eagerReducer:m.eagerReducer,eagerState:m.eagerState,next:null}),Vg(n,m.suspenseConfig),d=m.eagerReducer===a?m.eagerState:a(d,m.action);m=m.next}while(null!==m&&m!==e);null===h?f=d:h.next=g;Qa(d,b.memoizedState)||(ia=!0);b.memoizedState=d;b.baseState=f;b.baseQueue=h;c.lastRenderedState=d}return[b.memoizedState,
+c.dispatch]}function Wc(a,b,c){b=vb();c=b.queue;if(null===c)throw Error(k(311));c.lastRenderedReducer=a;var d=c.dispatch,e=c.pending,f=b.memoizedState;if(null!==e){c.pending=null;var g=e=e.next;do f=a(f,g.action),g=g.next;while(g!==e);Qa(f,b.memoizedState)||(ia=!0);b.memoizedState=f;null===b.baseQueue&&(b.baseState=f);c.lastRenderedState=f}return[f,d]}function xe(a){var b=ub();"function"===typeof a&&(a=a());b.memoizedState=b.baseState=a;a=b.queue={pending:null,dispatch:null,lastRenderedReducer:Ua,
+lastRenderedState:a};a=a.dispatch=ch.bind(null,z,a);return[b.memoizedState,a]}function ye(a,b,c,d){a={tag:a,create:b,destroy:c,deps:d,next:null};b=z.updateQueue;null===b?(b={lastEffect:null},z.updateQueue=b,b.lastEffect=a.next=a):(c=b.lastEffect,null===c?b.lastEffect=a.next=a:(d=c.next,c.next=a,a.next=d,b.lastEffect=a));return a}function dh(a){return vb().memoizedState}function ze(a,b,c,d){var e=ub();z.effectTag|=a;e.memoizedState=ye(1|b,c,void 0,void 0===d?null:d)}function Ae(a,b,c,d){var e=vb();
+d=void 0===d?null:d;var f=void 0;if(null!==K){var g=K.memoizedState;f=g.destroy;if(null!==d&&ve(d,g.deps)){ye(b,c,f,d);return}}z.effectTag|=a;e.memoizedState=ye(1|b,c,f,d)}function eh(a,b){return ze(516,4,a,b)}function Xc(a,b){return Ae(516,4,a,b)}function fh(a,b){return Ae(4,2,a,b)}function gh(a,b){if("function"===typeof b)return a=a(),b(a),function(){b(null)};if(null!==b&&void 0!==b)return a=a(),b.current=a,function(){b.current=null}}function hh(a,b,c){c=null!==c&&void 0!==c?c.concat([a]):null;
+return Ae(4,2,gh.bind(null,b,a),c)}function Be(a,b){}function ih(a,b){ub().memoizedState=[a,void 0===b?null:b];return a}function Yc(a,b){var c=vb();b=void 0===b?null:b;var d=c.memoizedState;if(null!==d&&null!==b&&ve(b,d[1]))return d[0];c.memoizedState=[a,b];return a}function jh(a,b){var c=vb();b=void 0===b?null:b;var d=c.memoizedState;if(null!==d&&null!==b&&ve(b,d[1]))return d[0];a=a();c.memoizedState=[a,b];return a}function Ce(a,b,c){var d=Cc();Da(98>d?98:d,function(){a(!0)});Da(97<d?97:d,function(){var d=
+X.suspense;X.suspense=void 0===b?null:b;try{a(!1),c()}finally{X.suspense=d}})}function ch(a,b,c){var d=ka(),e=Vb.suspense;d=Va(d,a,e);e={expirationTime:d,suspenseConfig:e,action:c,eagerReducer:null,eagerState:null,next:null};var f=b.pending;null===f?e.next=e:(e.next=f.next,f.next=e);b.pending=e;f=a.alternate;if(a===z||null!==f&&f===z)Uc=!0,e.expirationTime=Ia,z.expirationTime=Ia;else{if(0===a.expirationTime&&(null===f||0===f.expirationTime)&&(f=b.lastRenderedReducer,null!==f))try{var g=b.lastRenderedState,
+h=f(g,c);e.eagerReducer=f;e.eagerState=h;if(Qa(h,g))return}catch(m){}finally{}Ja(a,d)}}function kh(a,b){var c=la(5,null,null,0);c.elementType="DELETED";c.type="DELETED";c.stateNode=b;c.return=a;c.effectTag=8;null!==a.lastEffect?(a.lastEffect.nextEffect=c,a.lastEffect=c):a.firstEffect=a.lastEffect=c}function lh(a,b){switch(a.tag){case 5:var c=a.type;b=1!==b.nodeType||c.toLowerCase()!==b.nodeName.toLowerCase()?null:b;return null!==b?(a.stateNode=b,!0):!1;case 6:return b=""===a.pendingProps||3!==b.nodeType?
+null:b,null!==b?(a.stateNode=b,!0):!1;case 13:return!1;default:return!1}}function De(a){if(Wa){var b=Ka;if(b){var c=b;if(!lh(a,b)){b=kb(c.nextSibling);if(!b||!lh(a,b)){a.effectTag=a.effectTag&-1025|2;Wa=!1;ra=a;return}kh(ra,c)}ra=a;Ka=kb(b.firstChild)}else a.effectTag=a.effectTag&-1025|2,Wa=!1,ra=a}}function mh(a){for(a=a.return;null!==a&&5!==a.tag&&3!==a.tag&&13!==a.tag;)a=a.return;ra=a}function Zc(a){if(a!==ra)return!1;if(!Wa)return mh(a),Wa=!0,!1;var b=a.type;if(5!==a.tag||"head"!==b&&"body"!==
+b&&!Yd(b,a.memoizedProps))for(b=Ka;b;)kh(a,b),b=kb(b.nextSibling);mh(a);if(13===a.tag){a=a.memoizedState;a=null!==a?a.dehydrated:null;if(!a)throw Error(k(317));a:{a=a.nextSibling;for(b=0;a;){if(8===a.nodeType){var c=a.data;if(c===og){if(0===b){Ka=kb(a.nextSibling);break a}b--}else c!==ng&&c!==Zd&&c!==$d||b++}a=a.nextSibling}Ka=null}}else Ka=ra?kb(a.stateNode.nextSibling):null;return!0}function Ee(){Ka=ra=null;Wa=!1}function T(a,b,c,d){b.child=null===a?Fe(b,null,c,d):wb(b,a.child,c,d)}function nh(a,
+b,c,d,e){c=c.render;var f=b.ref;rb(b,e);d=we(a,b,c,d,f,e);if(null!==a&&!ia)return b.updateQueue=a.updateQueue,b.effectTag&=-517,a.expirationTime<=e&&(a.expirationTime=0),sa(a,b,e);b.effectTag|=1;T(a,b,d,e);return b.child}function oh(a,b,c,d,e,f){if(null===a){var g=c.type;if("function"===typeof g&&!Ge(g)&&void 0===g.defaultProps&&null===c.compare&&void 0===c.defaultProps)return b.tag=15,b.type=g,ph(a,b,g,d,e,f);a=Oc(c.type,null,d,null,b.mode,f);a.ref=b.ref;a.return=b;return b.child=a}g=a.child;if(e<
+f&&(e=g.memoizedProps,c=c.compare,c=null!==c?c:Ob,c(e,d)&&a.ref===b.ref))return sa(a,b,f);b.effectTag|=1;a=Sa(g,d);a.ref=b.ref;a.return=b;return b.child=a}function ph(a,b,c,d,e,f){return null!==a&&Ob(a.memoizedProps,d)&&a.ref===b.ref&&(ia=!1,e<f)?(b.expirationTime=a.expirationTime,sa(a,b,f)):He(a,b,c,d,f)}function qh(a,b){var c=b.ref;if(null===a&&null!==c||null!==a&&a.ref!==c)b.effectTag|=128}function He(a,b,c,d,e){var f=N(c)?Ra:B.current;f=pb(b,f);rb(b,e);c=we(a,b,c,d,f,e);if(null!==a&&!ia)return b.updateQueue=
+a.updateQueue,b.effectTag&=-517,a.expirationTime<=e&&(a.expirationTime=0),sa(a,b,e);b.effectTag|=1;T(a,b,c,e);return b.child}function rh(a,b,c,d,e){if(N(c)){var f=!0;Bc(b)}else f=!1;rb(b,e);if(null===b.stateNode)null!==a&&(a.alternate=null,b.alternate=null,b.effectTag|=2),Yg(b,c,d),pe(b,c,d,e),d=!0;else if(null===a){var g=b.stateNode,h=b.memoizedProps;g.props=h;var m=g.context,n=c.contextType;"object"===typeof n&&null!==n?n=W(n):(n=N(c)?Ra:B.current,n=pb(b,n));var l=c.getDerivedStateFromProps,k="function"===
+typeof l||"function"===typeof g.getSnapshotBeforeUpdate;k||"function"!==typeof g.UNSAFE_componentWillReceiveProps&&"function"!==typeof g.componentWillReceiveProps||(h!==d||m!==n)&&Zg(b,g,d,n);Ga=!1;var p=b.memoizedState;g.state=p;Qb(b,d,g,e);m=b.memoizedState;h!==d||p!==m||G.current||Ga?("function"===typeof l&&(Lc(b,c,l,d),m=b.memoizedState),(h=Ga||Xg(b,c,h,d,p,m,n))?(k||"function"!==typeof g.UNSAFE_componentWillMount&&"function"!==typeof g.componentWillMount||("function"===typeof g.componentWillMount&&
+g.componentWillMount(),"function"===typeof g.UNSAFE_componentWillMount&&g.UNSAFE_componentWillMount()),"function"===typeof g.componentDidMount&&(b.effectTag|=4)):("function"===typeof g.componentDidMount&&(b.effectTag|=4),b.memoizedProps=d,b.memoizedState=m),g.props=d,g.state=m,g.context=n,d=h):("function"===typeof g.componentDidMount&&(b.effectTag|=4),d=!1)}else g=b.stateNode,oe(a,b),h=b.memoizedProps,g.props=b.type===b.elementType?h:aa(b.type,h),m=g.context,n=c.contextType,"object"===typeof n&&null!==
+n?n=W(n):(n=N(c)?Ra:B.current,n=pb(b,n)),l=c.getDerivedStateFromProps,(k="function"===typeof l||"function"===typeof g.getSnapshotBeforeUpdate)||"function"!==typeof g.UNSAFE_componentWillReceiveProps&&"function"!==typeof g.componentWillReceiveProps||(h!==d||m!==n)&&Zg(b,g,d,n),Ga=!1,m=b.memoizedState,g.state=m,Qb(b,d,g,e),p=b.memoizedState,h!==d||m!==p||G.current||Ga?("function"===typeof l&&(Lc(b,c,l,d),p=b.memoizedState),(l=Ga||Xg(b,c,h,d,m,p,n))?(k||"function"!==typeof g.UNSAFE_componentWillUpdate&&
+"function"!==typeof g.componentWillUpdate||("function"===typeof g.componentWillUpdate&&g.componentWillUpdate(d,p,n),"function"===typeof g.UNSAFE_componentWillUpdate&&g.UNSAFE_componentWillUpdate(d,p,n)),"function"===typeof g.componentDidUpdate&&(b.effectTag|=4),"function"===typeof g.getSnapshotBeforeUpdate&&(b.effectTag|=256)):("function"!==typeof g.componentDidUpdate||h===a.memoizedProps&&m===a.memoizedState||(b.effectTag|=4),"function"!==typeof g.getSnapshotBeforeUpdate||h===a.memoizedProps&&m===
+a.memoizedState||(b.effectTag|=256),b.memoizedProps=d,b.memoizedState=p),g.props=d,g.state=p,g.context=n,d=l):("function"!==typeof g.componentDidUpdate||h===a.memoizedProps&&m===a.memoizedState||(b.effectTag|=4),"function"!==typeof g.getSnapshotBeforeUpdate||h===a.memoizedProps&&m===a.memoizedState||(b.effectTag|=256),d=!1);return Ie(a,b,c,d,f,e)}function Ie(a,b,c,d,e,f){qh(a,b);var g=0!==(b.effectTag&64);if(!d&&!g)return e&&Hg(b,c,!1),sa(a,b,f);d=b.stateNode;gj.current=b;var h=g&&"function"!==typeof c.getDerivedStateFromError?
+null:d.render();b.effectTag|=1;null!==a&&g?(b.child=wb(b,a.child,null,f),b.child=wb(b,null,h,f)):T(a,b,h,f);b.memoizedState=d.state;e&&Hg(b,c,!0);return b.child}function sh(a){var b=a.stateNode;b.pendingContext?Fg(a,b.pendingContext,b.pendingContext!==b.context):b.context&&Fg(a,b.context,!1);se(a,b.containerInfo)}function th(a,b,c){var d=b.mode,e=b.pendingProps,f=D.current,g=!1,h;(h=0!==(b.effectTag&64))||(h=0!==(f&2)&&(null===a||null!==a.memoizedState));h?(g=!0,b.effectTag&=-65):null!==a&&null===
+a.memoizedState||void 0===e.fallback||!0===e.unstable_avoidThisFallback||(f|=1);y(D,f&1);if(null===a){void 0!==e.fallback&&De(b);if(g){g=e.fallback;e=Ha(null,d,0,null);e.return=b;if(0===(b.mode&2))for(a=null!==b.memoizedState?b.child.child:b.child,e.child=a;null!==a;)a.return=e,a=a.sibling;c=Ha(g,d,c,null);c.return=b;e.sibling=c;b.memoizedState=Je;b.child=e;return c}d=e.children;b.memoizedState=null;return b.child=Fe(b,null,d,c)}if(null!==a.memoizedState){a=a.child;d=a.sibling;if(g){e=e.fallback;
+c=Sa(a,a.pendingProps);c.return=b;if(0===(b.mode&2)&&(g=null!==b.memoizedState?b.child.child:b.child,g!==a.child))for(c.child=g;null!==g;)g.return=c,g=g.sibling;d=Sa(d,e);d.return=b;c.sibling=d;c.childExpirationTime=0;b.memoizedState=Je;b.child=c;return d}c=wb(b,a.child,e.children,c);b.memoizedState=null;return b.child=c}a=a.child;if(g){g=e.fallback;e=Ha(null,d,0,null);e.return=b;e.child=a;null!==a&&(a.return=e);if(0===(b.mode&2))for(a=null!==b.memoizedState?b.child.child:b.child,e.child=a;null!==
+a;)a.return=e,a=a.sibling;c=Ha(g,d,c,null);c.return=b;e.sibling=c;c.effectTag|=2;e.childExpirationTime=0;b.memoizedState=Je;b.child=e;return c}b.memoizedState=null;return b.child=wb(b,a,e.children,c)}function uh(a,b){a.expirationTime<b&&(a.expirationTime=b);var c=a.alternate;null!==c&&c.expirationTime<b&&(c.expirationTime=b);Sg(a.return,b)}function Ke(a,b,c,d,e,f){var g=a.memoizedState;null===g?a.memoizedState={isBackwards:b,rendering:null,renderingStartTime:0,last:d,tail:c,tailExpiration:0,tailMode:e,
+lastEffect:f}:(g.isBackwards=b,g.rendering=null,g.renderingStartTime=0,g.last=d,g.tail=c,g.tailExpiration=0,g.tailMode=e,g.lastEffect=f)}function vh(a,b,c){var d=b.pendingProps,e=d.revealOrder,f=d.tail;T(a,b,d.children,c);d=D.current;if(0!==(d&2))d=d&1|2,b.effectTag|=64;else{if(null!==a&&0!==(a.effectTag&64))a:for(a=b.child;null!==a;){if(13===a.tag)null!==a.memoizedState&&uh(a,c);else if(19===a.tag)uh(a,c);else if(null!==a.child){a.child.return=a;a=a.child;continue}if(a===b)break a;for(;null===a.sibling;){if(null===
+a.return||a.return===b)break a;a=a.return}a.sibling.return=a.return;a=a.sibling}d&=1}y(D,d);if(0===(b.mode&2))b.memoizedState=null;else switch(e){case "forwards":c=b.child;for(e=null;null!==c;)a=c.alternate,null!==a&&null===Rc(a)&&(e=c),c=c.sibling;c=e;null===c?(e=b.child,b.child=null):(e=c.sibling,c.sibling=null);Ke(b,!1,e,c,f,b.lastEffect);break;case "backwards":c=null;e=b.child;for(b.child=null;null!==e;){a=e.alternate;if(null!==a&&null===Rc(a)){b.child=e;break}a=e.sibling;e.sibling=c;c=e;e=a}Ke(b,
+!0,c,null,f,b.lastEffect);break;case "together":Ke(b,!1,null,null,void 0,b.lastEffect);break;default:b.memoizedState=null}return b.child}function sa(a,b,c){null!==a&&(b.dependencies=a.dependencies);var d=b.expirationTime;0!==d&&Kc(d);if(b.childExpirationTime<c)return null;if(null!==a&&b.child!==a.child)throw Error(k(153));if(null!==b.child){a=b.child;c=Sa(a,a.pendingProps);b.child=c;for(c.return=b;null!==a.sibling;)a=a.sibling,c=c.sibling=Sa(a,a.pendingProps),c.return=b;c.sibling=null}return b.child}
+function $c(a,b){switch(a.tailMode){case "hidden":b=a.tail;for(var c=null;null!==b;)null!==b.alternate&&(c=b),b=b.sibling;null===c?a.tail=null:c.sibling=null;break;case "collapsed":c=a.tail;for(var d=null;null!==c;)null!==c.alternate&&(d=c),c=c.sibling;null===d?b||null===a.tail?a.tail=null:a.tail.sibling=null:d.sibling=null}}function hj(a,b,c){var d=b.pendingProps;switch(b.tag){case 2:case 16:case 15:case 0:case 11:case 7:case 8:case 12:case 9:case 14:return null;case 1:return N(b.type)&&(q(G),q(B)),
+null;case 3:return tb(),q(G),q(B),c=b.stateNode,c.pendingContext&&(c.context=c.pendingContext,c.pendingContext=null),null!==a&&null!==a.child||!Zc(b)||(b.effectTag|=4),wh(b),null;case 5:te(b);c=Ta(Tb.current);var e=b.type;if(null!==a&&null!=b.stateNode)ij(a,b,e,d,c),a.ref!==b.ref&&(b.effectTag|=128);else{if(!d){if(null===b.stateNode)throw Error(k(166));return null}a=Ta(ja.current);if(Zc(b)){d=b.stateNode;e=b.type;var f=b.memoizedProps;d[Aa]=b;d[vc]=f;switch(e){case "iframe":case "object":case "embed":w("load",
+d);break;case "video":case "audio":for(a=0;a<Db.length;a++)w(Db[a],d);break;case "source":w("error",d);break;case "img":case "image":case "link":w("error",d);w("load",d);break;case "form":w("reset",d);w("submit",d);break;case "details":w("toggle",d);break;case "input":Hf(d,f);w("invalid",d);oa(c,"onChange");break;case "select":d._wrapperState={wasMultiple:!!f.multiple};w("invalid",d);oa(c,"onChange");break;case "textarea":Kf(d,f),w("invalid",d),oa(c,"onChange")}Ud(e,f);a=null;for(var g in f)if(f.hasOwnProperty(g)){var h=
+f[g];"children"===g?"string"===typeof h?d.textContent!==h&&(a=["children",h]):"number"===typeof h&&d.textContent!==""+h&&(a=["children",""+h]):db.hasOwnProperty(g)&&null!=h&&oa(c,g)}switch(e){case "input":mc(d);Jf(d,f,!0);break;case "textarea":mc(d);Mf(d);break;case "select":case "option":break;default:"function"===typeof f.onClick&&(d.onclick=uc)}c=a;b.updateQueue=c;null!==c&&(b.effectTag|=4)}else{g=9===c.nodeType?c:c.ownerDocument;"http://www.w3.org/1999/xhtml"===a&&(a=Nf(e));"http://www.w3.org/1999/xhtml"===
+a?"script"===e?(a=g.createElement("div"),a.innerHTML="<script>\x3c/script>",a=a.removeChild(a.firstChild)):"string"===typeof d.is?a=g.createElement(e,{is:d.is}):(a=g.createElement(e),"select"===e&&(g=a,d.multiple?g.multiple=!0:d.size&&(g.size=d.size))):a=g.createElementNS(a,e);a[Aa]=b;a[vc]=d;jj(a,b,!1,!1);b.stateNode=a;g=Vd(e,d);switch(e){case "iframe":case "object":case "embed":w("load",a);h=d;break;case "video":case "audio":for(h=0;h<Db.length;h++)w(Db[h],a);h=d;break;case "source":w("error",a);
+h=d;break;case "img":case "image":case "link":w("error",a);w("load",a);h=d;break;case "form":w("reset",a);w("submit",a);h=d;break;case "details":w("toggle",a);h=d;break;case "input":Hf(a,d);h=Cd(a,d);w("invalid",a);oa(c,"onChange");break;case "option":h=Fd(a,d);break;case "select":a._wrapperState={wasMultiple:!!d.multiple};h=M({},d,{value:void 0});w("invalid",a);oa(c,"onChange");break;case "textarea":Kf(a,d);h=Gd(a,d);w("invalid",a);oa(c,"onChange");break;default:h=d}Ud(e,h);var m=h;for(f in m)if(m.hasOwnProperty(f)){var n=
+m[f];"style"===f?gg(a,n):"dangerouslySetInnerHTML"===f?(n=n?n.__html:void 0,null!=n&&xh(a,n)):"children"===f?"string"===typeof n?("textarea"!==e||""!==n)&&Wb(a,n):"number"===typeof n&&Wb(a,""+n):"suppressContentEditableWarning"!==f&&"suppressHydrationWarning"!==f&&"autoFocus"!==f&&(db.hasOwnProperty(f)?null!=n&&oa(c,f):null!=n&&xd(a,f,n,g))}switch(e){case "input":mc(a);Jf(a,d,!1);break;case "textarea":mc(a);Mf(a);break;case "option":null!=d.value&&a.setAttribute("value",""+va(d.value));break;case "select":a.multiple=
+!!d.multiple;c=d.value;null!=c?hb(a,!!d.multiple,c,!1):null!=d.defaultValue&&hb(a,!!d.multiple,d.defaultValue,!0);break;default:"function"===typeof h.onClick&&(a.onclick=uc)}lg(e,d)&&(b.effectTag|=4)}null!==b.ref&&(b.effectTag|=128)}return null;case 6:if(a&&null!=b.stateNode)kj(a,b,a.memoizedProps,d);else{if("string"!==typeof d&&null===b.stateNode)throw Error(k(166));c=Ta(Tb.current);Ta(ja.current);Zc(b)?(c=b.stateNode,d=b.memoizedProps,c[Aa]=b,c.nodeValue!==d&&(b.effectTag|=4)):(c=(9===c.nodeType?
+c:c.ownerDocument).createTextNode(d),c[Aa]=b,b.stateNode=c)}return null;case 13:q(D);d=b.memoizedState;if(0!==(b.effectTag&64))return b.expirationTime=c,b;c=null!==d;d=!1;null===a?void 0!==b.memoizedProps.fallback&&Zc(b):(e=a.memoizedState,d=null!==e,c||null===e||(e=a.child.sibling,null!==e&&(f=b.firstEffect,null!==f?(b.firstEffect=e,e.nextEffect=f):(b.firstEffect=b.lastEffect=e,e.nextEffect=null),e.effectTag=8)));if(c&&!d&&0!==(b.mode&2))if(null===a&&!0!==b.memoizedProps.unstable_avoidThisFallback||
+0!==(D.current&1))F===Xa&&(F=ad);else{if(F===Xa||F===ad)F=bd;0!==Xb&&null!==U&&(Ya(U,P),yh(U,Xb))}if(c||d)b.effectTag|=4;return null;case 4:return tb(),wh(b),null;case 10:return me(b),null;case 17:return N(b.type)&&(q(G),q(B)),null;case 19:q(D);d=b.memoizedState;if(null===d)return null;e=0!==(b.effectTag&64);f=d.rendering;if(null===f)if(e)$c(d,!1);else{if(F!==Xa||null!==a&&0!==(a.effectTag&64))for(f=b.child;null!==f;){a=Rc(f);if(null!==a){b.effectTag|=64;$c(d,!1);e=a.updateQueue;null!==e&&(b.updateQueue=
+e,b.effectTag|=4);null===d.lastEffect&&(b.firstEffect=null);b.lastEffect=d.lastEffect;for(d=b.child;null!==d;)e=d,f=c,e.effectTag&=2,e.nextEffect=null,e.firstEffect=null,e.lastEffect=null,a=e.alternate,null===a?(e.childExpirationTime=0,e.expirationTime=f,e.child=null,e.memoizedProps=null,e.memoizedState=null,e.updateQueue=null,e.dependencies=null):(e.childExpirationTime=a.childExpirationTime,e.expirationTime=a.expirationTime,e.child=a.child,e.memoizedProps=a.memoizedProps,e.memoizedState=a.memoizedState,
+e.updateQueue=a.updateQueue,f=a.dependencies,e.dependencies=null===f?null:{expirationTime:f.expirationTime,firstContext:f.firstContext,responders:f.responders}),d=d.sibling;y(D,D.current&1|2);return b.child}f=f.sibling}}else{if(!e)if(a=Rc(f),null!==a){if(b.effectTag|=64,e=!0,c=a.updateQueue,null!==c&&(b.updateQueue=c,b.effectTag|=4),$c(d,!0),null===d.tail&&"hidden"===d.tailMode&&!f.alternate)return b=b.lastEffect=d.lastEffect,null!==b&&(b.nextEffect=null),null}else 2*Y()-d.renderingStartTime>d.tailExpiration&&
+1<c&&(b.effectTag|=64,e=!0,$c(d,!1),b.expirationTime=b.childExpirationTime=c-1);d.isBackwards?(f.sibling=b.child,b.child=f):(c=d.last,null!==c?c.sibling=f:b.child=f,d.last=f)}return null!==d.tail?(0===d.tailExpiration&&(d.tailExpiration=Y()+500),c=d.tail,d.rendering=c,d.tail=c.sibling,d.lastEffect=b.lastEffect,d.renderingStartTime=Y(),c.sibling=null,b=D.current,y(D,e?b&1|2:b&1),c):null}throw Error(k(156,b.tag));}function lj(a,b){switch(a.tag){case 1:return N(a.type)&&(q(G),q(B)),b=a.effectTag,b&4096?
+(a.effectTag=b&-4097|64,a):null;case 3:tb();q(G);q(B);b=a.effectTag;if(0!==(b&64))throw Error(k(285));a.effectTag=b&-4097|64;return a;case 5:return te(a),null;case 13:return q(D),b=a.effectTag,b&4096?(a.effectTag=b&-4097|64,a):null;case 19:return q(D),null;case 4:return tb(),null;case 10:return me(a),null;default:return null}}function Le(a,b){return{value:a,source:b,stack:Bd(b)}}function Me(a,b){var c=b.source,d=b.stack;null===d&&null!==c&&(d=Bd(c));null!==c&&na(c.type);b=b.value;null!==a&&1===a.tag&&
+na(a.type);try{console.error(b)}catch(e){setTimeout(function(){throw e;})}}function mj(a,b){try{b.props=a.memoizedProps,b.state=a.memoizedState,b.componentWillUnmount()}catch(c){Za(a,c)}}function zh(a){var b=a.ref;if(null!==b)if("function"===typeof b)try{b(null)}catch(c){Za(a,c)}else b.current=null}function nj(a,b){switch(b.tag){case 0:case 11:case 15:case 22:return;case 1:if(b.effectTag&256&&null!==a){var c=a.memoizedProps,d=a.memoizedState;a=b.stateNode;b=a.getSnapshotBeforeUpdate(b.elementType===
+b.type?c:aa(b.type,c),d);a.__reactInternalSnapshotBeforeUpdate=b}return;case 3:case 5:case 6:case 4:case 17:return}throw Error(k(163));}function Ah(a,b){b=b.updateQueue;b=null!==b?b.lastEffect:null;if(null!==b){var c=b=b.next;do{if((c.tag&a)===a){var d=c.destroy;c.destroy=void 0;void 0!==d&&d()}c=c.next}while(c!==b)}}function Bh(a,b){b=b.updateQueue;b=null!==b?b.lastEffect:null;if(null!==b){var c=b=b.next;do{if((c.tag&a)===a){var d=c.create;c.destroy=d()}c=c.next}while(c!==b)}}function oj(a,b,c,d){switch(c.tag){case 0:case 11:case 15:case 22:Bh(3,
+c);return;case 1:a=c.stateNode;c.effectTag&4&&(null===b?a.componentDidMount():(d=c.elementType===c.type?b.memoizedProps:aa(c.type,b.memoizedProps),a.componentDidUpdate(d,b.memoizedState,a.__reactInternalSnapshotBeforeUpdate)));b=c.updateQueue;null!==b&&Wg(c,b,a);return;case 3:b=c.updateQueue;if(null!==b){a=null;if(null!==c.child)switch(c.child.tag){case 5:a=c.child.stateNode;break;case 1:a=c.child.stateNode}Wg(c,b,a)}return;case 5:a=c.stateNode;null===b&&c.effectTag&4&&lg(c.type,c.memoizedProps)&&
+a.focus();return;case 6:return;case 4:return;case 12:return;case 13:null===c.memoizedState&&(c=c.alternate,null!==c&&(c=c.memoizedState,null!==c&&(c=c.dehydrated,null!==c&&bg(c))));return;case 19:case 17:case 20:case 21:return}throw Error(k(163));}function Ch(a,b,c){"function"===typeof Ne&&Ne(b);switch(b.tag){case 0:case 11:case 14:case 15:case 22:a=b.updateQueue;if(null!==a&&(a=a.lastEffect,null!==a)){var d=a.next;Da(97<c?97:c,function(){var a=d;do{var c=a.destroy;if(void 0!==c){var g=b;try{c()}catch(h){Za(g,
+h)}}a=a.next}while(a!==d)})}break;case 1:zh(b);c=b.stateNode;"function"===typeof c.componentWillUnmount&&mj(b,c);break;case 5:zh(b);break;case 4:Dh(a,b,c)}}function Eh(a){var b=a.alternate;a.return=null;a.child=null;a.memoizedState=null;a.updateQueue=null;a.dependencies=null;a.alternate=null;a.firstEffect=null;a.lastEffect=null;a.pendingProps=null;a.memoizedProps=null;a.stateNode=null;null!==b&&Eh(b)}function Fh(a){return 5===a.tag||3===a.tag||4===a.tag}function Gh(a){a:{for(var b=a.return;null!==
+b;){if(Fh(b)){var c=b;break a}b=b.return}throw Error(k(160));}b=c.stateNode;switch(c.tag){case 5:var d=!1;break;case 3:b=b.containerInfo;d=!0;break;case 4:b=b.containerInfo;d=!0;break;default:throw Error(k(161));}c.effectTag&16&&(Wb(b,""),c.effectTag&=-17);a:b:for(c=a;;){for(;null===c.sibling;){if(null===c.return||Fh(c.return)){c=null;break a}c=c.return}c.sibling.return=c.return;for(c=c.sibling;5!==c.tag&&6!==c.tag&&18!==c.tag;){if(c.effectTag&2)continue b;if(null===c.child||4===c.tag)continue b;
+else c.child.return=c,c=c.child}if(!(c.effectTag&2)){c=c.stateNode;break a}}d?Oe(a,c,b):Pe(a,c,b)}function Oe(a,b,c){var d=a.tag,e=5===d||6===d;if(e)a=e?a.stateNode:a.stateNode.instance,b?8===c.nodeType?c.parentNode.insertBefore(a,b):c.insertBefore(a,b):(8===c.nodeType?(b=c.parentNode,b.insertBefore(a,c)):(b=c,b.appendChild(a)),c=c._reactRootContainer,null!==c&&void 0!==c||null!==b.onclick||(b.onclick=uc));else if(4!==d&&(a=a.child,null!==a))for(Oe(a,b,c),a=a.sibling;null!==a;)Oe(a,b,c),a=a.sibling}
+function Pe(a,b,c){var d=a.tag,e=5===d||6===d;if(e)a=e?a.stateNode:a.stateNode.instance,b?c.insertBefore(a,b):c.appendChild(a);else if(4!==d&&(a=a.child,null!==a))for(Pe(a,b,c),a=a.sibling;null!==a;)Pe(a,b,c),a=a.sibling}function Dh(a,b,c){for(var d=b,e=!1,f,g;;){if(!e){e=d.return;a:for(;;){if(null===e)throw Error(k(160));f=e.stateNode;switch(e.tag){case 5:g=!1;break a;case 3:f=f.containerInfo;g=!0;break a;case 4:f=f.containerInfo;g=!0;break a}e=e.return}e=!0}if(5===d.tag||6===d.tag){a:for(var h=
+a,m=d,n=c,l=m;;)if(Ch(h,l,n),null!==l.child&&4!==l.tag)l.child.return=l,l=l.child;else{if(l===m)break a;for(;null===l.sibling;){if(null===l.return||l.return===m)break a;l=l.return}l.sibling.return=l.return;l=l.sibling}g?(h=f,m=d.stateNode,8===h.nodeType?h.parentNode.removeChild(m):h.removeChild(m)):f.removeChild(d.stateNode)}else if(4===d.tag){if(null!==d.child){f=d.stateNode.containerInfo;g=!0;d.child.return=d;d=d.child;continue}}else if(Ch(a,d,c),null!==d.child){d.child.return=d;d=d.child;continue}if(d===
+b)break;for(;null===d.sibling;){if(null===d.return||d.return===b)return;d=d.return;4===d.tag&&(e=!1)}d.sibling.return=d.return;d=d.sibling}}function Qe(a,b){switch(b.tag){case 0:case 11:case 14:case 15:case 22:Ah(3,b);return;case 1:return;case 5:var c=b.stateNode;if(null!=c){var d=b.memoizedProps,e=null!==a?a.memoizedProps:d;a=b.type;var f=b.updateQueue;b.updateQueue=null;if(null!==f){c[vc]=d;"input"===a&&"radio"===d.type&&null!=d.name&&If(c,d);Vd(a,e);b=Vd(a,d);for(e=0;e<f.length;e+=2){var g=f[e],
+h=f[e+1];"style"===g?gg(c,h):"dangerouslySetInnerHTML"===g?xh(c,h):"children"===g?Wb(c,h):xd(c,g,h,b)}switch(a){case "input":Dd(c,d);break;case "textarea":Lf(c,d);break;case "select":b=c._wrapperState.wasMultiple,c._wrapperState.wasMultiple=!!d.multiple,a=d.value,null!=a?hb(c,!!d.multiple,a,!1):b!==!!d.multiple&&(null!=d.defaultValue?hb(c,!!d.multiple,d.defaultValue,!0):hb(c,!!d.multiple,d.multiple?[]:"",!1))}}}return;case 6:if(null===b.stateNode)throw Error(k(162));b.stateNode.nodeValue=b.memoizedProps;
+return;case 3:b=b.stateNode;b.hydrate&&(b.hydrate=!1,bg(b.containerInfo));return;case 12:return;case 13:c=b;null===b.memoizedState?d=!1:(d=!0,c=b.child,Re=Y());if(null!==c)a:for(a=c;;){if(5===a.tag)f=a.stateNode,d?(f=f.style,"function"===typeof f.setProperty?f.setProperty("display","none","important"):f.display="none"):(f=a.stateNode,e=a.memoizedProps.style,e=void 0!==e&&null!==e&&e.hasOwnProperty("display")?e.display:null,f.style.display=fg("display",e));else if(6===a.tag)a.stateNode.nodeValue=d?
+"":a.memoizedProps;else if(13===a.tag&&null!==a.memoizedState&&null===a.memoizedState.dehydrated){f=a.child.sibling;f.return=a;a=f;continue}else if(null!==a.child){a.child.return=a;a=a.child;continue}if(a===c)break;for(;null===a.sibling;){if(null===a.return||a.return===c)break a;a=a.return}a.sibling.return=a.return;a=a.sibling}Hh(b);return;case 19:Hh(b);return;case 17:return}throw Error(k(163));}function Hh(a){var b=a.updateQueue;if(null!==b){a.updateQueue=null;var c=a.stateNode;null===c&&(c=a.stateNode=
+new pj);b.forEach(function(b){var d=qj.bind(null,a,b);c.has(b)||(c.add(b),b.then(d,d))})}}function Ih(a,b,c){c=Ea(c,null);c.tag=3;c.payload={element:null};var d=b.value;c.callback=function(){cd||(cd=!0,Se=d);Me(a,b)};return c}function Jh(a,b,c){c=Ea(c,null);c.tag=3;var d=a.type.getDerivedStateFromError;if("function"===typeof d){var e=b.value;c.payload=function(){Me(a,b);return d(e)}}var f=a.stateNode;null!==f&&"function"===typeof f.componentDidCatch&&(c.callback=function(){"function"!==typeof d&&
+(null===La?La=new Set([this]):La.add(this),Me(a,b));var c=b.stack;this.componentDidCatch(b.value,{componentStack:null!==c?c:""})});return c}function ka(){return(p&(ca|ma))!==H?1073741821-(Y()/10|0):0!==dd?dd:dd=1073741821-(Y()/10|0)}function Va(a,b,c){b=b.mode;if(0===(b&2))return 1073741823;var d=Cc();if(0===(b&4))return 99===d?1073741823:1073741822;if((p&ca)!==H)return P;if(null!==c)a=Fc(a,c.timeoutMs|0||5E3,250);else switch(d){case 99:a=1073741823;break;case 98:a=Fc(a,150,100);break;case 97:case 96:a=
+Fc(a,5E3,250);break;case 95:a=2;break;default:throw Error(k(326));}null!==U&&a===P&&--a;return a}function ed(a,b){a.expirationTime<b&&(a.expirationTime=b);var c=a.alternate;null!==c&&c.expirationTime<b&&(c.expirationTime=b);var d=a.return,e=null;if(null===d&&3===a.tag)e=a.stateNode;else for(;null!==d;){c=d.alternate;d.childExpirationTime<b&&(d.childExpirationTime=b);null!==c&&c.childExpirationTime<b&&(c.childExpirationTime=b);if(null===d.return&&3===d.tag){e=d.stateNode;break}d=d.return}null!==e&&
+(U===e&&(Kc(b),F===bd&&Ya(e,P)),yh(e,b));return e}function fd(a){var b=a.lastExpiredTime;if(0!==b)return b;b=a.firstPendingTime;if(!Kh(a,b))return b;var c=a.lastPingedTime;a=a.nextKnownPendingLevel;a=c>a?c:a;return 2>=a&&b!==a?0:a}function V(a){if(0!==a.lastExpiredTime)a.callbackExpirationTime=1073741823,a.callbackPriority=99,a.callbackNode=Og(Te.bind(null,a));else{var b=fd(a),c=a.callbackNode;if(0===b)null!==c&&(a.callbackNode=null,a.callbackExpirationTime=0,a.callbackPriority=90);else{var d=ka();
+1073741823===b?d=99:1===b||2===b?d=95:(d=10*(1073741821-b)-10*(1073741821-d),d=0>=d?99:250>=d?98:5250>=d?97:95);if(null!==c){var e=a.callbackPriority;if(a.callbackExpirationTime===b&&e>=d)return;c!==Qg&&Rg(c)}a.callbackExpirationTime=b;a.callbackPriority=d;b=1073741823===b?Og(Te.bind(null,a)):Ng(d,Lh.bind(null,a),{timeout:10*(1073741821-b)-Y()});a.callbackNode=b}}}function Lh(a,b){dd=0;if(b)return b=ka(),Ue(a,b),V(a),null;var c=fd(a);if(0!==c){b=a.callbackNode;if((p&(ca|ma))!==H)throw Error(k(327));
+xb();a===U&&c===P||$a(a,c);if(null!==t){var d=p;p|=ca;var e=Mh();do try{rj();break}catch(h){Nh(a,h)}while(1);le();p=d;gd.current=e;if(F===hd)throw b=id,$a(a,c),Ya(a,c),V(a),b;if(null===t)switch(e=a.finishedWork=a.current.alternate,a.finishedExpirationTime=c,d=F,U=null,d){case Xa:case hd:throw Error(k(345));case Oh:Ue(a,2<c?2:c);break;case ad:Ya(a,c);d=a.lastSuspendedTime;c===d&&(a.nextKnownPendingLevel=Ve(e));if(1073741823===ta&&(e=Re+Ph-Y(),10<e)){if(jd){var f=a.lastPingedTime;if(0===f||f>=c){a.lastPingedTime=
+c;$a(a,c);break}}f=fd(a);if(0!==f&&f!==c)break;if(0!==d&&d!==c){a.lastPingedTime=d;break}a.timeoutHandle=We(ab.bind(null,a),e);break}ab(a);break;case bd:Ya(a,c);d=a.lastSuspendedTime;c===d&&(a.nextKnownPendingLevel=Ve(e));if(jd&&(e=a.lastPingedTime,0===e||e>=c)){a.lastPingedTime=c;$a(a,c);break}e=fd(a);if(0!==e&&e!==c)break;if(0!==d&&d!==c){a.lastPingedTime=d;break}1073741823!==Yb?d=10*(1073741821-Yb)-Y():1073741823===ta?d=0:(d=10*(1073741821-ta)-5E3,e=Y(),c=10*(1073741821-c)-e,d=e-d,0>d&&(d=0),d=
+(120>d?120:480>d?480:1080>d?1080:1920>d?1920:3E3>d?3E3:4320>d?4320:1960*sj(d/1960))-d,c<d&&(d=c));if(10<d){a.timeoutHandle=We(ab.bind(null,a),d);break}ab(a);break;case Xe:if(1073741823!==ta&&null!==kd){f=ta;var g=kd;d=g.busyMinDurationMs|0;0>=d?d=0:(e=g.busyDelayMs|0,f=Y()-(10*(1073741821-f)-(g.timeoutMs|0||5E3)),d=f<=e?0:e+d-f);if(10<d){Ya(a,c);a.timeoutHandle=We(ab.bind(null,a),d);break}}ab(a);break;default:throw Error(k(329));}V(a);if(a.callbackNode===b)return Lh.bind(null,a)}}return null}function Te(a){var b=
+a.lastExpiredTime;b=0!==b?b:1073741823;if((p&(ca|ma))!==H)throw Error(k(327));xb();a===U&&b===P||$a(a,b);if(null!==t){var c=p;p|=ca;var d=Mh();do try{tj();break}catch(e){Nh(a,e)}while(1);le();p=c;gd.current=d;if(F===hd)throw c=id,$a(a,b),Ya(a,b),V(a),c;if(null!==t)throw Error(k(261));a.finishedWork=a.current.alternate;a.finishedExpirationTime=b;U=null;ab(a);V(a)}return null}function uj(){if(null!==bb){var a=bb;bb=null;a.forEach(function(a,c){Ue(c,a);V(c)});ha()}}function Qh(a,b){var c=p;p|=1;try{return a(b)}finally{p=
+c,p===H&&ha()}}function Rh(a,b){var c=p;p&=-2;p|=Ye;try{return a(b)}finally{p=c,p===H&&ha()}}function $a(a,b){a.finishedWork=null;a.finishedExpirationTime=0;var c=a.timeoutHandle;-1!==c&&(a.timeoutHandle=-1,vj(c));if(null!==t)for(c=t.return;null!==c;){var d=c;switch(d.tag){case 1:d=d.type.childContextTypes;null!==d&&void 0!==d&&(q(G),q(B));break;case 3:tb();q(G);q(B);break;case 5:te(d);break;case 4:tb();break;case 13:q(D);break;case 19:q(D);break;case 10:me(d)}c=c.return}U=a;t=Sa(a.current,null);
+P=b;F=Xa;id=null;Yb=ta=1073741823;kd=null;Xb=0;jd=!1}function Nh(a,b){do{try{le();Sc.current=Tc;if(Uc)for(var c=z.memoizedState;null!==c;){var d=c.queue;null!==d&&(d.pending=null);c=c.next}Ia=0;J=K=z=null;Uc=!1;if(null===t||null===t.return)return F=hd,id=b,t=null;a:{var e=a,f=t.return,g=t,h=b;b=P;g.effectTag|=2048;g.firstEffect=g.lastEffect=null;if(null!==h&&"object"===typeof h&&"function"===typeof h.then){var m=h;if(0===(g.mode&2)){var n=g.alternate;n?(g.updateQueue=n.updateQueue,g.memoizedState=
+n.memoizedState,g.expirationTime=n.expirationTime):(g.updateQueue=null,g.memoizedState=null)}var l=0!==(D.current&1),k=f;do{var p;if(p=13===k.tag){var q=k.memoizedState;if(null!==q)p=null!==q.dehydrated?!0:!1;else{var w=k.memoizedProps;p=void 0===w.fallback?!1:!0!==w.unstable_avoidThisFallback?!0:l?!1:!0}}if(p){var y=k.updateQueue;if(null===y){var r=new Set;r.add(m);k.updateQueue=r}else y.add(m);if(0===(k.mode&2)){k.effectTag|=64;g.effectTag&=-2981;if(1===g.tag)if(null===g.alternate)g.tag=17;else{var O=
+Ea(1073741823,null);O.tag=Jc;Fa(g,O)}g.expirationTime=1073741823;break a}h=void 0;g=b;var v=e.pingCache;null===v?(v=e.pingCache=new wj,h=new Set,v.set(m,h)):(h=v.get(m),void 0===h&&(h=new Set,v.set(m,h)));if(!h.has(g)){h.add(g);var x=xj.bind(null,e,m,g);m.then(x,x)}k.effectTag|=4096;k.expirationTime=b;break a}k=k.return}while(null!==k);h=Error((na(g.type)||"A React component")+" suspended while rendering, but no fallback UI was specified.\n\nAdd a <Suspense fallback=...> component higher in the tree to provide a loading indicator or placeholder to display."+
+Bd(g))}F!==Xe&&(F=Oh);h=Le(h,g);k=f;do{switch(k.tag){case 3:m=h;k.effectTag|=4096;k.expirationTime=b;var A=Ih(k,m,b);Ug(k,A);break a;case 1:m=h;var u=k.type,B=k.stateNode;if(0===(k.effectTag&64)&&("function"===typeof u.getDerivedStateFromError||null!==B&&"function"===typeof B.componentDidCatch&&(null===La||!La.has(B)))){k.effectTag|=4096;k.expirationTime=b;var H=Jh(k,m,b);Ug(k,H);break a}}k=k.return}while(null!==k)}t=Sh(t)}catch(cj){b=cj;continue}break}while(1)}function Mh(a){a=gd.current;gd.current=
+Tc;return null===a?Tc:a}function Vg(a,b){a<ta&&2<a&&(ta=a);null!==b&&a<Yb&&2<a&&(Yb=a,kd=b)}function Kc(a){a>Xb&&(Xb=a)}function tj(){for(;null!==t;)t=Th(t)}function rj(){for(;null!==t&&!yj();)t=Th(t)}function Th(a){var b=zj(a.alternate,a,P);a.memoizedProps=a.pendingProps;null===b&&(b=Sh(a));Uh.current=null;return b}function Sh(a){t=a;do{var b=t.alternate;a=t.return;if(0===(t.effectTag&2048)){b=hj(b,t,P);if(1===P||1!==t.childExpirationTime){for(var c=0,d=t.child;null!==d;){var e=d.expirationTime,
+f=d.childExpirationTime;e>c&&(c=e);f>c&&(c=f);d=d.sibling}t.childExpirationTime=c}if(null!==b)return b;null!==a&&0===(a.effectTag&2048)&&(null===a.firstEffect&&(a.firstEffect=t.firstEffect),null!==t.lastEffect&&(null!==a.lastEffect&&(a.lastEffect.nextEffect=t.firstEffect),a.lastEffect=t.lastEffect),1<t.effectTag&&(null!==a.lastEffect?a.lastEffect.nextEffect=t:a.firstEffect=t,a.lastEffect=t))}else{b=lj(t);if(null!==b)return b.effectTag&=2047,b;null!==a&&(a.firstEffect=a.lastEffect=null,a.effectTag|=
+2048)}b=t.sibling;if(null!==b)return b;t=a}while(null!==t);F===Xa&&(F=Xe);return null}function Ve(a){var b=a.expirationTime;a=a.childExpirationTime;return b>a?b:a}function ab(a){var b=Cc();Da(99,Aj.bind(null,a,b));return null}function Aj(a,b){do xb();while(null!==Zb);if((p&(ca|ma))!==H)throw Error(k(327));var c=a.finishedWork,d=a.finishedExpirationTime;if(null===c)return null;a.finishedWork=null;a.finishedExpirationTime=0;if(c===a.current)throw Error(k(177));a.callbackNode=null;a.callbackExpirationTime=
+0;a.callbackPriority=90;a.nextKnownPendingLevel=0;var e=Ve(c);a.firstPendingTime=e;d<=a.lastSuspendedTime?a.firstSuspendedTime=a.lastSuspendedTime=a.nextKnownPendingLevel=0:d<=a.firstSuspendedTime&&(a.firstSuspendedTime=d-1);d<=a.lastPingedTime&&(a.lastPingedTime=0);d<=a.lastExpiredTime&&(a.lastExpiredTime=0);a===U&&(t=U=null,P=0);1<c.effectTag?null!==c.lastEffect?(c.lastEffect.nextEffect=c,e=c.firstEffect):e=c:e=c.firstEffect;if(null!==e){var f=p;p|=ma;Uh.current=null;Ze=tc;var g=kg();if(Xd(g)){if("selectionStart"in
+g)var h={start:g.selectionStart,end:g.selectionEnd};else a:{h=(h=g.ownerDocument)&&h.defaultView||window;var m=h.getSelection&&h.getSelection();if(m&&0!==m.rangeCount){h=m.anchorNode;var n=m.anchorOffset,q=m.focusNode;m=m.focusOffset;try{h.nodeType,q.nodeType}catch(sb){h=null;break a}var ba=0,w=-1,y=-1,B=0,D=0,r=g,z=null;b:for(;;){for(var v;;){r!==h||0!==n&&3!==r.nodeType||(w=ba+n);r!==q||0!==m&&3!==r.nodeType||(y=ba+m);3===r.nodeType&&(ba+=r.nodeValue.length);if(null===(v=r.firstChild))break;z=r;
+r=v}for(;;){if(r===g)break b;z===h&&++B===n&&(w=ba);z===q&&++D===m&&(y=ba);if(null!==(v=r.nextSibling))break;r=z;z=r.parentNode}r=v}h=-1===w||-1===y?null:{start:w,end:y}}else h=null}h=h||{start:0,end:0}}else h=null;$e={activeElementDetached:null,focusedElem:g,selectionRange:h};tc=!1;l=e;do try{Bj()}catch(sb){if(null===l)throw Error(k(330));Za(l,sb);l=l.nextEffect}while(null!==l);l=e;do try{for(g=a,h=b;null!==l;){var x=l.effectTag;x&16&&Wb(l.stateNode,"");if(x&128){var A=l.alternate;if(null!==A){var u=
+A.ref;null!==u&&("function"===typeof u?u(null):u.current=null)}}switch(x&1038){case 2:Gh(l);l.effectTag&=-3;break;case 6:Gh(l);l.effectTag&=-3;Qe(l.alternate,l);break;case 1024:l.effectTag&=-1025;break;case 1028:l.effectTag&=-1025;Qe(l.alternate,l);break;case 4:Qe(l.alternate,l);break;case 8:n=l,Dh(g,n,h),Eh(n)}l=l.nextEffect}}catch(sb){if(null===l)throw Error(k(330));Za(l,sb);l=l.nextEffect}while(null!==l);u=$e;A=kg();x=u.focusedElem;h=u.selectionRange;if(A!==x&&x&&x.ownerDocument&&jg(x.ownerDocument.documentElement,
+x)){null!==h&&Xd(x)&&(A=h.start,u=h.end,void 0===u&&(u=A),"selectionStart"in x?(x.selectionStart=A,x.selectionEnd=Math.min(u,x.value.length)):(u=(A=x.ownerDocument||document)&&A.defaultView||window,u.getSelection&&(u=u.getSelection(),n=x.textContent.length,g=Math.min(h.start,n),h=void 0===h.end?g:Math.min(h.end,n),!u.extend&&g>h&&(n=h,h=g,g=n),n=ig(x,g),q=ig(x,h),n&&q&&(1!==u.rangeCount||u.anchorNode!==n.node||u.anchorOffset!==n.offset||u.focusNode!==q.node||u.focusOffset!==q.offset)&&(A=A.createRange(),
+A.setStart(n.node,n.offset),u.removeAllRanges(),g>h?(u.addRange(A),u.extend(q.node,q.offset)):(A.setEnd(q.node,q.offset),u.addRange(A))))));A=[];for(u=x;u=u.parentNode;)1===u.nodeType&&A.push({element:u,left:u.scrollLeft,top:u.scrollTop});"function"===typeof x.focus&&x.focus();for(x=0;x<A.length;x++)u=A[x],u.element.scrollLeft=u.left,u.element.scrollTop=u.top}tc=!!Ze;$e=Ze=null;a.current=c;l=e;do try{for(x=a;null!==l;){var F=l.effectTag;F&36&&oj(x,l.alternate,l);if(F&128){A=void 0;var E=l.ref;if(null!==
+E){var G=l.stateNode;switch(l.tag){case 5:A=G;break;default:A=G}"function"===typeof E?E(A):E.current=A}}l=l.nextEffect}}catch(sb){if(null===l)throw Error(k(330));Za(l,sb);l=l.nextEffect}while(null!==l);l=null;Cj();p=f}else a.current=c;if(ld)ld=!1,Zb=a,$b=b;else for(l=e;null!==l;)b=l.nextEffect,l.nextEffect=null,l=b;b=a.firstPendingTime;0===b&&(La=null);1073741823===b?a===af?ac++:(ac=0,af=a):ac=0;"function"===typeof bf&&bf(c.stateNode,d);V(a);if(cd)throw cd=!1,a=Se,Se=null,a;if((p&Ye)!==H)return null;
+ha();return null}function Bj(){for(;null!==l;){var a=l.effectTag;0!==(a&256)&&nj(l.alternate,l);0===(a&512)||ld||(ld=!0,Ng(97,function(){xb();return null}));l=l.nextEffect}}function xb(){if(90!==$b){var a=97<$b?97:$b;$b=90;return Da(a,Dj)}}function Dj(){if(null===Zb)return!1;var a=Zb;Zb=null;if((p&(ca|ma))!==H)throw Error(k(331));var b=p;p|=ma;for(a=a.current.firstEffect;null!==a;){try{var c=a;if(0!==(c.effectTag&512))switch(c.tag){case 0:case 11:case 15:case 22:Ah(5,c),Bh(5,c)}}catch(d){if(null===
+a)throw Error(k(330));Za(a,d)}c=a.nextEffect;a.nextEffect=null;a=c}p=b;ha();return!0}function Vh(a,b,c){b=Le(c,b);b=Ih(a,b,1073741823);Fa(a,b);a=ed(a,1073741823);null!==a&&V(a)}function Za(a,b){if(3===a.tag)Vh(a,a,b);else for(var c=a.return;null!==c;){if(3===c.tag){Vh(c,a,b);break}else if(1===c.tag){var d=c.stateNode;if("function"===typeof c.type.getDerivedStateFromError||"function"===typeof d.componentDidCatch&&(null===La||!La.has(d))){a=Le(b,a);a=Jh(c,a,1073741823);Fa(c,a);c=ed(c,1073741823);null!==
+c&&V(c);break}}c=c.return}}function xj(a,b,c){var d=a.pingCache;null!==d&&d.delete(b);U===a&&P===c?F===bd||F===ad&&1073741823===ta&&Y()-Re<Ph?$a(a,P):jd=!0:Kh(a,c)&&(b=a.lastPingedTime,0!==b&&b<c||(a.lastPingedTime=c,V(a)))}function qj(a,b){var c=a.stateNode;null!==c&&c.delete(b);b=0;0===b&&(b=ka(),b=Va(b,a,null));a=ed(a,b);null!==a&&V(a)}function Ej(a){if("undefined"===typeof __REACT_DEVTOOLS_GLOBAL_HOOK__)return!1;var b=__REACT_DEVTOOLS_GLOBAL_HOOK__;if(b.isDisabled||!b.supportsFiber)return!0;try{var c=
+b.inject(a);bf=function(a,e){try{b.onCommitFiberRoot(c,a,void 0,64===(a.current.effectTag&64))}catch(f){}};Ne=function(a){try{b.onCommitFiberUnmount(c,a)}catch(e){}}}catch(d){}return!0}function Fj(a,b,c,d){this.tag=a;this.key=c;this.sibling=this.child=this.return=this.stateNode=this.type=this.elementType=null;this.index=0;this.ref=null;this.pendingProps=b;this.dependencies=this.memoizedState=this.updateQueue=this.memoizedProps=null;this.mode=d;this.effectTag=0;this.lastEffect=this.firstEffect=this.nextEffect=
+null;this.childExpirationTime=this.expirationTime=0;this.alternate=null}function Ge(a){a=a.prototype;return!(!a||!a.isReactComponent)}function Gj(a){if("function"===typeof a)return Ge(a)?1:0;if(void 0!==a&&null!==a){a=a.$$typeof;if(a===zd)return 11;if(a===Ad)return 14}return 2}function Sa(a,b){var c=a.alternate;null===c?(c=la(a.tag,b,a.key,a.mode),c.elementType=a.elementType,c.type=a.type,c.stateNode=a.stateNode,c.alternate=a,a.alternate=c):(c.pendingProps=b,c.effectTag=0,c.nextEffect=null,c.firstEffect=
+null,c.lastEffect=null);c.childExpirationTime=a.childExpirationTime;c.expirationTime=a.expirationTime;c.child=a.child;c.memoizedProps=a.memoizedProps;c.memoizedState=a.memoizedState;c.updateQueue=a.updateQueue;b=a.dependencies;c.dependencies=null===b?null:{expirationTime:b.expirationTime,firstContext:b.firstContext,responders:b.responders};c.sibling=a.sibling;c.index=a.index;c.ref=a.ref;return c}function Oc(a,b,c,d,e,f){var g=2;d=a;if("function"===typeof a)Ge(a)&&(g=1);else if("string"===typeof a)g=
+5;else a:switch(a){case Ma:return Ha(c.children,e,f,b);case Hj:g=8;e|=7;break;case Af:g=8;e|=1;break;case kc:return a=la(12,c,b,e|8),a.elementType=kc,a.type=kc,a.expirationTime=f,a;case lc:return a=la(13,c,b,e),a.type=lc,a.elementType=lc,a.expirationTime=f,a;case yd:return a=la(19,c,b,e),a.elementType=yd,a.expirationTime=f,a;default:if("object"===typeof a&&null!==a)switch(a.$$typeof){case Cf:g=10;break a;case Bf:g=9;break a;case zd:g=11;break a;case Ad:g=14;break a;case Ef:g=16;d=null;break a;case Df:g=
+22;break a}throw Error(k(130,null==a?a:typeof a,""));}b=la(g,c,b,e);b.elementType=a;b.type=d;b.expirationTime=f;return b}function Ha(a,b,c,d){a=la(7,a,d,b);a.expirationTime=c;return a}function qe(a,b,c){a=la(6,a,null,b);a.expirationTime=c;return a}function re(a,b,c){b=la(4,null!==a.children?a.children:[],a.key,b);b.expirationTime=c;b.stateNode={containerInfo:a.containerInfo,pendingChildren:null,implementation:a.implementation};return b}function Ij(a,b,c){this.tag=b;this.current=null;this.containerInfo=
+a;this.pingCache=this.pendingChildren=null;this.finishedExpirationTime=0;this.finishedWork=null;this.timeoutHandle=-1;this.pendingContext=this.context=null;this.hydrate=c;this.callbackNode=null;this.callbackPriority=90;this.lastExpiredTime=this.lastPingedTime=this.nextKnownPendingLevel=this.lastSuspendedTime=this.firstSuspendedTime=this.firstPendingTime=0}function Kh(a,b){var c=a.firstSuspendedTime;a=a.lastSuspendedTime;return 0!==c&&c>=b&&a<=b}function Ya(a,b){var c=a.firstSuspendedTime,d=a.lastSuspendedTime;
+c<b&&(a.firstSuspendedTime=b);if(d>b||0===c)a.lastSuspendedTime=b;b<=a.lastPingedTime&&(a.lastPingedTime=0);b<=a.lastExpiredTime&&(a.lastExpiredTime=0)}function yh(a,b){b>a.firstPendingTime&&(a.firstPendingTime=b);var c=a.firstSuspendedTime;0!==c&&(b>=c?a.firstSuspendedTime=a.lastSuspendedTime=a.nextKnownPendingLevel=0:b>=a.lastSuspendedTime&&(a.lastSuspendedTime=b+1),b>a.nextKnownPendingLevel&&(a.nextKnownPendingLevel=b))}function Ue(a,b){var c=a.lastExpiredTime;if(0===c||c>b)a.lastExpiredTime=b}
+function md(a,b,c,d){var e=b.current,f=ka(),g=Vb.suspense;f=Va(f,e,g);a:if(c){c=c._reactInternalFiber;b:{if(Na(c)!==c||1!==c.tag)throw Error(k(170));var h=c;do{switch(h.tag){case 3:h=h.stateNode.context;break b;case 1:if(N(h.type)){h=h.stateNode.__reactInternalMemoizedMergedChildContext;break b}}h=h.return}while(null!==h);throw Error(k(171));}if(1===c.tag){var m=c.type;if(N(m)){c=Gg(c,m,h);break a}}c=h}else c=Ca;null===b.context?b.context=c:b.pendingContext=c;b=Ea(f,g);b.payload={element:a};d=void 0===
+d?null:d;null!==d&&(b.callback=d);Fa(e,b);Ja(e,f);return f}function cf(a){a=a.current;if(!a.child)return null;switch(a.child.tag){case 5:return a.child.stateNode;default:return a.child.stateNode}}function Wh(a,b){a=a.memoizedState;null!==a&&null!==a.dehydrated&&a.retryTime<b&&(a.retryTime=b)}function df(a,b){Wh(a,b);(a=a.alternate)&&Wh(a,b)}function ef(a,b,c){c=null!=c&&!0===c.hydrate;var d=new Ij(a,b,c),e=la(3,null,null,2===b?7:1===b?3:0);d.current=e;e.stateNode=d;ne(e);a[Lb]=d.current;c&&0!==b&&
+xi(a,9===a.nodeType?a:a.ownerDocument);this._internalRoot=d}function bc(a){return!(!a||1!==a.nodeType&&9!==a.nodeType&&11!==a.nodeType&&(8!==a.nodeType||" react-mount-point-unstable "!==a.nodeValue))}function Jj(a,b){b||(b=a?9===a.nodeType?a.documentElement:a.firstChild:null,b=!(!b||1!==b.nodeType||!b.hasAttribute("data-reactroot")));if(!b)for(var c;c=a.lastChild;)a.removeChild(c);return new ef(a,0,b?{hydrate:!0}:void 0)}function nd(a,b,c,d,e){var f=c._reactRootContainer;if(f){var g=f._internalRoot;
+if("function"===typeof e){var h=e;e=function(){var a=cf(g);h.call(a)}}md(b,g,a,e)}else{f=c._reactRootContainer=Jj(c,d);g=f._internalRoot;if("function"===typeof e){var m=e;e=function(){var a=cf(g);m.call(a)}}Rh(function(){md(b,g,a,e)})}return cf(g)}function Kj(a,b,c){var d=3<arguments.length&&void 0!==arguments[3]?arguments[3]:null;return{$$typeof:gb,key:null==d?null:""+d,children:a,containerInfo:b,implementation:c}}function Xh(a,b){var c=2<arguments.length&&void 0!==arguments[2]?arguments[2]:null;
+if(!bc(b))throw Error(k(200));return Kj(a,b,null,c)}if(!ea)throw Error(k(227));var ki=function(a,b,c,d,e,f,g,h,m){var n=Array.prototype.slice.call(arguments,3);try{b.apply(c,n)}catch(C){this.onError(C)}},yb=!1,gc=null,hc=!1,pd=null,li={onError:function(a){yb=!0;gc=a}},td=null,rf=null,mf=null,ic=null,cb={},jc=[],qd={},db={},rd={},wa=!("undefined"===typeof window||"undefined"===typeof window.document||"undefined"===typeof window.document.createElement),M=ea.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.assign,
+sd=null,eb=null,fb=null,ee=function(a,b){return a(b)},eg=function(a,b,c,d,e){return a(b,c,d,e)},vd=function(){},vf=ee,Oa=!1,wd=!1,Z=ea.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.Scheduler,Lj=Z.unstable_cancelCallback,ff=Z.unstable_now,$f=Z.unstable_scheduleCallback,Mj=Z.unstable_shouldYield,Yh=Z.unstable_requestPaint,Pd=Z.unstable_runWithPriority,Nj=Z.unstable_getCurrentPriorityLevel,Oj=Z.unstable_ImmediatePriority,Zh=Z.unstable_UserBlockingPriority,ag=Z.unstable_NormalPriority,Pj=Z.unstable_LowPriority,
+Qj=Z.unstable_IdlePriority,oi=/^[:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD][:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\-.0-9\u00B7\u0300-\u036F\u203F-\u2040]*$/,wf=Object.prototype.hasOwnProperty,yf={},xf={},E={};"children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style".split(" ").forEach(function(a){E[a]=
+new L(a,0,!1,a,null,!1)});[["acceptCharset","accept-charset"],["className","class"],["htmlFor","for"],["httpEquiv","http-equiv"]].forEach(function(a){var b=a[0];E[b]=new L(b,1,!1,a[1],null,!1)});["contentEditable","draggable","spellCheck","value"].forEach(function(a){E[a]=new L(a,2,!1,a.toLowerCase(),null,!1)});["autoReverse","externalResourcesRequired","focusable","preserveAlpha"].forEach(function(a){E[a]=new L(a,2,!1,a,null,!1)});"allowFullScreen async autoFocus autoPlay controls default defer disabled disablePictureInPicture formNoValidate hidden loop noModule noValidate open playsInline readOnly required reversed scoped seamless itemScope".split(" ").forEach(function(a){E[a]=
+new L(a,3,!1,a.toLowerCase(),null,!1)});["checked","multiple","muted","selected"].forEach(function(a){E[a]=new L(a,3,!0,a,null,!1)});["capture","download"].forEach(function(a){E[a]=new L(a,4,!1,a,null,!1)});["cols","rows","size","span"].forEach(function(a){E[a]=new L(a,6,!1,a,null,!1)});["rowSpan","start"].forEach(function(a){E[a]=new L(a,5,!1,a.toLowerCase(),null,!1)});var gf=/[\-:]([a-z])/g,hf=function(a){return a[1].toUpperCase()};"accent-height alignment-baseline arabic-form baseline-shift cap-height clip-path clip-rule color-interpolation color-interpolation-filters color-profile color-rendering dominant-baseline enable-background fill-opacity fill-rule flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x horiz-origin-x image-rendering letter-spacing lighting-color marker-end marker-mid marker-start overline-position overline-thickness paint-order panose-1 pointer-events rendering-intent shape-rendering stop-color stop-opacity strikethrough-position strikethrough-thickness stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width text-anchor text-decoration text-rendering underline-position underline-thickness unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical vector-effect vert-adv-y vert-origin-x vert-origin-y word-spacing writing-mode xmlns:xlink x-height".split(" ").forEach(function(a){var b=
+a.replace(gf,hf);E[b]=new L(b,1,!1,a,null,!1)});"xlink:actuate xlink:arcrole xlink:role xlink:show xlink:title xlink:type".split(" ").forEach(function(a){var b=a.replace(gf,hf);E[b]=new L(b,1,!1,a,"http://www.w3.org/1999/xlink",!1)});["xml:base","xml:lang","xml:space"].forEach(function(a){var b=a.replace(gf,hf);E[b]=new L(b,1,!1,a,"http://www.w3.org/XML/1998/namespace",!1)});["tabIndex","crossOrigin"].forEach(function(a){E[a]=new L(a,1,!1,a.toLowerCase(),null,!1)});E.xlinkHref=new L("xlinkHref",1,
+!1,"xlink:href","http://www.w3.org/1999/xlink",!0);["src","href","action","formAction"].forEach(function(a){E[a]=new L(a,1,!1,a.toLowerCase(),null,!0)});var da=ea.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;da.hasOwnProperty("ReactCurrentDispatcher")||(da.ReactCurrentDispatcher={current:null});da.hasOwnProperty("ReactCurrentBatchConfig")||(da.ReactCurrentBatchConfig={suspense:null});var si=/^(.*)[\\\/]/,Q="function"===typeof Symbol&&Symbol.for,Pc=Q?Symbol.for("react.element"):60103,gb=Q?Symbol.for("react.portal"):
+60106,Ma=Q?Symbol.for("react.fragment"):60107,Af=Q?Symbol.for("react.strict_mode"):60108,kc=Q?Symbol.for("react.profiler"):60114,Cf=Q?Symbol.for("react.provider"):60109,Bf=Q?Symbol.for("react.context"):60110,Hj=Q?Symbol.for("react.concurrent_mode"):60111,zd=Q?Symbol.for("react.forward_ref"):60112,lc=Q?Symbol.for("react.suspense"):60113,yd=Q?Symbol.for("react.suspense_list"):60120,Ad=Q?Symbol.for("react.memo"):60115,Ef=Q?Symbol.for("react.lazy"):60116,Df=Q?Symbol.for("react.block"):60121,zf="function"===
+typeof Symbol&&Symbol.iterator,od,xh=function(a){return"undefined"!==typeof MSApp&&MSApp.execUnsafeLocalFunction?function(b,c,d,e){MSApp.execUnsafeLocalFunction(function(){return a(b,c,d,e)})}:a}(function(a,b){if("http://www.w3.org/2000/svg"!==a.namespaceURI||"innerHTML"in a)a.innerHTML=b;else{od=od||document.createElement("div");od.innerHTML="<svg>"+b.valueOf().toString()+"</svg>";for(b=od.firstChild;a.firstChild;)a.removeChild(a.firstChild);for(;b.firstChild;)a.appendChild(b.firstChild)}}),Wb=function(a,
+b){if(b){var c=a.firstChild;if(c&&c===a.lastChild&&3===c.nodeType){c.nodeValue=b;return}}a.textContent=b},ib={animationend:nc("Animation","AnimationEnd"),animationiteration:nc("Animation","AnimationIteration"),animationstart:nc("Animation","AnimationStart"),transitionend:nc("Transition","TransitionEnd")},Id={},Of={};wa&&(Of=document.createElement("div").style,"AnimationEvent"in window||(delete ib.animationend.animation,delete ib.animationiteration.animation,delete ib.animationstart.animation),"TransitionEvent"in
+window||delete ib.transitionend.transition);var $h=oc("animationend"),ai=oc("animationiteration"),bi=oc("animationstart"),ci=oc("transitionend"),Db="abort canplay canplaythrough durationchange emptied encrypted ended error loadeddata loadedmetadata loadstart pause play playing progress ratechange seeked seeking stalled suspend timeupdate volumechange waiting".split(" "),Pf=new ("function"===typeof WeakMap?WeakMap:Map),Ab=null,wi=function(a){if(a){var b=a._dispatchListeners,c=a._dispatchInstances;
+if(Array.isArray(b))for(var d=0;d<b.length&&!a.isPropagationStopped();d++)lf(a,b[d],c[d]);else b&&lf(a,b,c);a._dispatchListeners=null;a._dispatchInstances=null;a.isPersistent()||a.constructor.release(a)}},qc=[],Rd=!1,fa=[],xa=null,ya=null,za=null,Eb=new Map,Fb=new Map,Jb=[],Nd="mousedown mouseup touchcancel touchend touchstart auxclick dblclick pointercancel pointerdown pointerup dragend dragstart drop compositionend compositionstart keydown keypress keyup input textInput close cancel copy cut paste click change contextmenu reset submit".split(" "),
+yi="focus blur dragenter dragleave mouseover mouseout pointerover pointerout gotpointercapture lostpointercapture".split(" "),dg={},cg=new Map,Td=new Map,Rj=["abort","abort",$h,"animationEnd",ai,"animationIteration",bi,"animationStart","canplay","canPlay","canplaythrough","canPlayThrough","durationchange","durationChange","emptied","emptied","encrypted","encrypted","ended","ended","error","error","gotpointercapture","gotPointerCapture","load","load","loadeddata","loadedData","loadedmetadata","loadedMetadata",
+"loadstart","loadStart","lostpointercapture","lostPointerCapture","playing","playing","progress","progress","seeking","seeking","stalled","stalled","suspend","suspend","timeupdate","timeUpdate",ci,"transitionEnd","waiting","waiting"];Sd("blur blur cancel cancel click click close close contextmenu contextMenu copy copy cut cut auxclick auxClick dblclick doubleClick dragend dragEnd dragstart dragStart drop drop focus focus input input invalid invalid keydown keyDown keypress keyPress keyup keyUp mousedown mouseDown mouseup mouseUp paste paste pause pause play play pointercancel pointerCancel pointerdown pointerDown pointerup pointerUp ratechange rateChange reset reset seeked seeked submit submit touchcancel touchCancel touchend touchEnd touchstart touchStart volumechange volumeChange".split(" "),
+0);Sd("drag drag dragenter dragEnter dragexit dragExit dragleave dragLeave dragover dragOver mousemove mouseMove mouseout mouseOut mouseover mouseOver pointermove pointerMove pointerout pointerOut pointerover pointerOver scroll scroll toggle toggle touchmove touchMove wheel wheel".split(" "),1);Sd(Rj,2);(function(a,b){for(var c=0;c<a.length;c++)Td.set(a[c],b)})("change selectionchange textInput compositionstart compositionend compositionupdate".split(" "),0);var Hi=Zh,Gi=Pd,tc=!0,Kb={animationIterationCount:!0,
+borderImageOutset:!0,borderImageSlice:!0,borderImageWidth:!0,boxFlex:!0,boxFlexGroup:!0,boxOrdinalGroup:!0,columnCount:!0,columns:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,flexOrder:!0,gridArea:!0,gridRow:!0,gridRowEnd:!0,gridRowSpan:!0,gridRowStart:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnSpan:!0,gridColumnStart:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,floodOpacity:!0,stopOpacity:!0,
+strokeDasharray:!0,strokeDashoffset:!0,strokeMiterlimit:!0,strokeOpacity:!0,strokeWidth:!0},Sj=["Webkit","ms","Moz","O"];Object.keys(Kb).forEach(function(a){Sj.forEach(function(b){b=b+a.charAt(0).toUpperCase()+a.substring(1);Kb[b]=Kb[a]})});var Ii=M({menuitem:!0},{area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0}),ng="$",og="/$",$d="$?",Zd="$!",Ze=null,$e=null,We="function"===typeof setTimeout?setTimeout:void 0,vj="function"===
+typeof clearTimeout?clearTimeout:void 0,jf=Math.random().toString(36).slice(2),Aa="__reactInternalInstance$"+jf,vc="__reactEventHandlers$"+jf,Lb="__reactContainere$"+jf,Ba=null,ce=null,wc=null;M(R.prototype,{preventDefault:function(){this.defaultPrevented=!0;var a=this.nativeEvent;a&&(a.preventDefault?a.preventDefault():"unknown"!==typeof a.returnValue&&(a.returnValue=!1),this.isDefaultPrevented=xc)},stopPropagation:function(){var a=this.nativeEvent;a&&(a.stopPropagation?a.stopPropagation():"unknown"!==
+typeof a.cancelBubble&&(a.cancelBubble=!0),this.isPropagationStopped=xc)},persist:function(){this.isPersistent=xc},isPersistent:yc,destructor:function(){var a=this.constructor.Interface,b;for(b in a)this[b]=null;this.nativeEvent=this._targetInst=this.dispatchConfig=null;this.isPropagationStopped=this.isDefaultPrevented=yc;this._dispatchInstances=this._dispatchListeners=null}});R.Interface={type:null,target:null,currentTarget:function(){return null},eventPhase:null,bubbles:null,cancelable:null,timeStamp:function(a){return a.timeStamp||
+Date.now()},defaultPrevented:null,isTrusted:null};R.extend=function(a){function b(){return c.apply(this,arguments)}var c=this,d=function(){};d.prototype=c.prototype;d=new d;M(d,b.prototype);b.prototype=d;b.prototype.constructor=b;b.Interface=M({},c.Interface,a);b.extend=c.extend;sg(b);return b};sg(R);var Tj=R.extend({data:null}),Uj=R.extend({data:null}),Ni=[9,13,27,32],de=wa&&"CompositionEvent"in window,cc=null;wa&&"documentMode"in document&&(cc=document.documentMode);var Vj=wa&&"TextEvent"in window&&
+!cc,xg=wa&&(!de||cc&&8<cc&&11>=cc),wg=String.fromCharCode(32),ua={beforeInput:{phasedRegistrationNames:{bubbled:"onBeforeInput",captured:"onBeforeInputCapture"},dependencies:["compositionend","keypress","textInput","paste"]},compositionEnd:{phasedRegistrationNames:{bubbled:"onCompositionEnd",captured:"onCompositionEndCapture"},dependencies:"blur compositionend keydown keypress keyup mousedown".split(" ")},compositionStart:{phasedRegistrationNames:{bubbled:"onCompositionStart",captured:"onCompositionStartCapture"},
+dependencies:"blur compositionstart keydown keypress keyup mousedown".split(" ")},compositionUpdate:{phasedRegistrationNames:{bubbled:"onCompositionUpdate",captured:"onCompositionUpdateCapture"},dependencies:"blur compositionupdate keydown keypress keyup mousedown".split(" ")}},vg=!1,mb=!1,Wj={eventTypes:ua,extractEvents:function(a,b,c,d,e){var f;if(de)b:{switch(a){case "compositionstart":var g=ua.compositionStart;break b;case "compositionend":g=ua.compositionEnd;break b;case "compositionupdate":g=
+ua.compositionUpdate;break b}g=void 0}else mb?tg(a,c)&&(g=ua.compositionEnd):"keydown"===a&&229===c.keyCode&&(g=ua.compositionStart);g?(xg&&"ko"!==c.locale&&(mb||g!==ua.compositionStart?g===ua.compositionEnd&&mb&&(f=rg()):(Ba=d,ce="value"in Ba?Ba.value:Ba.textContent,mb=!0)),e=Tj.getPooled(g,b,c,d),f?e.data=f:(f=ug(c),null!==f&&(e.data=f)),lb(e),f=e):f=null;(a=Vj?Oi(a,c):Pi(a,c))?(b=Uj.getPooled(ua.beforeInput,b,c,d),b.data=a,lb(b)):b=null;return null===f?b:null===b?f:[f,b]}},Qi={color:!0,date:!0,
+datetime:!0,"datetime-local":!0,email:!0,month:!0,number:!0,password:!0,range:!0,search:!0,tel:!0,text:!0,time:!0,url:!0,week:!0},Ag={change:{phasedRegistrationNames:{bubbled:"onChange",captured:"onChangeCapture"},dependencies:"blur change click focus input keydown keyup selectionchange".split(" ")}},Mb=null,Nb=null,kf=!1;wa&&(kf=Tf("input")&&(!document.documentMode||9<document.documentMode));var Xj={eventTypes:Ag,_isInputEventSupported:kf,extractEvents:function(a,b,c,d,e){e=b?Pa(b):window;var f=
+e.nodeName&&e.nodeName.toLowerCase();if("select"===f||"input"===f&&"file"===e.type)var g=Si;else if(yg(e))if(kf)g=Wi;else{g=Ui;var h=Ti}else(f=e.nodeName)&&"input"===f.toLowerCase()&&("checkbox"===e.type||"radio"===e.type)&&(g=Vi);if(g&&(g=g(a,b)))return zg(g,c,d);h&&h(a,e,b);"blur"===a&&(a=e._wrapperState)&&a.controlled&&"number"===e.type&&Ed(e,"number",e.value)}},dc=R.extend({view:null,detail:null}),Yi={Alt:"altKey",Control:"ctrlKey",Meta:"metaKey",Shift:"shiftKey"},di=0,ei=0,fi=!1,gi=!1,ec=dc.extend({screenX:null,
+screenY:null,clientX:null,clientY:null,pageX:null,pageY:null,ctrlKey:null,shiftKey:null,altKey:null,metaKey:null,getModifierState:fe,button:null,buttons:null,relatedTarget:function(a){return a.relatedTarget||(a.fromElement===a.srcElement?a.toElement:a.fromElement)},movementX:function(a){if("movementX"in a)return a.movementX;var b=di;di=a.screenX;return fi?"mousemove"===a.type?a.screenX-b:0:(fi=!0,0)},movementY:function(a){if("movementY"in a)return a.movementY;var b=ei;ei=a.screenY;return gi?"mousemove"===
+a.type?a.screenY-b:0:(gi=!0,0)}}),hi=ec.extend({pointerId:null,width:null,height:null,pressure:null,tangentialPressure:null,tiltX:null,tiltY:null,twist:null,pointerType:null,isPrimary:null}),fc={mouseEnter:{registrationName:"onMouseEnter",dependencies:["mouseout","mouseover"]},mouseLeave:{registrationName:"onMouseLeave",dependencies:["mouseout","mouseover"]},pointerEnter:{registrationName:"onPointerEnter",dependencies:["pointerout","pointerover"]},pointerLeave:{registrationName:"onPointerLeave",dependencies:["pointerout",
+"pointerover"]}},Yj={eventTypes:fc,extractEvents:function(a,b,c,d,e){var f="mouseover"===a||"pointerover"===a,g="mouseout"===a||"pointerout"===a;if(f&&0===(e&32)&&(c.relatedTarget||c.fromElement)||!g&&!f)return null;f=d.window===d?d:(f=d.ownerDocument)?f.defaultView||f.parentWindow:window;if(g){if(g=b,b=(b=c.relatedTarget||c.toElement)?Bb(b):null,null!==b){var h=Na(b);if(b!==h||5!==b.tag&&6!==b.tag)b=null}}else g=null;if(g===b)return null;if("mouseout"===a||"mouseover"===a){var m=ec;var n=fc.mouseLeave;
+var l=fc.mouseEnter;var k="mouse"}else if("pointerout"===a||"pointerover"===a)m=hi,n=fc.pointerLeave,l=fc.pointerEnter,k="pointer";a=null==g?f:Pa(g);f=null==b?f:Pa(b);n=m.getPooled(n,g,c,d);n.type=k+"leave";n.target=a;n.relatedTarget=f;c=m.getPooled(l,b,c,d);c.type=k+"enter";c.target=f;c.relatedTarget=a;d=g;k=b;if(d&&k)a:{m=d;l=k;g=0;for(a=m;a;a=pa(a))g++;a=0;for(b=l;b;b=pa(b))a++;for(;0<g-a;)m=pa(m),g--;for(;0<a-g;)l=pa(l),a--;for(;g--;){if(m===l||m===l.alternate)break a;m=pa(m);l=pa(l)}m=null}else m=
+null;l=m;for(m=[];d&&d!==l;){g=d.alternate;if(null!==g&&g===l)break;m.push(d);d=pa(d)}for(d=[];k&&k!==l;){g=k.alternate;if(null!==g&&g===l)break;d.push(k);k=pa(k)}for(k=0;k<m.length;k++)be(m[k],"bubbled",n);for(k=d.length;0<k--;)be(d[k],"captured",c);return 0===(e&64)?[n]:[n,c]}},Qa="function"===typeof Object.is?Object.is:Zi,$i=Object.prototype.hasOwnProperty,Zj=wa&&"documentMode"in document&&11>=document.documentMode,Eg={select:{phasedRegistrationNames:{bubbled:"onSelect",captured:"onSelectCapture"},
+dependencies:"blur contextmenu dragend focus keydown keyup mousedown mouseup selectionchange".split(" ")}},nb=null,he=null,Pb=null,ge=!1,ak={eventTypes:Eg,extractEvents:function(a,b,c,d,e,f){e=f||(d.window===d?d.document:9===d.nodeType?d:d.ownerDocument);if(!(f=!e)){a:{e=Jd(e);f=rd.onSelect;for(var g=0;g<f.length;g++)if(!e.has(f[g])){e=!1;break a}e=!0}f=!e}if(f)return null;e=b?Pa(b):window;switch(a){case "focus":if(yg(e)||"true"===e.contentEditable)nb=e,he=b,Pb=null;break;case "blur":Pb=he=nb=null;
+break;case "mousedown":ge=!0;break;case "contextmenu":case "mouseup":case "dragend":return ge=!1,Dg(c,d);case "selectionchange":if(Zj)break;case "keydown":case "keyup":return Dg(c,d)}return null}},bk=R.extend({animationName:null,elapsedTime:null,pseudoElement:null}),ck=R.extend({clipboardData:function(a){return"clipboardData"in a?a.clipboardData:window.clipboardData}}),dk=dc.extend({relatedTarget:null}),ek={Esc:"Escape",Spacebar:" ",Left:"ArrowLeft",Up:"ArrowUp",Right:"ArrowRight",Down:"ArrowDown",
+Del:"Delete",Win:"OS",Menu:"ContextMenu",Apps:"ContextMenu",Scroll:"ScrollLock",MozPrintableKey:"Unidentified"},fk={8:"Backspace",9:"Tab",12:"Clear",13:"Enter",16:"Shift",17:"Control",18:"Alt",19:"Pause",20:"CapsLock",27:"Escape",32:" ",33:"PageUp",34:"PageDown",35:"End",36:"Home",37:"ArrowLeft",38:"ArrowUp",39:"ArrowRight",40:"ArrowDown",45:"Insert",46:"Delete",112:"F1",113:"F2",114:"F3",115:"F4",116:"F5",117:"F6",118:"F7",119:"F8",120:"F9",121:"F10",122:"F11",123:"F12",144:"NumLock",145:"ScrollLock",
+224:"Meta"},gk=dc.extend({key:function(a){if(a.key){var b=ek[a.key]||a.key;if("Unidentified"!==b)return b}return"keypress"===a.type?(a=Ac(a),13===a?"Enter":String.fromCharCode(a)):"keydown"===a.type||"keyup"===a.type?fk[a.keyCode]||"Unidentified":""},location:null,ctrlKey:null,shiftKey:null,altKey:null,metaKey:null,repeat:null,locale:null,getModifierState:fe,charCode:function(a){return"keypress"===a.type?Ac(a):0},keyCode:function(a){return"keydown"===a.type||"keyup"===a.type?a.keyCode:0},which:function(a){return"keypress"===
+a.type?Ac(a):"keydown"===a.type||"keyup"===a.type?a.keyCode:0}}),hk=ec.extend({dataTransfer:null}),ik=dc.extend({touches:null,targetTouches:null,changedTouches:null,altKey:null,metaKey:null,ctrlKey:null,shiftKey:null,getModifierState:fe}),jk=R.extend({propertyName:null,elapsedTime:null,pseudoElement:null}),kk=ec.extend({deltaX:function(a){return"deltaX"in a?a.deltaX:"wheelDeltaX"in a?-a.wheelDeltaX:0},deltaY:function(a){return"deltaY"in a?a.deltaY:"wheelDeltaY"in a?-a.wheelDeltaY:"wheelDelta"in a?
+-a.wheelDelta:0},deltaZ:null,deltaMode:null}),lk={eventTypes:dg,extractEvents:function(a,b,c,d,e){e=cg.get(a);if(!e)return null;switch(a){case "keypress":if(0===Ac(c))return null;case "keydown":case "keyup":a=gk;break;case "blur":case "focus":a=dk;break;case "click":if(2===c.button)return null;case "auxclick":case "dblclick":case "mousedown":case "mousemove":case "mouseup":case "mouseout":case "mouseover":case "contextmenu":a=ec;break;case "drag":case "dragend":case "dragenter":case "dragexit":case "dragleave":case "dragover":case "dragstart":case "drop":a=
+hk;break;case "touchcancel":case "touchend":case "touchmove":case "touchstart":a=ik;break;case $h:case ai:case bi:a=bk;break;case ci:a=jk;break;case "scroll":a=dc;break;case "wheel":a=kk;break;case "copy":case "cut":case "paste":a=ck;break;case "gotpointercapture":case "lostpointercapture":case "pointercancel":case "pointerdown":case "pointermove":case "pointerout":case "pointerover":case "pointerup":a=hi;break;default:a=R}b=a.getPooled(e,b,c,d);lb(b);return b}};(function(a){if(ic)throw Error(k(101));
+ic=Array.prototype.slice.call(a);nf()})("ResponderEventPlugin SimpleEventPlugin EnterLeaveEventPlugin ChangeEventPlugin SelectEventPlugin BeforeInputEventPlugin".split(" "));(function(a,b,c){td=a;rf=b;mf=c})(ae,Hb,Pa);pf({SimpleEventPlugin:lk,EnterLeaveEventPlugin:Yj,ChangeEventPlugin:Xj,SelectEventPlugin:ak,BeforeInputEventPlugin:Wj});var ie=[],ob=-1,Ca={},B={current:Ca},G={current:!1},Ra=Ca,bj=Pd,je=$f,Rg=Lj,aj=Nj,Dc=Oj,Ig=Zh,Jg=ag,Kg=Pj,Lg=Qj,Qg={},yj=Mj,Cj=void 0!==Yh?Yh:function(){},qa=null,
+Ec=null,ke=!1,ii=ff(),Y=1E4>ii?ff:function(){return ff()-ii},Ic={current:null},Hc=null,qb=null,Gc=null,Tg=0,Jc=2,Ga=!1,Vb=da.ReactCurrentBatchConfig,$g=(new ea.Component).refs,Mc={isMounted:function(a){return(a=a._reactInternalFiber)?Na(a)===a:!1},enqueueSetState:function(a,b,c){a=a._reactInternalFiber;var d=ka(),e=Vb.suspense;d=Va(d,a,e);e=Ea(d,e);e.payload=b;void 0!==c&&null!==c&&(e.callback=c);Fa(a,e);Ja(a,d)},enqueueReplaceState:function(a,b,c){a=a._reactInternalFiber;var d=ka(),e=Vb.suspense;
+d=Va(d,a,e);e=Ea(d,e);e.tag=1;e.payload=b;void 0!==c&&null!==c&&(e.callback=c);Fa(a,e);Ja(a,d)},enqueueForceUpdate:function(a,b){a=a._reactInternalFiber;var c=ka(),d=Vb.suspense;c=Va(c,a,d);d=Ea(c,d);d.tag=Jc;void 0!==b&&null!==b&&(d.callback=b);Fa(a,d);Ja(a,c)}},Qc=Array.isArray,wb=ah(!0),Fe=ah(!1),Sb={},ja={current:Sb},Ub={current:Sb},Tb={current:Sb},D={current:0},Sc=da.ReactCurrentDispatcher,X=da.ReactCurrentBatchConfig,Ia=0,z=null,K=null,J=null,Uc=!1,Tc={readContext:W,useCallback:S,useContext:S,
+useEffect:S,useImperativeHandle:S,useLayoutEffect:S,useMemo:S,useReducer:S,useRef:S,useState:S,useDebugValue:S,useResponder:S,useDeferredValue:S,useTransition:S},dj={readContext:W,useCallback:ih,useContext:W,useEffect:eh,useImperativeHandle:function(a,b,c){c=null!==c&&void 0!==c?c.concat([a]):null;return ze(4,2,gh.bind(null,b,a),c)},useLayoutEffect:function(a,b){return ze(4,2,a,b)},useMemo:function(a,b){var c=ub();b=void 0===b?null:b;a=a();c.memoizedState=[a,b];return a},useReducer:function(a,b,c){var d=
+ub();b=void 0!==c?c(b):b;d.memoizedState=d.baseState=b;a=d.queue={pending:null,dispatch:null,lastRenderedReducer:a,lastRenderedState:b};a=a.dispatch=ch.bind(null,z,a);return[d.memoizedState,a]},useRef:function(a){var b=ub();a={current:a};return b.memoizedState=a},useState:xe,useDebugValue:Be,useResponder:ue,useDeferredValue:function(a,b){var c=xe(a),d=c[0],e=c[1];eh(function(){var c=X.suspense;X.suspense=void 0===b?null:b;try{e(a)}finally{X.suspense=c}},[a,b]);return d},useTransition:function(a){var b=
+xe(!1),c=b[0];b=b[1];return[ih(Ce.bind(null,b,a),[b,a]),c]}},ej={readContext:W,useCallback:Yc,useContext:W,useEffect:Xc,useImperativeHandle:hh,useLayoutEffect:fh,useMemo:jh,useReducer:Vc,useRef:dh,useState:function(a){return Vc(Ua)},useDebugValue:Be,useResponder:ue,useDeferredValue:function(a,b){var c=Vc(Ua),d=c[0],e=c[1];Xc(function(){var c=X.suspense;X.suspense=void 0===b?null:b;try{e(a)}finally{X.suspense=c}},[a,b]);return d},useTransition:function(a){var b=Vc(Ua),c=b[0];b=b[1];return[Yc(Ce.bind(null,
+b,a),[b,a]),c]}},fj={readContext:W,useCallback:Yc,useContext:W,useEffect:Xc,useImperativeHandle:hh,useLayoutEffect:fh,useMemo:jh,useReducer:Wc,useRef:dh,useState:function(a){return Wc(Ua)},useDebugValue:Be,useResponder:ue,useDeferredValue:function(a,b){var c=Wc(Ua),d=c[0],e=c[1];Xc(function(){var c=X.suspense;X.suspense=void 0===b?null:b;try{e(a)}finally{X.suspense=c}},[a,b]);return d},useTransition:function(a){var b=Wc(Ua),c=b[0];b=b[1];return[Yc(Ce.bind(null,b,a),[b,a]),c]}},ra=null,Ka=null,Wa=
+!1,gj=da.ReactCurrentOwner,ia=!1,Je={dehydrated:null,retryTime:0};var jj=function(a,b,c,d){for(c=b.child;null!==c;){if(5===c.tag||6===c.tag)a.appendChild(c.stateNode);else if(4!==c.tag&&null!==c.child){c.child.return=c;c=c.child;continue}if(c===b)break;for(;null===c.sibling;){if(null===c.return||c.return===b)return;c=c.return}c.sibling.return=c.return;c=c.sibling}};var wh=function(a){};var ij=function(a,b,c,d,e){var f=a.memoizedProps;if(f!==d){var g=b.stateNode;Ta(ja.current);a=null;switch(c){case "input":f=
+Cd(g,f);d=Cd(g,d);a=[];break;case "option":f=Fd(g,f);d=Fd(g,d);a=[];break;case "select":f=M({},f,{value:void 0});d=M({},d,{value:void 0});a=[];break;case "textarea":f=Gd(g,f);d=Gd(g,d);a=[];break;default:"function"!==typeof f.onClick&&"function"===typeof d.onClick&&(g.onclick=uc)}Ud(c,d);var h,m;c=null;for(h in f)if(!d.hasOwnProperty(h)&&f.hasOwnProperty(h)&&null!=f[h])if("style"===h)for(m in g=f[h],g)g.hasOwnProperty(m)&&(c||(c={}),c[m]="");else"dangerouslySetInnerHTML"!==h&&"children"!==h&&"suppressContentEditableWarning"!==
+h&&"suppressHydrationWarning"!==h&&"autoFocus"!==h&&(db.hasOwnProperty(h)?a||(a=[]):(a=a||[]).push(h,null));for(h in d){var k=d[h];g=null!=f?f[h]:void 0;if(d.hasOwnProperty(h)&&k!==g&&(null!=k||null!=g))if("style"===h)if(g){for(m in g)!g.hasOwnProperty(m)||k&&k.hasOwnProperty(m)||(c||(c={}),c[m]="");for(m in k)k.hasOwnProperty(m)&&g[m]!==k[m]&&(c||(c={}),c[m]=k[m])}else c||(a||(a=[]),a.push(h,c)),c=k;else"dangerouslySetInnerHTML"===h?(k=k?k.__html:void 0,g=g?g.__html:void 0,null!=k&&g!==k&&(a=a||
+[]).push(h,k)):"children"===h?g===k||"string"!==typeof k&&"number"!==typeof k||(a=a||[]).push(h,""+k):"suppressContentEditableWarning"!==h&&"suppressHydrationWarning"!==h&&(db.hasOwnProperty(h)?(null!=k&&oa(e,h),a||g===k||(a=[])):(a=a||[]).push(h,k))}c&&(a=a||[]).push("style",c);e=a;if(b.updateQueue=e)b.effectTag|=4}};var kj=function(a,b,c,d){c!==d&&(b.effectTag|=4)};var pj="function"===typeof WeakSet?WeakSet:Set,wj="function"===typeof WeakMap?WeakMap:Map,sj=Math.ceil,gd=da.ReactCurrentDispatcher,
+Uh=da.ReactCurrentOwner,H=0,Ye=8,ca=16,ma=32,Xa=0,hd=1,Oh=2,ad=3,bd=4,Xe=5,p=H,U=null,t=null,P=0,F=Xa,id=null,ta=1073741823,Yb=1073741823,kd=null,Xb=0,jd=!1,Re=0,Ph=500,l=null,cd=!1,Se=null,La=null,ld=!1,Zb=null,$b=90,bb=null,ac=0,af=null,dd=0,Ja=function(a,b){if(50<ac)throw ac=0,af=null,Error(k(185));a=ed(a,b);if(null!==a){var c=Cc();1073741823===b?(p&Ye)!==H&&(p&(ca|ma))===H?Te(a):(V(a),p===H&&ha()):V(a);(p&4)===H||98!==c&&99!==c||(null===bb?bb=new Map([[a,b]]):(c=bb.get(a),(void 0===c||c>b)&&bb.set(a,
+b)))}};var zj=function(a,b,c){var d=b.expirationTime;if(null!==a){var e=b.pendingProps;if(a.memoizedProps!==e||G.current)ia=!0;else{if(d<c){ia=!1;switch(b.tag){case 3:sh(b);Ee();break;case 5:bh(b);if(b.mode&4&&1!==c&&e.hidden)return b.expirationTime=b.childExpirationTime=1,null;break;case 1:N(b.type)&&Bc(b);break;case 4:se(b,b.stateNode.containerInfo);break;case 10:d=b.memoizedProps.value;e=b.type._context;y(Ic,e._currentValue);e._currentValue=d;break;case 13:if(null!==b.memoizedState){d=b.child.childExpirationTime;
+if(0!==d&&d>=c)return th(a,b,c);y(D,D.current&1);b=sa(a,b,c);return null!==b?b.sibling:null}y(D,D.current&1);break;case 19:d=b.childExpirationTime>=c;if(0!==(a.effectTag&64)){if(d)return vh(a,b,c);b.effectTag|=64}e=b.memoizedState;null!==e&&(e.rendering=null,e.tail=null);y(D,D.current);if(!d)return null}return sa(a,b,c)}ia=!1}}else ia=!1;b.expirationTime=0;switch(b.tag){case 2:d=b.type;null!==a&&(a.alternate=null,b.alternate=null,b.effectTag|=2);a=b.pendingProps;e=pb(b,B.current);rb(b,c);e=we(null,
+b,d,a,e,c);b.effectTag|=1;if("object"===typeof e&&null!==e&&"function"===typeof e.render&&void 0===e.$$typeof){b.tag=1;b.memoizedState=null;b.updateQueue=null;if(N(d)){var f=!0;Bc(b)}else f=!1;b.memoizedState=null!==e.state&&void 0!==e.state?e.state:null;ne(b);var g=d.getDerivedStateFromProps;"function"===typeof g&&Lc(b,d,g,a);e.updater=Mc;b.stateNode=e;e._reactInternalFiber=b;pe(b,d,a,c);b=Ie(null,b,d,!0,f,c)}else b.tag=0,T(null,b,e,c),b=b.child;return b;case 16:a:{e=b.elementType;null!==a&&(a.alternate=
+null,b.alternate=null,b.effectTag|=2);a=b.pendingProps;ri(e);if(1!==e._status)throw e._result;e=e._result;b.type=e;f=b.tag=Gj(e);a=aa(e,a);switch(f){case 0:b=He(null,b,e,a,c);break a;case 1:b=rh(null,b,e,a,c);break a;case 11:b=nh(null,b,e,a,c);break a;case 14:b=oh(null,b,e,aa(e.type,a),d,c);break a}throw Error(k(306,e,""));}return b;case 0:return d=b.type,e=b.pendingProps,e=b.elementType===d?e:aa(d,e),He(a,b,d,e,c);case 1:return d=b.type,e=b.pendingProps,e=b.elementType===d?e:aa(d,e),rh(a,b,d,e,c);
+case 3:sh(b);d=b.updateQueue;if(null===a||null===d)throw Error(k(282));d=b.pendingProps;e=b.memoizedState;e=null!==e?e.element:null;oe(a,b);Qb(b,d,null,c);d=b.memoizedState.element;if(d===e)Ee(),b=sa(a,b,c);else{if(e=b.stateNode.hydrate)Ka=kb(b.stateNode.containerInfo.firstChild),ra=b,e=Wa=!0;if(e)for(c=Fe(b,null,d,c),b.child=c;c;)c.effectTag=c.effectTag&-3|1024,c=c.sibling;else T(a,b,d,c),Ee();b=b.child}return b;case 5:return bh(b),null===a&&De(b),d=b.type,e=b.pendingProps,f=null!==a?a.memoizedProps:
+null,g=e.children,Yd(d,e)?g=null:null!==f&&Yd(d,f)&&(b.effectTag|=16),qh(a,b),b.mode&4&&1!==c&&e.hidden?(b.expirationTime=b.childExpirationTime=1,b=null):(T(a,b,g,c),b=b.child),b;case 6:return null===a&&De(b),null;case 13:return th(a,b,c);case 4:return se(b,b.stateNode.containerInfo),d=b.pendingProps,null===a?b.child=wb(b,null,d,c):T(a,b,d,c),b.child;case 11:return d=b.type,e=b.pendingProps,e=b.elementType===d?e:aa(d,e),nh(a,b,d,e,c);case 7:return T(a,b,b.pendingProps,c),b.child;case 8:return T(a,
+b,b.pendingProps.children,c),b.child;case 12:return T(a,b,b.pendingProps.children,c),b.child;case 10:a:{d=b.type._context;e=b.pendingProps;g=b.memoizedProps;f=e.value;var h=b.type._context;y(Ic,h._currentValue);h._currentValue=f;if(null!==g)if(h=g.value,f=Qa(h,f)?0:("function"===typeof d._calculateChangedBits?d._calculateChangedBits(h,f):1073741823)|0,0===f){if(g.children===e.children&&!G.current){b=sa(a,b,c);break a}}else for(h=b.child,null!==h&&(h.return=b);null!==h;){var m=h.dependencies;if(null!==
+m){g=h.child;for(var l=m.firstContext;null!==l;){if(l.context===d&&0!==(l.observedBits&f)){1===h.tag&&(l=Ea(c,null),l.tag=Jc,Fa(h,l));h.expirationTime<c&&(h.expirationTime=c);l=h.alternate;null!==l&&l.expirationTime<c&&(l.expirationTime=c);Sg(h.return,c);m.expirationTime<c&&(m.expirationTime=c);break}l=l.next}}else g=10===h.tag?h.type===b.type?null:h.child:h.child;if(null!==g)g.return=h;else for(g=h;null!==g;){if(g===b){g=null;break}h=g.sibling;if(null!==h){h.return=g.return;g=h;break}g=g.return}h=
+g}T(a,b,e.children,c);b=b.child}return b;case 9:return e=b.type,f=b.pendingProps,d=f.children,rb(b,c),e=W(e,f.unstable_observedBits),d=d(e),b.effectTag|=1,T(a,b,d,c),b.child;case 14:return e=b.type,f=aa(e,b.pendingProps),f=aa(e.type,f),oh(a,b,e,f,d,c);case 15:return ph(a,b,b.type,b.pendingProps,d,c);case 17:return d=b.type,e=b.pendingProps,e=b.elementType===d?e:aa(d,e),null!==a&&(a.alternate=null,b.alternate=null,b.effectTag|=2),b.tag=1,N(d)?(a=!0,Bc(b)):a=!1,rb(b,c),Yg(b,d,e),pe(b,d,e,c),Ie(null,
+b,d,!0,a,c);case 19:return vh(a,b,c)}throw Error(k(156,b.tag));};var bf=null,Ne=null,la=function(a,b,c,d){return new Fj(a,b,c,d)};ef.prototype.render=function(a){md(a,this._internalRoot,null,null)};ef.prototype.unmount=function(){var a=this._internalRoot,b=a.containerInfo;md(null,a,null,function(){b[Lb]=null})};var Di=function(a){if(13===a.tag){var b=Fc(ka(),150,100);Ja(a,b);df(a,b)}};var Yf=function(a){13===a.tag&&(Ja(a,3),df(a,3))};var Bi=function(a){if(13===a.tag){var b=ka();b=Va(b,a,null);Ja(a,
+b);df(a,b)}};sd=function(a,b,c){switch(b){case "input":Dd(a,c);b=c.name;if("radio"===c.type&&null!=b){for(c=a;c.parentNode;)c=c.parentNode;c=c.querySelectorAll("input[name="+JSON.stringify(""+b)+'][type="radio"]');for(b=0;b<c.length;b++){var d=c[b];if(d!==a&&d.form===a.form){var e=ae(d);if(!e)throw Error(k(90));Gf(d);Dd(d,e)}}}break;case "textarea":Lf(a,c);break;case "select":b=c.value,null!=b&&hb(a,!!c.multiple,b,!1)}};(function(a,b,c,d){ee=a;eg=b;vd=c;vf=d})(Qh,function(a,b,c,d,e){var f=p;p|=4;
+try{return Da(98,a.bind(null,b,c,d,e))}finally{p=f,p===H&&ha()}},function(){(p&(1|ca|ma))===H&&(uj(),xb())},function(a,b){var c=p;p|=2;try{return a(b)}finally{p=c,p===H&&ha()}});var mk={Events:[Hb,Pa,ae,pf,qd,lb,function(a){Kd(a,Ki)},sf,tf,sc,pc,xb,{current:!1}]};(function(a){var b=a.findFiberByHostInstance;return Ej(M({},a,{overrideHookState:null,overrideProps:null,setSuspenseHandler:null,scheduleUpdate:null,currentDispatcherRef:da.ReactCurrentDispatcher,findHostInstanceByFiber:function(a){a=Sf(a);
+return null===a?null:a.stateNode},findFiberByHostInstance:function(a){return b?b(a):null},findHostInstancesForRefresh:null,scheduleRefresh:null,scheduleRoot:null,setRefreshHandler:null,getCurrentFiber:null}))})({findFiberByHostInstance:Bb,bundleType:0,version:"16.13.1",rendererPackageName:"react-dom"});I.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=mk;I.createPortal=Xh;I.findDOMNode=function(a){if(null==a)return null;if(1===a.nodeType)return a;var b=a._reactInternalFiber;if(void 0===
+b){if("function"===typeof a.render)throw Error(k(188));throw Error(k(268,Object.keys(a)));}a=Sf(b);a=null===a?null:a.stateNode;return a};I.flushSync=function(a,b){if((p&(ca|ma))!==H)throw Error(k(187));var c=p;p|=1;try{return Da(99,a.bind(null,b))}finally{p=c,ha()}};I.hydrate=function(a,b,c){if(!bc(b))throw Error(k(200));return nd(null,a,b,!0,c)};I.render=function(a,b,c){if(!bc(b))throw Error(k(200));return nd(null,a,b,!1,c)};I.unmountComponentAtNode=function(a){if(!bc(a))throw Error(k(40));return a._reactRootContainer?
+(Rh(function(){nd(null,null,a,!1,function(){a._reactRootContainer=null;a[Lb]=null})}),!0):!1};I.unstable_batchedUpdates=Qh;I.unstable_createPortal=function(a,b){return Xh(a,b,2<arguments.length&&void 0!==arguments[2]?arguments[2]:null)};I.unstable_renderSubtreeIntoContainer=function(a,b,c,d){if(!bc(c))throw Error(k(200));if(null==a||void 0===a._reactInternalFiber)throw Error(k(38));return nd(a,b,c,!1,d)};I.version="16.13.1"});
+</script>
+    <script>const e = React.createElement;
+
+function pathToString(path) {
+  if (path[0] === '/') {
+    return '/' + path.slice(1).join('/');
+  } else {
+    return path.join('/');
+  }
+}
+
+function findCommonPath(files) {
+  if (!files || !files.length) {
+    return [];
+  }
+
+  function isPrefix(arr, prefix) {
+    if (arr.length < prefix.length) {
+      return false;
+    }
+    for (let i = prefix.length - 1; i >= 0; --i) {
+      if (arr[i] !== prefix[i]) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  let commonPath = files[0].path.slice(0, -1);
+  while (commonPath.length) {
+    if (files.every(file => isPrefix(file.path, commonPath))) {
+      break;
+    }
+    commonPath.pop();
+  }
+  return commonPath;
+}
+
+function findFolders(files) {
+  if (!files || !files.length) {
+    return [];
+  }
+
+  let folders = files.filter(file => file.path.length > 1).map(file => file.path[0]);
+  folders = [...new Set(folders)]; // unique
+  folders.sort();
+
+  folders = folders.map(folder => {
+    let filesInFolder = files
+      .filter(file => file.path[0] === folder)
+      .map(file => ({
+        ...file,
+        path: file.path.slice(1),
+        parent: [...file.parent, file.path[0]],
+      }));
+
+    const children = findFolders(filesInFolder); // recursion
+
+    return {
+      is_folder: true,
+      path: [folder],
+      parent: files[0].parent,
+      children,
+      covered: children.reduce((sum, file) => sum + file.covered, 0),
+      coverable: children.reduce((sum, file) => sum + file.coverable, 0),
+      prevRun: {
+        covered: children.reduce((sum, file) => sum + file.prevRun.covered, 0),
+        coverable: children.reduce((sum, file) => sum + file.prevRun.coverable, 0),
+      }
+    };
+  });
+
+  return [
+    ...folders,
+    ...files.filter(file => file.path.length === 1),
+  ];
+}
+
+class App extends React.Component {
+  constructor(...args) {
+    super(...args);
+
+    this.state = {
+      current: [],
+    };
+  }
+
+  componentDidMount() {
+    this.updateStateFromLocation();
+    window.addEventListener("hashchange", () => this.updateStateFromLocation(), false);
+  }
+
+  updateStateFromLocation() {
+    if (window.location.hash.length > 1) {
+      const current = window.location.hash.substr(1).split('/');
+      this.setState({current});
+    } else {
+      this.setState({current: []});
+    }
+  }
+
+  getCurrentPath() {
+    let file = this.props.root;
+    let path = [file];
+    for (let p of this.state.current) {
+      file = file.children.find(file => file.path[0] === p);
+      if (!file) {
+        return path;
+      }
+      path.push(file);
+    }
+    return path;
+  }
+
+  render() {
+    const path = this.getCurrentPath();
+    const file = path[path.length - 1];
+
+    let w = null;
+    if (file.is_folder) {
+      w = e(FilesList, {
+        folder: file,
+        onSelectFile: this.selectFile.bind(this),
+        onBack: path.length > 1 ? this.back.bind(this) : null,
+      });
+    } else {
+      w = e(DisplayFile, {
+        file,
+        onBack: this.back.bind(this),
+      });
+    }
+
+    return e('div', {className: 'app'}, w);
+  }
+
+  selectFile(file) {
+    this.setState(({current}) => {
+      return {current: [...current, file.path[0]]};
+    }, () => this.updateHash());
+  }
+
+  back(file) {
+    this.setState(({current}) => {
+      return {current: current.slice(0, current.length - 1)};
+    }, () => this.updateHash());
+  }
+
+  updateHash() {
+    if (!this.state.current || !this.state.current.length) {
+      window.location = '#';
+    } else {
+      window.location = '#' + this.state.current.join('/');
+    }
+  }
+}
+
+function FilesList({folder, onSelectFile, onBack}) {
+  let files = folder.children;
+  return e('div', {className: 'display-folder'},
+    e(FileHeader, {file: folder, onBack}),
+    e('table', {className: 'files-list'},
+      e('thead', {className: 'files-list__head'},
+        e('tr', null,
+          e('th', null, "Path"),
+          e('th', null, "Coverage")
+        )
+      ),
+      e('tbody', {className: 'files-list__body'},
+        files.map(file => e(File, {file, onClick: onSelectFile}))
+      )
+    )
+  );
+}
+
+function File({file, onClick}) {
+  const coverage = file.coverable ? file.covered / file.coverable * 100 : -1;
+  const coverageDelta = file.prevRun &&
+    (file.covered / file.coverable * 100 - file.prevRun.covered / file.prevRun.coverable * 100);
+
+  return e('tr', {
+      className: 'files-list__file'
+        + (coverage >= 0 && coverage < 50 ? ' files-list__file_low': '')
+        + (coverage >= 50 && coverage < 80 ? ' files-list__file_medium': '')
+        + (coverage >= 80 ? ' files-list__file_high': '')
+        + (file.is_folder ? ' files-list__file_folder': ''),
+      onClick: () => onClick(file),
+    },
+    e('td', null, e('a', null, pathToString(file.path))),
+    e('td', null,
+      file.covered + ' / ' + file.coverable +
+      (coverage >= 0 ? ' (' + coverage.toFixed(2) + '%)' : ''),
+      e('span', {title: 'Change from the previous run'},
+        (coverageDelta ? ` (${coverageDelta > 0 ? '+' : ''}${coverageDelta.toFixed(2)}%)` : ''))
+    )
+  );
+}
+
+function DisplayFile({file, onBack}) {
+  return e('div', {className: 'display-file'},
+    e(FileHeader, {file, onBack}),
+    e(FileContent, {file})
+  );
+}
+
+function FileHeader({file, onBack}) {
+  const coverage = file.covered / file.coverable * 100;
+  const coverageDelta = file.prevRun && (coverage - file.prevRun.covered / file.prevRun.coverable * 100);
+
+  return e('div', {className: 'file-header'},
+    onBack ? e('a', {className: 'file-header__back', onClick: onBack}, 'Back') : null,
+    e('div', {className: 'file-header__name'}, pathToString([...file.parent, ...file.path])),
+    e('div', {className: 'file-header__stat'},
+      'Covered: ' + file.covered + ' of ' + file.coverable +
+      (file.coverable ? ' (' + coverage.toFixed(2) + '%)' : ''),
+      e('span', {title: 'Change from the previous run'},
+        (coverageDelta ? ` (${coverageDelta > 0 ? '+' : ''}${coverageDelta.toFixed(2)}%)` : ''))
+    )
+  );
+}
+
+function FileContent({file}) {
+  return e('pre', {className: 'file-content'},
+    file.content.split(/\r?\n/).map((line, index) => {
+      const trace = file.traces.find(trace => trace.line === index + 1);
+      const covered = trace && trace.stats.Line;
+      const uncovered = trace && !trace.stats.Line;
+      return e('code', {
+          className: 'code-line'
+            + (covered ? ' code-line_covered' : '')
+            + (uncovered ? ' code-line_uncovered' : ''),
+          title: trace ? JSON.stringify(trace.stats, null, 2) : null,
+        }, line);
+    })
+  );
+}
+
+(function(){
+  const commonPath = findCommonPath(data.files);
+  const prevFilesMap = new Map();
+
+  previousData && previousData.files.forEach((file) => {
+    const path = file.path.slice(commonPath.length).join('/');
+    prevFilesMap.set(path, file);
+  });
+
+  const files = data.files.map((file) => {
+    const path = file.path.slice(commonPath.length);
+    const { covered = 0, coverable = 0 } = prevFilesMap.get(path.join('/')) || {};
+    return {
+      ...file,
+      path,
+      parent: commonPath,
+      prevRun: { covered, coverable },
+    };
+  });
+
+  const children = findFolders(files);
+
+  const root = {
+    is_folder: true,
+    children,
+    path: commonPath,
+    parent: [],
+    covered: children.reduce((sum, file) => sum + file.covered, 0),
+    coverable: children.reduce((sum, file) => sum + file.coverable, 0),
+    prevRun: {
+      covered: children.reduce((sum, file) => sum + file.prevRun.covered, 0),
+      coverable: children.reduce((sum, file) => sum + file.prevRun.coverable, 0),
+    }
+  };
+
+  ReactDOM.render(e(App, {root, prevFilesMap}), document.getElementById('root'));
+}());
+</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/tarpaulin-report.json b/tarpaulin-report.json
new file mode 100644
index 0000000..4b31ac4
--- /dev/null
+++ b/tarpaulin-report.json
@@ -0,0 +1 @@
+{"files":[{"path":["/","home","runner","work","influxdb-rust","influxdb-rust","benches","client.rs"],"content":"use chrono::{DateTime, Utc};\nuse influxdb::Error;\nuse influxdb::InfluxDbWriteable;\nuse influxdb::{Client, ReadQuery};\nuse std::sync::Arc;\nuse std::time::Instant;\nuse tokio::sync::mpsc::unbounded_channel;\nuse tokio::sync::Semaphore;\n\n#[derive(InfluxDbWriteable, Clone)]\nstruct WeatherReading {\n    time: DateTime<Utc>,\n    humidity: i32,\n    #[influxdb(tag)]\n    wind_direction: String,\n}\n\n#[tokio::main]\nasync fn main() {\n    let db_name = \"bench\";\n    let url = \"http://localhost:8086\";\n    let number_of_total_requests = 20000;\n    let concurrent_requests = 1000;\n\n    let client = Client::new(url, db_name);\n    let concurrency_limit = Arc::new(Semaphore::new(concurrent_requests));\n\n    prepare_influxdb(&client, db_name).await;\n    let measurements = generate_measurements(number_of_total_requests);\n    let (tx, mut rx) = unbounded_channel::<Result<String, Error>>();\n\n    let start = Instant::now();\n    for m in measurements {\n        let permit = concurrency_limit.clone().acquire_owned().await;\n        let client_task = client.clone();\n        let tx_task = tx.clone();\n        tokio::spawn(async move {\n            let res = client_task.query(&m.into_query(\"weather\")).await;\n            let _ = tx_task.send(res);\n            drop(permit);\n        });\n    }\n    drop(tx);\n\n    let mut successful_count = 0;\n    let mut error_count = 0;\n    while let Some(res) = rx.recv().await {\n        if res.is_err() {\n            error_count += 1;\n        } else {\n            successful_count += 1;\n        }\n    }\n\n    let end = Instant::now();\n\n    println!(\n        \"Throughput: {:.1} request/s\",\n        1000000.0 * successful_count as f64 / (end - start).as_micros() as f64\n    );\n    println!(\n        \"{} successful requests, {} errors\",\n        successful_count, error_count\n    );\n}\n\nasync fn prepare_influxdb(client: &Client, db_name: &str) {\n    let create_db_stmt = format!(\"CREATE DATABASE {}\", db_name);\n    client\n        .query(&ReadQuery::new(create_db_stmt))\n        .await\n        .expect(\"failed to create database\");\n}\n\nfn generate_measurements(n: u64) -> Vec<WeatherReading> {\n    (0..n)\n        .collect::<Vec<u64>>()\n        .iter_mut()\n        .map(|_| WeatherReading {\n            time: Utc::now(),\n            humidity: 30,\n            wind_direction: String::from(\"north\"),\n        })\n        .collect()\n}\n","traces":[],"covered":0,"coverable":0},{"path":["/","home","runner","work","influxdb-rust","influxdb-rust","influxdb","src","client","mod.rs"],"content":"//! Client which can read and write data from InfluxDB.\n//!\n//! # Arguments\n//!\n//!  * `url`: The URL where InfluxDB is running (ex. `http://localhost:8086`).\n//!  * `database`: The Database against which queries and writes will be run.\n//!\n//! # Examples\n//!\n//! ```rust\n//! use influxdb::Client;\n//!\n//! let client = Client::new(\"http://localhost:8086\", \"test\");\n//!\n//! assert_eq!(client.database_name(), \"test\");\n//! ```\n\nuse futures_util::TryFutureExt;\n#[cfg(feature = \"reqwest\")]\nuse reqwest::{Client as HttpClient, RequestBuilder, Response as HttpResponse};\nuse std::collections::{BTreeMap, HashMap};\nuse std::fmt::{self, Debug, Formatter};\nuse std::sync::Arc;\n#[cfg(feature = \"surf\")]\nuse surf::{Client as HttpClient, RequestBuilder, Response as HttpResponse};\n\nuse crate::query::QueryType;\nuse crate::Error;\nuse crate::Query;\n\n#[derive(Clone)]\n/// Internal Representation of a Client\npub struct Client {\n    pub(crate) url: Arc<String>,\n    pub(crate) parameters: Arc<HashMap<&'static str, String>>,\n    pub(crate) token: Option<String>,\n    pub(crate) client: HttpClient,\n}\n\nstruct RedactPassword<'a>(&'a HashMap<&'static str, String>);\n\nimpl<'a> Debug for RedactPassword<'a> {\n    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {\n        let entries = self\n            .0\n            .iter()\n            .map(|(k, v)| match *k {\n                \"p\" => (*k, \"<redacted>\"),\n                _ => (*k, v.as_str()),\n            })\n            .collect::<BTreeMap<&'static str, &str>>();\n        f.debug_map().entries(entries).finish()\n    }\n}\n\nimpl Debug for Client {\n    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {\n        f.debug_struct(\"Client\")\n            .field(\"url\", &self.url)\n            .field(\"parameters\", &RedactPassword(&self.parameters))\n            .finish_non_exhaustive()\n    }\n}\n\nimpl Client {\n    /// Instantiates a new [`Client`](crate::Client)\n    ///\n    /// # Arguments\n    ///\n    ///  * `url`: The URL where InfluxDB is running (ex. `http://localhost:8086`).\n    ///  * `database`: The Database against which queries and writes will be run.\n    ///\n    /// # Examples\n    ///\n    /// ```rust\n    /// use influxdb::Client;\n    ///\n    /// let _client = Client::new(\"http://localhost:8086\", \"test\");\n    /// ```\n    #[must_use = \"Creating a client is pointless unless you use it\"]\n    pub fn new<S1, S2>(url: S1, database: S2) -> Self\n    where\n        S1: Into<String>,\n        S2: Into<String>,\n    {\n        let mut parameters = HashMap::<&str, String>::new();\n        parameters.insert(\"db\", database.into());\n        Client {\n            url: Arc::new(url.into()),\n            parameters: Arc::new(parameters),\n            client: HttpClient::new(),\n            token: None,\n        }\n    }\n\n    /// Add authentication/authorization information to [`Client`](crate::Client)\n    ///\n    /// # Arguments\n    ///\n    /// * username: The Username for InfluxDB.\n    /// * password: The Password for the user.\n    ///\n    /// # Examples\n    ///\n    /// ```rust\n    /// use influxdb::Client;\n    ///\n    /// let _client = Client::new(\"http://localhost:9086\", \"test\").with_auth(\"admin\", \"password\");\n    /// ```\n    #[must_use = \"Creating a client is pointless unless you use it\"]\n    pub fn with_auth<S1, S2>(mut self, username: S1, password: S2) -> Self\n    where\n        S1: Into<String>,\n        S2: Into<String>,\n    {\n        let mut with_auth = self.parameters.as_ref().clone();\n        with_auth.insert(\"u\", username.into());\n        with_auth.insert(\"p\", password.into());\n        self.parameters = Arc::new(with_auth);\n        self\n    }\n\n    /// Replaces the HTTP Client\n    #[must_use = \"Creating a client is pointless unless you use it\"]\n    pub fn with_http_client(mut self, http_client: HttpClient) -> Self {\n        self.client = http_client;\n        self\n    }\n\n    /// Add authorization token to [`Client`](crate::Client)\n    ///\n    /// This is designed for influxdb 2.0's backward-compatible API which\n    /// requires authorization by default. You can create such token from\n    /// console of influxdb 2.0 .\n    pub fn with_token<S>(mut self, token: S) -> Self\n    where\n        S: Into<String>,\n    {\n        self.token = Some(token.into());\n        self\n    }\n\n    /// Returns the name of the database the client is using\n    pub fn database_name(&self) -> &str {\n        // safe to unwrap: we always set the database name in `Self::new`\n        self.parameters.get(\"db\").unwrap()\n    }\n\n    /// Returns the URL of the InfluxDB installation the client is using\n    pub fn database_url(&self) -> &str {\n        &self.url\n    }\n\n    /// Pings the InfluxDB Server\n    ///\n    /// Returns a tuple of build type and version number\n    pub async fn ping(&self) -> Result<(String, String), Error> {\n        let url = &format!(\"{}/ping\", self.url);\n        let res = self\n            .client\n            .get(url)\n            .send()\n            .await\n            .map_err(|err| Error::ProtocolError {\n                error: format!(\"{}\", err),\n            })?;\n\n        const BUILD_HEADER: &str = \"X-Influxdb-Build\";\n        const VERSION_HEADER: &str = \"X-Influxdb-Version\";\n\n        #[cfg(feature = \"reqwest\")]\n        let (build, version) = {\n            let hdrs = res.headers();\n            (\n                hdrs.get(BUILD_HEADER).and_then(|value| value.to_str().ok()),\n                hdrs.get(VERSION_HEADER)\n                    .and_then(|value| value.to_str().ok()),\n            )\n        };\n\n        #[cfg(feature = \"surf\")]\n        let build = res.header(BUILD_HEADER).map(|value| value.as_str());\n        #[cfg(feature = \"surf\")]\n        let version = res.header(VERSION_HEADER).map(|value| value.as_str());\n\n        Ok((build.unwrap().to_owned(), version.unwrap().to_owned()))\n    }\n\n    /// Sends a [`ReadQuery`](crate::ReadQuery) or [`WriteQuery`](crate::WriteQuery) to the InfluxDB Server.\n    ///\n    /// A version capable of parsing the returned string is available under the [serde_integration](crate::integrations::serde_integration)\n    ///\n    /// # Arguments\n    ///\n    ///  * `q`: Query of type [`ReadQuery`](crate::ReadQuery) or [`WriteQuery`](crate::WriteQuery)\n    ///\n    /// # Examples\n    ///\n    /// ```rust,no_run\n    /// use influxdb::{Client, Query, Timestamp};\n    /// use influxdb::InfluxDbWriteable;\n    /// use std::time::{SystemTime, UNIX_EPOCH};\n    ///\n    /// # #[async_std::main]\n    /// # async fn main() -> Result<(), influxdb::Error> {\n    /// let start = SystemTime::now();\n    /// let since_the_epoch = start\n    ///   .duration_since(UNIX_EPOCH)\n    ///   .expect(\"Time went backwards\")\n    ///   .as_millis();\n    ///\n    /// let client = Client::new(\"http://localhost:8086\", \"test\");\n    /// let query = Timestamp::Milliseconds(since_the_epoch)\n    ///     .into_query(\"weather\")\n    ///     .add_field(\"temperature\", 82);\n    /// let results = client.query(query).await?;\n    ///\n    /// # Ok(())\n    /// # }\n    /// ```\n    /// # Errors\n    ///\n    /// If the function can not finish the query,\n    /// a [`Error`] variant will be returned.\n    ///\n    /// [`Error`]: enum.Error.html\n    pub async fn query<Q>(&self, q: Q) -> Result<String, Error>\n    where\n        Q: Query,\n    {\n        let query = q.build().map_err(|err| Error::InvalidQueryError {\n            error: err.to_string(),\n        })?;\n\n        let mut parameters = self.parameters.as_ref().clone();\n        let request_builder = match q.get_type() {\n            QueryType::ReadQuery => {\n                let read_query = query.get();\n                let url = &format!(\"{}/query\", &self.url);\n                parameters.insert(\"q\", read_query.clone());\n\n                if read_query.contains(\"SELECT\") || read_query.contains(\"SHOW\") {\n                    self.client.get(url).query(&parameters)\n                } else {\n                    self.client.post(url).query(&parameters)\n                }\n            }\n            QueryType::WriteQuery(precision) => {\n                let url = &format!(\"{}/write\", &self.url);\n                let mut parameters = self.parameters.as_ref().clone();\n                parameters.insert(\"precision\", precision);\n\n                self.client.post(url).body(query.get()).query(&parameters)\n            }\n        };\n\n        #[cfg(feature = \"surf\")]\n        let request_builder = request_builder.map_err(|err| Error::UrlConstructionError {\n            error: err.to_string(),\n        })?;\n\n        let res = self\n            .auth_if_needed(request_builder)\n            .send()\n            .map_err(|err| Error::ConnectionError {\n                error: err.to_string(),\n            })\n            .await?;\n        check_status(&res)?;\n\n        #[cfg(feature = \"reqwest\")]\n        let body = res.text();\n        #[cfg(feature = \"surf\")]\n        let mut res = res;\n        #[cfg(feature = \"surf\")]\n        let body = res.body_string();\n\n        let s = body.await.map_err(|_| Error::DeserializationError {\n            error: \"response could not be converted to UTF-8\".to_string(),\n        })?;\n\n        // todo: improve error parsing without serde\n        if s.contains(\"\\\"error\\\"\") || s.contains(\"\\\"Error\\\"\") {\n            return Err(Error::DatabaseError {\n                error: format!(\"influxdb error: \\\"{}\\\"\", s),\n            });\n        }\n\n        Ok(s)\n    }\n\n    fn auth_if_needed(&self, rb: RequestBuilder) -> RequestBuilder {\n        if let Some(ref token) = self.token {\n            rb.header(\"Authorization\", format!(\"Token {}\", token))\n        } else {\n            rb\n        }\n    }\n}\n\npub(crate) fn check_status(res: &HttpResponse) -> Result<(), Error> {\n    let status = res.status();\n    if !status.is_success() {\n        return Err(Error::ApiError(status.into()));\n    }\n    Ok(())\n}\n\n#[cfg(test)]\nmod tests {\n    use super::Client;\n    use indoc::indoc;\n\n    #[test]\n    fn test_client_debug_redacted_password() {\n        let client = Client::new(\"https://localhost:8086\", \"db\").with_auth(\"user\", \"pass\");\n        let actual = format!(\"{:#?}\", client);\n        let expected = indoc! { r#\"\n            Client {\n                url: \"https://localhost:8086\",\n                parameters: {\n                    \"db\": \"db\",\n                    \"p\": \"<redacted>\",\n                    \"u\": \"user\",\n                },\n                ..\n            }\n        \"# };\n        assert_eq!(actual.trim(), expected.trim());\n    }\n\n    #[test]\n    fn test_fn_database() {\n        let client = Client::new(\"http://localhost:8068\", \"database\");\n        assert_eq!(client.database_name(), \"database\");\n        assert_eq!(client.database_url(), \"http://localhost:8068\");\n    }\n\n    #[test]\n    fn test_with_auth() {\n        let client = Client::new(\"http://localhost:8068\", \"database\");\n        assert_eq!(client.parameters.len(), 1);\n        assert_eq!(client.parameters.get(\"db\").unwrap(), \"database\");\n\n        let with_auth = client.with_auth(\"username\", \"password\");\n        assert_eq!(with_auth.parameters.len(), 3);\n        assert_eq!(with_auth.parameters.get(\"db\").unwrap(), \"database\");\n        assert_eq!(with_auth.parameters.get(\"u\").unwrap(), \"username\");\n        assert_eq!(with_auth.parameters.get(\"p\").unwrap(), \"password\");\n\n        let client = Client::new(\"http://localhost:8068\", \"database\");\n        let with_auth = client.with_token(\"token\");\n        assert_eq!(with_auth.parameters.len(), 1);\n        assert_eq!(with_auth.parameters.get(\"db\").unwrap(), \"database\");\n        assert_eq!(with_auth.token.unwrap(), \"token\");\n    }\n}\n","traces":[{"line":43,"address":[],"length":0,"stats":{"Line":1}},{"line":44,"address":[2155260],"length":1,"stats":{"Line":1}},{"line":45,"address":[],"length":0,"stats":{"Line":0}},{"line":47,"address":[],"length":0,"stats":{"Line":2}},{"line":48,"address":[6948104,6948001],"length":1,"stats":{"Line":2}},{"line":49,"address":[2155623],"length":1,"stats":{"Line":1}},{"line":52,"address":[6947806,6947746],"length":1,"stats":{"Line":2}},{"line":57,"address":[6948160],"length":1,"stats":{"Line":1}},{"line":58,"address":[6948178,6948209,6948268],"length":1,"stats":{"Line":3}},{"line":59,"address":[2155789],"length":1,"stats":{"Line":1}},{"line":60,"address":[6948248],"length":1,"stats":{"Line":1}},{"line":81,"address":[2155904,2156569,2156607],"length":1,"stats":{"Line":11}},{"line":86,"address":[2354816,2355605],"length":1,"stats":{"Line":11}},{"line":87,"address":[2156156,2156076],"length":1,"stats":{"Line":22}},{"line":89,"address":[2355855,2355095],"length":1,"stats":{"Line":12}},{"line":90,"address":[2355166,2356042,2355282,2355926],"length":1,"stats":{"Line":24}},{"line":91,"address":[2355290,2356050],"length":1,"stats":{"Line":12}},{"line":111,"address":[2157298,2156624,2157261],"length":1,"stats":{"Line":6}},{"line":116,"address":[2156813,2156706],"length":1,"stats":{"Line":10}},{"line":117,"address":[2156838,2156910],"length":1,"stats":{"Line":11}},{"line":118,"address":[2724770],"length":1,"stats":{"Line":5}},{"line":119,"address":[2157072],"length":1,"stats":{"Line":6}},{"line":120,"address":[2157215],"length":1,"stats":{"Line":6}},{"line":125,"address":[6948320,6948449],"length":1,"stats":{"Line":0}},{"line":126,"address":[6948356,6948425],"length":1,"stats":{"Line":0}},{"line":127,"address":[6948429],"length":1,"stats":{"Line":0}},{"line":135,"address":[2157718,2157456],"length":1,"stats":{"Line":1}},{"line":139,"address":[],"length":0,"stats":{"Line":2}},{"line":140,"address":[],"length":0,"stats":{"Line":1}},{"line":144,"address":[7487936],"length":1,"stats":{"Line":1}},{"line":146,"address":[7487941],"length":1,"stats":{"Line":1}},{"line":150,"address":[6948560],"length":1,"stats":{"Line":1}},{"line":151,"address":[2157813],"length":1,"stats":{"Line":1}},{"line":157,"address":[6948829,6948786,6948624,6950489,6949196,6948671,6948592,6948600],"length":1,"stats":{"Line":4}},{"line":158,"address":[6948879,6948763],"length":1,"stats":{"Line":2}},{"line":159,"address":[6949082,6949442,6949136,6949011,6949365,6949667],"length":1,"stats":{"Line":5}},{"line":163,"address":[2158402,2158600,2158060,2158365,2158461],"length":1,"stats":{"Line":4}},{"line":164,"address":[2159965,2159792,2160021],"length":1,"stats":{"Line":0}},{"line":165,"address":[2159875,2159827],"length":1,"stats":{"Line":0}},{"line":172,"address":[2159157],"length":1,"stats":{"Line":1}},{"line":173,"address":[6949620,6949756],"length":1,"stats":{"Line":2}},{"line":175,"address":[2158985,2160048,2160057],"length":1,"stats":{"Line":3}},{"line":176,"address":[6949846],"length":1,"stats":{"Line":1}},{"line":177,"address":[2160096,2160105],"length":1,"stats":{"Line":2}},{"line":186,"address":[7489482,7489572],"length":1,"stats":{"Line":2}},{"line":227,"address":[2356288,2356492,2356320,2361484],"length":1,"stats":{"Line":15}},{"line":231,"address":[2364197,2361580,2356965,2361925,2366704,2366774,2366822,2359261,2367008,2367078,2361726,2367126,2356595,2356766],"length":1,"stats":{"Line":16}},{"line":232,"address":[],"length":0,"stats":{"Line":0}},{"line":235,"address":[2361870,2362011,2357051,2356910],"length":1,"stats":{"Line":14}},{"line":236,"address":[],"length":0,"stats":{"Line":14}},{"line":237,"address":[],"length":0,"stats":{"Line":0}},{"line":238,"address":[2719312,2714195],"length":1,"stats":{"Line":5}},{"line":239,"address":[2362400,2357369,2362317,2357452],"length":1,"stats":{"Line":10}},{"line":240,"address":[2357568,2362611,2362516,2357667],"length":1,"stats":{"Line":10}},{"line":242,"address":[2362842,2363027,2362677,2358091,2357898,2357733],"length":1,"stats":{"Line":10}},{"line":243,"address":[],"length":0,"stats":{"Line":2}},{"line":245,"address":[2714949,2720055],"length":1,"stats":{"Line":4}},{"line":248,"address":[],"length":0,"stats":{"Line":2}},{"line":249,"address":[2714317,2715265,2719431,2720356],"length":1,"stats":{"Line":4}},{"line":250,"address":[],"length":0,"stats":{"Line":4}},{"line":251,"address":[2715608,2720568,2720699,2715477],"length":1,"stats":{"Line":4}},{"line":253,"address":[],"length":0,"stats":{"Line":4}},{"line":258,"address":[],"length":0,"stats":{"Line":0}},{"line":259,"address":[],"length":0,"stats":{"Line":0}},{"line":262,"address":[2364013,2359077,2364638,2364374,2365011,2364436,2358172,2359723,2359521,2359150,2360096,2359459,2363108,2364086],"length":1,"stats":{"Line":29}},{"line":263,"address":[2715130,2720224],"length":1,"stats":{"Line":7}},{"line":265,"address":[2723472,2723547,2723851,2723904,2723600,2723776],"length":1,"stats":{"Line":2}},{"line":266,"address":[],"length":0,"stats":{"Line":1}},{"line":268,"address":[2716754,2721255,2721573,2718768,2721292,2713633,2716509,2721445,2721803,2716378,2716179,2716219],"length":1,"stats":{"Line":23}},{"line":269,"address":[],"length":0,"stats":{"Line":12}},{"line":272,"address":[],"length":0,"stats":{"Line":4}},{"line":274,"address":[],"length":0,"stats":{"Line":0}},{"line":276,"address":[],"length":0,"stats":{"Line":0}},{"line":278,"address":[2366095,2366306,2366384,2360148,2361658,2365059,2360007,2356677,2365461,2366466,2361258,2360550,2364922,2366519,2366224,2366359],"length":1,"stats":{"Line":6}},{"line":279,"address":[],"length":0,"stats":{"Line":0}},{"line":283,"address":[2360637,2365650,2365412,2360739,2365548,2360501],"length":1,"stats":{"Line":13}},{"line":284,"address":[],"length":0,"stats":{"Line":0}},{"line":285,"address":[],"length":0,"stats":{"Line":0}},{"line":289,"address":[],"length":0,"stats":{"Line":5}},{"line":292,"address":[6950928,6951300,6951329],"length":1,"stats":{"Line":6}},{"line":293,"address":[2160300,2160178],"length":1,"stats":{"Line":11}},{"line":294,"address":[2160305,2160525,2160230],"length":1,"stats":{"Line":0}},{"line":296,"address":[2160290],"length":1,"stats":{"Line":5}},{"line":301,"address":[6951344],"length":1,"stats":{"Line":2}},{"line":302,"address":[2160590],"length":1,"stats":{"Line":2}},{"line":303,"address":[2160600],"length":1,"stats":{"Line":2}},{"line":304,"address":[2160614],"length":1,"stats":{"Line":1}},{"line":306,"address":[2160694],"length":1,"stats":{"Line":2}}],"covered":72,"coverable":88},{"path":["/","home","runner","work","influxdb-rust","influxdb-rust","influxdb","src","error.rs"],"content":"//! Errors that might happen in the crate\n\nuse thiserror::Error;\n\n#[derive(Debug, Eq, PartialEq, Error)]\n#[non_exhaustive]\npub enum Error {\n    #[error(\"query is invalid: {error}\")]\n    /// Error happens when a query is invalid\n    InvalidQueryError { error: String },\n\n    #[error(\"Failed to build URL: {error}\")]\n    /// Error happens when a query is invalid\n    UrlConstructionError { error: String },\n\n    #[error(\"http protocol error: {error}\")]\n    /// Error happens when a query is invalid\n    ProtocolError { error: String },\n\n    #[error(\"http protocol error: {error}\")]\n    /// Error happens when Serde cannot deserialize the response\n    DeserializationError { error: String },\n\n    #[error(\"InfluxDB encountered the following error: {error}\")]\n    /// Error which has happened inside InfluxDB\n    DatabaseError { error: String },\n\n    #[error(\"API error with a status code: {0}\")]\n    /// Error happens when API returns non 2xx status code.\n    ApiError(u16),\n\n    #[error(\"connection error: {error}\")]\n    /// Error happens when HTTP request fails\n    ConnectionError { error: String },\n}\n","traces":[],"covered":0,"coverable":0},{"path":["/","home","runner","work","influxdb-rust","influxdb-rust","influxdb","src","integrations","serde_integration","de.rs"],"content":"use super::{Series, TaggedSeries};\nuse serde::de::{\n    value, Deserialize, DeserializeSeed, Deserializer, Error, IntoDeserializer, MapAccess,\n    SeqAccess, Visitor,\n};\nuse serde_derive::Deserialize;\nuse std::fmt;\nuse std::marker::PhantomData;\n\n// Based on https://serde.rs/deserialize-struct.html\nimpl<'de, T> Deserialize<'de> for Series<T>\nwhere\n    T: Deserialize<'de>,\n{\n    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>\n    where\n        D: Deserializer<'de>,\n    {\n        // Field name deserializer\n        #[derive(Deserialize)]\n        #[serde(field_identifier, rename_all = \"lowercase\")]\n        enum Field {\n            Name,\n            Columns,\n            Values,\n        }\n\n        struct SeriesVisitor<T> {\n            _inner_type: PhantomData<T>,\n        }\n\n        impl<'de, T> Visitor<'de> for SeriesVisitor<T>\n        where\n            T: Deserialize<'de>,\n        {\n            type Value = Series<T>;\n\n            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {\n                formatter.write_str(\"struct Series\")\n            }\n\n            fn visit_map<V>(self, mut map: V) -> Result<Series<T>, V::Error>\n            where\n                V: MapAccess<'de>,\n            {\n                let mut name = None;\n                let mut columns: Option<Vec<String>> = None;\n                let mut values: Option<Vec<T>> = None;\n                while let Some(key) = map.next_key()? {\n                    match key {\n                        Field::Name => {\n                            if name.is_some() {\n                                return Err(Error::duplicate_field(\"name\"));\n                            }\n                            name = Some(map.next_value()?);\n                        }\n                        Field::Columns => {\n                            if columns.is_some() {\n                                return Err(Error::duplicate_field(\"columns\"));\n                            }\n                            columns = Some(map.next_value()?);\n                        }\n                        Field::Values => {\n                            if values.is_some() {\n                                return Err(Error::duplicate_field(\"values\"));\n                            }\n                            // Error out if \"values\" is encountered before \"columns\"\n                            // Hopefully, InfluxDB never does this.\n                            if columns.is_none() {\n                                return Err(Error::custom(\n                                    \"series values encountered before columns\",\n                                ));\n                            }\n                            // Deserialize using a HeaderVec deserializer\n                            // seeded with the headers from the \"columns\" field\n                            values = Some(map.next_value_seed(HeaderVec::<T> {\n                                header: columns.as_ref().unwrap(),\n                                _inner_type: PhantomData,\n                            })?);\n                        }\n                    }\n                }\n                let name = name.ok_or_else(|| Error::missing_field(\"name\"))?;\n                let values = values.unwrap_or_default();\n\n                Ok(Series { name, values })\n            }\n        }\n\n        const FIELDS: &[&str] = &[\"name\", \"values\"];\n        deserializer.deserialize_struct(\n            \"Series\",\n            FIELDS,\n            SeriesVisitor::<T> {\n                _inner_type: PhantomData,\n            },\n        )\n    }\n}\n\n// Based on https://serde.rs/deserialize-struct.html\nimpl<'de, TAG, T> Deserialize<'de> for TaggedSeries<TAG, T>\nwhere\n    TAG: Deserialize<'de>,\n    T: Deserialize<'de>,\n{\n    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>\n    where\n        D: Deserializer<'de>,\n    {\n        // Field name deserializer\n        #[derive(Deserialize)]\n        #[serde(field_identifier, rename_all = \"lowercase\")]\n        enum Field {\n            Name,\n            Tags,\n            Columns,\n            Values,\n        }\n\n        struct SeriesVisitor<TAG, T> {\n            _tag_type: PhantomData<TAG>,\n            _value_type: PhantomData<T>,\n        }\n\n        impl<'de, TAG, T> Visitor<'de> for SeriesVisitor<TAG, T>\n        where\n            TAG: Deserialize<'de>,\n            T: Deserialize<'de>,\n        {\n            type Value = TaggedSeries<TAG, T>;\n\n            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {\n                formatter.write_str(\"struct TaggedSeries\")\n            }\n\n            fn visit_map<V>(self, mut map: V) -> Result<TaggedSeries<TAG, T>, V::Error>\n            where\n                V: MapAccess<'de>,\n            {\n                let mut name = None;\n                let mut tags: Option<TAG> = None;\n                let mut columns: Option<Vec<String>> = None;\n                let mut values: Option<Vec<T>> = None;\n                while let Some(key) = map.next_key()? {\n                    match key {\n                        Field::Name => {\n                            if name.is_some() {\n                                return Err(Error::duplicate_field(\"name\"));\n                            }\n                            name = Some(map.next_value()?);\n                        }\n                        Field::Tags => {\n                            if tags.is_some() {\n                                return Err(Error::duplicate_field(\"tags\"));\n                            }\n                            tags = Some(map.next_value()?);\n                        }\n                        Field::Columns => {\n                            if columns.is_some() {\n                                return Err(Error::duplicate_field(\"columns\"));\n                            }\n                            columns = Some(map.next_value()?);\n                        }\n                        Field::Values => {\n                            if values.is_some() {\n                                return Err(Error::duplicate_field(\"values\"));\n                            }\n                            // Error out if \"values\" is encountered before \"columns\"\n                            // Hopefully, InfluxDB never does this.\n                            if columns.is_none() {\n                                return Err(Error::custom(\n                                    \"series values encountered before columns\",\n                                ));\n                            }\n                            // Deserialize using a HeaderVec deserializer\n                            // seeded with the headers from the \"columns\" field\n                            values = Some(map.next_value_seed(HeaderVec::<T> {\n                                header: columns.as_ref().unwrap(),\n                                _inner_type: PhantomData,\n                            })?);\n                        }\n                    }\n                }\n                let name = name.ok_or_else(|| Error::missing_field(\"name\"))?;\n                let tags = tags.ok_or_else(|| Error::missing_field(\"tags\"))?;\n                let values = values.ok_or_else(|| Error::missing_field(\"values\"))?;\n                Ok(TaggedSeries { name, tags, values })\n            }\n        }\n\n        const FIELDS: &[&str] = &[\"name\", \"tags\", \"values\"];\n        deserializer.deserialize_struct(\n            \"TaggedSeries\",\n            FIELDS,\n            SeriesVisitor::<TAG, T> {\n                _tag_type: PhantomData,\n                _value_type: PhantomData,\n            },\n        )\n    }\n}\n\n// Deserializer that takes a header as a seed\n// and deserializes an array of arrays into a\n// Vec of map-like values using the header as\n// keys and the values as values.\nstruct HeaderVec<'h, T> {\n    header: &'h [String],\n    _inner_type: PhantomData<T>,\n}\n\nimpl<'de, 'h, T> DeserializeSeed<'de> for HeaderVec<'h, T>\nwhere\n    T: Deserialize<'de>,\n{\n    type Value = Vec<T>;\n\n    fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>\n    where\n        D: Deserializer<'de>,\n    {\n        struct HeaderVecVisitor<'h, T> {\n            header: &'h [String],\n            _inner_type: PhantomData<T>,\n        }\n        impl<'de, 'h, T> Visitor<'de> for HeaderVecVisitor<'h, T>\n        where\n            T: Deserialize<'de>,\n        {\n            type Value = Vec<T>;\n\n            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {\n                write!(formatter, \"an array of arrays\")\n            }\n\n            fn visit_seq<A>(self, mut seq: A) -> Result<Vec<T>, A::Error>\n            where\n                A: SeqAccess<'de>,\n            {\n                let mut vec = Vec::new();\n\n                while let Some(v) = seq.next_element_seed(RowWithHeader {\n                    header: self.header,\n                    _inner_type: PhantomData,\n                })? {\n                    vec.push(v);\n                }\n\n                Ok(vec)\n            }\n        }\n        deserializer.deserialize_seq(HeaderVecVisitor {\n            header: self.header,\n            _inner_type: PhantomData,\n        })\n    }\n}\n\n// Deserializer that takes a header as a seed\n// and deserializes an array into a map-like\n// value using the header as keys and the values\n// as values.\nstruct RowWithHeader<'h, T> {\n    header: &'h [String],\n    _inner_type: PhantomData<T>,\n}\n\nimpl<'de, 'h, T> DeserializeSeed<'de> for RowWithHeader<'h, T>\nwhere\n    T: Deserialize<'de>,\n{\n    type Value = T;\n\n    fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>\n    where\n        D: Deserializer<'de>,\n    {\n        struct RowWithHeaderVisitor<'h, T> {\n            header: &'h [String],\n            _inner: PhantomData<fn() -> T>,\n        }\n\n        impl<'de, 'h, T> Visitor<'de> for RowWithHeaderVisitor<'h, T>\n        where\n            T: Deserialize<'de>,\n        {\n            type Value = T;\n\n            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {\n                formatter.write_str(\"array\")\n            }\n\n            fn visit_seq<A>(self, seq: A) -> Result<T, A::Error>\n            where\n                A: SeqAccess<'de>,\n            {\n                // `MapAccessDeserializer` is a wrapper that turns a `MapAccess`\n                // into a `Deserializer`, allowing it to be used as the input to T's\n                // `Deserialize` implementation. T then deserializes itself using\n                // the entries from the map visitor.\n                Deserialize::deserialize(value::MapAccessDeserializer::new(HeaderMapAccess {\n                    header: self.header,\n                    field: 0,\n                    data: seq,\n                }))\n            }\n        }\n\n        deserializer.deserialize_seq(RowWithHeaderVisitor {\n            header: self.header,\n            _inner: PhantomData,\n        })\n    }\n}\n\n// MapAccess implementation that holds a reference to\n// the header for keys and a serde sequence for values.\n// When asked for a key, it returns the next header and\n// advances its header field index. When asked for a value,\n// it tries to deserialize the next element in the serde\n// sequence into the desired type, and returns an error\n// if no element is returned (the sequence is exhausted).\nstruct HeaderMapAccess<'h, A> {\n    header: &'h [String],\n    field: usize,\n    data: A,\n}\n\nimpl<'de, 'h, A> MapAccess<'de> for HeaderMapAccess<'h, A>\nwhere\n    A: SeqAccess<'de>,\n{\n    type Error = <A as SeqAccess<'de>>::Error;\n\n    fn next_key_seed<K: DeserializeSeed<'de>>(\n        &mut self,\n        seed: K,\n    ) -> Result<Option<K::Value>, Self::Error> {\n        let field = match self.header.get(self.field) {\n            None => return Ok(None),\n            Some(field) => field,\n        };\n        self.field += 1;\n        seed.deserialize(field.clone().into_deserializer())\n            .map(Some)\n    }\n\n    fn next_value_seed<K: DeserializeSeed<'de>>(\n        &mut self,\n        seed: K,\n    ) -> Result<K::Value, Self::Error> {\n        match self.data.next_element_seed(seed)? {\n            Some(value) => Ok(value),\n            None => Err(Error::custom(\"next_value_seed called but no value\")),\n        }\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::Series;\n    use std::borrow::Cow;\n    use std::collections::HashMap;\n\n    const TEST_DATA: &str = r#\"\n    {\n        \"name\": \"series_name\",\n        \"columns\": [\"foo\", \"bar\"],\n        \"values\": [\n            [\"foo_a\", \"bar_a\"],\n            [\"foo_b\", \"bar_b\"]\n        ]\n    }\n    \"#;\n\n    // we can derive all the impls we want here\n    #[derive(Debug, PartialEq, Eq)]\n    struct EqSeries<T> {\n        pub name: String,\n        pub values: Vec<T>,\n    }\n\n    impl<T> From<Series<T>> for EqSeries<T> {\n        fn from(Series { name, values }: Series<T>) -> Self {\n            EqSeries { name, values }\n        }\n    }\n\n    #[test]\n    fn test_deserialize_cow() {\n        // Unfortunately, Cow is not automatically borrowed,\n        // so this is basically equivalent to String, String\n        let result = serde_json::from_str::<Series<HashMap<Cow<str>, Cow<str>>>>(TEST_DATA);\n        assert!(result.is_ok());\n        assert_eq!(\n            EqSeries::from(result.unwrap()),\n            EqSeries {\n                name: \"series_name\".into(),\n                values: vec![\n                    {\n                        let mut h = std::collections::HashMap::new();\n                        h.insert(\"foo\".into(), \"foo_a\".into());\n                        h.insert(\"bar\".into(), \"bar_a\".into());\n                        h\n                    },\n                    {\n                        let mut h = std::collections::HashMap::new();\n                        h.insert(\"foo\".into(), \"foo_b\".into());\n                        h.insert(\"bar\".into(), \"bar_b\".into());\n                        h\n                    },\n                ],\n            },\n        );\n    }\n\n    #[test]\n    fn test_deserialize_borrowed() {\n        use serde_derive::Deserialize;\n\n        // Deserializing a string that cannot be passed through\n        // without escaping will result in an error like this:\n        // `invalid type: string \"\\n\", expected a borrowed string at line 6 column 43`\n        // but if it doesn't need escaping it's fine.\n        #[derive(Deserialize, Debug, PartialEq, Eq)]\n        struct BorrowingStruct<'a> {\n            foo: &'a str,\n            bar: &'a str,\n        }\n\n        let result = serde_json::from_str::<Series<BorrowingStruct>>(TEST_DATA);\n        assert!(result.is_ok(), \"{}\", result.unwrap_err());\n        assert_eq!(\n            EqSeries::from(result.unwrap()),\n            EqSeries {\n                name: \"series_name\".into(),\n                values: vec![\n                    BorrowingStruct {\n                        foo: \"foo_a\",\n                        bar: \"bar_a\",\n                    },\n                    BorrowingStruct {\n                        foo: \"foo_b\",\n                        bar: \"bar_b\",\n                    },\n                ],\n            },\n        );\n    }\n}\n","traces":[{"line":15,"address":[2771984,2772128,2772032,2772080,2772176],"length":1,"stats":{"Line":8}},{"line":32,"address":[],"length":0,"stats":{"Line":0}},{"line":38,"address":[2375248],"length":1,"stats":{"Line":0}},{"line":39,"address":[2102409,2102345],"length":1,"stats":{"Line":0}},{"line":42,"address":[],"length":0,"stats":{"Line":8}},{"line":46,"address":[2375334],"length":1,"stats":{"Line":8}},{"line":47,"address":[2375373],"length":1,"stats":{"Line":8}},{"line":48,"address":[2934687,2939807,2942367,2932127,2937247],"length":1,"stats":{"Line":8}},{"line":49,"address":[2939544,2942406,2934424,2937286,2942470,2937350,2944664,2942104,2936984,2939846,2934790,2932166,2934726,2932230,2939910],"length":1,"stats":{"Line":16}},{"line":50,"address":[],"length":0,"stats":{"Line":8}},{"line":51,"address":[],"length":0,"stats":{"Line":8}},{"line":52,"address":[2375780,2375712],"length":1,"stats":{"Line":16}},{"line":53,"address":[2935102,2940222,2940595,2938035,2943155,2935475,2937662,2942782,2932542,2932915],"length":1,"stats":{"Line":0}},{"line":55,"address":[],"length":0,"stats":{"Line":16}},{"line":57,"address":[2103721,2106361],"length":1,"stats":{"Line":8}},{"line":58,"address":[2940618,2943178,2935036,2937596,2938058,2940156,2932476,2932938,2935498,2942716],"length":1,"stats":{"Line":16}},{"line":59,"address":[2376228,2376577],"length":1,"stats":{"Line":0}},{"line":61,"address":[2940637,2943538,2943197,2935858,2943251,2940978,2935517,2932957,2938131,2935571,2938418,2940691,2933298,2933011,2938077],"length":1,"stats":{"Line":16}},{"line":63,"address":[],"length":0,"stats":{"Line":8}},{"line":64,"address":[2941019,2935899,2938459,2943579,2932498,2940178,2942738,2935058,2933339,2937618],"length":1,"stats":{"Line":16}},{"line":65,"address":[2377160,2376628],"length":1,"stats":{"Line":0}},{"line":69,"address":[2103827,2103781,2106467,2106421],"length":1,"stats":{"Line":16}},{"line":70,"address":[],"length":0,"stats":{"Line":0}},{"line":71,"address":[],"length":0,"stats":{"Line":0}},{"line":76,"address":[],"length":0,"stats":{"Line":8}},{"line":77,"address":[],"length":0,"stats":{"Line":16}},{"line":78,"address":[],"length":0,"stats":{"Line":0}},{"line":83,"address":[2105434,2107728,2107055,2104589,2104415,2107229,2104896,2107536,2102794,2107760,2107761,2107729],"length":1,"stats":{"Line":16}},{"line":84,"address":[2107161,2104521],"length":1,"stats":{"Line":8}},{"line":86,"address":[2104671,2107311],"length":1,"stats":{"Line":8}},{"line":91,"address":[2772040,2772088,2772184,2771992,2772136],"length":1,"stats":{"Line":8}},{"line":93,"address":[],"length":0,"stats":{"Line":0}},{"line":94,"address":[],"length":0,"stats":{"Line":0}},{"line":95,"address":[],"length":0,"stats":{"Line":0}},{"line":107,"address":[2772224],"length":1,"stats":{"Line":1}},{"line":126,"address":[],"length":0,"stats":{"Line":0}},{"line":133,"address":[],"length":0,"stats":{"Line":0}},{"line":134,"address":[],"length":0,"stats":{"Line":0}},{"line":137,"address":[2945072,2948645,2948438],"length":1,"stats":{"Line":1}},{"line":141,"address":[],"length":0,"stats":{"Line":1}},{"line":142,"address":[2945141],"length":1,"stats":{"Line":1}},{"line":143,"address":[],"length":0,"stats":{"Line":1}},{"line":144,"address":[],"length":0,"stats":{"Line":1}},{"line":145,"address":[],"length":0,"stats":{"Line":2}},{"line":146,"address":[],"length":0,"stats":{"Line":1}},{"line":147,"address":[],"length":0,"stats":{"Line":1}},{"line":148,"address":[],"length":0,"stats":{"Line":2}},{"line":149,"address":[2946001,2945621],"length":1,"stats":{"Line":0}},{"line":151,"address":[],"length":0,"stats":{"Line":2}},{"line":153,"address":[],"length":0,"stats":{"Line":1}},{"line":154,"address":[2946024,2945533],"length":1,"stats":{"Line":2}},{"line":155,"address":[],"length":0,"stats":{"Line":0}},{"line":157,"address":[],"length":0,"stats":{"Line":2}},{"line":159,"address":[],"length":0,"stats":{"Line":1}},{"line":160,"address":[2945555,2946441],"length":1,"stats":{"Line":2}},{"line":161,"address":[],"length":0,"stats":{"Line":0}},{"line":163,"address":[],"length":0,"stats":{"Line":2}},{"line":165,"address":[],"length":0,"stats":{"Line":1}},{"line":166,"address":[],"length":0,"stats":{"Line":2}},{"line":167,"address":[],"length":0,"stats":{"Line":0}},{"line":171,"address":[2946902,2946856],"length":1,"stats":{"Line":2}},{"line":172,"address":[2946928,2947367],"length":1,"stats":{"Line":0}},{"line":173,"address":[],"length":0,"stats":{"Line":0}},{"line":178,"address":[],"length":0,"stats":{"Line":1}},{"line":179,"address":[],"length":0,"stats":{"Line":2}},{"line":180,"address":[],"length":0,"stats":{"Line":0}},{"line":185,"address":[2948449,2947615,2948737,2948736,2945440,2947421],"length":1,"stats":{"Line":2}},{"line":186,"address":[],"length":0,"stats":{"Line":2}},{"line":187,"address":[],"length":0,"stats":{"Line":2}},{"line":188,"address":[],"length":0,"stats":{"Line":1}},{"line":193,"address":[2772232],"length":1,"stats":{"Line":1}},{"line":195,"address":[],"length":0,"stats":{"Line":0}},{"line":196,"address":[],"length":0,"stats":{"Line":0}},{"line":197,"address":[],"length":0,"stats":{"Line":0}},{"line":198,"address":[],"length":0,"stats":{"Line":0}},{"line":219,"address":[2925984,2926112,2926304,2926048,2926176,2926240],"length":1,"stats":{"Line":9}},{"line":227,"address":[],"length":0,"stats":{"Line":0}},{"line":233,"address":[2107920,2107984],"length":1,"stats":{"Line":0}},{"line":234,"address":[2107938,2108002],"length":1,"stats":{"Line":0}},{"line":237,"address":[2109088,2108645,2108576,2108048,2108592,2108101],"length":1,"stats":{"Line":9}},{"line":241,"address":[2108638,2108680,2108136,2108094],"length":1,"stats":{"Line":18}},{"line":243,"address":[2108705,2108161,2108762,2108215,2108393,2108882],"length":1,"stats":{"Line":18}},{"line":244,"address":[],"length":0,"stats":{"Line":9}},{"line":245,"address":[],"length":0,"stats":{"Line":0}},{"line":247,"address":[2108436,2108465,2108938,2108977],"length":1,"stats":{"Line":18}},{"line":250,"address":[2927755,2930558,2928878,2929998,2928318,2929438],"length":1,"stats":{"Line":9}},{"line":253,"address":[],"length":0,"stats":{"Line":9}},{"line":254,"address":[2107830,2107894],"length":1,"stats":{"Line":9}},{"line":255,"address":[],"length":0,"stats":{"Line":0}},{"line":275,"address":[2109168,2109104],"length":1,"stats":{"Line":9}},{"line":284,"address":[],"length":0,"stats":{"Line":0}},{"line":290,"address":[2930800,2930672,2930736,2930992,2930864,2930928],"length":1,"stats":{"Line":0}},{"line":291,"address":[2109321,2109257],"length":1,"stats":{"Line":0}},{"line":294,"address":[],"length":0,"stats":{"Line":9}},{"line":302,"address":[2931318,2931430,2931094,2931542,2931206,2931654],"length":1,"stats":{"Line":9}},{"line":303,"address":[2109551,2109407],"length":1,"stats":{"Line":9}},{"line":304,"address":[],"length":0,"stats":{"Line":0}},{"line":305,"address":[],"length":0,"stats":{"Line":0}},{"line":310,"address":[2109152,2109216],"length":1,"stats":{"Line":9}},{"line":311,"address":[],"length":0,"stats":{"Line":9}},{"line":312,"address":[],"length":0,"stats":{"Line":0}},{"line":336,"address":[2371712,2372132],"length":1,"stats":{"Line":9}},{"line":340,"address":[2924782,2923345,2923438,2924689,2924241,2922897,2923793,2922542,2923886,2924334,2922449,2922990],"length":1,"stats":{"Line":18}},{"line":341,"address":[],"length":0,"stats":{"Line":9}},{"line":342,"address":[],"length":0,"stats":{"Line":9}},{"line":344,"address":[2371962,2371998,2371914],"length":1,"stats":{"Line":18}},{"line":345,"address":[2372018,2371966],"length":1,"stats":{"Line":9}},{"line":346,"address":[],"length":0,"stats":{"Line":0}},{"line":349,"address":[2110576,2110960,2110736],"length":1,"stats":{"Line":8}},{"line":353,"address":[2110754,2110981,2110588],"length":1,"stats":{"Line":8}},{"line":354,"address":[],"length":0,"stats":{"Line":8}},{"line":355,"address":[],"length":0,"stats":{"Line":0}}],"covered":73,"coverable":112},{"path":["/","home","runner","work","influxdb-rust","influxdb-rust","influxdb","src","integrations","serde_integration","mod.rs"],"content":"//! Serde Integration for InfluxDB. Provides deserialization of query returns.\n//!\n//! When querying multiple series in the same query (e.g. with a regex query), it might be desirable to flat map\n//! the resulting series into a single `Vec` like so. The example assumes, that there are weather readings in multiple\n//! series named `weather_<city_name>` (e.g. `weather_berlin`, or `weather_london`). Since we're using a Regex query,\n//! we don't actually know which series will be returned. To assign the city name to the series, we can use the series\n//! `name`, InfluxDB provides alongside query results.\n//!\n//! ```rust,no_run\n//! use influxdb::{Client, Query};\n//! use serde_derive::Deserialize;\n//!\n//! #[derive(Deserialize)]\n//! struct WeatherWithoutCityName {\n//!     temperature: i32,\n//! }\n//!\n//! #[derive(Deserialize)]\n//! struct Weather {\n//!     city_name: String,\n//!     weather: WeatherWithoutCityName,\n//! }\n//!\n//! # #[async_std::main]\n//! # async fn main() -> Result<(), influxdb::Error> {\n//! let client = Client::new(\"http://localhost:8086\", \"test\");\n//! let query = Query::raw_read_query(\n//!     \"SELECT temperature FROM /weather_[a-z]*$/ WHERE time > now() - 1m ORDER BY DESC\",\n//! );\n//! let mut db_result = client.json_query(query).await?;\n//! let _result = db_result\n//!     .deserialize_next::<WeatherWithoutCityName>()?\n//!     .series\n//!     .into_iter()\n//!     .map(|mut city_series| {\n//!         let city_name =\n//!             city_series.name.split(\"_\").collect::<Vec<&str>>().remove(2);\n//!         Weather {\n//!             weather: city_series.values.remove(0),\n//!             city_name: city_name.to_string(),\n//!         }\n//!     })\n//!     .collect::<Vec<Weather>>();\n//! # Ok(())\n//! # }\n//! ```\n\nmod de;\n\nuse serde::de::DeserializeOwned;\nuse serde_derive::Deserialize;\n\nuse crate::{client::check_status, Client, Error, Query, ReadQuery};\n\n#[derive(Deserialize)]\n#[doc(hidden)]\nstruct _DatabaseError {\n    error: String,\n}\n\n#[derive(Deserialize, Debug)]\n#[doc(hidden)]\npub struct DatabaseQueryResult {\n    pub results: Vec<serde_json::Value>,\n}\n\nimpl DatabaseQueryResult {\n    pub fn deserialize_next<T: 'static>(&mut self) -> Result<Return<T>, Error>\n    where\n        T: DeserializeOwned + Send,\n    {\n        serde_json::from_value::<Return<T>>(self.results.remove(0)).map_err(|err| {\n            Error::DeserializationError {\n                error: format!(\"could not deserialize: {}\", err),\n            }\n        })\n    }\n\n    pub fn deserialize_next_tagged<TAG, T: 'static>(\n        &mut self,\n    ) -> Result<TaggedReturn<TAG, T>, Error>\n    where\n        TAG: DeserializeOwned + Send,\n        T: DeserializeOwned + Send,\n    {\n        serde_json::from_value::<TaggedReturn<TAG, T>>(self.results.remove(0)).map_err(|err| {\n            Error::DeserializationError {\n                error: format!(\"could not deserialize: {}\", err),\n            }\n        })\n    }\n}\n\n#[derive(Deserialize, Debug)]\n#[doc(hidden)]\npub struct Return<T> {\n    #[serde(default = \"Vec::new\")]\n    pub series: Vec<Series<T>>,\n}\n\n#[derive(Debug)]\n/// Represents a returned series from InfluxDB\npub struct Series<T> {\n    pub name: String,\n    pub values: Vec<T>,\n}\n\n#[derive(Deserialize, Debug)]\n#[doc(hidden)]\npub struct TaggedReturn<TAG, T> {\n    #[serde(default = \"Vec::new\")]\n    pub series: Vec<TaggedSeries<TAG, T>>,\n}\n\n#[derive(Debug)]\n/// Represents a returned series from InfluxDB\npub struct TaggedSeries<TAG, T> {\n    pub name: String,\n    pub tags: TAG,\n    pub values: Vec<T>,\n}\n\nimpl Client {\n    pub async fn json_query(&self, q: ReadQuery) -> Result<DatabaseQueryResult, Error> {\n        let query = q.build().map_err(|err| Error::InvalidQueryError {\n            error: format!(\"{}\", err),\n        })?;\n\n        let read_query = query.get();\n        let read_query_lower = read_query.to_lowercase();\n\n        if !read_query_lower.contains(\"select\") && !read_query_lower.contains(\"show\") {\n            let error = Error::InvalidQueryError {\n                error: String::from(\n                    \"Only SELECT and SHOW queries supported with JSON deserialization\",\n                ),\n            };\n            return Err(error);\n        }\n\n        let url = &format!(\"{}/query\", &self.url);\n        let mut parameters = self.parameters.as_ref().clone();\n        parameters.insert(\"q\", read_query);\n        let mut request_builder = self.client.get(url);\n        if let Some(ref token) = self.token {\n            request_builder = request_builder.header(\"Authorization\", format!(\"Token {}\", token))\n        }\n        let request_builder = request_builder.query(&parameters);\n\n        #[cfg(feature = \"surf\")]\n        let request_builder = request_builder.map_err(|err| Error::UrlConstructionError {\n            error: err.to_string(),\n        })?;\n\n        let res = request_builder\n            .send()\n            .await\n            .map_err(|err| Error::ConnectionError {\n                error: err.to_string(),\n            })?;\n        check_status(&res)?;\n\n        #[cfg(feature = \"reqwest\")]\n        let body = res.bytes();\n        #[cfg(feature = \"surf\")]\n        let mut res = res;\n        #[cfg(feature = \"surf\")]\n        let body = res.body_bytes();\n\n        let body = body.await.map_err(|err| Error::ProtocolError {\n            error: err.to_string(),\n        })?;\n\n        // Try parsing InfluxDBs { \"error\": \"error message here\" }\n        if let Ok(error) = serde_json::from_slice::<_DatabaseError>(&body) {\n            return Err(Error::DatabaseError { error: error.error });\n        }\n\n        // Json has another structure, let's try actually parsing it to the type we're deserializing\n        serde_json::from_slice::<DatabaseQueryResult>(&body).map_err(|err| {\n            Error::DeserializationError {\n                error: format!(\"serde error: {}\", err),\n            }\n        })\n    }\n}\n","traces":[{"line":68,"address":[2769760,2769840,2769920,2770000,2769680],"length":1,"stats":{"Line":6}},{"line":72,"address":[2770825,2769699,2771104,2770080,2770569,2770592,2770848,2771337,2769939,2770336,2770313,2770019,2769859,2769779,2771081],"length":1,"stats":{"Line":6}},{"line":73,"address":[],"length":0,"stats":{"Line":0}},{"line":74,"address":[],"length":0,"stats":{"Line":0}},{"line":79,"address":[2771360],"length":1,"stats":{"Line":1}},{"line":86,"address":[],"length":0,"stats":{"Line":1}},{"line":87,"address":[],"length":0,"stats":{"Line":0}},{"line":88,"address":[2771462,2771527],"length":1,"stats":{"Line":0}},{"line":124,"address":[1966623,1969005,1964722,1966823,1964526,1964464],"length":1,"stats":{"Line":8}},{"line":125,"address":[1969579,1965092,1969360,1964844,1966784,1969529,1964695],"length":1,"stats":{"Line":4}},{"line":126,"address":[1969434,1969390],"length":1,"stats":{"Line":0}},{"line":129,"address":[1964983,1965188],"length":1,"stats":{"Line":4}},{"line":130,"address":[6956215,6956314],"length":1,"stats":{"Line":4}},{"line":132,"address":[6956337,6956436,6956574],"length":1,"stats":{"Line":5}},{"line":134,"address":[6956611],"length":1,"stats":{"Line":1}},{"line":138,"address":[6956696],"length":1,"stats":{"Line":1}},{"line":141,"address":[1965762,1965503],"length":1,"stats":{"Line":4}},{"line":142,"address":[6956996,6956923],"length":1,"stats":{"Line":4}},{"line":143,"address":[6957160,6957019],"length":1,"stats":{"Line":4}},{"line":144,"address":[1966152],"length":1,"stats":{"Line":2}},{"line":145,"address":[6957223,6957638],"length":1,"stats":{"Line":2}},{"line":146,"address":[7496864,7497099,7497112,7496725],"length":1,"stats":{"Line":0}},{"line":148,"address":[7496823],"length":1,"stats":{"Line":2}},{"line":155,"address":[1967290,1966992,1966632,1966724,1967679,1967080],"length":1,"stats":{"Line":8}},{"line":157,"address":[2384703],"length":1,"stats":{"Line":8}},{"line":158,"address":[1969616,1969740,1969687],"length":1,"stats":{"Line":0}},{"line":159,"address":[6960786],"length":1,"stats":{"Line":0}},{"line":161,"address":[6958298,6958449,6958740,6958583],"length":1,"stats":{"Line":6}},{"line":164,"address":[1967420],"length":1,"stats":{"Line":2}},{"line":170,"address":[2384726],"length":1,"stats":{"Line":5}},{"line":171,"address":[7500402],"length":1,"stats":{"Line":0}},{"line":175,"address":[6959141,6959281],"length":1,"stats":{"Line":4}},{"line":176,"address":[1968281],"length":1,"stats":{"Line":0}},{"line":180,"address":[1968624,1968548,1970133,1969904],"length":1,"stats":{"Line":4}},{"line":181,"address":[1970077],"length":1,"stats":{"Line":0}},{"line":182,"address":[1969987,1969939],"length":1,"stats":{"Line":0}}],"covered":24,"coverable":36},{"path":["/","home","runner","work","influxdb-rust","influxdb-rust","influxdb","src","lib.rs"],"content":"//! Pull requests are always welcome. See [Contributing](https://github.com/influxdb-rs/influxdb-rust/blob/main/CONTRIBUTING.md) and [Code of Conduct](https://github.com/influxdb-rs/influxdb-rust/blob/main/CODE_OF_CONDUCT.md). For a list of past changes, see [CHANGELOG.md](https://github.com/influxdb-rs/influxdb-rust/blob/main/CHANGELOG.md).\n//!\n//! ## Currently Supported Features\n//!\n//! -   Reading and writing to InfluxDB\n//! -   Optional Serde support for deserialization\n//! -   Running multiple queries in one request (e.g. `SELECT * FROM weather_berlin; SELECT * FROM weather_london`)\n//! -   Writing single or multiple measurements in one request (e.g. `WriteQuery` or `Vec<WriteQuery>` argument)\n//! -   Authenticated and unauthenticated connections\n//! -   `async`/`await` support\n//! -   `#[derive(InfluxDbWriteable)]` derive macro for writing / reading into structs\n//! -   `GROUP BY` support\n//! -   Tokio and async-std support (see example below) or [available backends](https://github.com/influxdb-rs/influxdb-rust/blob/main/influxdb/Cargo.toml)\n//! -   Swappable HTTP backends ([see below](#Choice-of-HTTP-backend))\n//!\n//! # Quickstart\n//!\n//! Add the following to your `Cargo.toml`\n//!\n#![doc = cargo_toml!(indent=\"\", \"derive\")]\n//!\n//! For an example with using Serde deserialization, please refer to [serde_integration](crate::integrations::serde_integration)\n//!\n//! ```rust,no_run\n//! use chrono::{DateTime, Utc};\n//! use influxdb::{Client, Error, InfluxDbWriteable, ReadQuery, Timestamp};\n//!\n//! #[tokio::main]\n//! // or #[async_std::main] if you prefer\n//! async fn main() -> Result<(), Error> {\n//!     // Connect to db `test` on `http://localhost:8086`\n//!     let client = Client::new(\"http://localhost:8086\", \"test\");\n//!\n//!     #[derive(InfluxDbWriteable)]\n//!     struct WeatherReading {\n//!         time: DateTime<Utc>,\n//!         humidity: i32,\n//!         #[influxdb(tag)]\n//!         wind_direction: String,\n//!     }\n//!\n//!     // Let's write some data into a measurement called `weather`\n//!     let weather_readings = vec![\n//!         WeatherReading {\n//!             time: Timestamp::Hours(1).into(),\n//!             humidity: 30,\n//!             wind_direction: String::from(\"north\"),\n//!         }\n//!         .into_query(\"weather\"),\n//!         WeatherReading {\n//!             time: Timestamp::Hours(2).into(),\n//!             humidity: 40,\n//!             wind_direction: String::from(\"west\"),\n//!         }\n//!         .into_query(\"weather\"),\n//!     ];\n//!\n//!     client.query(weather_readings).await?;\n//!\n//!     // Read back all records\n//!     let read_query = ReadQuery::new(\"SELECT * FROM weather\");\n//!\n//!     let read_result = client.query(read_query).await?;\n//!     println!(\"{}\", read_result);\n//!     Ok(())\n//! }\n//! ```\n//!\n//! For further examples, check out the integration tests in `tests/integration_tests.rs`\n//! in the repository.\n//!\n//! # Choice of HTTP backend\n//!\n//! To communicate with InfluxDB, you can choose the HTTP backend to be used configuring the appropriate feature. We recommend sticking with the default reqwest-based client, unless you really need async-std compatibility.\n//!\n//! - **[hyper](https://github.com/hyperium/hyper)** (through reqwest, used by default), with [rustls](https://github.com/ctz/rustls)\n#![doc = cargo_toml!(indent=\"\\t\", \"derive\")]\n//! - **[hyper](https://github.com/hyperium/hyper)** (through reqwest), with native TLS (OpenSSL)\n#![doc = cargo_toml!(indent=\"\\t\", default-features = false, \"derive\", \"serde\", \"reqwest-client-native-tls\")]\n//! - **[hyper](https://github.com/hyperium/hyper)** (through reqwest), with vendored native TLS (OpenSSL)\n#![doc = cargo_toml!(indent=\"\\t\", default-features = false, \"derive\", \"serde\", \"reqwest-client-native-tls-vendored\")]\n//! - **[hyper](https://github.com/hyperium/hyper)** (through surf), use this if you need tokio 0.2 compatibility\n#![doc = cargo_toml!(indent=\"\\t\", default-features = false, \"derive\", \"serde\", \"hyper-client\")]\n//! - **[curl](https://github.com/alexcrichton/curl-rust)**, using [libcurl](https://curl.se/libcurl/)\n#![doc = cargo_toml!(indent=\"\\t\", default-features = false, \"derive\", \"serde\", \"curl-client\")]\n//! - **[async-h1](https://github.com/http-rs/async-h1)** with native TLS (OpenSSL)\n#![doc = cargo_toml!(indent=\"\\t\", default-features = false, \"derive\", \"serde\", \"h1-client\")]\n//! - **[async-h1](https://github.com/http-rs/async-h1)** with [rustls](https://github.com/ctz/rustls)\n#![doc = cargo_toml!(indent=\"\\t\", default-features = false, \"derive\", \"serde\", \"h1-client-rustls\")]\n//! - WebAssembly's `window.fetch`, via `web-sys` and **[wasm-bindgen](https://github.com/rustwasm/wasm-bindgen)**\n#![doc = cargo_toml!(indent=\"\\t\", default-features = false, \"derive\", \"serde\", \"wasm-client\")]\n//!\n//! # License\n//!\n//! [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n\n#![allow(clippy::needless_doctest_main)]\n#![allow(clippy::needless_lifetimes)] // False positive in client/mod.rs query fn\n#![forbid(bare_trait_objects)]\n\nmacro_rules! cargo_toml {\n    (indent=$indent:literal, $firstfeat:literal $(, $feature:literal)*) => {\n        cargo_toml_private!($indent, \"\", $firstfeat $(, $feature)*)\n    };\n\n    (indent=$indent:literal, default-features = false, $firstfeat:literal $(, $feature:literal)*) => {\n        cargo_toml_private!($indent, \"default-features = false, \", $firstfeat $(, $feature)*)\n    };\n}\n\nmacro_rules! cargo_toml_private {\n    ($indent:literal, $deffeats:literal, $firstfeat:literal $(, $feature:literal)*) => {\n        concat!(\n            $indent,\n            \"```toml\\n\",\n\n            $indent,\n            \"influxdb = { version = \\\"\",\n            env!(\"CARGO_PKG_VERSION\"),\n            \"\\\", \",\n            $deffeats,\n            \"features = [\",\n            \"\\\"\", $firstfeat, \"\\\"\",\n            $(\", \\\"\", $feature, \"\\\"\",)*\n            \"] }\\n\",\n\n            $indent,\n            \"```\"\n        )\n    };\n}\n\n#[cfg(all(feature = \"reqwest\", feature = \"surf\"))]\ncompile_error!(\"You need to choose between reqwest and surf; enabling both is not supported\");\n\n#[cfg(not(any(feature = \"reqwest\", feature = \"surf\")))]\ncompile_error!(\"You need to choose an http client; consider not disabling default features\");\n\nmod client;\nmod error;\nmod query;\n\npub use client::Client;\npub use error::Error;\npub use query::{\n    read_query::ReadQuery,\n    write_query::{Type, WriteQuery},\n    InfluxDbWriteable, Query, QueryType, Timestamp, ValidQuery,\n};\n\n#[cfg(feature = \"serde\")]\npub mod integrations {\n    #[cfg(feature = \"serde\")]\n    pub mod serde_integration;\n}\n","traces":[],"covered":0,"coverable":0},{"path":["/","home","runner","work","influxdb-rust","influxdb-rust","influxdb","src","query","consts.rs"],"content":"pub const MINUTES_PER_HOUR: u128 = 60;\npub const SECONDS_PER_MINUTE: u128 = 60;\npub const MILLIS_PER_SECOND: u128 = 1000;\npub const NANOS_PER_MILLI: u128 = 1_000_000;\npub const NANOS_PER_MICRO: u128 = 1000;\n","traces":[],"covered":0,"coverable":0},{"path":["/","home","runner","work","influxdb-rust","influxdb-rust","influxdb","src","query","line_proto_term.rs"],"content":"/// InfluxDB Line Protocol escaping helper module.\n/// https://docs.influxdata.com/influxdb/v1.7/write_protocols/line_protocol_tutorial/\nuse crate::Type;\nuse lazy_regex::{lazy_regex, Lazy, Regex};\n\npub static COMMAS_SPACES: Lazy<Regex> = lazy_regex!(\"[, ]\");\npub static COMMAS_SPACES_EQUALS: Lazy<Regex> = lazy_regex!(\"[, =]\");\npub static QUOTES_SLASHES: Lazy<Regex> = lazy_regex!(r#\"[\"\\\\]\"#);\npub static SLASHES: Lazy<Regex> = lazy_regex!(r#\"(\\\\|,| |=|\")\"#);\n\npub enum LineProtoTerm<'a> {\n    Measurement(&'a str), // escape commas, spaces\n    TagKey(&'a str),      // escape commas, equals, spaces\n    TagValue(&'a Type),   // escape commas, equals, spaces\n    FieldKey(&'a str),    // escape commas, equals, spaces\n    FieldValue(&'a Type), // escape quotes, backslashes + quote\n}\n\nimpl LineProtoTerm<'_> {\n    pub fn escape(self) -> String {\n        use LineProtoTerm::*;\n        match self {\n            Measurement(x) => Self::escape_any(x, &COMMAS_SPACES),\n            TagKey(x) | FieldKey(x) => Self::escape_any(x, &COMMAS_SPACES_EQUALS),\n            FieldValue(x) => Self::escape_field_value(x, false),\n            TagValue(x) => Self::escape_tag_value(x),\n        }\n    }\n\n    pub fn escape_v2(self) -> String {\n        use LineProtoTerm::*;\n        match self {\n            Measurement(x) => Self::escape_any(x, &COMMAS_SPACES),\n            TagKey(x) | FieldKey(x) => Self::escape_any(x, &COMMAS_SPACES_EQUALS),\n            FieldValue(x) => Self::escape_field_value(x, true),\n            TagValue(x) => Self::escape_tag_value(x),\n        }\n    }\n\n    fn escape_field_value(v: &Type, use_v2: bool) -> String {\n        use Type::*;\n        match v {\n            Boolean(v) => {\n                if *v {\n                    \"true\"\n                } else {\n                    \"false\"\n                }\n            }\n            .to_string(),\n            Float(v) => v.to_string(),\n            SignedInteger(v) => format!(\"{}i\", v),\n            UnsignedInteger(v) => {\n                if use_v2 {\n                    format!(\"{}u\", v)\n                } else {\n                    format!(\"{}i\", v)\n                }\n            }\n            Text(v) => format!(r#\"\"{}\"\"#, Self::escape_any(v, &QUOTES_SLASHES)),\n        }\n    }\n\n    fn escape_tag_value(v: &Type) -> String {\n        use Type::*;\n        match v {\n            Boolean(v) => {\n                if *v {\n                    \"true\"\n                } else {\n                    \"false\"\n                }\n            }\n            .to_string(),\n            Float(v) => format!(r#\"{}\"#, v),\n            SignedInteger(v) => format!(r#\"{}\"#, v),\n            UnsignedInteger(v) => format!(r#\"{}\"#, v),\n            Text(v) => Self::escape_any(v, &SLASHES),\n        }\n    }\n\n    fn escape_any(s: &str, re: &Regex) -> String {\n        re.replace_all(s, r\"\\$0\").to_string()\n    }\n}\n\n#[cfg(test)]\nmod test {\n    use crate::query::line_proto_term::LineProtoTerm::*;\n    use crate::Type;\n\n    #[test]\n    fn test() {\n        assert_eq!(TagValue(&Type::Boolean(true)).escape(), r#\"true\"#);\n        assert_eq!(TagValue(&Type::Float(1.8324f64)).escape(), r#\"1.8324\"#);\n        assert_eq!(TagValue(&Type::SignedInteger(-1i64)).escape(), r#\"-1\"#);\n        assert_eq!(TagValue(&Type::UnsignedInteger(1u64)).escape(), r#\"1\"#);\n\n        assert_eq!(\n            TagValue(&Type::Text(\"this is my special string\".into())).escape(),\n            r\"this\\ is\\ my\\ special\\ string\"\n        );\n        assert_eq!(\n            TagValue(&Type::Text(\"a tag w=i th == tons of escapes\".into())).escape(),\n            r\"a\\ tag\\ w\\=i\\ th\\ \\=\\=\\ tons\\ of\\ escapes\"\n        );\n        assert_eq!(\n            TagValue(&Type::Text(\"no_escapes\".into())).escape(),\n            r#\"no_escapes\"#\n        );\n        assert_eq!(\n            TagValue(&Type::Text(\"some,commas,here\".into())).escape(),\n            r\"some\\,commas\\,here\"\n        );\n\n        assert_eq!(Measurement(r#\"wea\", ther\"#).escape(), r#\"wea\"\\,\\ ther\"#);\n        assert_eq!(TagKey(r\"locat\\ ,=ion\").escape(), r\"locat\\\\ \\,\\=ion\");\n\n        assert_eq!(FieldValue(&Type::Boolean(true)).escape(), r#\"true\"#);\n        assert_eq!(FieldValue(&Type::Boolean(false)).escape(), r#\"false\"#);\n\n        assert_eq!(FieldValue(&Type::Float(0.0)).escape(), r#\"0\"#);\n        assert_eq!(FieldValue(&Type::Float(-0.1)).escape(), r#\"-0.1\"#);\n\n        assert_eq!(FieldValue(&Type::SignedInteger(0)).escape(), r#\"0i\"#);\n        assert_eq!(FieldValue(&Type::SignedInteger(83)).escape(), r#\"83i\"#);\n\n        assert_eq!(FieldValue(&Type::UnsignedInteger(0)).escape(), r#\"0i\"#);\n        assert_eq!(FieldValue(&Type::UnsignedInteger(83)).escape(), r#\"83i\"#);\n\n        assert_eq!(FieldValue(&Type::UnsignedInteger(0)).escape_v2(), r#\"0u\"#);\n        assert_eq!(FieldValue(&Type::UnsignedInteger(83)).escape_v2(), r#\"83u\"#);\n\n        assert_eq!(FieldValue(&Type::Text(\"\".into())).escape(), r#\"\"\"\"#);\n        assert_eq!(FieldValue(&Type::Text(\"0\".into())).escape(), r#\"\"0\"\"#);\n        assert_eq!(FieldValue(&Type::Text(\"\\\"\".into())).escape(), r#\"\"\\\"\"\"#);\n        assert_eq!(\n            FieldValue(&Type::Text(r#\"locat\"\\ ,=ion\"#.into())).escape(),\n            r#\"\"locat\\\"\\\\ ,=ion\"\"#\n        );\n    }\n\n    #[test]\n    fn test_empty_tag_value() {\n        // InfluxDB doesn't support empty tag values. But that's a job\n        // of a calling site to validate an entire write request.\n        assert_eq!(TagValue(&Type::Text(\"\".into())).escape(), r#\"\"#);\n    }\n}\n","traces":[{"line":6,"address":[7552032,7552057],"length":1,"stats":{"Line":6}},{"line":7,"address":[7012921,7012896],"length":1,"stats":{"Line":6}},{"line":8,"address":[2165904,2165929],"length":1,"stats":{"Line":2}},{"line":9,"address":[2166208,2166233],"length":1,"stats":{"Line":4}},{"line":20,"address":[7547680],"length":1,"stats":{"Line":3}},{"line":22,"address":[2160739,2160863,2160914],"length":1,"stats":{"Line":11}},{"line":23,"address":[7008279],"length":1,"stats":{"Line":3}},{"line":24,"address":[2160845,2160896,2160952],"length":1,"stats":{"Line":12}},{"line":25,"address":[7547887],"length":1,"stats":{"Line":3}},{"line":26,"address":[7008380],"length":1,"stats":{"Line":3}},{"line":30,"address":[7547984],"length":1,"stats":{"Line":1}},{"line":32,"address":[2161043,2161167,2161218],"length":1,"stats":{"Line":2}},{"line":33,"address":[2161079],"length":1,"stats":{"Line":2}},{"line":34,"address":[2161149,2161200,2161259],"length":1,"stats":{"Line":2}},{"line":35,"address":[2161230],"length":1,"stats":{"Line":1}},{"line":36,"address":[7548140],"length":1,"stats":{"Line":0}},{"line":40,"address":[2161328,2162341],"length":1,"stats":{"Line":3}},{"line":42,"address":[7008877],"length":1,"stats":{"Line":3}},{"line":43,"address":[2161817,2161438],"length":1,"stats":{"Line":2}},{"line":44,"address":[2161779,2161807,2161453],"length":1,"stats":{"Line":3}},{"line":45,"address":[2161781],"length":1,"stats":{"Line":1}},{"line":47,"address":[7548724],"length":1,"stats":{"Line":1}},{"line":51,"address":[7548438],"length":1,"stats":{"Line":1}},{"line":52,"address":[7548466],"length":1,"stats":{"Line":3}},{"line":53,"address":[2161635],"length":1,"stats":{"Line":1}},{"line":54,"address":[7009153],"length":1,"stats":{"Line":1}},{"line":55,"address":[2161964],"length":1,"stats":{"Line":1}},{"line":57,"address":[7548802],"length":1,"stats":{"Line":1}},{"line":60,"address":[7549058,7548627],"length":1,"stats":{"Line":1}},{"line":64,"address":[7009888],"length":1,"stats":{"Line":3}},{"line":66,"address":[7009918],"length":1,"stats":{"Line":3}},{"line":67,"address":[2162463,2163030],"length":1,"stats":{"Line":2}},{"line":68,"address":[7009998,7010515,7010543],"length":1,"stats":{"Line":2}},{"line":69,"address":[7010517],"length":1,"stats":{"Line":1}},{"line":71,"address":[2162971],"length":1,"stats":{"Line":0}},{"line":75,"address":[2162498],"length":1,"stats":{"Line":1}},{"line":76,"address":[2162624],"length":1,"stats":{"Line":1}},{"line":77,"address":[2162768],"length":1,"stats":{"Line":2}},{"line":78,"address":[2162913],"length":1,"stats":{"Line":2}},{"line":82,"address":[2163203,2163056],"length":1,"stats":{"Line":4}},{"line":83,"address":[2163101],"length":1,"stats":{"Line":4}}],"covered":39,"coverable":41},{"path":["/","home","runner","work","influxdb-rust","influxdb-rust","influxdb","src","query","mod.rs"],"content":"//! Used to create queries of type [`ReadQuery`](crate::query::read_query::ReadQuery) or\n//! [`WriteQuery`](crate::query::write_query::WriteQuery) which can be executed in InfluxDB\n//!\n//! # Examples\n//!\n//! ```rust\n//! use influxdb::{Query, Timestamp};\n//! use influxdb::InfluxDbWriteable;\n//!\n//! let write_query = Timestamp::Nanoseconds(0).into_query(\"measurement\")\n//!     .add_field(\"field1\", 5)\n//!     .add_tag(\"author\", \"Gero\")\n//!     .build();\n//!\n//! assert!(write_query.is_ok());\n//!\n//! let read_query = Query::raw_read_query(\"SELECT * FROM weather\")\n//!     .build();\n//!\n//! assert!(read_query.is_ok());\n//! ```\n\nuse chrono::prelude::{DateTime, TimeZone, Utc};\nuse std::convert::TryInto;\n\npub mod consts;\nmod line_proto_term;\npub mod read_query;\npub mod write_query;\nuse std::fmt;\n\nuse crate::{Error, ReadQuery, WriteQuery};\nuse consts::{\n    MILLIS_PER_SECOND, MINUTES_PER_HOUR, NANOS_PER_MICRO, NANOS_PER_MILLI, SECONDS_PER_MINUTE,\n};\n\n#[cfg(feature = \"derive\")]\npub use influxdb_derive::InfluxDbWriteable;\n\n#[derive(PartialEq, Eq, Debug, Copy, Clone)]\npub enum Timestamp {\n    Nanoseconds(u128),\n    Microseconds(u128),\n    Milliseconds(u128),\n    Seconds(u128),\n    Minutes(u128),\n    Hours(u128),\n}\n\nimpl fmt::Display for Timestamp {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        use Timestamp::*;\n        match self {\n            Nanoseconds(ts) | Microseconds(ts) | Milliseconds(ts) | Seconds(ts) | Minutes(ts)\n            | Hours(ts) => write!(f, \"{}\", ts),\n        }\n    }\n}\n\nimpl From<Timestamp> for DateTime<Utc> {\n    fn from(ts: Timestamp) -> DateTime<Utc> {\n        match ts {\n            Timestamp::Hours(h) => {\n                let nanos =\n                    h * MINUTES_PER_HOUR * SECONDS_PER_MINUTE * MILLIS_PER_SECOND * NANOS_PER_MILLI;\n                Utc.timestamp_nanos(nanos.try_into().unwrap())\n            }\n            Timestamp::Minutes(m) => {\n                let nanos = m * SECONDS_PER_MINUTE * MILLIS_PER_SECOND * NANOS_PER_MILLI;\n                Utc.timestamp_nanos(nanos.try_into().unwrap())\n            }\n            Timestamp::Seconds(s) => {\n                let nanos = s * MILLIS_PER_SECOND * NANOS_PER_MILLI;\n                Utc.timestamp_nanos(nanos.try_into().unwrap())\n            }\n            Timestamp::Milliseconds(millis) => {\n                let nanos = millis * NANOS_PER_MILLI;\n                Utc.timestamp_nanos(nanos.try_into().unwrap())\n            }\n            Timestamp::Nanoseconds(nanos) => Utc.timestamp_nanos(nanos.try_into().unwrap()),\n            Timestamp::Microseconds(micros) => {\n                let nanos = micros * NANOS_PER_MICRO;\n                Utc.timestamp_nanos(nanos.try_into().unwrap())\n            }\n        }\n    }\n}\n\nimpl<T> From<DateTime<T>> for Timestamp\nwhere\n    T: TimeZone,\n{\n    fn from(date_time: DateTime<T>) -> Self {\n        Timestamp::Nanoseconds(date_time.timestamp_nanos_opt().unwrap() as u128)\n    }\n}\n\npub trait Query {\n    /// Builds valid InfluxSQL which can be run against the Database.\n    /// In case no fields have been specified, it will return an error,\n    /// as that is invalid InfluxSQL syntax.\n    ///\n    /// # Examples\n    ///\n    /// ```rust\n    /// use influxdb::{Query, Timestamp};\n    /// use influxdb::InfluxDbWriteable;\n    ///\n    /// let invalid_query = Timestamp::Nanoseconds(0).into_query(\"measurement\").build();\n    /// assert!(invalid_query.is_err());\n    ///\n    /// let valid_query = Timestamp::Nanoseconds(0).into_query(\"measurement\").add_field(\"myfield1\", 11).build();\n    /// assert!(valid_query.is_ok());\n    /// ```\n    fn build(&self) -> Result<ValidQuery, Error>;\n\n    /// Like [build] but with additional support for unsigned integers in the line protocol.\n    /// Please note, this crate can only interact with InfluxDB 2.0 in compatibility mode\n    /// and does not natively support InfluxDB 2.0.\n    ///\n    /// # Examples\n    ///\n    /// ```rust\n    /// use influxdb::{Query, Timestamp};\n    /// use influxdb::InfluxDbWriteable;\n    ///\n    /// let use_v2 = true;\n    ///\n    /// let invalid_query = Timestamp::Nanoseconds(0).into_query(\"measurement\").build_with_opts(use_v2);\n    /// assert!(invalid_query.is_err());\n    ///\n    /// let valid_query = Timestamp::Nanoseconds(0).into_query(\"measurement\").add_field(\"myfield1\", 11).build_with_opts(use_v2);\n    /// assert!(valid_query.is_ok());\n    /// ```\n    fn build_with_opts(&self, use_v2: bool) -> Result<ValidQuery, Error>;\n\n    fn get_type(&self) -> QueryType;\n}\n\nimpl<Q: Query> Query for &Q {\n    fn build(&self) -> Result<ValidQuery, Error> {\n        Q::build_with_opts(self, false)\n    }\n\n    fn build_with_opts(&self, use_v2: bool) -> Result<ValidQuery, Error> {\n        Q::build_with_opts(self, use_v2)\n    }\n\n    fn get_type(&self) -> QueryType {\n        Q::get_type(self)\n    }\n}\n\nimpl<Q: Query> Query for Box<Q> {\n    fn build(&self) -> Result<ValidQuery, Error> {\n        Q::build(self)\n    }\n\n    fn build_with_opts(&self, use_v2: bool) -> Result<ValidQuery, Error> {\n        Q::build_with_opts(self, use_v2)\n    }\n\n    fn get_type(&self) -> QueryType {\n        Q::get_type(self)\n    }\n}\n\npub trait InfluxDbWriteable {\n    fn into_query<I: Into<String>>(self, name: I) -> WriteQuery;\n}\n\nimpl InfluxDbWriteable for Timestamp {\n    fn into_query<I: Into<String>>(self, name: I) -> WriteQuery {\n        WriteQuery::new(self, name.into())\n    }\n}\n\nimpl dyn Query {\n    /// Returns a [`ReadQuery`](crate::ReadQuery) builder.\n    ///\n    /// # Examples\n    ///\n    /// ```rust\n    /// use influxdb::Query;\n    ///\n    /// Query::raw_read_query(\"SELECT * FROM weather\"); // Is of type [`ReadQuery`](crate::ReadQuery)\n    /// ```\n    #[deprecated(since = \"0.5.0\", note = \"Use ReadQuery::new instead\")]\n    pub fn raw_read_query<S>(read_query: S) -> ReadQuery\n    where\n        S: Into<String>,\n    {\n        ReadQuery::new(read_query)\n    }\n}\n\n#[derive(Debug)]\n#[doc(hidden)]\npub struct ValidQuery(String);\nimpl ValidQuery {\n    pub fn get(self) -> String {\n        self.0\n    }\n}\nimpl<T> From<T> for ValidQuery\nwhere\n    T: Into<String>,\n{\n    fn from(string: T) -> Self {\n        Self(string.into())\n    }\n}\nimpl PartialEq<String> for ValidQuery {\n    fn eq(&self, other: &String) -> bool {\n        &self.0 == other\n    }\n}\nimpl PartialEq<&str> for ValidQuery {\n    fn eq(&self, other: &&str) -> bool {\n        &self.0 == other\n    }\n}\n\n/// Internal Enum used to decide if a `POST` or `GET` request should be sent to InfluxDB. See [InfluxDB Docs](https://docs.influxdata.com/influxdb/v1.7/tools/api/#query-http-endpoint).\n#[derive(PartialEq, Eq, Debug)]\npub enum QueryType {\n    ReadQuery,\n    /// write query with precision\n    WriteQuery(String),\n}\n\n#[cfg(test)]\nmod tests {\n    use super::consts::{\n        MILLIS_PER_SECOND, MINUTES_PER_HOUR, NANOS_PER_MICRO, NANOS_PER_MILLI, SECONDS_PER_MINUTE,\n    };\n    use crate::query::{Timestamp, ValidQuery};\n    use chrono::prelude::{DateTime, TimeZone, Utc};\n    use std::convert::TryInto;\n    #[test]\n    fn test_equality_str() {\n        assert_eq!(ValidQuery::from(\"hello\"), \"hello\");\n    }\n    #[test]\n    fn test_equality_string() {\n        assert_eq!(\n            ValidQuery::from(String::from(\"hello\")),\n            String::from(\"hello\")\n        );\n    }\n    #[test]\n    fn test_format_for_timestamp_else() {\n        assert!(format!(\"{}\", Timestamp::Nanoseconds(100)) == \"100\");\n    }\n    #[test]\n    fn test_chrono_datetime_from_timestamp_hours() {\n        let datetime_from_timestamp: DateTime<Utc> = Timestamp::Hours(2).into();\n        assert_eq!(\n            Utc.timestamp_nanos(\n                (2 * MINUTES_PER_HOUR * SECONDS_PER_MINUTE * MILLIS_PER_SECOND * NANOS_PER_MILLI)\n                    .try_into()\n                    .unwrap()\n            ),\n            datetime_from_timestamp\n        )\n    }\n    #[test]\n    fn test_chrono_datetime_from_timestamp_minutes() {\n        let datetime_from_timestamp: DateTime<Utc> = Timestamp::Minutes(2).into();\n        assert_eq!(\n            Utc.timestamp_nanos(\n                (2 * SECONDS_PER_MINUTE * MILLIS_PER_SECOND * NANOS_PER_MILLI)\n                    .try_into()\n                    .unwrap()\n            ),\n            datetime_from_timestamp\n        )\n    }\n    #[test]\n    fn test_chrono_datetime_from_timestamp_seconds() {\n        let datetime_from_timestamp: DateTime<Utc> = Timestamp::Seconds(2).into();\n        assert_eq!(\n            Utc.timestamp_nanos(\n                (2 * MILLIS_PER_SECOND * NANOS_PER_MILLI)\n                    .try_into()\n                    .unwrap()\n            ),\n            datetime_from_timestamp\n        )\n    }\n    #[test]\n    fn test_chrono_datetime_from_timestamp_millis() {\n        let datetime_from_timestamp: DateTime<Utc> = Timestamp::Milliseconds(2).into();\n        assert_eq!(\n            Utc.timestamp_nanos((2 * NANOS_PER_MILLI).try_into().unwrap()),\n            datetime_from_timestamp\n        )\n    }\n    #[test]\n    fn test_chrono_datetime_from_timestamp_nanos() {\n        let datetime_from_timestamp: DateTime<Utc> = Timestamp::Nanoseconds(1).into();\n        assert_eq!(Utc.timestamp_nanos(1), datetime_from_timestamp)\n    }\n    #[test]\n    fn test_chrono_datetime_from_timestamp_micros() {\n        let datetime_from_timestamp: DateTime<Utc> = Timestamp::Microseconds(2).into();\n        assert_eq!(\n            Utc.timestamp_nanos((2 * NANOS_PER_MICRO).try_into().unwrap()),\n            datetime_from_timestamp\n        )\n    }\n    #[test]\n    fn test_timestamp_from_chrono_date() {\n        let timestamp_from_datetime: Timestamp = Utc\n            .with_ymd_and_hms(1970, 1, 1, 0, 0, 1)\n            .single()\n            .unwrap()\n            .into();\n        assert_eq!(\n            Timestamp::Nanoseconds(MILLIS_PER_SECOND * NANOS_PER_MILLI),\n            timestamp_from_datetime\n        )\n    }\n}\n","traces":[{"line":51,"address":[7530592],"length":1,"stats":{"Line":3}},{"line":53,"address":[2070219,2070267,2070235,2070203,2070158,2070251],"length":1,"stats":{"Line":6}},{"line":54,"address":[2070274],"length":1,"stats":{"Line":1}},{"line":61,"address":[7010752],"length":1,"stats":{"Line":2}},{"line":62,"address":[7550263],"length":1,"stats":{"Line":2}},{"line":63,"address":[7011420],"length":1,"stats":{"Line":2}},{"line":64,"address":[7011465,7012237,7012551],"length":1,"stats":{"Line":4}},{"line":66,"address":[2072107],"length":1,"stats":{"Line":2}},{"line":68,"address":[2070914],"length":1,"stats":{"Line":1}},{"line":69,"address":[7550800,7551430,7551664],"length":1,"stats":{"Line":2}},{"line":70,"address":[2071765],"length":1,"stats":{"Line":1}},{"line":72,"address":[2070793],"length":1,"stats":{"Line":1}},{"line":73,"address":[2070838,2071557,2071386],"length":1,"stats":{"Line":2}},{"line":74,"address":[2071503],"length":1,"stats":{"Line":1}},{"line":76,"address":[7011057],"length":1,"stats":{"Line":1}},{"line":77,"address":[7550558,7551129,7551200],"length":1,"stats":{"Line":2}},{"line":78,"address":[7011689],"length":1,"stats":{"Line":1}},{"line":80,"address":[2070465],"length":1,"stats":{"Line":2}},{"line":81,"address":[2070551],"length":1,"stats":{"Line":1}},{"line":82,"address":[7011573,7010981,7011641],"length":1,"stats":{"Line":2}},{"line":83,"address":[2071204],"length":1,"stats":{"Line":1}},{"line":93,"address":[],"length":0,"stats":{"Line":2}},{"line":94,"address":[2072219,2072276],"length":1,"stats":{"Line":4}},{"line":141,"address":[],"length":0,"stats":{"Line":1}},{"line":142,"address":[],"length":0,"stats":{"Line":1}},{"line":145,"address":[],"length":0,"stats":{"Line":0}},{"line":146,"address":[],"length":0,"stats":{"Line":0}},{"line":149,"address":[],"length":0,"stats":{"Line":1}},{"line":150,"address":[],"length":0,"stats":{"Line":1}},{"line":155,"address":[],"length":0,"stats":{"Line":0}},{"line":156,"address":[],"length":0,"stats":{"Line":0}},{"line":159,"address":[],"length":0,"stats":{"Line":0}},{"line":160,"address":[],"length":0,"stats":{"Line":0}},{"line":163,"address":[],"length":0,"stats":{"Line":0}},{"line":164,"address":[],"length":0,"stats":{"Line":0}},{"line":173,"address":[],"length":0,"stats":{"Line":5}},{"line":174,"address":[],"length":0,"stats":{"Line":5}},{"line":193,"address":[],"length":0,"stats":{"Line":0}},{"line":201,"address":[6991376],"length":1,"stats":{"Line":5}},{"line":202,"address":[2072659],"length":1,"stats":{"Line":6}},{"line":209,"address":[],"length":0,"stats":{"Line":2}},{"line":210,"address":[],"length":0,"stats":{"Line":2}},{"line":214,"address":[7530864],"length":1,"stats":{"Line":1}},{"line":215,"address":[2072877],"length":1,"stats":{"Line":1}},{"line":219,"address":[2072912],"length":1,"stats":{"Line":1}},{"line":220,"address":[2072925],"length":1,"stats":{"Line":1}}],"covered":37,"coverable":46},{"path":["/","home","runner","work","influxdb-rust","influxdb-rust","influxdb","src","query","read_query.rs"],"content":"//! Read Query Builder returned by Query::raw_read_query\n//!\n//! Can only be instantiated by using Query::raw_read_query\n\nuse crate::query::{QueryType, ValidQuery};\nuse crate::{Error, Query};\n\n#[derive(Debug, Clone)]\npub struct ReadQuery {\n    queries: Vec<String>,\n}\n\nimpl ReadQuery {\n    /// Creates a new [`ReadQuery`]\n    #[must_use = \"Creating a query is pointless unless you execute it\"]\n    pub fn new<S>(query: S) -> Self\n    where\n        S: Into<String>,\n    {\n        ReadQuery {\n            queries: vec![query.into()],\n        }\n    }\n\n    /// Adds a query to the [`ReadQuery`]\n    #[must_use = \"Creating a query is pointless unless you execute it\"]\n    pub fn add_query<S>(mut self, query: S) -> Self\n    where\n        S: Into<String>,\n    {\n        self.queries.push(query.into());\n        self\n    }\n}\n\nimpl Query for ReadQuery {\n    fn build(&self) -> Result<ValidQuery, Error> {\n        Ok(ValidQuery(self.queries.join(\";\")))\n    }\n\n    fn build_with_opts(&self, _use_v2: bool) -> Result<ValidQuery, Error> {\n        Ok(ValidQuery(self.queries.join(\";\")))\n    }\n\n    fn get_type(&self) -> QueryType {\n        QueryType::ReadQuery\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use crate::query::{Query, QueryType, ReadQuery};\n\n    #[test]\n    fn test_read_builder_single_query() {\n        let query = ReadQuery::new(\"SELECT * FROM aachen\").build();\n\n        assert_eq!(query.unwrap(), \"SELECT * FROM aachen\");\n    }\n\n    #[test]\n    fn test_read_builder_multi_query() {\n        let query = ReadQuery::new(\"SELECT * FROM aachen\")\n            .add_query(\"SELECT * FROM cologne\")\n            .build();\n\n        assert_eq!(query.unwrap(), \"SELECT * FROM aachen;SELECT * FROM cologne\");\n    }\n\n    #[test]\n    fn test_correct_query_type() {\n        let query = ReadQuery::new(\"SELECT * FROM aachen\");\n\n        assert_eq!(query.get_type(), QueryType::ReadQuery);\n    }\n}\n","traces":[{"line":16,"address":[2031872,2032253,2032239],"length":1,"stats":{"Line":8}},{"line":21,"address":[],"length":0,"stats":{"Line":14}},{"line":27,"address":[2032448,2032272],"length":1,"stats":{"Line":2}},{"line":31,"address":[],"length":0,"stats":{"Line":4}},{"line":32,"address":[2032421],"length":1,"stats":{"Line":2}},{"line":37,"address":[2032480],"length":1,"stats":{"Line":7}},{"line":38,"address":[2032512],"length":1,"stats":{"Line":7}},{"line":41,"address":[2032624],"length":1,"stats":{"Line":0}},{"line":42,"address":[2032662],"length":1,"stats":{"Line":0}},{"line":45,"address":[2032784],"length":1,"stats":{"Line":6}},{"line":46,"address":[2032792],"length":1,"stats":{"Line":6}}],"covered":9,"coverable":11},{"path":["/","home","runner","work","influxdb-rust","influxdb-rust","influxdb","src","query","write_query.rs"],"content":"//! Write Query Builder returned by Query::write_query\n//!\n//! Can only be instantiated by using Query::write_query\n\nuse crate::query::line_proto_term::LineProtoTerm;\nuse crate::query::{QueryType, ValidQuery};\nuse crate::{Error, Query, Timestamp};\nuse std::fmt::{Display, Formatter};\n\npub trait WriteType {\n    fn add_to(self, tag: String, fields_or_tags: &mut Vec<(String, Type)>);\n}\n\nimpl<T: Into<Type>> WriteType for T {\n    fn add_to(self, tag: String, fields_or_tags: &mut Vec<(String, Type)>) {\n        let val: Type = self.into();\n        fields_or_tags.push((tag, val));\n    }\n}\n\nimpl<T: Into<Type>> WriteType for Option<T> {\n    fn add_to(self, tag: String, fields_or_tags: &mut Vec<(String, Type)>) {\n        if let Some(val) = self {\n            val.add_to(tag, fields_or_tags);\n        }\n    }\n}\n\n/// Internal Representation of a Write query that has not yet been built\n#[derive(Debug, Clone)]\npub struct WriteQuery {\n    fields: Vec<(String, Type)>,\n    tags: Vec<(String, Type)>,\n    measurement: String,\n    timestamp: Timestamp,\n}\n\nimpl WriteQuery {\n    /// Creates a new [`WriteQuery`](crate::query::write_query::WriteQuery)\n    #[must_use = \"Creating a query is pointless unless you execute it\"]\n    pub fn new<S>(timestamp: Timestamp, measurement: S) -> Self\n    where\n        S: Into<String>,\n    {\n        WriteQuery {\n            fields: vec![],\n            tags: vec![],\n            measurement: measurement.into(),\n            timestamp,\n        }\n    }\n\n    /// Adds a field to the [`WriteQuery`](crate::WriteQuery)\n    ///\n    /// # Examples\n    ///\n    /// ```rust\n    /// use influxdb::{Query, Timestamp};\n    /// use influxdb::InfluxDbWriteable;\n    ///\n    /// Timestamp::Nanoseconds(0).into_query(\"measurement\").add_field(\"field1\", 5).build();\n    /// ```\n    #[must_use = \"Creating a query is pointless unless you execute it\"]\n    pub fn add_field<S, F>(mut self, field: S, value: F) -> Self\n    where\n        S: Into<String>,\n        F: WriteType,\n    {\n        value.add_to(field.into(), &mut self.fields);\n        self\n    }\n\n    /// Adds a tag to the [`WriteQuery`](crate::WriteQuery)\n    ///\n    /// Please note that a [`WriteQuery`](crate::WriteQuery) requires at least one field. Composing a query with\n    /// only tags will result in a failure building the query.\n    ///\n    /// # Examples\n    ///\n    /// ```rust\n    /// use influxdb::{Query, Timestamp};\n    /// use influxdb::InfluxDbWriteable;\n    ///\n    /// Timestamp::Nanoseconds(0)\n    ///     .into_query(\"measurement\")\n    ///     .add_tag(\"field1\", 5); // calling `.build()` now would result in a `Err(Error::InvalidQueryError)`\n    /// ```\n    #[must_use = \"Creating a query is pointless unless you execute it\"]\n    pub fn add_tag<S, I>(mut self, tag: S, value: I) -> Self\n    where\n        S: Into<String>,\n        I: WriteType,\n    {\n        value.add_to(tag.into(), &mut self.tags);\n        self\n    }\n\n    pub fn get_precision(&self) -> String {\n        let modifier = match self.timestamp {\n            Timestamp::Nanoseconds(_) => \"ns\",\n            Timestamp::Microseconds(_) => \"u\",\n            Timestamp::Milliseconds(_) => \"ms\",\n            Timestamp::Seconds(_) => \"s\",\n            Timestamp::Minutes(_) => \"m\",\n            Timestamp::Hours(_) => \"h\",\n        };\n        modifier.to_string()\n    }\n}\n\n#[derive(Debug, Clone)]\npub enum Type {\n    Boolean(bool),\n    Float(f64),\n    SignedInteger(i64),\n    UnsignedInteger(u64),\n    Text(String),\n}\n\nimpl Display for Type {\n    fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {\n        use Type::*;\n\n        match self {\n            Boolean(x) => write!(f, \"{}\", x),\n            Float(x) => write!(f, \"{}\", x),\n            SignedInteger(x) => write!(f, \"{}\", x),\n            UnsignedInteger(x) => write!(f, \"{}\", x),\n            Text(text) => write!(f, \"{text}\", text = text),\n        }\n    }\n}\n\nmacro_rules! from_impl {\n        ( $variant:ident => $( $typ:ident ),+ ) => (\n                $(\n                    impl From<$typ> for Type {\n                        fn from(b: $typ) -> Self {\n                            Type::$variant(b.into())\n                        }\n                    }\n                )+\n        )\n}\nfrom_impl! {Boolean => bool}\nfrom_impl! {Float => f32, f64}\nfrom_impl! {SignedInteger => i8, i16, i32, i64}\nfrom_impl! {UnsignedInteger => u8, u16, u32, u64}\nfrom_impl! {Text => String}\nimpl From<&str> for Type {\n    fn from(b: &str) -> Self {\n        Type::Text(b.into())\n    }\n}\nimpl<T> From<&T> for Type\nwhere\n    T: Copy + Into<Type>,\n{\n    fn from(t: &T) -> Self {\n        (*t).into()\n    }\n}\n\nimpl Query for WriteQuery {\n    fn build(&self) -> Result<ValidQuery, Error> {\n        self.build_with_opts(false)\n    }\n\n    fn build_with_opts(&self, use_v2: bool) -> Result<ValidQuery, Error> {\n        if self.fields.is_empty() {\n            return Err(Error::InvalidQueryError {\n                error: \"fields cannot be empty\".to_string(),\n            });\n        }\n\n        let mut tags = self\n            .tags\n            .iter()\n            .map(|(tag, value)| {\n                let escaped_tag_key = if use_v2 {\n                    LineProtoTerm::TagKey(tag).escape_v2()\n                } else {\n                    LineProtoTerm::TagKey(tag).escape()\n                };\n                let escaped_tag_value = if use_v2 {\n                    LineProtoTerm::TagValue(value).escape_v2()\n                } else {\n                    LineProtoTerm::TagValue(value).escape()\n                };\n                format!(\n                    \"{tag}={value}\",\n                    tag = escaped_tag_key,\n                    value = escaped_tag_value,\n                )\n            })\n            .collect::<Vec<String>>()\n            .join(\",\");\n\n        if !tags.is_empty() {\n            tags.insert(0, ',');\n        }\n        let fields = self\n            .fields\n            .iter()\n            .map(|(field, value)| {\n                let escaped_field_key = if use_v2 {\n                    LineProtoTerm::FieldKey(field).escape_v2()\n                } else {\n                    LineProtoTerm::FieldKey(field).escape()\n                };\n                let escaped_field_value = if use_v2 {\n                    LineProtoTerm::FieldValue(value).escape_v2()\n                } else {\n                    LineProtoTerm::FieldValue(value).escape()\n                };\n                format!(\n                    \"{field}={value}\",\n                    field = escaped_field_key,\n                    value = escaped_field_value,\n                )\n            })\n            .collect::<Vec<String>>()\n            .join(\",\");\n\n        let escaped_measurement = if use_v2 {\n            LineProtoTerm::Measurement(&self.measurement).escape_v2()\n        } else {\n            LineProtoTerm::Measurement(&self.measurement).escape()\n        };\n\n        Ok(ValidQuery(format!(\n            \"{measurement}{tags} {fields} {time}\",\n            measurement = escaped_measurement,\n            tags = tags,\n            fields = fields,\n            time = self.timestamp\n        )))\n    }\n\n    fn get_type(&self) -> QueryType {\n        QueryType::WriteQuery(self.get_precision())\n    }\n}\n\nimpl Query for Vec<WriteQuery> {\n    fn build(&self) -> Result<ValidQuery, Error> {\n        let mut qlines = Vec::new();\n\n        for q in self {\n            let valid_query = q.build()?;\n            qlines.push(valid_query.0);\n        }\n\n        Ok(ValidQuery(qlines.join(\"\\n\")))\n    }\n\n    fn build_with_opts(&self, use_v2: bool) -> Result<ValidQuery, Error> {\n        let mut qlines = Vec::new();\n\n        for q in self {\n            let valid_query = q.build_with_opts(use_v2)?;\n            qlines.push(valid_query.0);\n        }\n\n        Ok(ValidQuery(qlines.join(\"\\n\")))\n    }\n\n    fn get_type(&self) -> QueryType {\n        QueryType::WriteQuery(\n            self.first()\n                .map(|q| q.get_precision())\n                // use \"ms\" as placeholder if query is empty\n                .unwrap_or_else(|| \"ms\".to_owned()),\n        )\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use crate::query::{InfluxDbWriteable, Query, Timestamp};\n\n    #[test]\n    fn test_write_builder_empty_query() {\n        let query = Timestamp::Hours(5)\n            .into_query(\"marina_3\".to_string())\n            .build();\n\n        assert!(query.is_err(), \"Query was not empty\");\n    }\n\n    #[test]\n    fn test_write_builder_single_field() {\n        let query = Timestamp::Hours(11)\n            .into_query(\"weather\".to_string())\n            .add_field(\"temperature\", 82)\n            .build();\n\n        assert!(query.is_ok(), \"Query was empty\");\n        assert_eq!(query.unwrap(), \"weather temperature=82i 11\");\n    }\n\n    #[test]\n    fn test_write_builder_multiple_fields() {\n        let query = Timestamp::Hours(11)\n            .into_query(\"weather\".to_string())\n            .add_field(\"temperature\", 82)\n            .add_field(\"wind_strength\", 3.7)\n            .add_field(\"temperature_unsigned\", 82u64)\n            .build();\n\n        assert!(query.is_ok(), \"Query was empty\");\n        assert_eq!(\n            query.unwrap(),\n            \"weather temperature=82i,wind_strength=3.7,temperature_unsigned=82i 11\"\n        );\n    }\n\n    #[test]\n    fn test_write_builder_multiple_fields_with_v2() {\n        let query = Timestamp::Hours(11)\n            .into_query(\"weather\".to_string())\n            .add_field(\"temperature\", 82)\n            .add_field(\"wind_strength\", 3.7)\n            .add_field(\"temperature_unsigned\", 82u64)\n            .build_with_opts(true);\n\n        assert!(query.is_ok(), \"Query was empty\");\n        assert_eq!(\n            query.unwrap(),\n            \"weather temperature=82i,wind_strength=3.7,temperature_unsigned=82u 11\"\n        );\n    }\n\n    #[test]\n    fn test_write_builder_optional_fields() {\n        let query = Timestamp::Hours(11)\n            .into_query(\"weather\".to_string())\n            .add_field(\"temperature\", 82u64)\n            .add_tag(\"wind_strength\", <Option<u64>>::None)\n            .build();\n\n        assert!(query.is_ok(), \"Query was empty\");\n        assert_eq!(query.unwrap(), \"weather temperature=82i 11\");\n    }\n\n    #[test]\n    fn test_write_builder_optional_fields_with_v2() {\n        let query = Timestamp::Hours(11)\n            .into_query(\"weather\".to_string())\n            .add_field(\"temperature\", 82u64)\n            .add_tag(\"wind_strength\", <Option<u64>>::None)\n            .build_with_opts(true);\n\n        assert!(query.is_ok(), \"Query was empty\");\n        assert_eq!(query.unwrap(), \"weather temperature=82u 11\");\n    }\n\n    #[test]\n    fn test_write_builder_only_tags() {\n        let query = Timestamp::Hours(11)\n            .into_query(\"weather\".to_string())\n            .add_tag(\"season\", \"summer\")\n            .build();\n\n        assert!(query.is_err(), \"Query missing one or more fields\");\n    }\n\n    #[test]\n    fn test_write_builder_full_query() {\n        let query = Timestamp::Hours(11)\n            .into_query(\"weather\".to_string())\n            .add_field(\"temperature\", 82)\n            .add_tag(\"location\", \"us-midwest\")\n            .add_tag(\"season\", \"summer\")\n            .build();\n\n        assert!(query.is_ok(), \"Query was empty\");\n        assert_eq!(\n            query.unwrap(),\n            r#\"weather,location=us-midwest,season=summer temperature=82i 11\"#\n        );\n    }\n\n    #[test]\n    fn test_correct_query_type() {\n        use crate::query::QueryType;\n\n        let query = Timestamp::Hours(11)\n            .into_query(\"weather\".to_string())\n            .add_field(\"temperature\", 82)\n            .add_tag(\"location\", \"us-midwest\")\n            .add_tag(\"season\", \"summer\");\n\n        assert_eq!(query.get_type(), QueryType::WriteQuery(\"h\".to_owned()));\n    }\n\n    #[test]\n    fn test_escaping() {\n        let query = Timestamp::Hours(11)\n            .into_query(\"wea, ther=\")\n            .add_field(\"temperature\", 82)\n            .add_field(\"\\\"temp=era,t ure\\\"\", r#\"too\"\\\\hot\"#)\n            .add_field(\"float\", 82.0)\n            .add_tag(\"location\", \"us-midwest\")\n            .add_tag(\"loc, =\\\"ation\", r#\"us, \"mid=west\"#)\n            .build();\n\n        assert!(query.is_ok(), \"Query was empty\");\n        let query_res = query.unwrap().get();\n        assert_eq!(\n            query_res,\n            r#\"wea\\,\\ ther=,location=us-midwest,loc\\,\\ \\=\"ation=us\\,\\ \\\"mid\\=west temperature=82i,\"temp\\=era\\,t\\ ure\"=\"too\\\"\\\\\\\\hot\",float=82 11\"#\n        );\n    }\n\n    #[test]\n    fn test_batch() {\n        let q0 = Timestamp::Hours(11)\n            .into_query(\"weather\")\n            .add_field(\"temperature\", 82)\n            .add_tag(\"location\", \"us-midwest\");\n\n        let q1 = Timestamp::Hours(12)\n            .into_query(\"weather\")\n            .add_field(\"temperature\", 65)\n            .add_tag(\"location\", \"us-midwest\");\n\n        let query = vec![q0, q1].build();\n\n        assert_eq!(\n            query.unwrap().get(),\n            r#\"weather,location=us-midwest temperature=82i 11\nweather,location=us-midwest temperature=65i 12\"#\n        );\n    }\n}\n","traces":[{"line":15,"address":[2033072,2033315,2033525,2033554,2033328,2033568,2033025,2033810,2033054,2033286,2032816,2033781],"length":1,"stats":{"Line":8}},{"line":16,"address":[2351826,2351575],"length":1,"stats":{"Line":10}},{"line":17,"address":[],"length":0,"stats":{"Line":8}},{"line":22,"address":[],"length":0,"stats":{"Line":3}},{"line":23,"address":[2769484],"length":1,"stats":{"Line":3}},{"line":24,"address":[2769605,2769536],"length":1,"stats":{"Line":2}},{"line":41,"address":[2959427,2959024],"length":1,"stats":{"Line":3}},{"line":46,"address":[2353897],"length":1,"stats":{"Line":4}},{"line":47,"address":[2033971],"length":1,"stats":{"Line":3}},{"line":48,"address":[2354020],"length":1,"stats":{"Line":4}},{"line":64,"address":[2034940,2034713,2034960,2035162,2034256,2034512,2034736,2034481],"length":1,"stats":{"Line":7}},{"line":69,"address":[2959793,2960195,2959932,2960045],"length":1,"stats":{"Line":8}},{"line":70,"address":[2034906,2034444,2034679,2035128],"length":1,"stats":{"Line":8}},{"line":89,"address":[2035409,2035665,2035184,2035440],"length":1,"stats":{"Line":5}},{"line":94,"address":[2035407,2035261,2035517,2035663],"length":1,"stats":{"Line":5}},{"line":95,"address":[2354460],"length":1,"stats":{"Line":5}},{"line":98,"address":[2035696],"length":1,"stats":{"Line":3}},{"line":99,"address":[2035715],"length":1,"stats":{"Line":3}},{"line":100,"address":[7491010],"length":1,"stats":{"Line":1}},{"line":101,"address":[6951577],"length":1,"stats":{"Line":0}},{"line":102,"address":[7491056],"length":1,"stats":{"Line":0}},{"line":103,"address":[6951623],"length":1,"stats":{"Line":0}},{"line":104,"address":[7491102],"length":1,"stats":{"Line":0}},{"line":105,"address":[7491125],"length":1,"stats":{"Line":2}},{"line":107,"address":[6951695],"length":1,"stats":{"Line":3}},{"line":121,"address":[7491184],"length":1,"stats":{"Line":0}},{"line":124,"address":[2035952],"length":1,"stats":{"Line":0}},{"line":125,"address":[6951824],"length":1,"stats":{"Line":0}},{"line":126,"address":[2036114],"length":1,"stats":{"Line":0}},{"line":127,"address":[2036235],"length":1,"stats":{"Line":0}},{"line":128,"address":[7491628],"length":1,"stats":{"Line":0}},{"line":129,"address":[6952297],"length":1,"stats":{"Line":0}},{"line":138,"address":[2045344,2045664,2045904,2045200,2045824,2045264,2045040,2045136,2045424,2045504,2045584,2045744],"length":1,"stats":{"Line":6}},{"line":139,"address":[6963155,6963773,6963685,6963284,6963365,6963536,6963219,6963065,6963917,6963856,6963604,6963453],"length":1,"stats":{"Line":7}},{"line":151,"address":[7491888],"length":1,"stats":{"Line":2}},{"line":152,"address":[7491911],"length":1,"stats":{"Line":3}},{"line":159,"address":[],"length":0,"stats":{"Line":0}},{"line":160,"address":[],"length":0,"stats":{"Line":0}},{"line":165,"address":[2036720],"length":1,"stats":{"Line":3}},{"line":166,"address":[2036737],"length":1,"stats":{"Line":3}},{"line":169,"address":[7492032,7493517],"length":1,"stats":{"Line":3}},{"line":170,"address":[2036829],"length":1,"stats":{"Line":3}},{"line":171,"address":[2036985],"length":1,"stats":{"Line":1}},{"line":172,"address":[7492232],"length":1,"stats":{"Line":1}},{"line":176,"address":[6952974,6952659],"length":1,"stats":{"Line":6}},{"line":179,"address":[2038240,2038282,2038790],"length":1,"stats":{"Line":6}},{"line":180,"address":[7493619],"length":1,"stats":{"Line":3}},{"line":181,"address":[6954220],"length":1,"stats":{"Line":0}},{"line":183,"address":[2038319],"length":1,"stats":{"Line":3}},{"line":185,"address":[2038408],"length":1,"stats":{"Line":3}},{"line":186,"address":[6954322,6954429],"length":1,"stats":{"Line":0}},{"line":188,"address":[2038421,2038547],"length":1,"stats":{"Line":7}},{"line":190,"address":[6954405,6954469],"length":1,"stats":{"Line":7}},{"line":199,"address":[7492533],"length":1,"stats":{"Line":4}},{"line":200,"address":[2037326,2037290],"length":1,"stats":{"Line":7}},{"line":202,"address":[2037338,2037494,2037305],"length":1,"stats":{"Line":14}},{"line":205,"address":[7494170,7494678,7494128],"length":1,"stats":{"Line":7}},{"line":206,"address":[6954739],"length":1,"stats":{"Line":5}},{"line":207,"address":[2038940],"length":1,"stats":{"Line":1}},{"line":209,"address":[2038895],"length":1,"stats":{"Line":5}},{"line":211,"address":[6954840],"length":1,"stats":{"Line":3}},{"line":212,"address":[6954898,6955005],"length":1,"stats":{"Line":2}},{"line":214,"address":[2038997,2039123],"length":1,"stats":{"Line":8}},{"line":216,"address":[6955045,6954981],"length":1,"stats":{"Line":8}},{"line":225,"address":[6953430],"length":1,"stats":{"Line":6}},{"line":226,"address":[2037757,2037636],"length":1,"stats":{"Line":3}},{"line":228,"address":[7492964,7492904],"length":1,"stats":{"Line":9}},{"line":231,"address":[2037854,2037720],"length":1,"stats":{"Line":8}},{"line":240,"address":[2039392],"length":1,"stats":{"Line":3}},{"line":241,"address":[2039411],"length":1,"stats":{"Line":3}},{"line":246,"address":[2163986,2163232,2163953],"length":1,"stats":{"Line":1}},{"line":247,"address":[2163262],"length":1,"stats":{"Line":1}},{"line":249,"address":[2163445,2163289,2163357,2163929],"length":1,"stats":{"Line":4}},{"line":250,"address":[6937247,6937446,6937066],"length":1,"stats":{"Line":2}},{"line":251,"address":[6937373],"length":1,"stats":{"Line":1}},{"line":254,"address":[6937028,6937097],"length":1,"stats":{"Line":2}},{"line":257,"address":[2164790,2164757,2164000],"length":1,"stats":{"Line":0}},{"line":258,"address":[6937677],"length":1,"stats":{"Line":0}},{"line":260,"address":[6937776,6937873,6937704,6938382],"length":1,"stats":{"Line":0}},{"line":261,"address":[2164631,2164446,2164246],"length":1,"stats":{"Line":0}},{"line":262,"address":[2164555],"length":1,"stats":{"Line":0}},{"line":265,"address":[2164203,2164280],"length":1,"stats":{"Line":0}},{"line":268,"address":[2164816],"length":1,"stats":{"Line":0}},{"line":270,"address":[2164848],"length":1,"stats":{"Line":0}},{"line":271,"address":[2039488,2039472],"length":1,"stats":{"Line":0}},{"line":273,"address":[2039504,2039516],"length":1,"stats":{"Line":0}}],"covered":61,"coverable":86},{"path":["/","home","runner","work","influxdb-rust","influxdb-rust","influxdb","tests","derive_integration_tests.rs"],"content":"#[path = \"./utilities.rs\"]\nmod utilities;\n\n#[cfg(feature = \"derive\")]\nuse influxdb::InfluxDbWriteable;\n\nuse chrono::{DateTime, Utc};\nuse influxdb::{Query, ReadQuery, Timestamp};\n\n#[cfg(feature = \"serde\")]\nuse serde_derive::Deserialize;\n\nuse utilities::{assert_result_ok, create_client, create_db, delete_db, run_test};\n\n#[derive(Debug, PartialEq)]\n#[cfg_attr(feature = \"derive\", derive(InfluxDbWriteable))]\nstruct WeatherReading {\n    time: DateTime<Utc>,\n    #[influxdb(ignore)]\n    humidity: i32,\n    pressure: i32,\n    #[influxdb(tag)]\n    wind_strength: Option<u64>,\n}\n\n#[derive(Debug)]\n#[cfg_attr(feature = \"serde\", derive(Deserialize))]\nstruct WeatherReadingWithoutIgnored {\n    time: DateTime<Utc>,\n    pressure: i32,\n    wind_strength: Option<u64>,\n}\n\n#[test]\nfn test_build_query() {\n    let weather_reading = WeatherReading {\n        time: Timestamp::Hours(1).into(),\n        humidity: 30,\n        pressure: 100,\n        wind_strength: Some(5),\n    };\n    let query = weather_reading.into_query(\"weather_reading\");\n    let query = query.build().unwrap();\n    assert_eq!(\n        query.get(),\n        \"weather_reading,wind_strength=5 pressure=100i 3600000000000\"\n    );\n}\n\n#[cfg(feature = \"derive\")]\n/// INTEGRATION TEST\n///\n/// This integration tests that writing data and retrieving the data again is working\n#[async_std::test]\n#[cfg(not(tarpaulin_include))]\nasync fn test_derive_simple_write() {\n    const TEST_NAME: &str = \"test_derive_simple_write\";\n\n    run_test(\n        || async move {\n            create_db(TEST_NAME).await.expect(\"could not setup db\");\n            let client = create_client(TEST_NAME);\n            let weather_reading = WeatherReading {\n                time: Timestamp::Nanoseconds(0).into(),\n                humidity: 30,\n                wind_strength: Some(5),\n                pressure: 100,\n            };\n            let query = weather_reading.into_query(\"weather_reading\");\n            let result = client.query(&query).await;\n            assert!(result.is_ok(), \"unable to insert into db\");\n        },\n        || async move {\n            delete_db(TEST_NAME).await.expect(\"could not clean up db\");\n        },\n    )\n    .await;\n}\n\n/// INTEGRATION TEST\n///\n/// This integration tests that writing data and retrieving the data again is working\n#[cfg(feature = \"derive\")]\n#[cfg(feature = \"serde\")]\n#[async_std::test]\n#[cfg(not(tarpaulin_include))]\nasync fn test_write_and_read_option() {\n    const TEST_NAME: &str = \"test_write_and_read_option\";\n\n    run_test(\n        || async move {\n            create_db(TEST_NAME).await.expect(\"could not setup db\");\n            let client = create_client(TEST_NAME);\n            let weather_reading = WeatherReading {\n                time: Timestamp::Hours(11).into(),\n                humidity: 30,\n                wind_strength: None,\n                pressure: 100,\n            };\n            let write_result = client\n                .query(&weather_reading.into_query(\"weather_reading\".to_string()))\n                .await;\n            assert_result_ok(&write_result);\n\n            let query = ReadQuery::new(\"SELECT time, pressure, wind_strength FROM weather_reading\");\n            let result = client.json_query(query).await.and_then(|mut db_result| {\n                println!(\"{:?}\", db_result);\n                db_result.deserialize_next::<WeatherReadingWithoutIgnored>()\n            });\n            assert_result_ok(&result);\n            let result = result.unwrap();\n            let value = &result.series[0].values[0];\n            assert_eq!(value.time, Timestamp::Hours(11).into());\n            assert_eq!(value.pressure, 100);\n            assert_eq!(value.wind_strength, None);\n        },\n        || async move {\n            delete_db(TEST_NAME).await.expect(\"could not clean up db\");\n        },\n    )\n    .await;\n}\n","traces":[],"covered":0,"coverable":0},{"path":["/","home","runner","work","influxdb-rust","influxdb-rust","influxdb","tests","integration_tests.rs"],"content":"extern crate influxdb;\n\n#[path = \"./utilities.rs\"]\nmod utilities;\n\nuse serde_derive::Deserialize;\nuse utilities::{\n    assert_result_err, assert_result_ok, create_client, create_db, delete_db, run_test,\n};\n\nuse influxdb::InfluxDbWriteable;\nuse influxdb::{Client, Error, ReadQuery, Timestamp};\n\n/// INTEGRATION TEST\n///\n/// This test case tests whether the InfluxDB server can be connected to and gathers info about it - tested with async_std\n#[async_std::test]\n#[cfg(not(tarpaulin_include))]\nasync fn test_ping_influx_db_async_std() {\n    let client = create_client(\"notusedhere\");\n    let result = client.ping().await;\n    assert_result_ok(&result);\n\n    let (build, version) = result.unwrap();\n    assert!(!build.is_empty(), \"Build should not be empty\");\n    assert!(!version.is_empty(), \"Build should not be empty\");\n\n    println!(\"build: {} version: {}\", build, version);\n}\n\n/// INTEGRATION TEST\n///\n/// This test case tests whether the InfluxDB server can be connected to and gathers info about it - tested with tokio 1.0\n#[tokio::test]\n#[cfg(not(any(tarpaulin_include, feature = \"hyper-client\")))]\nasync fn test_ping_influx_db_tokio() {\n    let client = create_client(\"notusedhere\");\n    let result = client.ping().await;\n    assert_result_ok(&result);\n\n    let (build, version) = result.unwrap();\n    assert!(!build.is_empty(), \"Build should not be empty\");\n    assert!(!version.is_empty(), \"Build should not be empty\");\n\n    println!(\"build: {} version: {}\", build, version);\n}\n\n/// INTEGRATION TEST\n///\n/// This test case tests connection error\n#[async_std::test]\n#[cfg(not(tarpaulin_include))]\nasync fn test_connection_error() {\n    let test_name = \"test_connection_error\";\n    let client =\n        Client::new(\"http://127.0.0.1:10086\", test_name).with_auth(\"nopriv_user\", \"password\");\n    let read_query = ReadQuery::new(\"SELECT * FROM weather\");\n    let read_result = client.query(read_query).await;\n    assert_result_err(&read_result);\n    match read_result {\n        Err(Error::ConnectionError { .. }) => {}\n        _ => panic!(\n            \"Should cause a ConnectionError: {}\",\n            read_result.unwrap_err()\n        ),\n    }\n}\n\n/// INTEGRATION TEST\n///\n/// This test case tests the Authentication\n#[async_std::test]\n#[cfg(not(tarpaulin_include))]\nasync fn test_authed_write_and_read() {\n    const TEST_NAME: &str = \"test_authed_write_and_read\";\n\n    run_test(\n        || async move {\n            let client =\n                Client::new(\"http://127.0.0.1:9086\", TEST_NAME).with_auth(\"admin\", \"password\");\n            let query = format!(\"CREATE DATABASE {}\", TEST_NAME);\n            client\n                .query(ReadQuery::new(query))\n                .await\n                .expect(\"could not setup db\");\n\n            let client =\n                Client::new(\"http://127.0.0.1:9086\", TEST_NAME).with_auth(\"admin\", \"password\");\n            let write_query = Timestamp::Hours(11)\n                .into_query(\"weather\")\n                .add_field(\"temperature\", 82);\n            let write_result = client.query(write_query).await;\n            assert_result_ok(&write_result);\n\n            let read_query = ReadQuery::new(\"SELECT * FROM weather\");\n            let read_result = client.query(read_query).await;\n            assert_result_ok(&read_result);\n            assert!(\n                !read_result.unwrap().contains(\"error\"),\n                \"Data contained a database error\"\n            );\n        },\n        || async move {\n            let client =\n                Client::new(\"http://127.0.0.1:9086\", TEST_NAME).with_auth(\"admin\", \"password\");\n            let query = format!(\"DROP DATABASE {}\", TEST_NAME);\n\n            client\n                .query(ReadQuery::new(query))\n                .await\n                .expect(\"could not clean up db\");\n        },\n    )\n    .await;\n}\n\n/// INTEGRATION TEST\n///\n/// This test case tests the Authentication\n#[async_std::test]\n#[cfg(not(tarpaulin_include))]\nasync fn test_wrong_authed_write_and_read() {\n    use http::StatusCode;\n\n    const TEST_NAME: &str = \"test_wrong_authed_write_and_read\";\n\n    run_test(\n        || async move {\n            let client =\n                Client::new(\"http://127.0.0.1:9086\", TEST_NAME).with_auth(\"admin\", \"password\");\n            let query = format!(\"CREATE DATABASE {}\", TEST_NAME);\n            client\n                .query(ReadQuery::new(query))\n                .await\n                .expect(\"could not setup db\");\n\n            let client =\n                Client::new(\"http://127.0.0.1:9086\", TEST_NAME).with_auth(\"wrong_user\", \"password\");\n            let write_query = Timestamp::Hours(11)\n                .into_query(\"weather\")\n                .add_field(\"temperature\", 82);\n            let write_result = client.query(write_query).await;\n            assert_result_err(&write_result);\n            match write_result {\n                Err(Error::ApiError(code)) if code == StatusCode::UNAUTHORIZED.as_u16() => {}\n                _ => panic!(\n                    \"Should be an ApiError(UNAUTHORIZED): {}\",\n                    write_result.unwrap_err()\n                ),\n            }\n\n            let read_query = ReadQuery::new(\"SELECT * FROM weather\");\n            let read_result = client.query(read_query).await;\n            assert_result_err(&read_result);\n            match read_result {\n                Err(Error::ApiError(code)) if code == StatusCode::UNAUTHORIZED.as_u16() => {}\n                _ => panic!(\n                    \"Should be an ApiError(UNAUTHORIZED): {}\",\n                    read_result.unwrap_err()\n                ),\n            }\n\n            let client = Client::new(\"http://127.0.0.1:9086\", TEST_NAME)\n                .with_auth(\"nopriv_user\", \"password\");\n            let read_query = ReadQuery::new(\"SELECT * FROM weather\");\n            let read_result = client.query(read_query).await;\n            assert_result_err(&read_result);\n            match read_result {\n                Err(Error::ApiError(code)) if code == StatusCode::FORBIDDEN.as_u16() => {}\n                _ => panic!(\n                    \"Should be an ApiError(UNAUTHENTICATED): {}\",\n                    read_result.unwrap_err()\n                ),\n            }\n        },\n        || async move {\n            let client =\n                Client::new(\"http://127.0.0.1:9086\", TEST_NAME).with_auth(\"admin\", \"password\");\n            let query = format!(\"DROP DATABASE {}\", TEST_NAME);\n            client\n                .query(ReadQuery::new(query))\n                .await\n                .expect(\"could not clean up db\");\n        },\n    )\n    .await;\n}\n\n/// INTEGRATION TEST\n///\n/// This test case tests the Authentication\n#[async_std::test]\n#[cfg(not(tarpaulin_include))]\nasync fn test_non_authed_write_and_read() {\n    use http::StatusCode;\n\n    const TEST_NAME: &str = \"test_non_authed_write_and_read\";\n\n    run_test(\n        || async move {\n            let client =\n                Client::new(\"http://127.0.0.1:9086\", TEST_NAME).with_auth(\"admin\", \"password\");\n            let query = format!(\"CREATE DATABASE {}\", TEST_NAME);\n            client\n                .query(ReadQuery::new(query))\n                .await\n                .expect(\"could not setup db\");\n            let non_authed_client = Client::new(\"http://127.0.0.1:9086\", TEST_NAME);\n            let write_query = Timestamp::Hours(11)\n                .into_query(\"weather\")\n                .add_field(\"temperature\", 82);\n            let write_result = non_authed_client.query(write_query).await;\n            assert_result_err(&write_result);\n            match write_result {\n                Err(Error::ApiError(code)) if code == StatusCode::UNAUTHORIZED.as_u16() => {}\n                _ => panic!(\n                    \"Should be an ApiError(UNAUTHORIZED): {}\",\n                    write_result.unwrap_err()\n                ),\n            }\n\n            let read_query = ReadQuery::new(\"SELECT * FROM weather\");\n            let read_result = non_authed_client.query(read_query).await;\n\n            assert_result_err(&read_result);\n            match read_result {\n                Err(Error::ApiError(code)) if code == StatusCode::UNAUTHORIZED.as_u16() => {}\n                _ => panic!(\n                    \"Should be an ApiError(UNAUTHORIZED): {}\",\n                    read_result.unwrap_err()\n                ),\n            }\n        },\n        || async move {\n            let client =\n                Client::new(\"http://127.0.0.1:9086\", TEST_NAME).with_auth(\"admin\", \"password\");\n            let query = format!(\"DROP DATABASE {}\", TEST_NAME);\n            client\n                .query(ReadQuery::new(query))\n                .await\n                .expect(\"could not clean up db\");\n        },\n    )\n    .await;\n}\n\n/// INTEGRATION TEST\n///\n/// This integration tests that writing data and retrieving the data again is working\n#[async_std::test]\n#[cfg(not(tarpaulin_include))]\nasync fn test_write_and_read_field() {\n    const TEST_NAME: &str = \"test_write_field\";\n\n    run_test(\n        || async move {\n            create_db(TEST_NAME).await.expect(\"could not setup db\");\n            let client = create_client(TEST_NAME);\n            let write_query = Timestamp::Hours(11)\n                .into_query(\"weather\")\n                .add_field(\"temperature\", 82);\n            let write_result = client.query(write_query).await;\n            assert_result_ok(&write_result);\n\n            let read_query = ReadQuery::new(\"SELECT * FROM weather\");\n            let read_result = client.query(read_query).await;\n            assert_result_ok(&read_result);\n            assert!(\n                !read_result.unwrap().contains(\"error\"),\n                \"Data contained a database error\"\n            );\n        },\n        || async move {\n            delete_db(TEST_NAME).await.expect(\"could not clean up db\");\n        },\n    )\n    .await;\n}\n\n/// INTEGRATION TEST\n///\n/// This test case tests the authentication on json reads\n#[async_std::test]\n#[cfg(feature = \"serde\")]\n#[cfg(not(tarpaulin_include))]\nasync fn test_json_non_authed_read() {\n    use http::StatusCode;\n\n    const TEST_NAME: &str = \"test_json_non_authed_read\";\n\n    run_test(\n        || async move {\n            let client =\n                Client::new(\"http://127.0.0.1:9086\", TEST_NAME).with_auth(\"admin\", \"password\");\n            let query = format!(\"CREATE DATABASE {}\", TEST_NAME);\n            client\n                .query(ReadQuery::new(query))\n                .await\n                .expect(\"could not setup db\");\n            let non_authed_client = Client::new(\"http://127.0.0.1:9086\", TEST_NAME);\n\n            let read_query = ReadQuery::new(\"SELECT * FROM weather\");\n            let read_result = non_authed_client.json_query(read_query).await;\n            assert_result_err(&read_result);\n            match read_result {\n                Err(Error::ApiError(code)) if code == StatusCode::UNAUTHORIZED.as_u16() => {}\n                _ => panic!(\n                    \"Should be an ApiError(UNAUTHORIZED): {}\",\n                    read_result.unwrap_err()\n                ),\n            }\n        },\n        || async move {\n            let client =\n                Client::new(\"http://127.0.0.1:9086\", TEST_NAME).with_auth(\"admin\", \"password\");\n            let query = format!(\"DROP DATABASE {}\", TEST_NAME);\n\n            client\n                .query(ReadQuery::new(query))\n                .await\n                .expect(\"could not clean up db\");\n        },\n    )\n    .await\n}\n\n/// INTEGRATION TEST\n///\n/// This test case tests the authentication on json reads\n#[async_std::test]\n#[cfg(feature = \"serde\")]\n#[cfg(not(tarpaulin_include))]\nasync fn test_json_authed_read() {\n    const TEST_NAME: &str = \"test_json_authed_read\";\n\n    run_test(\n        || async move {\n            let client =\n                Client::new(\"http://127.0.0.1:9086\", TEST_NAME).with_auth(\"admin\", \"password\");\n            let query = format!(\"CREATE DATABASE {}\", TEST_NAME);\n            client\n                .query(ReadQuery::new(query))\n                .await\n                .expect(\"could not setup db\");\n\n            let read_query = ReadQuery::new(\"SELECT * FROM weather\");\n            let read_result = client.json_query(read_query).await;\n            assert_result_ok(&read_result);\n        },\n        || async move {\n            let client =\n                Client::new(\"http://127.0.0.1:9086\", TEST_NAME).with_auth(\"admin\", \"password\");\n            let query = format!(\"DROP DATABASE {}\", TEST_NAME);\n\n            client\n                .query(ReadQuery::new(query))\n                .await\n                .expect(\"could not clean up db\");\n        },\n    )\n    .await\n}\n\n/// INTEGRATION TEST\n///\n/// This integration tests that writing data and retrieving the data again is working\n#[async_std::test]\n#[cfg(feature = \"serde\")]\n#[cfg(not(tarpaulin_include))]\nasync fn test_write_and_read_option() {\n    const TEST_NAME: &str = \"test_write_and_read_option\";\n\n    run_test(\n        || {\n            async move {\n                create_db(TEST_NAME).await.expect(\"could not setup db\");\n\n                let client = create_client(TEST_NAME);\n                // Todo: Convert this to derive based insert for easier comparison of structs\n                let write_query = Timestamp::Hours(11)\n                    .into_query(\"weather\")\n                    .add_field(\"temperature\", 82)\n                    .add_field(\"wind_strength\", <Option<u64>>::None);\n                let write_result = client.query(write_query).await;\n                assert_result_ok(&write_result);\n\n                #[derive(Deserialize, Debug, PartialEq)]\n                struct Weather {\n                    time: String,\n                    // different order to verify field names\n                    // are being used instead of just order\n                    wind_strength: Option<u64>,\n                    temperature: i32,\n                }\n\n                let query = ReadQuery::new(\"SELECT time, temperature, wind_strength FROM weather\");\n                let result = client\n                    .json_query(query)\n                    .await\n                    .and_then(|mut db_result| db_result.deserialize_next::<Weather>());\n                assert_result_ok(&result);\n\n                assert_eq!(\n                    result.unwrap().series[0].values[0],\n                    Weather {\n                        time: \"1970-01-01T11:00:00Z\".to_string(),\n                        temperature: 82,\n                        wind_strength: None,\n                    }\n                );\n            }\n        },\n        || async move {\n            delete_db(\"test_write_and_read_option\")\n                .await\n                .expect(\"could not clean up db\");\n        },\n    )\n    .await;\n}\n\n/// INTEGRATION TEST\n///\n/// This test case tests whether JSON can be decoded from a InfluxDB response and whether that JSON\n/// is equal to the data which was written to the database\n#[async_std::test]\n#[cfg(feature = \"serde\")]\n#[cfg(not(tarpaulin_include))]\nasync fn test_json_query() {\n    const TEST_NAME: &str = \"test_json_query\";\n\n    run_test(\n        || async move {\n            create_db(TEST_NAME).await.expect(\"could not setup db\");\n\n            let client = create_client(TEST_NAME);\n\n            let write_query = Timestamp::Hours(11)\n                .into_query(\"weather\")\n                .add_field(\"temperature\", 82);\n            let write_result = client.query(write_query).await;\n            assert_result_ok(&write_result);\n\n            #[derive(Deserialize, Debug, PartialEq)]\n            struct Weather {\n                time: String,\n                temperature: i32,\n            }\n\n            let query = ReadQuery::new(\"SELECT * FROM weather\");\n            let result = client\n                .json_query(query)\n                .await\n                .and_then(|mut db_result| db_result.deserialize_next::<Weather>());\n            assert_result_ok(&result);\n\n            assert_eq!(\n                result.unwrap().series[0].values[0],\n                Weather {\n                    time: \"1970-01-01T11:00:00Z\".to_string(),\n                    temperature: 82\n                }\n            );\n        },\n        || async move {\n            delete_db(TEST_NAME).await.expect(\"could not clean up db\");\n        },\n    )\n    .await;\n}\n\n/// INTEGRATION TEST\n///\n/// This test case tests whether the response to a GROUP BY can be parsed by\n/// deserialize_next_tagged into a tags struct\n#[async_std::test]\n#[cfg(feature = \"serde\")]\n#[cfg(not(tarpaulin_include))]\nasync fn test_json_query_tagged() {\n    const TEST_NAME: &str = \"test_json_query_tagged\";\n\n    run_test(\n        || async move {\n            create_db(TEST_NAME).await.expect(\"could not setup db\");\n\n            let client = create_client(TEST_NAME);\n\n            let write_query = Timestamp::Hours(11)\n                .into_query(\"weather\")\n                .add_tag(\"location\", \"London\")\n                .add_field(\"temperature\", 82);\n            let write_result = client.query(write_query).await;\n            assert_result_ok(&write_result);\n\n            #[derive(Deserialize, Debug, PartialEq)]\n            struct WeatherMeta {\n                location: String,\n            }\n\n            #[derive(Deserialize, Debug, PartialEq)]\n            struct Weather {\n                time: String,\n                temperature: i32,\n            }\n\n            let query = ReadQuery::new(\"SELECT * FROM weather GROUP BY location\");\n            let result = client.json_query(query).await.and_then(|mut db_result| {\n                db_result.deserialize_next_tagged::<WeatherMeta, Weather>()\n            });\n            assert_result_ok(&result);\n            let result = result.unwrap();\n\n            assert_eq!(\n                result.series[0].tags,\n                WeatherMeta {\n                    location: \"London\".to_string(),\n                }\n            );\n            assert_eq!(\n                result.series[0].values[0],\n                Weather {\n                    time: \"1970-01-01T11:00:00Z\".to_string(),\n                    temperature: 82\n                }\n            );\n        },\n        || async move {\n            delete_db(TEST_NAME).await.expect(\"could not clean up db\");\n        },\n    )\n    .await;\n}\n\n/// INTEGRATION TEST\n///\n/// This test case tests whether JSON can be decoded from a InfluxDB response and whether that JSON\n/// is equal to the data which was written to the database\n/// (tested with tokio)\n#[tokio::test]\n#[cfg(all(\n    feature = \"serde\",\n    not(any(tarpaulin_include, feature = \"hyper-client\"))\n))]\nasync fn test_json_query_vec() {\n    const TEST_NAME: &str = \"test_json_query_vec\";\n\n    run_test(\n        || async move {\n            create_db(TEST_NAME).await.expect(\"could not setup db\");\n\n            let client = create_client(TEST_NAME);\n            let write_query1 = Timestamp::Hours(11)\n                .into_query(\"temperature_vec\")\n                .add_field(\"temperature\", 16);\n            let write_query2 = Timestamp::Hours(12)\n                .into_query(\"temperature_vec\")\n                .add_field(\"temperature\", 17);\n            let write_query3 = Timestamp::Hours(13)\n                .into_query(\"temperature_vec\")\n                .add_field(\"temperature\", 18);\n\n            let _write_result = client.query(write_query1).await;\n            let _write_result2 = client.query(write_query2).await;\n            let _write_result2 = client.query(write_query3).await;\n\n            #[derive(Deserialize, Debug, PartialEq)]\n            struct Weather {\n                time: String,\n                temperature: i32,\n            }\n\n            let query = ReadQuery::new(\"SELECT * FROM temperature_vec\");\n            let result = client\n                .json_query(query)\n                .await\n                .and_then(|mut db_result| db_result.deserialize_next::<Weather>());\n            assert_result_ok(&result);\n            assert_eq!(result.unwrap().series[0].values.len(), 3);\n        },\n        || async move {\n            delete_db(TEST_NAME).await.expect(\"could not clean up db\");\n        },\n    )\n    .await;\n}\n\n/// INTEGRATION TEST\n///\n/// This integration test tests whether using the wrong query method fails building the query\n#[async_std::test]\n#[cfg(feature = \"serde\")]\n#[cfg(not(tarpaulin_include))]\nasync fn test_serde_multi_query() {\n    const TEST_NAME: &str = \"test_serde_multi_query\";\n\n    run_test(\n        || async move {\n            create_db(TEST_NAME).await.expect(\"could not setup db\");\n\n            #[derive(Deserialize, Debug, PartialEq)]\n            struct Temperature {\n                time: String,\n                temperature: i32,\n            }\n\n            #[derive(Deserialize, Debug, PartialEq)]\n            struct Humidity {\n                time: String,\n                humidity: i32,\n            }\n\n            let client = create_client(TEST_NAME);\n            let write_query = Timestamp::Hours(11)\n                .into_query(\"temperature\")\n                .add_field(\"temperature\", 16);\n            let write_query2 = Timestamp::Hours(11)\n                .into_query(\"humidity\")\n                .add_field(\"humidity\", 69);\n\n            let write_result = client.query(write_query).await;\n            let write_result2 = client.query(write_query2).await;\n            assert_result_ok(&write_result);\n            assert_result_ok(&write_result2);\n\n            let result = client\n                .json_query(\n                    ReadQuery::new(\"SELECT * FROM temperature\").add_query(\"SELECT * FROM humidity\"),\n                )\n                .await\n                .and_then(|mut db_result| {\n                    let temp = db_result.deserialize_next::<Temperature>()?;\n                    let humidity = db_result.deserialize_next::<Humidity>()?;\n\n                    Ok((temp, humidity))\n                });\n            assert_result_ok(&result);\n\n            let (temp, humidity) = result.unwrap();\n            assert_eq!(\n                temp.series[0].values[0],\n                Temperature {\n                    time: \"1970-01-01T11:00:00Z\".to_string(),\n                    temperature: 16\n                },\n            );\n            assert_eq!(\n                humidity.series[0].values[0],\n                Humidity {\n                    time: \"1970-01-01T11:00:00Z\".to_string(),\n                    humidity: 69\n                }\n            );\n        },\n        || async move {\n            delete_db(TEST_NAME).await.expect(\"could not clean up db\");\n        },\n    )\n    .await;\n}\n\n/// INTEGRATION TEST\n///\n/// This integration test tests whether using the wrong query method fails building the query\n#[async_std::test]\n#[cfg(feature = \"serde\")]\n#[cfg(not(tarpaulin_include))]\nasync fn test_wrong_query_errors() {\n    let client = create_client(\"test_name\");\n    let result = client\n        .json_query(ReadQuery::new(\"CREATE DATABASE this_should_fail\"))\n        .await;\n    assert!(\n        result.is_err(),\n        \"Should only build SELECT and SHOW queries.\"\n    );\n}\n","traces":[],"covered":0,"coverable":0},{"path":["/","home","runner","work","influxdb-rust","influxdb-rust","influxdb","tests","integration_tests_v2.rs"],"content":"extern crate influxdb;\n\n#[path = \"./utilities.rs\"]\nmod utilities;\nuse utilities::{assert_result_err, assert_result_ok, run_test};\n\nuse influxdb::InfluxDbWriteable;\nuse influxdb::{Client, Error, ReadQuery, Timestamp};\n\n/// INTEGRATION TEST\n///\n\n/// This test case tests the Authentication\n#[async_std::test]\n#[cfg(not(tarpaulin))]\nasync fn test_authed_write_and_read() {\n    run_test(\n        || async move {\n            let client = Client::new(\"http://127.0.0.1:2086\", \"mydb\").with_token(\"admintoken\");\n            let write_query = Timestamp::Hours(11)\n                .into_query(\"weather\")\n                .add_field(\"temperature\", 82);\n            let write_result = client.query(&write_query).await;\n            assert_result_ok(&write_result);\n\n            let read_query = ReadQuery::new(\"SELECT * FROM weather\");\n            let read_result = client.query(read_query).await;\n            assert_result_ok(&read_result);\n            assert!(\n                !read_result.unwrap().contains(\"error\"),\n                \"Data contained a database error\"\n            );\n        },\n        || async move {\n            let client = Client::new(\"http://127.0.0.1:2086\", \"mydb\").with_token(\"admintoken\");\n            let read_query = ReadQuery::new(\"DROP MEASUREMENT \\\"weather\\\"\");\n            let read_result = client.query(read_query).await;\n            assert_result_ok(&read_result);\n            assert!(!read_result.unwrap().contains(\"error\"), \"Teardown failed\");\n        },\n    )\n    .await;\n}\n\n/// INTEGRATION TEST\n///\n/// This test case tests the Authentication\n#[async_std::test]\n#[cfg(not(tarpaulin))]\nasync fn test_wrong_authed_write_and_read() {\n    use http::StatusCode;\n\n    run_test(\n        || async move {\n            let client = Client::new(\"http://127.0.0.1:2086\", \"mydb\").with_token(\"falsetoken\");\n            let write_query = Timestamp::Hours(11)\n                .into_query(\"weather\")\n                .add_field(\"temperature\", 82);\n            let write_result = client.query(&write_query).await;\n            assert_result_err(&write_result);\n            match write_result {\n                Err(Error::ApiError(code)) if code == StatusCode::UNAUTHORIZED.as_u16() => {}\n                _ => panic!(\n                    \"Should be an ApiError(UNAUTHORIZED): {}\",\n                    write_result.unwrap_err()\n                ),\n            }\n\n            let read_query = ReadQuery::new(\"SELECT * FROM weather\");\n            let read_result = client.query(&read_query).await;\n            assert_result_err(&read_result);\n            match read_result {\n                Err(Error::ApiError(code)) if code == StatusCode::UNAUTHORIZED.as_u16() => {}\n                _ => panic!(\n                    \"Should be an ApiError(UNAUTHORIZED): {}\",\n                    read_result.unwrap_err()\n                ),\n            }\n        },\n        || async move {},\n    )\n    .await;\n}\n\n/// INTEGRATION TEST\n///\n/// This test case tests the Authentication\n#[async_std::test]\n#[cfg(not(tarpaulin))]\nasync fn test_non_authed_write_and_read() {\n    use http::StatusCode;\n\n    run_test(\n        || async move {\n            let non_authed_client = Client::new(\"http://127.0.0.1:2086\", \"mydb\");\n            let write_query = Timestamp::Hours(11)\n                .into_query(\"weather\")\n                .add_field(\"temperature\", 82);\n            let write_result = non_authed_client.query(&write_query).await;\n            assert_result_err(&write_result);\n            match write_result {\n                Err(Error::ApiError(code)) if code == StatusCode::UNAUTHORIZED.as_u16() => {}\n                _ => panic!(\n                    \"Should be an ApiError(UNAUTHORIZED): {}\",\n                    write_result.unwrap_err()\n                ),\n            }\n\n            let read_query = ReadQuery::new(\"SELECT * FROM weather\");\n            let read_result = non_authed_client.query(&read_query).await;\n            assert_result_err(&read_result);\n            match read_result {\n                Err(Error::ApiError(code)) if code == StatusCode::UNAUTHORIZED.as_u16() => {}\n                _ => panic!(\n                    \"Should be an ApiError(UNAUTHORIZED): {}\",\n                    read_result.unwrap_err()\n                ),\n            }\n        },\n        || async move {},\n    )\n    .await;\n}\n","traces":[],"covered":0,"coverable":0},{"path":["/","home","runner","work","influxdb-rust","influxdb-rust","influxdb","tests","utilities.rs"],"content":"use futures_util::FutureExt;\nuse influxdb::{Client, Error, ReadQuery};\nuse std::future::Future;\nuse std::panic::{AssertUnwindSafe, UnwindSafe};\n\n#[allow(dead_code)]\n#[cfg(not(tarpaulin_include))]\npub fn assert_result_err<A: std::fmt::Debug, B: std::fmt::Debug>(result: &Result<A, B>) {\n    result.as_ref().expect_err(\"assert_result_err failed\");\n}\n\n#[cfg(not(tarpaulin_include))]\npub fn assert_result_ok<A: std::fmt::Debug, B: std::fmt::Debug>(result: &Result<A, B>) {\n    result.as_ref().expect(\"assert_result_ok failed\");\n}\n\n#[allow(dead_code)]\n#[cfg(not(tarpaulin_include))]\npub fn create_client<T>(db_name: T) -> Client\nwhere\n    T: Into<String>,\n{\n    Client::new(\"http://127.0.0.1:8086\", db_name)\n}\n\n#[allow(dead_code)]\n#[cfg(not(tarpaulin_include))]\npub async fn create_db<T>(name: T) -> Result<String, Error>\nwhere\n    T: Into<String>,\n{\n    let test_name = name.into();\n    let query = format!(\"CREATE DATABASE {}\", test_name);\n    create_client(test_name).query(ReadQuery::new(query)).await\n}\n\n#[allow(dead_code)]\n#[cfg(not(tarpaulin_include))]\npub async fn delete_db<T>(name: T) -> Result<String, Error>\nwhere\n    T: Into<String>,\n{\n    let test_name = name.into();\n    let query = format!(\"DROP DATABASE {}\", test_name);\n    create_client(test_name).query(ReadQuery::new(query)).await\n}\n\n#[cfg(not(tarpaulin_include))]\npub async fn run_test<F, T, Fut1, Fut2>(test_fn: F, teardown: T)\nwhere\n    F: FnOnce() -> Fut1 + UnwindSafe,\n    T: FnOnce() -> Fut2,\n    Fut1: Future,\n    Fut2: Future,\n{\n    let test_result = AssertUnwindSafe(test_fn()).catch_unwind().await;\n    AssertUnwindSafe(teardown())\n        .catch_unwind()\n        .await\n        .expect(\"failed teardown\");\n    test_result.expect(\"failed test\");\n}\n","traces":[],"covered":0,"coverable":0},{"path":["/","home","runner","work","influxdb-rust","influxdb-rust","influxdb_derive","src","lib.rs"],"content":"use proc_macro::TokenStream;\n\nmod writeable;\nuse syn::parse_macro_input;\nuse writeable::expand_writeable;\n\n#[proc_macro_derive(InfluxDbWriteable, attributes(influxdb))]\npub fn derive_writeable(input: TokenStream) -> TokenStream {\n    expand_writeable(parse_macro_input!(input))\n        .unwrap_or_else(syn::Error::into_compile_error)\n        .into()\n}\n","traces":[{"line":8,"address":[299840,300128],"length":1,"stats":{"Line":0}},{"line":9,"address":[300040,299856],"length":1,"stats":{"Line":0}}],"covered":0,"coverable":2},{"path":["/","home","runner","work","influxdb-rust","influxdb-rust","influxdb_derive","src","writeable.rs"],"content":"use proc_macro2::TokenStream;\nuse quote::{format_ident, quote};\nuse std::convert::TryFrom;\nuse syn::{\n    parse::{Parse, ParseStream},\n    punctuated::Punctuated,\n    Data, DeriveInput, Field, Fields, Ident, Meta, Token,\n};\n\n#[derive(Debug)]\nstruct WriteableField {\n    ident: Ident,\n    is_tag: bool,\n    is_ignore: bool,\n}\n\nmod kw {\n    use syn::custom_keyword;\n\n    custom_keyword!(tag);\n    custom_keyword!(ignore);\n}\n\nenum FieldAttr {\n    Tag(kw::tag),\n    Ignore(kw::ignore),\n}\n\nimpl Parse for FieldAttr {\n    fn parse(input: ParseStream<'_>) -> syn::Result<Self> {\n        let lookahead = input.lookahead1();\n        if lookahead.peek(kw::tag) {\n            Ok(Self::Tag(input.parse()?))\n        } else if lookahead.peek(kw::ignore) {\n            Ok(Self::Ignore(input.parse()?))\n        } else {\n            Err(lookahead.error())\n        }\n    }\n}\n\nstruct FieldAttrs(Punctuated<FieldAttr, Token![,]>);\n\nimpl Parse for FieldAttrs {\n    fn parse(input: ParseStream<'_>) -> syn::Result<Self> {\n        Ok(Self(Punctuated::parse_terminated(input)?))\n    }\n}\n\nimpl TryFrom<Field> for WriteableField {\n    type Error = syn::Error;\n\n    fn try_from(field: Field) -> syn::Result<WriteableField> {\n        let ident = field.ident.expect(\"fields without ident are not supported\");\n        let mut is_tag = false;\n        let mut is_ignore = false;\n\n        for attr in field.attrs {\n            match attr.meta {\n                Meta::List(list) if list.path.is_ident(\"influxdb\") => {\n                    for attr in syn::parse2::<FieldAttrs>(list.tokens)?.0 {\n                        match attr {\n                            FieldAttr::Tag(_) => is_tag = true,\n                            FieldAttr::Ignore(_) => is_ignore = true,\n                        }\n                    }\n                }\n                _ => {}\n            }\n        }\n\n        Ok(WriteableField {\n            ident,\n            is_tag,\n            is_ignore,\n        })\n    }\n}\n\npub fn expand_writeable(input: DeriveInput) -> syn::Result<TokenStream> {\n    let ident = input.ident;\n    let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();\n\n    let fields = match input.data {\n        Data::Struct(strukt) => strukt.fields,\n        Data::Enum(inum) => {\n            return Err(syn::Error::new(\n                inum.enum_token.span,\n                \"#[derive(InfluxDbWriteable)] can only be used on structs\",\n            ))\n        }\n        Data::Union(cdu) => {\n            return Err(syn::Error::new(\n                cdu.union_token.span,\n                \"#[derive(InfluxDbWriteable)] can only be used on structs\",\n            ))\n        }\n    };\n\n    let time_field = format_ident!(\"time\");\n    let time_field_str = time_field.to_string();\n    #[allow(clippy::cmp_owned)] // that's not how idents work clippy\n    let fields = match fields {\n        Fields::Named(fields) => fields\n            .named\n            .into_iter()\n            .filter_map(|f| {\n                WriteableField::try_from(f)\n                    .map(|wf| {\n                        if !wf.is_ignore && wf.ident.to_string() != time_field_str {\n                            let ident = wf.ident;\n                            Some(match wf.is_tag {\n                                true => quote!(query.add_tag(stringify!(#ident), self.#ident)),\n                                false => quote!(query.add_field(stringify!(#ident), self.#ident)),\n                            })\n                        } else {\n                            None\n                        }\n                    })\n                    .transpose()\n            })\n            .collect::<syn::Result<Vec<_>>>()?,\n        _ => panic!(\"a struct without named fields is not supported\"),\n    };\n\n    Ok(quote! {\n        impl #impl_generics ::influxdb::InfluxDbWriteable for #ident #ty_generics #where_clause {\n            fn into_query<I: Into<String>>(self, name: I) -> ::influxdb::WriteQuery {\n                let timestamp: ::influxdb::Timestamp = self.#time_field.into();\n                let mut query = timestamp.into_query(name);\n                #(\n                    query = #fields;\n                )*\n                query\n            }\n        }\n    })\n}\n","traces":[{"line":30,"address":[290144,290918,290947],"length":1,"stats":{"Line":0}},{"line":31,"address":[290174],"length":1,"stats":{"Line":0}},{"line":32,"address":[290214,290270,290816],"length":1,"stats":{"Line":0}},{"line":33,"address":[290913,290722,290826,290305],"length":1,"stats":{"Line":0}},{"line":34,"address":[290619,290281,290319],"length":1,"stats":{"Line":0}},{"line":35,"address":[290629,290425,290507],"length":1,"stats":{"Line":0}},{"line":37,"address":[290325,290437],"length":1,"stats":{"Line":0}},{"line":45,"address":[290960],"length":1,"stats":{"Line":0}},{"line":46,"address":[290985,291197],"length":1,"stats":{"Line":0}},{"line":53,"address":[291966,291264],"length":1,"stats":{"Line":0}},{"line":54,"address":[291286],"length":1,"stats":{"Line":0}},{"line":55,"address":[291416],"length":1,"stats":{"Line":0}},{"line":56,"address":[291421],"length":1,"stats":{"Line":0}},{"line":58,"address":[291693,291648,293117,291426,291529],"length":1,"stats":{"Line":0}},{"line":59,"address":[291727],"length":1,"stats":{"Line":0}},{"line":60,"address":[291988,292137],"length":1,"stats":{"Line":0}},{"line":61,"address":[292247,292362,292688,292742],"length":1,"stats":{"Line":0}},{"line":62,"address":[292770],"length":1,"stats":{"Line":0}},{"line":63,"address":[292807],"length":1,"stats":{"Line":0}},{"line":64,"address":[292817],"length":1,"stats":{"Line":0}},{"line":72,"address":[291811],"length":1,"stats":{"Line":0}},{"line":73,"address":[291777],"length":1,"stats":{"Line":0}},{"line":74,"address":[291803],"length":1,"stats":{"Line":0}},{"line":75,"address":[291807],"length":1,"stats":{"Line":0}},{"line":80,"address":[293216,297207],"length":1,"stats":{"Line":0}},{"line":81,"address":[293238],"length":1,"stats":{"Line":0}},{"line":82,"address":[293318,293387],"length":1,"stats":{"Line":0}},{"line":84,"address":[293429],"length":1,"stats":{"Line":0}},{"line":85,"address":[293494],"length":1,"stats":{"Line":0}},{"line":86,"address":[293667],"length":1,"stats":{"Line":0}},{"line":87,"address":[297500,293718],"length":1,"stats":{"Line":0}},{"line":88,"address":[293711],"length":1,"stats":{"Line":0}},{"line":92,"address":[293757],"length":1,"stats":{"Line":0}},{"line":93,"address":[293820,297608],"length":1,"stats":{"Line":0}},{"line":94,"address":[293813],"length":1,"stats":{"Line":0}},{"line":100,"address":[293633,293912],"length":1,"stats":{"Line":0}},{"line":101,"address":[294133],"length":1,"stats":{"Line":0}},{"line":103,"address":[294160],"length":1,"stats":{"Line":0}},{"line":104,"address":[294571,294171,294387],"length":1,"stats":{"Line":0}},{"line":107,"address":[298032],"length":1,"stats":{"Line":0}},{"line":108,"address":[298067,298085],"length":1,"stats":{"Line":0}},{"line":109,"address":[299776,298082,299148,298128],"length":1,"stats":{"Line":0}},{"line":110,"address":[298216,298262,298155],"length":1,"stats":{"Line":0}},{"line":111,"address":[298371],"length":1,"stats":{"Line":0}},{"line":112,"address":[298405,299112],"length":1,"stats":{"Line":0}},{"line":113,"address":[299157,298430],"length":1,"stats":{"Line":0}},{"line":114,"address":[298490,298411],"length":1,"stats":{"Line":0}},{"line":117,"address":[298203],"length":1,"stats":{"Line":0}},{"line":126,"address":[294515,294640,297229],"length":1,"stats":{"Line":0}}],"covered":0,"coverable":49}],"coverage":66.87898089171973,"covered":315,"coverable":471}
\ No newline at end of file
