更新libclamav库1.0.0版本
This commit is contained in:
1
clamav/libclamav_rust/.cargo/vendor/humantime/.cargo-checksum.json
vendored
Normal file
1
clamav/libclamav_rust/.cargo/vendor/humantime/.cargo-checksum.json
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"files":{"Cargo.toml":"c0d1443ae237dee3c09cb70185fa947d8d8cb660acfbcb8f650798bd4e0c019e","LICENSE-APACHE":"c6596eb7be8581c18be736c846fb9173b69eccf6ef94c5135893ec56bd92ba08","LICENSE-MIT":"f6deca8261a8f4a3403dc74c725c46051157fd36c27cd4b100277eb1f303ad11","README.md":"e4bb65f28ddffb11d7eb337e9585947651f2fc11a5e4290f0ca126e21c582c1e","benches/datetime_format.rs":"ffe2e459e9b48e8fdbfb3686f6297257d66b29369ecd6750ae9fbba527ccc681","benches/datetime_parse.rs":"8039c4bd5f1795dbb54e1e39da5988f1d2df6c86c42d8fd378094fc78074d31e","bulk.yaml":"17c2548388e0cd3a63473021a2f1e4ddedee082d79d9167cb31ad06a1890d3fc","src/date.rs":"a8159494372ba8ec8a3a0a5b69c9b185f3e7ab007f283188bf96a6f071151f20","src/duration.rs":"4939ae2d1c3056424de421c4b124d0fb387e058d9abc82a21b83b38d66a40753","src/lib.rs":"ad4dbed28080d9a64ef0100c96b20ff4988d9dde908f56e28ece7252f5932990","src/wrapper.rs":"badc640e77379a42b2fcb728337d60a764b7f00a1b5b1d50c7372ddc20941967","vagga.yaml":"8396fe1510117c1c7bc3e896b62290dcf2dd300346071297018b0077ad9e45ce"},"package":"9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"}
|
||||
37
clamav/libclamav_rust/.cargo/vendor/humantime/Cargo.toml
vendored
Normal file
37
clamav/libclamav_rust/.cargo/vendor/humantime/Cargo.toml
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
|
||||
#
|
||||
# When uploading crates to the registry Cargo will automatically
|
||||
# "normalize" Cargo.toml files for maximal compatibility
|
||||
# with all versions of Cargo and also rewrite `path` dependencies
|
||||
# to registry (e.g., crates.io) dependencies
|
||||
#
|
||||
# If you believe there's an error in this file please file an
|
||||
# issue against the rust-lang/cargo repository. If you're
|
||||
# editing this file be aware that the upstream Cargo.toml
|
||||
# will likely look very different (and much more reasonable)
|
||||
|
||||
[package]
|
||||
edition = "2018"
|
||||
name = "humantime"
|
||||
version = "2.1.0"
|
||||
authors = ["Paul Colomiets <paul@colomiets.name>"]
|
||||
description = " A parser and formatter for std::time::{Duration, SystemTime}\n"
|
||||
homepage = "https://github.com/tailhook/humantime"
|
||||
documentation = "https://docs.rs/humantime"
|
||||
readme = "README.md"
|
||||
keywords = ["time", "human", "human-friendly", "parser", "duration"]
|
||||
categories = ["date-and-time"]
|
||||
license = "MIT/Apache-2.0"
|
||||
repository = "https://github.com/tailhook/humantime"
|
||||
|
||||
[lib]
|
||||
name = "humantime"
|
||||
path = "src/lib.rs"
|
||||
[dev-dependencies.chrono]
|
||||
version = "0.4"
|
||||
|
||||
[dev-dependencies.rand]
|
||||
version = "0.6"
|
||||
|
||||
[dev-dependencies.time]
|
||||
version = "0.1"
|
||||
202
clamav/libclamav_rust/.cargo/vendor/humantime/LICENSE-APACHE
vendored
Normal file
202
clamav/libclamav_rust/.cargo/vendor/humantime/LICENSE-APACHE
vendored
Normal file
@@ -0,0 +1,202 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright {yyyy} {name of copyright owner}
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
26
clamav/libclamav_rust/.cargo/vendor/humantime/LICENSE-MIT
vendored
Normal file
26
clamav/libclamav_rust/.cargo/vendor/humantime/LICENSE-MIT
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
Copyright (c) 2016 The humantime Developers
|
||||
|
||||
Includes parts of http date with the following copyright:
|
||||
Copyright (c) 2016 Pyfisch
|
||||
|
||||
Includes portions of musl libc with the following copyright:
|
||||
Copyright © 2005-2013 Rich Felker
|
||||
|
||||
|
||||
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.
|
||||
68
clamav/libclamav_rust/.cargo/vendor/humantime/README.md
vendored
Normal file
68
clamav/libclamav_rust/.cargo/vendor/humantime/README.md
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
Human Time
|
||||
==========
|
||||
|
||||
**Status: stable**
|
||||
|
||||
[Documentation](https://docs.rs/humantime) |
|
||||
[Github](https://github.com/tailhook/humantime) |
|
||||
[Crate](https://crates.io/crates/humantime)
|
||||
|
||||
|
||||
Features:
|
||||
|
||||
* Parses durations in free form like `15days 2min 2s`
|
||||
* Formats durations in similar form `2years 2min 12us`
|
||||
* Parses and formats timestamp in `rfc3339` format: `2018-01-01T12:53:00Z`
|
||||
* Parses timestamps in a weaker format: `2018-01-01 12:53:00`
|
||||
|
||||
Timestamp parsing/formatting is super-fast because format is basically
|
||||
fixed.
|
||||
|
||||
Here are some micro-benchmarks:
|
||||
|
||||
```
|
||||
test result: ok. 0 passed; 0 failed; 26 ignored; 0 measured; 0 filtered out
|
||||
|
||||
Running target/release/deps/datetime_format-8facb4ac832d9770
|
||||
|
||||
running 2 tests
|
||||
test rfc3339_chrono ... bench: 737 ns/iter (+/- 37)
|
||||
test rfc3339_humantime_seconds ... bench: 73 ns/iter (+/- 2)
|
||||
|
||||
test result: ok. 0 passed; 0 failed; 0 ignored; 2 measured; 0 filtered out
|
||||
|
||||
Running target/release/deps/datetime_parse-342628f877d7867c
|
||||
|
||||
running 6 tests
|
||||
test datetime_utc_parse_millis ... bench: 228 ns/iter (+/- 11)
|
||||
test datetime_utc_parse_nanos ... bench: 236 ns/iter (+/- 10)
|
||||
test datetime_utc_parse_seconds ... bench: 204 ns/iter (+/- 18)
|
||||
test rfc3339_humantime_millis ... bench: 28 ns/iter (+/- 1)
|
||||
test rfc3339_humantime_nanos ... bench: 36 ns/iter (+/- 2)
|
||||
test rfc3339_humantime_seconds ... bench: 24 ns/iter (+/- 1)
|
||||
|
||||
test result: ok. 0 passed; 0 failed; 0 ignored; 6 measured; 0 filtered out
|
||||
```
|
||||
|
||||
See [humantime-serde] for serde integration (previous crate [serde-humantime] looks unmaintained).
|
||||
|
||||
[serde-humantime]: https://docs.rs/serde-humantime/0.1.1/serde_humantime/
|
||||
[humantime-serde]: https://docs.rs/humantime-serde
|
||||
|
||||
License
|
||||
=======
|
||||
|
||||
Licensed under either of
|
||||
|
||||
* Apache License, Version 2.0, (./LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
|
||||
* MIT license (./LICENSE-MIT or http://opensource.org/licenses/MIT)
|
||||
|
||||
at your option.
|
||||
|
||||
Contribution
|
||||
------------
|
||||
|
||||
Unless you explicitly state otherwise, any contribution intentionally
|
||||
submitted for inclusion in the work by you, as defined in the Apache-2.0
|
||||
license, shall be dual licensed as above, without any additional terms or
|
||||
conditions.
|
||||
56
clamav/libclamav_rust/.cargo/vendor/humantime/benches/datetime_format.rs
vendored
Normal file
56
clamav/libclamav_rust/.cargo/vendor/humantime/benches/datetime_format.rs
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
#![feature(test)]
|
||||
extern crate test;
|
||||
|
||||
use std::io::Write;
|
||||
use std::time::{Duration, UNIX_EPOCH};
|
||||
|
||||
use humantime::format_rfc3339;
|
||||
|
||||
#[bench]
|
||||
fn rfc3339_humantime_seconds(b: &mut test::Bencher) {
|
||||
let time = UNIX_EPOCH + Duration::new(1_483_228_799, 0);
|
||||
let mut buf = Vec::with_capacity(100);
|
||||
b.iter(|| {
|
||||
buf.truncate(0);
|
||||
write!(&mut buf, "{}", format_rfc3339(time)).unwrap()
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn rfc3339_chrono(b: &mut test::Bencher) {
|
||||
use chrono::{DateTime, NaiveDateTime, Utc};
|
||||
use chrono::format::Item;
|
||||
use chrono::format::Item::*;
|
||||
use chrono::format::Numeric::*;
|
||||
use chrono::format::Fixed::*;
|
||||
use chrono::format::Pad::*;
|
||||
|
||||
let time = DateTime::<Utc>::from_utc(
|
||||
NaiveDateTime::from_timestamp(1_483_228_799, 0), Utc);
|
||||
let mut buf = Vec::with_capacity(100);
|
||||
|
||||
// formatting code from env_logger
|
||||
const ITEMS: &[Item<'static>] = {
|
||||
&[
|
||||
Numeric(Year, Zero),
|
||||
Literal("-"),
|
||||
Numeric(Month, Zero),
|
||||
Literal("-"),
|
||||
Numeric(Day, Zero),
|
||||
Literal("T"),
|
||||
Numeric(Hour, Zero),
|
||||
Literal(":"),
|
||||
Numeric(Minute, Zero),
|
||||
Literal(":"),
|
||||
Numeric(Second, Zero),
|
||||
Fixed(TimezoneOffsetZ),
|
||||
]
|
||||
};
|
||||
|
||||
|
||||
b.iter(|| {
|
||||
buf.truncate(0);
|
||||
write!(&mut buf, "{}", time.format_with_items(ITEMS.iter().cloned()))
|
||||
.unwrap()
|
||||
});
|
||||
}
|
||||
47
clamav/libclamav_rust/.cargo/vendor/humantime/benches/datetime_parse.rs
vendored
Normal file
47
clamav/libclamav_rust/.cargo/vendor/humantime/benches/datetime_parse.rs
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
#![feature(test)]
|
||||
extern crate test;
|
||||
|
||||
use chrono::{DateTime};
|
||||
use humantime::parse_rfc3339;
|
||||
|
||||
#[bench]
|
||||
fn rfc3339_humantime_seconds(b: &mut test::Bencher) {
|
||||
b.iter(|| {
|
||||
parse_rfc3339("2018-02-13T23:08:32Z").unwrap()
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn datetime_utc_parse_seconds(b: &mut test::Bencher) {
|
||||
b.iter(|| {
|
||||
DateTime::parse_from_rfc3339("2018-02-13T23:08:32Z").unwrap()
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn rfc3339_humantime_millis(b: &mut test::Bencher) {
|
||||
b.iter(|| {
|
||||
parse_rfc3339("2018-02-13T23:08:32.123Z").unwrap()
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn datetime_utc_parse_millis(b: &mut test::Bencher) {
|
||||
b.iter(|| {
|
||||
DateTime::parse_from_rfc3339("2018-02-13T23:08:32.123Z").unwrap()
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn rfc3339_humantime_nanos(b: &mut test::Bencher) {
|
||||
b.iter(|| {
|
||||
parse_rfc3339("2018-02-13T23:08:32.123456983Z").unwrap()
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn datetime_utc_parse_nanos(b: &mut test::Bencher) {
|
||||
b.iter(|| {
|
||||
DateTime::parse_from_rfc3339("2018-02-13T23:08:32.123456983Z").unwrap()
|
||||
});
|
||||
}
|
||||
8
clamav/libclamav_rust/.cargo/vendor/humantime/bulk.yaml
vendored
Normal file
8
clamav/libclamav_rust/.cargo/vendor/humantime/bulk.yaml
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
minimum-bulk: v0.4.5
|
||||
|
||||
versions:
|
||||
|
||||
- file: Cargo.toml
|
||||
block-start: ^\[package\]
|
||||
block-end: ^\[.*\]
|
||||
regex: ^version\s*=\s*"(\S+)"
|
||||
623
clamav/libclamav_rust/.cargo/vendor/humantime/src/date.rs
vendored
Normal file
623
clamav/libclamav_rust/.cargo/vendor/humantime/src/date.rs
vendored
Normal file
@@ -0,0 +1,623 @@
|
||||
use std::error::Error as StdError;
|
||||
use std::fmt;
|
||||
use std::str;
|
||||
use std::time::{SystemTime, Duration, UNIX_EPOCH};
|
||||
|
||||
#[cfg(target_os="cloudabi")]
|
||||
mod max {
|
||||
pub const SECONDS: u64 = ::std::u64::MAX / 1_000_000_000;
|
||||
#[allow(unused)]
|
||||
pub const TIMESTAMP: &'static str = "2554-07-21T23:34:33Z";
|
||||
}
|
||||
#[cfg(all(
|
||||
target_pointer_width="32",
|
||||
not(target_os="cloudabi"),
|
||||
not(target_os="windows"),
|
||||
not(all(target_arch="wasm32", not(target_os="emscripten")))
|
||||
))]
|
||||
mod max {
|
||||
pub const SECONDS: u64 = ::std::i32::MAX as u64;
|
||||
#[allow(unused)]
|
||||
pub const TIMESTAMP: &'static str = "2038-01-19T03:14:07Z";
|
||||
}
|
||||
|
||||
#[cfg(any(
|
||||
target_pointer_width="64",
|
||||
target_os="windows",
|
||||
all(target_arch="wasm32", not(target_os="emscripten")),
|
||||
))]
|
||||
mod max {
|
||||
pub const SECONDS: u64 = 253_402_300_800-1; // last second of year 9999
|
||||
#[allow(unused)]
|
||||
pub const TIMESTAMP: &str = "9999-12-31T23:59:59Z";
|
||||
}
|
||||
|
||||
/// Error parsing datetime (timestamp)
|
||||
#[derive(Debug, PartialEq, Clone, Copy)]
|
||||
pub enum Error {
|
||||
/// Numeric component is out of range
|
||||
OutOfRange,
|
||||
/// Bad character where digit is expected
|
||||
InvalidDigit,
|
||||
/// Other formatting errors
|
||||
InvalidFormat,
|
||||
}
|
||||
|
||||
impl StdError for Error {}
|
||||
|
||||
impl fmt::Display for Error {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Error::OutOfRange => write!(f, "numeric component is out of range"),
|
||||
Error::InvalidDigit => write!(f, "bad character where digit is expected"),
|
||||
Error::InvalidFormat => write!(f, "timestamp format is invalid"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
enum Precision {
|
||||
Smart,
|
||||
Seconds,
|
||||
Millis,
|
||||
Micros,
|
||||
Nanos,
|
||||
}
|
||||
|
||||
/// A wrapper type that allows you to Display a SystemTime
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Rfc3339Timestamp(SystemTime, Precision);
|
||||
|
||||
#[inline]
|
||||
fn two_digits(b1: u8, b2: u8) -> Result<u64, Error> {
|
||||
if b1 < b'0' || b2 < b'0' || b1 > b'9' || b2 > b'9' {
|
||||
return Err(Error::InvalidDigit);
|
||||
}
|
||||
Ok(((b1 - b'0')*10 + (b2 - b'0')) as u64)
|
||||
}
|
||||
|
||||
/// Parse RFC3339 timestamp `2018-02-14T00:28:07Z`
|
||||
///
|
||||
/// Supported feature: any precision of fractional
|
||||
/// digits `2018-02-14T00:28:07.133Z`.
|
||||
///
|
||||
/// Unsupported feature: localized timestamps. Only UTC is supported.
|
||||
pub fn parse_rfc3339(s: &str) -> Result<SystemTime, Error> {
|
||||
if s.len() < "2018-02-14T00:28:07Z".len() {
|
||||
return Err(Error::InvalidFormat);
|
||||
}
|
||||
let b = s.as_bytes();
|
||||
if b[10] != b'T' || b[b.len()-1] != b'Z' {
|
||||
return Err(Error::InvalidFormat);
|
||||
}
|
||||
parse_rfc3339_weak(s)
|
||||
}
|
||||
|
||||
/// Parse RFC3339-like timestamp `2018-02-14 00:28:07`
|
||||
///
|
||||
/// Supported features:
|
||||
///
|
||||
/// 1. Any precision of fractional digits `2018-02-14 00:28:07.133`.
|
||||
/// 2. Supports timestamp with or without either of `T` or `Z`
|
||||
/// 3. Anything valid for `parse_3339` is valid for this function
|
||||
///
|
||||
/// Unsupported feature: localized timestamps. Only UTC is supported, even if
|
||||
/// `Z` is not specified.
|
||||
///
|
||||
/// This function is intended to use for parsing human input. Whereas
|
||||
/// `parse_rfc3339` is for strings generated programmatically.
|
||||
pub fn parse_rfc3339_weak(s: &str) -> Result<SystemTime, Error> {
|
||||
if s.len() < "2018-02-14T00:28:07".len() {
|
||||
return Err(Error::InvalidFormat);
|
||||
}
|
||||
let b = s.as_bytes(); // for careless slicing
|
||||
if b[4] != b'-' || b[7] != b'-' || (b[10] != b'T' && b[10] != b' ') ||
|
||||
b[13] != b':' || b[16] != b':'
|
||||
{
|
||||
return Err(Error::InvalidFormat);
|
||||
}
|
||||
let year = two_digits(b[0], b[1])? * 100 + two_digits(b[2], b[3])?;
|
||||
let month = two_digits(b[5], b[6])?;
|
||||
let day = two_digits(b[8], b[9])?;
|
||||
let hour = two_digits(b[11], b[12])?;
|
||||
let minute = two_digits(b[14], b[15])?;
|
||||
let mut second = two_digits(b[17], b[18])?;
|
||||
|
||||
if year < 1970 || hour > 23 || minute > 59 || second > 60 {
|
||||
return Err(Error::OutOfRange);
|
||||
}
|
||||
// TODO(tailhook) should we check that leaps second is only on midnight ?
|
||||
if second == 60 {
|
||||
second = 59
|
||||
};
|
||||
let leap_years = ((year - 1) - 1968) / 4 - ((year - 1) - 1900) / 100 +
|
||||
((year - 1) - 1600) / 400;
|
||||
let leap = is_leap_year(year);
|
||||
let (mut ydays, mdays) = match month {
|
||||
1 => (0, 31),
|
||||
2 if leap => (31, 29),
|
||||
2 => (31, 28),
|
||||
3 => (59, 31),
|
||||
4 => (90, 30),
|
||||
5 => (120, 31),
|
||||
6 => (151, 30),
|
||||
7 => (181, 31),
|
||||
8 => (212, 31),
|
||||
9 => (243, 30),
|
||||
10 => (273, 31),
|
||||
11 => (304, 30),
|
||||
12 => (334, 31),
|
||||
_ => return Err(Error::OutOfRange),
|
||||
};
|
||||
if day > mdays || day == 0 {
|
||||
return Err(Error::OutOfRange);
|
||||
}
|
||||
ydays += day - 1;
|
||||
if leap && month > 2 {
|
||||
ydays += 1;
|
||||
}
|
||||
let days = (year - 1970) * 365 + leap_years + ydays;
|
||||
|
||||
let time = second + minute * 60 + hour * 3600;
|
||||
|
||||
let mut nanos = 0;
|
||||
let mut mult = 100_000_000;
|
||||
if b.get(19) == Some(&b'.') {
|
||||
for idx in 20..b.len() {
|
||||
if b[idx] == b'Z' {
|
||||
if idx == b.len()-1 {
|
||||
break;
|
||||
} else {
|
||||
return Err(Error::InvalidDigit);
|
||||
}
|
||||
}
|
||||
if b[idx] < b'0' || b[idx] > b'9' {
|
||||
return Err(Error::InvalidDigit);
|
||||
}
|
||||
nanos += mult * (b[idx] - b'0') as u32;
|
||||
mult /= 10;
|
||||
}
|
||||
} else if b.len() != 19 && (b.len() > 20 || b[19] != b'Z') {
|
||||
return Err(Error::InvalidFormat);
|
||||
}
|
||||
|
||||
let total_seconds = time + days * 86400;
|
||||
if total_seconds > max::SECONDS {
|
||||
return Err(Error::OutOfRange);
|
||||
}
|
||||
|
||||
Ok(UNIX_EPOCH + Duration::new(total_seconds, nanos))
|
||||
}
|
||||
|
||||
fn is_leap_year(y: u64) -> bool {
|
||||
y % 4 == 0 && (y % 100 != 0 || y % 400 == 0)
|
||||
}
|
||||
|
||||
/// Format an RFC3339 timestamp `2018-02-14T00:28:07Z`
|
||||
///
|
||||
/// This function formats timestamp with smart precision: i.e. if it has no
|
||||
/// fractional seconds, they aren't written at all. And up to nine digits if
|
||||
/// they are.
|
||||
///
|
||||
/// The value is always UTC and ignores system timezone.
|
||||
pub fn format_rfc3339(system_time: SystemTime) -> Rfc3339Timestamp {
|
||||
Rfc3339Timestamp(system_time, Precision::Smart)
|
||||
}
|
||||
|
||||
/// Format an RFC3339 timestamp `2018-02-14T00:28:07Z`
|
||||
///
|
||||
/// This format always shows timestamp without fractional seconds.
|
||||
///
|
||||
/// The value is always UTC and ignores system timezone.
|
||||
pub fn format_rfc3339_seconds(system_time: SystemTime) -> Rfc3339Timestamp {
|
||||
Rfc3339Timestamp(system_time, Precision::Seconds)
|
||||
}
|
||||
|
||||
/// Format an RFC3339 timestamp `2018-02-14T00:28:07.000Z`
|
||||
///
|
||||
/// This format always shows milliseconds even if millisecond value is zero.
|
||||
///
|
||||
/// The value is always UTC and ignores system timezone.
|
||||
pub fn format_rfc3339_millis(system_time: SystemTime) -> Rfc3339Timestamp {
|
||||
Rfc3339Timestamp(system_time, Precision::Millis)
|
||||
}
|
||||
|
||||
/// Format an RFC3339 timestamp `2018-02-14T00:28:07.000000Z`
|
||||
///
|
||||
/// This format always shows microseconds even if microsecond value is zero.
|
||||
///
|
||||
/// The value is always UTC and ignores system timezone.
|
||||
pub fn format_rfc3339_micros(system_time: SystemTime) -> Rfc3339Timestamp {
|
||||
Rfc3339Timestamp(system_time, Precision::Micros)
|
||||
}
|
||||
|
||||
/// Format an RFC3339 timestamp `2018-02-14T00:28:07.000000000Z`
|
||||
///
|
||||
/// This format always shows nanoseconds even if nanosecond value is zero.
|
||||
///
|
||||
/// The value is always UTC and ignores system timezone.
|
||||
pub fn format_rfc3339_nanos(system_time: SystemTime) -> Rfc3339Timestamp {
|
||||
Rfc3339Timestamp(system_time, Precision::Nanos)
|
||||
}
|
||||
|
||||
impl Rfc3339Timestamp {
|
||||
/// Returns a reference to the [`SystemTime`][] that is being formatted.
|
||||
pub fn get_ref(&self) -> &SystemTime {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Rfc3339Timestamp {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
use self::Precision::*;
|
||||
|
||||
let dur = self.0.duration_since(UNIX_EPOCH)
|
||||
.expect("all times should be after the epoch");
|
||||
let secs_since_epoch = dur.as_secs();
|
||||
let nanos = dur.subsec_nanos();
|
||||
|
||||
if secs_since_epoch >= 253_402_300_800 { // year 9999
|
||||
return Err(fmt::Error);
|
||||
}
|
||||
|
||||
/* 2000-03-01 (mod 400 year, immediately after feb29 */
|
||||
const LEAPOCH: i64 = 11017;
|
||||
const DAYS_PER_400Y: i64 = 365*400 + 97;
|
||||
const DAYS_PER_100Y: i64 = 365*100 + 24;
|
||||
const DAYS_PER_4Y: i64 = 365*4 + 1;
|
||||
|
||||
let days = (secs_since_epoch / 86400) as i64 - LEAPOCH;
|
||||
let secs_of_day = secs_since_epoch % 86400;
|
||||
|
||||
let mut qc_cycles = days / DAYS_PER_400Y;
|
||||
let mut remdays = days % DAYS_PER_400Y;
|
||||
|
||||
if remdays < 0 {
|
||||
remdays += DAYS_PER_400Y;
|
||||
qc_cycles -= 1;
|
||||
}
|
||||
|
||||
let mut c_cycles = remdays / DAYS_PER_100Y;
|
||||
if c_cycles == 4 { c_cycles -= 1; }
|
||||
remdays -= c_cycles * DAYS_PER_100Y;
|
||||
|
||||
let mut q_cycles = remdays / DAYS_PER_4Y;
|
||||
if q_cycles == 25 { q_cycles -= 1; }
|
||||
remdays -= q_cycles * DAYS_PER_4Y;
|
||||
|
||||
let mut remyears = remdays / 365;
|
||||
if remyears == 4 { remyears -= 1; }
|
||||
remdays -= remyears * 365;
|
||||
|
||||
let mut year = 2000 +
|
||||
remyears + 4*q_cycles + 100*c_cycles + 400*qc_cycles;
|
||||
|
||||
let months = [31,30,31,30,31,31,30,31,30,31,31,29];
|
||||
let mut mon = 0;
|
||||
for mon_len in months.iter() {
|
||||
mon += 1;
|
||||
if remdays < *mon_len {
|
||||
break;
|
||||
}
|
||||
remdays -= *mon_len;
|
||||
}
|
||||
let mday = remdays+1;
|
||||
let mon = if mon + 2 > 12 {
|
||||
year += 1;
|
||||
mon - 10
|
||||
} else {
|
||||
mon + 2
|
||||
};
|
||||
|
||||
let mut buf: [u8; 30] = [
|
||||
// Too long to write as: b"0000-00-00T00:00:00.000000000Z"
|
||||
b'0', b'0', b'0', b'0', b'-', b'0', b'0', b'-', b'0', b'0', b'T',
|
||||
b'0', b'0', b':', b'0', b'0', b':', b'0', b'0',
|
||||
b'.', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'Z',
|
||||
];
|
||||
buf[0] = b'0' + (year / 1000) as u8;
|
||||
buf[1] = b'0' + (year / 100 % 10) as u8;
|
||||
buf[2] = b'0' + (year / 10 % 10) as u8;
|
||||
buf[3] = b'0' + (year % 10) as u8;
|
||||
buf[5] = b'0' + (mon / 10) as u8;
|
||||
buf[6] = b'0' + (mon % 10) as u8;
|
||||
buf[8] = b'0' + (mday / 10) as u8;
|
||||
buf[9] = b'0' + (mday % 10) as u8;
|
||||
buf[11] = b'0' + (secs_of_day / 3600 / 10) as u8;
|
||||
buf[12] = b'0' + (secs_of_day / 3600 % 10) as u8;
|
||||
buf[14] = b'0' + (secs_of_day / 60 / 10 % 6) as u8;
|
||||
buf[15] = b'0' + (secs_of_day / 60 % 10) as u8;
|
||||
buf[17] = b'0' + (secs_of_day / 10 % 6) as u8;
|
||||
buf[18] = b'0' + (secs_of_day % 10) as u8;
|
||||
|
||||
let offset = if self.1 == Seconds || nanos == 0 && self.1 == Smart {
|
||||
buf[19] = b'Z';
|
||||
19
|
||||
} else if self.1 == Millis {
|
||||
buf[20] = b'0' + (nanos / 100_000_000) as u8;
|
||||
buf[21] = b'0' + (nanos / 10_000_000 % 10) as u8;
|
||||
buf[22] = b'0' + (nanos / 1_000_000 % 10) as u8;
|
||||
buf[23] = b'Z';
|
||||
23
|
||||
} else if self.1 == Micros {
|
||||
buf[20] = b'0' + (nanos / 100_000_000) as u8;
|
||||
buf[21] = b'0' + (nanos / 10_000_000 % 10) as u8;
|
||||
buf[22] = b'0' + (nanos / 1_000_000 % 10) as u8;
|
||||
buf[23] = b'0' + (nanos / 100_000 % 10) as u8;
|
||||
buf[24] = b'0' + (nanos / 10_000 % 10) as u8;
|
||||
buf[25] = b'0' + (nanos / 1_000 % 10) as u8;
|
||||
buf[26] = b'Z';
|
||||
26
|
||||
} else {
|
||||
buf[20] = b'0' + (nanos / 100_000_000) as u8;
|
||||
buf[21] = b'0' + (nanos / 10_000_000 % 10) as u8;
|
||||
buf[22] = b'0' + (nanos / 1_000_000 % 10) as u8;
|
||||
buf[23] = b'0' + (nanos / 100_000 % 10) as u8;
|
||||
buf[24] = b'0' + (nanos / 10_000 % 10) as u8;
|
||||
buf[25] = b'0' + (nanos / 1_000 % 10) as u8;
|
||||
buf[26] = b'0' + (nanos / 100 % 10) as u8;
|
||||
buf[27] = b'0' + (nanos / 10 % 10) as u8;
|
||||
buf[28] = b'0' + (nanos / 1 % 10) as u8;
|
||||
// 29th is 'Z'
|
||||
29
|
||||
};
|
||||
|
||||
// we know our chars are all ascii
|
||||
f.write_str(str::from_utf8(&buf[..=offset]).expect("Conversion to utf8 failed"))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use std::str::from_utf8;
|
||||
use std::time::{UNIX_EPOCH, SystemTime, Duration};
|
||||
|
||||
use rand::Rng;
|
||||
|
||||
use super::{parse_rfc3339, parse_rfc3339_weak, format_rfc3339};
|
||||
use super::{format_rfc3339_millis, format_rfc3339_micros};
|
||||
use super::{format_rfc3339_nanos};
|
||||
use super::max;
|
||||
|
||||
fn from_sec(sec: u64) -> (String, SystemTime) {
|
||||
let s = time::at_utc(time::Timespec { sec: sec as i64, nsec: 0 })
|
||||
.rfc3339().to_string();
|
||||
let time = UNIX_EPOCH + Duration::new(sec, 0);
|
||||
(s, time)
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(all(target_pointer_width="32", target_os="linux"))]
|
||||
fn year_after_2038_fails_gracefully() {
|
||||
// next second
|
||||
assert_eq!(parse_rfc3339("2038-01-19T03:14:08Z").unwrap_err(),
|
||||
super::Error::OutOfRange);
|
||||
assert_eq!(parse_rfc3339("9999-12-31T23:59:59Z").unwrap_err(),
|
||||
super::Error::OutOfRange);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn smoke_tests_parse() {
|
||||
assert_eq!(parse_rfc3339("1970-01-01T00:00:00Z").unwrap(),
|
||||
UNIX_EPOCH + Duration::new(0, 0));
|
||||
assert_eq!(parse_rfc3339("1970-01-01T00:00:01Z").unwrap(),
|
||||
UNIX_EPOCH + Duration::new(1, 0));
|
||||
assert_eq!(parse_rfc3339("2018-02-13T23:08:32Z").unwrap(),
|
||||
UNIX_EPOCH + Duration::new(1_518_563_312, 0));
|
||||
assert_eq!(parse_rfc3339("2012-01-01T00:00:00Z").unwrap(),
|
||||
UNIX_EPOCH + Duration::new(1_325_376_000, 0));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn smoke_tests_format() {
|
||||
assert_eq!(
|
||||
format_rfc3339(UNIX_EPOCH + Duration::new(0, 0)).to_string(),
|
||||
"1970-01-01T00:00:00Z");
|
||||
assert_eq!(
|
||||
format_rfc3339(UNIX_EPOCH + Duration::new(1, 0)).to_string(),
|
||||
"1970-01-01T00:00:01Z");
|
||||
assert_eq!(
|
||||
format_rfc3339(UNIX_EPOCH + Duration::new(1_518_563_312, 0)).to_string(),
|
||||
"2018-02-13T23:08:32Z");
|
||||
assert_eq!(
|
||||
format_rfc3339(UNIX_EPOCH + Duration::new(1_325_376_000, 0)).to_string(),
|
||||
"2012-01-01T00:00:00Z");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn smoke_tests_format_millis() {
|
||||
assert_eq!(
|
||||
format_rfc3339_millis(UNIX_EPOCH +
|
||||
Duration::new(0, 0)).to_string(),
|
||||
"1970-01-01T00:00:00.000Z");
|
||||
assert_eq!(
|
||||
format_rfc3339_millis(UNIX_EPOCH +
|
||||
Duration::new(1_518_563_312, 123_000_000)).to_string(),
|
||||
"2018-02-13T23:08:32.123Z");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn smoke_tests_format_micros() {
|
||||
assert_eq!(
|
||||
format_rfc3339_micros(UNIX_EPOCH +
|
||||
Duration::new(0, 0)).to_string(),
|
||||
"1970-01-01T00:00:00.000000Z");
|
||||
assert_eq!(
|
||||
format_rfc3339_micros(UNIX_EPOCH +
|
||||
Duration::new(1_518_563_312, 123_000_000)).to_string(),
|
||||
"2018-02-13T23:08:32.123000Z");
|
||||
assert_eq!(
|
||||
format_rfc3339_micros(UNIX_EPOCH +
|
||||
Duration::new(1_518_563_312, 456_123_000)).to_string(),
|
||||
"2018-02-13T23:08:32.456123Z");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn smoke_tests_format_nanos() {
|
||||
assert_eq!(
|
||||
format_rfc3339_nanos(UNIX_EPOCH +
|
||||
Duration::new(0, 0)).to_string(),
|
||||
"1970-01-01T00:00:00.000000000Z");
|
||||
assert_eq!(
|
||||
format_rfc3339_nanos(UNIX_EPOCH +
|
||||
Duration::new(1_518_563_312, 123_000_000)).to_string(),
|
||||
"2018-02-13T23:08:32.123000000Z");
|
||||
assert_eq!(
|
||||
format_rfc3339_nanos(UNIX_EPOCH +
|
||||
Duration::new(1_518_563_312, 789_456_123)).to_string(),
|
||||
"2018-02-13T23:08:32.789456123Z");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn upper_bound() {
|
||||
let max = UNIX_EPOCH + Duration::new(max::SECONDS, 0);
|
||||
assert_eq!(parse_rfc3339(&max::TIMESTAMP).unwrap(), max);
|
||||
assert_eq!(format_rfc3339(max).to_string(), max::TIMESTAMP);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn leap_second() {
|
||||
assert_eq!(parse_rfc3339("2016-12-31T23:59:60Z").unwrap(),
|
||||
UNIX_EPOCH + Duration::new(1_483_228_799, 0));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn first_731_days() {
|
||||
let year_start = 0; // 1970
|
||||
for day in 0..= 365 * 2 { // scan leap year and non-leap year
|
||||
let (s, time) = from_sec(year_start + day * 86400);
|
||||
assert_eq!(parse_rfc3339(&s).unwrap(), time);
|
||||
assert_eq!(format_rfc3339(time).to_string(), s);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn the_731_consecutive_days() {
|
||||
let year_start = 1_325_376_000; // 2012
|
||||
for day in 0..= 365 * 2 { // scan leap year and non-leap year
|
||||
let (s, time) = from_sec(year_start + day * 86400);
|
||||
assert_eq!(parse_rfc3339(&s).unwrap(), time);
|
||||
assert_eq!(format_rfc3339(time).to_string(), s);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn all_86400_seconds() {
|
||||
let day_start = 1_325_376_000;
|
||||
for second in 0..86400 { // scan leap year and non-leap year
|
||||
let (s, time) = from_sec(day_start + second);
|
||||
assert_eq!(parse_rfc3339(&s).unwrap(), time);
|
||||
assert_eq!(format_rfc3339(time).to_string(), s);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn random_past() {
|
||||
let upper = SystemTime::now().duration_since(UNIX_EPOCH).unwrap()
|
||||
.as_secs();
|
||||
for _ in 0..10000 {
|
||||
let sec = rand::thread_rng().gen_range(0, upper);
|
||||
let (s, time) = from_sec(sec);
|
||||
assert_eq!(parse_rfc3339(&s).unwrap(), time);
|
||||
assert_eq!(format_rfc3339(time).to_string(), s);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn random_wide_range() {
|
||||
for _ in 0..100_000 {
|
||||
let sec = rand::thread_rng().gen_range(0, max::SECONDS);
|
||||
let (s, time) = from_sec(sec);
|
||||
assert_eq!(parse_rfc3339(&s).unwrap(), time);
|
||||
assert_eq!(format_rfc3339(time).to_string(), s);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn milliseconds() {
|
||||
assert_eq!(parse_rfc3339("1970-01-01T00:00:00.123Z").unwrap(),
|
||||
UNIX_EPOCH + Duration::new(0, 123_000_000));
|
||||
assert_eq!(format_rfc3339(UNIX_EPOCH + Duration::new(0, 123_000_000))
|
||||
.to_string(), "1970-01-01T00:00:00.123000000Z");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected="OutOfRange")]
|
||||
fn zero_month() {
|
||||
parse_rfc3339("1970-00-01T00:00:00Z").unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected="OutOfRange")]
|
||||
fn big_month() {
|
||||
parse_rfc3339("1970-32-01T00:00:00Z").unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected="OutOfRange")]
|
||||
fn zero_day() {
|
||||
parse_rfc3339("1970-01-00T00:00:00Z").unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected="OutOfRange")]
|
||||
fn big_day() {
|
||||
parse_rfc3339("1970-12-35T00:00:00Z").unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected="OutOfRange")]
|
||||
fn big_day2() {
|
||||
parse_rfc3339("1970-02-30T00:00:00Z").unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected="OutOfRange")]
|
||||
fn big_second() {
|
||||
parse_rfc3339("1970-12-30T00:00:78Z").unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected="OutOfRange")]
|
||||
fn big_minute() {
|
||||
parse_rfc3339("1970-12-30T00:78:00Z").unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected="OutOfRange")]
|
||||
fn big_hour() {
|
||||
parse_rfc3339("1970-12-30T24:00:00Z").unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn break_data() {
|
||||
for pos in 0.."2016-12-31T23:59:60Z".len() {
|
||||
let mut s = b"2016-12-31T23:59:60Z".to_vec();
|
||||
s[pos] = b'x';
|
||||
parse_rfc3339(from_utf8(&s).unwrap()).unwrap_err();
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn weak_smoke_tests() {
|
||||
assert_eq!(parse_rfc3339_weak("1970-01-01 00:00:00").unwrap(),
|
||||
UNIX_EPOCH + Duration::new(0, 0));
|
||||
parse_rfc3339("1970-01-01 00:00:00").unwrap_err();
|
||||
|
||||
assert_eq!(parse_rfc3339_weak("1970-01-01 00:00:00.000123").unwrap(),
|
||||
UNIX_EPOCH + Duration::new(0, 123_000));
|
||||
parse_rfc3339("1970-01-01 00:00:00.000123").unwrap_err();
|
||||
|
||||
assert_eq!(parse_rfc3339_weak("1970-01-01T00:00:00.000123").unwrap(),
|
||||
UNIX_EPOCH + Duration::new(0, 123_000));
|
||||
parse_rfc3339("1970-01-01T00:00:00.000123").unwrap_err();
|
||||
|
||||
assert_eq!(parse_rfc3339_weak("1970-01-01 00:00:00.000123Z").unwrap(),
|
||||
UNIX_EPOCH + Duration::new(0, 123_000));
|
||||
parse_rfc3339("1970-01-01 00:00:00.000123Z").unwrap_err();
|
||||
|
||||
assert_eq!(parse_rfc3339_weak("1970-01-01 00:00:00Z").unwrap(),
|
||||
UNIX_EPOCH + Duration::new(0, 0));
|
||||
parse_rfc3339("1970-01-01 00:00:00Z").unwrap_err();
|
||||
}
|
||||
}
|
||||
456
clamav/libclamav_rust/.cargo/vendor/humantime/src/duration.rs
vendored
Normal file
456
clamav/libclamav_rust/.cargo/vendor/humantime/src/duration.rs
vendored
Normal file
@@ -0,0 +1,456 @@
|
||||
use std::error::Error as StdError;
|
||||
use std::fmt;
|
||||
use std::str::Chars;
|
||||
use std::time::Duration;
|
||||
|
||||
/// Error parsing human-friendly duration
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub enum Error {
|
||||
/// Invalid character during parsing
|
||||
///
|
||||
/// More specifically anything that is not alphanumeric is prohibited
|
||||
///
|
||||
/// The field is an byte offset of the character in the string.
|
||||
InvalidCharacter(usize),
|
||||
/// Non-numeric value where number is expected
|
||||
///
|
||||
/// This usually means that either time unit is broken into words,
|
||||
/// e.g. `m sec` instead of `msec`, or just number is omitted,
|
||||
/// for example `2 hours min` instead of `2 hours 1 min`
|
||||
///
|
||||
/// The field is an byte offset of the errorneous character
|
||||
/// in the string.
|
||||
NumberExpected(usize),
|
||||
/// Unit in the number is not one of allowed units
|
||||
///
|
||||
/// See documentation of `parse_duration` for the list of supported
|
||||
/// time units.
|
||||
///
|
||||
/// The two fields are start and end (exclusive) of the slice from
|
||||
/// the original string, containing errorneous value
|
||||
UnknownUnit {
|
||||
/// Start of the invalid unit inside the original string
|
||||
start: usize,
|
||||
/// End of the invalid unit inside the original string
|
||||
end: usize,
|
||||
/// The unit verbatim
|
||||
unit: String,
|
||||
/// A number associated with the unit
|
||||
value: u64,
|
||||
},
|
||||
/// The numeric value is too large
|
||||
///
|
||||
/// Usually this means value is too large to be useful. If user writes
|
||||
/// data in subsecond units, then the maximum is about 3k years. When
|
||||
/// using seconds, or larger units, the limit is even larger.
|
||||
NumberOverflow,
|
||||
/// The value was an empty string (or consists only whitespace)
|
||||
Empty,
|
||||
}
|
||||
|
||||
impl StdError for Error {}
|
||||
|
||||
impl fmt::Display for Error {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Error::InvalidCharacter(offset) => write!(f, "invalid character at {}", offset),
|
||||
Error::NumberExpected(offset) => write!(f, "expected number at {}", offset),
|
||||
Error::UnknownUnit { unit, value, .. } if &unit == &"" => {
|
||||
write!(f,
|
||||
"time unit needed, for example {0}sec or {0}ms",
|
||||
value,
|
||||
)
|
||||
}
|
||||
Error::UnknownUnit { unit, .. } => {
|
||||
write!(
|
||||
f,
|
||||
"unknown time unit {:?}, \
|
||||
supported units: ns, us, ms, sec, min, hours, days, \
|
||||
weeks, months, years (and few variations)",
|
||||
unit
|
||||
)
|
||||
}
|
||||
Error::NumberOverflow => write!(f, "number is too large"),
|
||||
Error::Empty => write!(f, "value was empty"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A wrapper type that allows you to Display a Duration
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct FormattedDuration(Duration);
|
||||
|
||||
trait OverflowOp: Sized {
|
||||
fn mul(self, other: Self) -> Result<Self, Error>;
|
||||
fn add(self, other: Self) -> Result<Self, Error>;
|
||||
}
|
||||
|
||||
impl OverflowOp for u64 {
|
||||
fn mul(self, other: Self) -> Result<Self, Error> {
|
||||
self.checked_mul(other).ok_or(Error::NumberOverflow)
|
||||
}
|
||||
fn add(self, other: Self) -> Result<Self, Error> {
|
||||
self.checked_add(other).ok_or(Error::NumberOverflow)
|
||||
}
|
||||
}
|
||||
|
||||
struct Parser<'a> {
|
||||
iter: Chars<'a>,
|
||||
src: &'a str,
|
||||
current: (u64, u64),
|
||||
}
|
||||
|
||||
impl<'a> Parser<'a> {
|
||||
fn off(&self) -> usize {
|
||||
self.src.len() - self.iter.as_str().len()
|
||||
}
|
||||
|
||||
fn parse_first_char(&mut self) -> Result<Option<u64>, Error> {
|
||||
let off = self.off();
|
||||
for c in self.iter.by_ref() {
|
||||
match c {
|
||||
'0'..='9' => {
|
||||
return Ok(Some(c as u64 - '0' as u64));
|
||||
}
|
||||
c if c.is_whitespace() => continue,
|
||||
_ => {
|
||||
return Err(Error::NumberExpected(off));
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(None)
|
||||
}
|
||||
fn parse_unit(&mut self, n: u64, start: usize, end: usize)
|
||||
-> Result<(), Error>
|
||||
{
|
||||
let (mut sec, nsec) = match &self.src[start..end] {
|
||||
"nanos" | "nsec" | "ns" => (0u64, n),
|
||||
"usec" | "us" => (0u64, n.mul(1000)?),
|
||||
"millis" | "msec" | "ms" => (0u64, n.mul(1_000_000)?),
|
||||
"seconds" | "second" | "secs" | "sec" | "s" => (n, 0),
|
||||
"minutes" | "minute" | "min" | "mins" | "m"
|
||||
=> (n.mul(60)?, 0),
|
||||
"hours" | "hour" | "hr" | "hrs" | "h" => (n.mul(3600)?, 0),
|
||||
"days" | "day" | "d" => (n.mul(86400)?, 0),
|
||||
"weeks" | "week" | "w" => (n.mul(86400*7)?, 0),
|
||||
"months" | "month" | "M" => (n.mul(2_630_016)?, 0), // 30.44d
|
||||
"years" | "year" | "y" => (n.mul(31_557_600)?, 0), // 365.25d
|
||||
_ => {
|
||||
return Err(Error::UnknownUnit {
|
||||
start, end,
|
||||
unit: self.src[start..end].to_string(),
|
||||
value: n,
|
||||
});
|
||||
}
|
||||
};
|
||||
let mut nsec = self.current.1.add(nsec)?;
|
||||
if nsec > 1_000_000_000 {
|
||||
sec = sec.add(nsec / 1_000_000_000)?;
|
||||
nsec %= 1_000_000_000;
|
||||
}
|
||||
sec = self.current.0.add(sec)?;
|
||||
self.current = (sec, nsec);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn parse(mut self) -> Result<Duration, Error> {
|
||||
let mut n = self.parse_first_char()?.ok_or(Error::Empty)?;
|
||||
'outer: loop {
|
||||
let mut off = self.off();
|
||||
while let Some(c) = self.iter.next() {
|
||||
match c {
|
||||
'0'..='9' => {
|
||||
n = n.checked_mul(10)
|
||||
.and_then(|x| x.checked_add(c as u64 - '0' as u64))
|
||||
.ok_or(Error::NumberOverflow)?;
|
||||
}
|
||||
c if c.is_whitespace() => {}
|
||||
'a'..='z' | 'A'..='Z' => {
|
||||
break;
|
||||
}
|
||||
_ => {
|
||||
return Err(Error::InvalidCharacter(off));
|
||||
}
|
||||
}
|
||||
off = self.off();
|
||||
}
|
||||
let start = off;
|
||||
let mut off = self.off();
|
||||
while let Some(c) = self.iter.next() {
|
||||
match c {
|
||||
'0'..='9' => {
|
||||
self.parse_unit(n, start, off)?;
|
||||
n = c as u64 - '0' as u64;
|
||||
continue 'outer;
|
||||
}
|
||||
c if c.is_whitespace() => break,
|
||||
'a'..='z' | 'A'..='Z' => {}
|
||||
_ => {
|
||||
return Err(Error::InvalidCharacter(off));
|
||||
}
|
||||
}
|
||||
off = self.off();
|
||||
}
|
||||
self.parse_unit(n, start, off)?;
|
||||
n = match self.parse_first_char()? {
|
||||
Some(n) => n,
|
||||
None => return Ok(
|
||||
Duration::new(self.current.0, self.current.1 as u32)),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// Parse duration object `1hour 12min 5s`
|
||||
///
|
||||
/// The duration object is a concatenation of time spans. Where each time
|
||||
/// span is an integer number and a suffix. Supported suffixes:
|
||||
///
|
||||
/// * `nsec`, `ns` -- nanoseconds
|
||||
/// * `usec`, `us` -- microseconds
|
||||
/// * `msec`, `ms` -- milliseconds
|
||||
/// * `seconds`, `second`, `sec`, `s`
|
||||
/// * `minutes`, `minute`, `min`, `m`
|
||||
/// * `hours`, `hour`, `hr`, `h`
|
||||
/// * `days`, `day`, `d`
|
||||
/// * `weeks`, `week`, `w`
|
||||
/// * `months`, `month`, `M` -- defined as 30.44 days
|
||||
/// * `years`, `year`, `y` -- defined as 365.25 days
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::time::Duration;
|
||||
/// use humantime::parse_duration;
|
||||
///
|
||||
/// assert_eq!(parse_duration("2h 37min"), Ok(Duration::new(9420, 0)));
|
||||
/// assert_eq!(parse_duration("32ms"), Ok(Duration::new(0, 32_000_000)));
|
||||
/// ```
|
||||
pub fn parse_duration(s: &str) -> Result<Duration, Error> {
|
||||
Parser {
|
||||
iter: s.chars(),
|
||||
src: s,
|
||||
current: (0, 0),
|
||||
}.parse()
|
||||
}
|
||||
|
||||
/// Formats duration into a human-readable string
|
||||
///
|
||||
/// Note: this format is guaranteed to have same value when using
|
||||
/// parse_duration, but we can change some details of the exact composition
|
||||
/// of the value.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::time::Duration;
|
||||
/// use humantime::format_duration;
|
||||
///
|
||||
/// let val1 = Duration::new(9420, 0);
|
||||
/// assert_eq!(format_duration(val1).to_string(), "2h 37m");
|
||||
/// let val2 = Duration::new(0, 32_000_000);
|
||||
/// assert_eq!(format_duration(val2).to_string(), "32ms");
|
||||
/// ```
|
||||
pub fn format_duration(val: Duration) -> FormattedDuration {
|
||||
FormattedDuration(val)
|
||||
}
|
||||
|
||||
fn item_plural(f: &mut fmt::Formatter, started: &mut bool,
|
||||
name: &str, value: u64)
|
||||
-> fmt::Result
|
||||
{
|
||||
if value > 0 {
|
||||
if *started {
|
||||
f.write_str(" ")?;
|
||||
}
|
||||
write!(f, "{}{}", value, name)?;
|
||||
if value > 1 {
|
||||
f.write_str("s")?;
|
||||
}
|
||||
*started = true;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
fn item(f: &mut fmt::Formatter, started: &mut bool, name: &str, value: u32)
|
||||
-> fmt::Result
|
||||
{
|
||||
if value > 0 {
|
||||
if *started {
|
||||
f.write_str(" ")?;
|
||||
}
|
||||
write!(f, "{}{}", value, name)?;
|
||||
*started = true;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
impl FormattedDuration {
|
||||
/// Returns a reference to the [`Duration`][] that is being formatted.
|
||||
pub fn get_ref(&self) -> &Duration {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for FormattedDuration {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let secs = self.0.as_secs();
|
||||
let nanos = self.0.subsec_nanos();
|
||||
|
||||
if secs == 0 && nanos == 0 {
|
||||
f.write_str("0s")?;
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let years = secs / 31_557_600; // 365.25d
|
||||
let ydays = secs % 31_557_600;
|
||||
let months = ydays / 2_630_016; // 30.44d
|
||||
let mdays = ydays % 2_630_016;
|
||||
let days = mdays / 86400;
|
||||
let day_secs = mdays % 86400;
|
||||
let hours = day_secs / 3600;
|
||||
let minutes = day_secs % 3600 / 60;
|
||||
let seconds = day_secs % 60;
|
||||
|
||||
let millis = nanos / 1_000_000;
|
||||
let micros = nanos / 1000 % 1000;
|
||||
let nanosec = nanos % 1000;
|
||||
|
||||
let ref mut started = false;
|
||||
item_plural(f, started, "year", years)?;
|
||||
item_plural(f, started, "month", months)?;
|
||||
item_plural(f, started, "day", days)?;
|
||||
item(f, started, "h", hours as u32)?;
|
||||
item(f, started, "m", minutes as u32)?;
|
||||
item(f, started, "s", seconds as u32)?;
|
||||
item(f, started, "ms", millis)?;
|
||||
item(f, started, "us", micros)?;
|
||||
item(f, started, "ns", nanosec)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use std::time::Duration;
|
||||
|
||||
use rand::Rng;
|
||||
|
||||
use super::{parse_duration, format_duration};
|
||||
use super::Error;
|
||||
|
||||
#[test]
|
||||
#[allow(clippy::cognitive_complexity)]
|
||||
fn test_units() {
|
||||
assert_eq!(parse_duration("17nsec"), Ok(Duration::new(0, 17)));
|
||||
assert_eq!(parse_duration("17nanos"), Ok(Duration::new(0, 17)));
|
||||
assert_eq!(parse_duration("33ns"), Ok(Duration::new(0, 33)));
|
||||
assert_eq!(parse_duration("3usec"), Ok(Duration::new(0, 3000)));
|
||||
assert_eq!(parse_duration("78us"), Ok(Duration::new(0, 78000)));
|
||||
assert_eq!(parse_duration("31msec"), Ok(Duration::new(0, 31_000_000)));
|
||||
assert_eq!(parse_duration("31millis"), Ok(Duration::new(0, 31_000_000)));
|
||||
assert_eq!(parse_duration("6ms"), Ok(Duration::new(0, 6_000_000)));
|
||||
assert_eq!(parse_duration("3000s"), Ok(Duration::new(3000, 0)));
|
||||
assert_eq!(parse_duration("300sec"), Ok(Duration::new(300, 0)));
|
||||
assert_eq!(parse_duration("300secs"), Ok(Duration::new(300, 0)));
|
||||
assert_eq!(parse_duration("50seconds"), Ok(Duration::new(50, 0)));
|
||||
assert_eq!(parse_duration("1second"), Ok(Duration::new(1, 0)));
|
||||
assert_eq!(parse_duration("100m"), Ok(Duration::new(6000, 0)));
|
||||
assert_eq!(parse_duration("12min"), Ok(Duration::new(720, 0)));
|
||||
assert_eq!(parse_duration("12mins"), Ok(Duration::new(720, 0)));
|
||||
assert_eq!(parse_duration("1minute"), Ok(Duration::new(60, 0)));
|
||||
assert_eq!(parse_duration("7minutes"), Ok(Duration::new(420, 0)));
|
||||
assert_eq!(parse_duration("2h"), Ok(Duration::new(7200, 0)));
|
||||
assert_eq!(parse_duration("7hr"), Ok(Duration::new(25200, 0)));
|
||||
assert_eq!(parse_duration("7hrs"), Ok(Duration::new(25200, 0)));
|
||||
assert_eq!(parse_duration("1hour"), Ok(Duration::new(3600, 0)));
|
||||
assert_eq!(parse_duration("24hours"), Ok(Duration::new(86400, 0)));
|
||||
assert_eq!(parse_duration("1day"), Ok(Duration::new(86400, 0)));
|
||||
assert_eq!(parse_duration("2days"), Ok(Duration::new(172_800, 0)));
|
||||
assert_eq!(parse_duration("365d"), Ok(Duration::new(31_536_000, 0)));
|
||||
assert_eq!(parse_duration("1week"), Ok(Duration::new(604_800, 0)));
|
||||
assert_eq!(parse_duration("7weeks"), Ok(Duration::new(4_233_600, 0)));
|
||||
assert_eq!(parse_duration("52w"), Ok(Duration::new(31_449_600, 0)));
|
||||
assert_eq!(parse_duration("1month"), Ok(Duration::new(2_630_016, 0)));
|
||||
assert_eq!(parse_duration("3months"), Ok(Duration::new(3*2_630_016, 0)));
|
||||
assert_eq!(parse_duration("12M"), Ok(Duration::new(31_560_192, 0)));
|
||||
assert_eq!(parse_duration("1year"), Ok(Duration::new(31_557_600, 0)));
|
||||
assert_eq!(parse_duration("7years"), Ok(Duration::new(7*31_557_600, 0)));
|
||||
assert_eq!(parse_duration("17y"), Ok(Duration::new(536_479_200, 0)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_combo() {
|
||||
assert_eq!(parse_duration("20 min 17 nsec "), Ok(Duration::new(1200, 17)));
|
||||
assert_eq!(parse_duration("2h 15m"), Ok(Duration::new(8100, 0)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn all_86400_seconds() {
|
||||
for second in 0..86400 { // scan leap year and non-leap year
|
||||
let d = Duration::new(second, 0);
|
||||
assert_eq!(d,
|
||||
parse_duration(&format_duration(d).to_string()).unwrap());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn random_second() {
|
||||
for _ in 0..10000 {
|
||||
let sec = rand::thread_rng().gen_range(0, 253_370_764_800);
|
||||
let d = Duration::new(sec, 0);
|
||||
assert_eq!(d,
|
||||
parse_duration(&format_duration(d).to_string()).unwrap());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn random_any() {
|
||||
for _ in 0..10000 {
|
||||
let sec = rand::thread_rng().gen_range(0, 253_370_764_800);
|
||||
let nanos = rand::thread_rng().gen_range(0, 1_000_000_000);
|
||||
let d = Duration::new(sec, nanos);
|
||||
assert_eq!(d,
|
||||
parse_duration(&format_duration(d).to_string()).unwrap());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_overlow() {
|
||||
// Overflow on subseconds is earlier because of how we do conversion
|
||||
// we could fix it, but I don't see any good reason for this
|
||||
assert_eq!(parse_duration("100000000000000000000ns"),
|
||||
Err(Error::NumberOverflow));
|
||||
assert_eq!(parse_duration("100000000000000000us"),
|
||||
Err(Error::NumberOverflow));
|
||||
assert_eq!(parse_duration("100000000000000ms"),
|
||||
Err(Error::NumberOverflow));
|
||||
|
||||
assert_eq!(parse_duration("100000000000000000000s"),
|
||||
Err(Error::NumberOverflow));
|
||||
assert_eq!(parse_duration("10000000000000000000m"),
|
||||
Err(Error::NumberOverflow));
|
||||
assert_eq!(parse_duration("1000000000000000000h"),
|
||||
Err(Error::NumberOverflow));
|
||||
assert_eq!(parse_duration("100000000000000000d"),
|
||||
Err(Error::NumberOverflow));
|
||||
assert_eq!(parse_duration("10000000000000000w"),
|
||||
Err(Error::NumberOverflow));
|
||||
assert_eq!(parse_duration("1000000000000000M"),
|
||||
Err(Error::NumberOverflow));
|
||||
assert_eq!(parse_duration("10000000000000y"),
|
||||
Err(Error::NumberOverflow));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_nice_error_message() {
|
||||
assert_eq!(parse_duration("123").unwrap_err().to_string(),
|
||||
"time unit needed, for example 123sec or 123ms");
|
||||
assert_eq!(parse_duration("10 months 1").unwrap_err().to_string(),
|
||||
"time unit needed, for example 1sec or 1ms");
|
||||
assert_eq!(parse_duration("10nights").unwrap_err().to_string(),
|
||||
"unknown time unit \"nights\", supported units: \
|
||||
ns, us, ms, sec, min, hours, days, weeks, months, \
|
||||
years (and few variations)");
|
||||
}
|
||||
}
|
||||
34
clamav/libclamav_rust/.cargo/vendor/humantime/src/lib.rs
vendored
Normal file
34
clamav/libclamav_rust/.cargo/vendor/humantime/src/lib.rs
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
//! Human-friendly time parser and formatter
|
||||
//!
|
||||
//! Features:
|
||||
//!
|
||||
//! * Parses durations in free form like `15days 2min 2s`
|
||||
//! * Formats durations in similar form `2years 2min 12us`
|
||||
//! * Parses and formats timestamp in `rfc3339` format: `2018-01-01T12:53:00Z`
|
||||
//! * Parses timestamps in a weaker format: `2018-01-01 12:53:00`
|
||||
//!
|
||||
//! Timestamp parsing/formatting is super-fast because format is basically
|
||||
//! fixed.
|
||||
//!
|
||||
//! See [humantime-serde] for serde integration (previous crate [serde-humantime] looks unmaintained).
|
||||
//!
|
||||
//! [serde-humantime]: https://docs.rs/serde-humantime/0.1.1/serde_humantime/
|
||||
//! [humantime-serde]: https://docs.rs/humantime-serde
|
||||
|
||||
#![forbid(unsafe_code)]
|
||||
#![warn(missing_debug_implementations)]
|
||||
#![warn(missing_docs)]
|
||||
|
||||
mod duration;
|
||||
mod wrapper;
|
||||
mod date;
|
||||
|
||||
pub use self::duration::{parse_duration, Error as DurationError};
|
||||
pub use self::duration::{format_duration, FormattedDuration};
|
||||
pub use self::wrapper::{Duration, Timestamp};
|
||||
pub use self::date::{parse_rfc3339, parse_rfc3339_weak, Error as TimestampError};
|
||||
pub use self::date::{
|
||||
format_rfc3339, format_rfc3339_micros, format_rfc3339_millis, format_rfc3339_nanos,
|
||||
format_rfc3339_seconds,
|
||||
};
|
||||
pub use self::date::{Rfc3339Timestamp};
|
||||
107
clamav/libclamav_rust/.cargo/vendor/humantime/src/wrapper.rs
vendored
Normal file
107
clamav/libclamav_rust/.cargo/vendor/humantime/src/wrapper.rs
vendored
Normal file
@@ -0,0 +1,107 @@
|
||||
use std::str::FromStr;
|
||||
use std::ops::Deref;
|
||||
use std::fmt;
|
||||
use std::time::{Duration as StdDuration, SystemTime};
|
||||
|
||||
use crate::duration::{self, parse_duration, format_duration};
|
||||
use crate::date::{self, parse_rfc3339_weak, format_rfc3339};
|
||||
|
||||
/// A wrapper for duration that has `FromStr` implementation
|
||||
///
|
||||
/// This is useful if you want to use it somewhere where `FromStr` is
|
||||
/// expected.
|
||||
///
|
||||
/// See `parse_duration` for the description of the format.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// use std::time::Duration;
|
||||
/// let x: Duration;
|
||||
/// x = "12h 5min 2ns".parse::<humantime::Duration>().unwrap().into();
|
||||
/// assert_eq!(x, Duration::new(12*3600 + 5*60, 2))
|
||||
/// ```
|
||||
///
|
||||
#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)]
|
||||
pub struct Duration(StdDuration);
|
||||
|
||||
/// A wrapper for SystemTime that has `FromStr` implementation
|
||||
///
|
||||
/// This is useful if you want to use it somewhere where `FromStr` is
|
||||
/// expected.
|
||||
///
|
||||
/// See `parse_rfc3339_weak` for the description of the format. The "weak"
|
||||
/// format is used as it's more pemissive for human input as this is the
|
||||
/// expected use of the type (e.g. command-line parsing).
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// use std::time::SystemTime;
|
||||
/// let x: SystemTime;
|
||||
/// x = "2018-02-16T00:31:37Z".parse::<humantime::Timestamp>().unwrap().into();
|
||||
/// assert_eq!(humantime::format_rfc3339(x).to_string(), "2018-02-16T00:31:37Z");
|
||||
/// ```
|
||||
///
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
pub struct Timestamp(SystemTime);
|
||||
|
||||
impl AsRef<StdDuration> for Duration {
|
||||
fn as_ref(&self) -> &StdDuration { &self.0 }
|
||||
}
|
||||
|
||||
impl Deref for Duration {
|
||||
type Target = StdDuration;
|
||||
fn deref(&self) -> &StdDuration { &self.0 }
|
||||
}
|
||||
|
||||
impl Into<StdDuration> for Duration {
|
||||
fn into(self) -> StdDuration { self.0 }
|
||||
}
|
||||
|
||||
impl From<StdDuration> for Duration {
|
||||
fn from(dur: StdDuration) -> Duration { Duration(dur) }
|
||||
}
|
||||
|
||||
impl FromStr for Duration {
|
||||
type Err = duration::Error;
|
||||
fn from_str(s: &str) -> Result<Duration, Self::Err> {
|
||||
parse_duration(s).map(Duration)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Duration {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
format_duration(self.0).fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<SystemTime> for Timestamp {
|
||||
fn as_ref(&self) -> &SystemTime { &self.0 }
|
||||
}
|
||||
|
||||
impl Deref for Timestamp {
|
||||
type Target = SystemTime;
|
||||
fn deref(&self) -> &SystemTime { &self.0 }
|
||||
}
|
||||
|
||||
impl Into<SystemTime> for Timestamp {
|
||||
fn into(self) -> SystemTime { self.0 }
|
||||
}
|
||||
|
||||
impl From<SystemTime> for Timestamp {
|
||||
fn from(dur: SystemTime) -> Timestamp { Timestamp(dur) }
|
||||
}
|
||||
|
||||
impl FromStr for Timestamp {
|
||||
type Err = date::Error;
|
||||
fn from_str(s: &str) -> Result<Timestamp, Self::Err> {
|
||||
parse_rfc3339_weak(s).map(Timestamp)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Timestamp {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
format_rfc3339(self.0).fmt(f)
|
||||
}
|
||||
}
|
||||
92
clamav/libclamav_rust/.cargo/vendor/humantime/vagga.yaml
vendored
Normal file
92
clamav/libclamav_rust/.cargo/vendor/humantime/vagga.yaml
vendored
Normal file
@@ -0,0 +1,92 @@
|
||||
commands:
|
||||
|
||||
cargo: !Command
|
||||
description: Run any cargo command
|
||||
container: ubuntu
|
||||
run: [cargo]
|
||||
|
||||
make: !Command
|
||||
description: Build the library
|
||||
container: ubuntu
|
||||
run: [cargo, build]
|
||||
|
||||
test64: !Command
|
||||
description: Test the 64bit library
|
||||
container: ubuntu
|
||||
environ: { RUST_BACKTRACE: 1 }
|
||||
run: [cargo, test]
|
||||
|
||||
test32: !Command
|
||||
description: Test the 32bit library
|
||||
container: ubuntu32
|
||||
environ: { RUST_BACKTRACE: 1 }
|
||||
run: [cargo, test]
|
||||
|
||||
test: !Command
|
||||
description: Test the 64bit library
|
||||
container: ubuntu
|
||||
environ: { RUST_BACKTRACE: 1 }
|
||||
prerequisites: [test64, test32]
|
||||
run: [echo, okay]
|
||||
|
||||
bench: !Command
|
||||
description: Run benchmarks
|
||||
container: bench
|
||||
environ: { RUST_BACKTRACE: 1 }
|
||||
run: [cargo, bench]
|
||||
|
||||
_bulk: !Command
|
||||
description: Run `bulk` command (for version bookkeeping)
|
||||
container: ubuntu
|
||||
run: [bulk]
|
||||
|
||||
containers:
|
||||
|
||||
ubuntu:
|
||||
setup:
|
||||
- !Ubuntu xenial
|
||||
- !UbuntuUniverse
|
||||
- !Install [ca-certificates, build-essential, vim]
|
||||
|
||||
- !TarInstall
|
||||
url: "https://static.rust-lang.org/dist/rust-1.31.0-x86_64-unknown-linux-gnu.tar.gz"
|
||||
script: "./install.sh --prefix=/usr \
|
||||
--components=rustc,rust-std-x86_64-unknown-linux-gnu,cargo"
|
||||
- &bulk !Tar
|
||||
url: "https://github.com/tailhook/bulk/releases/download/v0.4.10/bulk-v0.4.10.tar.gz"
|
||||
sha256: 481513f8a0306a9857d045497fb5b50b50a51e9ff748909ecf7d2bda1de275ab
|
||||
path: /
|
||||
|
||||
environ:
|
||||
HOME: /work/target
|
||||
USER: pc
|
||||
|
||||
ubuntu32:
|
||||
setup:
|
||||
- !UbuntuRelease
|
||||
codename: xenial
|
||||
arch: i386
|
||||
- !UbuntuUniverse
|
||||
- !Install [ca-certificates, build-essential, vim]
|
||||
|
||||
- !TarInstall
|
||||
url: "https://static.rust-lang.org/dist/rust-1.31.0-i686-unknown-linux-gnu.tar.gz"
|
||||
script: "./install.sh --prefix=/usr \
|
||||
--components=rustc,rust-std-i686-unknown-linux-gnu,cargo"
|
||||
|
||||
environ:
|
||||
HOME: /work/target
|
||||
USER: pc
|
||||
|
||||
bench:
|
||||
setup:
|
||||
- !Ubuntu xenial
|
||||
- !Install [ca-certificates, wget, build-essential]
|
||||
- !TarInstall
|
||||
url: https://static.rust-lang.org/dist/rust-nightly-x86_64-unknown-linux-gnu.tar.gz
|
||||
script: |
|
||||
./install.sh --prefix=/usr \
|
||||
--components=rustc,rust-std-x86_64-unknown-linux-gnu,cargo
|
||||
environ:
|
||||
HOME: /work/target
|
||||
USER: pc
|
||||
Reference in New Issue
Block a user