diff options
| author | mo khan <mo@mokhan.ca> | 2025-07-15 16:37:08 -0600 |
|---|---|---|
| committer | mo khan <mo@mokhan.ca> | 2025-07-17 16:30:22 -0600 |
| commit | 45df4d0d9b577fecee798d672695fe24ff57fb1b (patch) | |
| tree | 1b99bf645035b58e0d6db08c7a83521f41f7a75b /vendor/time | |
| parent | f94f79608393d4ab127db63cc41668445ef6b243 (diff) | |
feat: migrate from Cedar to SpiceDB authorization system
This is a major architectural change that replaces the Cedar policy-based
authorization system with SpiceDB's relation-based authorization.
Key changes:
- Migrate from Rust to Go implementation
- Replace Cedar policies with SpiceDB schema and relationships
- Switch from envoy `ext_authz` with Cedar to SpiceDB permission checks
- Update build system and dependencies for Go ecosystem
- Maintain Envoy integration for external authorization
This change enables more flexible permission modeling through SpiceDB's
Google Zanzibar inspired relation-based system, supporting complex
hierarchical permissions that were difficult to express in Cedar.
Breaking change: Existing Cedar policies and Rust-based configuration
will no longer work and need to be migrated to SpiceDB schema.
Diffstat (limited to 'vendor/time')
93 files changed, 0 insertions, 22515 deletions
diff --git a/vendor/time/.cargo-checksum.json b/vendor/time/.cargo-checksum.json deleted file mode 100644 index 96475fc6..00000000 --- a/vendor/time/.cargo-checksum.json +++ /dev/null @@ -1 +0,0 @@ -{"files":{"Cargo.lock":"54ec18fc70d29545aedf23b042a08cc9362636c69ec2a61c03d6c12b74d93a6b","Cargo.toml":"266015f9745494d625f3ebfd148d72c282a1ec2bb5a34c88012b3c2c31f87f04","LICENSE-Apache":"0d542e0c8804e39aa7f37eb00da5a762149dc682d7829451287e11b938e94594","LICENSE-MIT":"2537228d9a1b44a5dc595241349cae7090b326c8de165aaf89bfddef4a00d0fc","README.md":"28ca0b1f1e88d8d2b2fa7ad2614daa06c301040d6d2980f90508e92283d47daf","src/date.rs":"8fa1c067f62882bf66c2f66b7a84d152f4cc0cd67d88551b37af19aeaf92faa4","src/duration.rs":"4af9d384d1a18653e2214bc79d94fa921725199e57b6241bc785196fc6affde1","src/error/component_range.rs":"f9ad9b0688088e16ec4299348f172ea769bbc85e8fa5c254c91b06c286d2c739","src/error/conversion_range.rs":"972abb765370070de01e2fc2e1bb1e80808a069e6213577d7beaca02e1d707c3","src/error/different_variant.rs":"107bef7b3addd7108b36a2da8389f611d4482f34a5b63429841141e05c8cb30c","src/error/format.rs":"086bfdd271e8b28d59eb07568bc6ad6a6296c2d74786a3e076d74c6140dc46bf","src/error/indeterminate_offset.rs":"1f52f9ea107847fa781399cfcc8046451d70155fb497486c80b2138f82782941","src/error/invalid_format_description.rs":"16eafff868a943877ef6d9f36ae2b32775e30c5a5803ef93731449c02f6f54f6","src/error/invalid_variant.rs":"b653a3e6e902f06cb9f2e0366c4da84b92e8bdb03164c2f8cb15fe66415706e4","src/error/mod.rs":"336265f0a88d01305f749e6382edfe6ebdf61002ff2cb2d6e7f575e03e977398","src/error/parse.rs":"170be4ed1a058342ac07f61330f594512aec30d36e32261766f93a5fa8852122","src/error/parse_from_description.rs":"2de1f5b5af3d9bb358cee1c66a2721a78ee99f0ee5e0c06f159e62de7a294a5f","src/error/try_from_parsed.rs":"8c227be52653a1d33af01a8024c0fc56f1f9803f08ef01487a7eaa5833adbb57","src/ext/digit_count.rs":"d32af3cac57077870f6b31c5bd6e0da3a530a7c713aaebdcd27125d9fd8857a3","src/ext/instant.rs":"96945bc0af1de8eddef110c2d5ec9d5459dde86ba4e3e361fce5927a2388b514","src/ext/mod.rs":"dc70d230a170ddd1bf7798703d9ff7cac419aaadc82b5f8dbf46d5320322e2c5","src/ext/numerical_duration.rs":"92fe416dd1c404d97f06ced3256e664b283b44ecc272aa4307f8a7d84e602cd4","src/ext/numerical_std_duration.rs":"0ada71ca29daa0a8a8d4d7fb477f0eec2114787a345d75a2d4d42534a2a20267","src/format_description/borrowed_format_item.rs":"ac61ff3b6f1e6fa1947669c7bea7ece6d65940731cced34a66db28fdc48ebc10","src/format_description/component.rs":"b65c0ca896ea6ec8dbfc7570c69849c88cbba6031a2847dcfdce06d721a59397","src/format_description/mod.rs":"d6ca12469c42910fd459d2cf5cebf93e694220cf51a6028cca6912fbe92b96ff","src/format_description/modifier.rs":"b7e6c637aa0f149aace9425285df43974b4c7539ee40bc52b777f4107b64dfef","src/format_description/owned_format_item.rs":"bfdf371ebef1125161e364fba745efc5ab3aebe1d0c9570e85cd9396b391f96d","src/format_description/parse/ast.rs":"645e7bce15323529902e9bd22c2a2e06beaa0af934e203e67031b5269a159c46","src/format_description/parse/format_item.rs":"c8ef68b6b0f882e4896033c9761b7f384f09626e8c438aea2e53d2966fb00318","src/format_description/parse/lexer.rs":"8f5bc750f83489e2a5fdc2e5e00ed8f0e5def0a376e9da541fc5fedad709a2c0","src/format_description/parse/mod.rs":"715d5bddfd98f1c1d6b15fe3797b61f2311561c29050fea4497af6f6efae3e99","src/format_description/parse/strftime.rs":"f125b20aefe5ee2eedb32d72cec535cbbce639fccd79e1348c9d0b76bb792377","src/format_description/well_known/iso8601.rs":"30b2f495044ab4e1f3ff6a317a8b4ca2ffb46b7cc23428eca8b685c0f16518cc","src/format_description/well_known/iso8601/adt_hack.rs":"fa099ffded092ce9d875c744891253045a065fa138adf4182c3b2b7e6ca466a4","src/format_description/well_known/rfc2822.rs":"36c23394724ae12250d4193cab26887a6ff8f82ca441ea6b0d03c4f1c928b3dd","src/format_description/well_known/rfc3339.rs":"1a6318dffd3ebb6ac7cf96eae3d9b1eb44b1089cf4284fa6a7e935c6fcf1b43c","src/formatting/formattable.rs":"6c32458f3bf34144ebe7405a568acb0ac85fc71cff6ff71ae72ceff2470ca77f","src/formatting/iso8601.rs":"f99f0d206d88f5360665c18e6119b0001e88fb1a6b7c62bcad06b70021effce9","src/formatting/mod.rs":"3c013d91e54eb4c9bd7661a8a8af92c2ecf6bdc99320c7db9ec588f240bc0e39","src/hint.rs":"7ec8b5320c8e133f0c02942d3e6be83643f84f73053597909ff6a2f06aa7b591","src/instant.rs":"5c0420795708954322b0da7410424ca5b93f5c91b3b799b18e419eb52977c9b0","src/internal_macros.rs":"c1c98ff11424b6f2f05c14bed88cfa146894a4607fd87fae490451f63257e500","src/interop/js_sys_date_offsetdatetime.rs":"f4d60aa1ac398a96a89533d063f9375a7e94021eb9ef8c2ccbcb7caa2c394abf","src/interop/js_sys_date_utcdatetime.rs":"4721b739d6ca06126b236dd9bcfde6b4f35872a7cc232e7026878a383ac63e09","src/interop/mod.rs":"d8c0905e9fea22e4dddab981a020f79a637f849e17f53e5102416dbce1f6dbea","src/interop/offsetdatetime_systemtime.rs":"b59e68dd35e3f47460355a71b2b0be2fb7d239afce2bf1b8ed933abb391b532f","src/interop/offsetdatetime_utcdatetime.rs":"07b1e2d25404fb2f38cf85eb7b27c0e503e6e70bc8107877edfc578eec6323b3","src/interop/utcdatetime_systemtime.rs":"dd0c5f21d77e1cc5909feec22eb20101c9ebdea4089e278e66855159d73daed8","src/lib.rs":"82226f3f9266794e4183759cc6310f0ee541c070eb8adedf57b408e29ad5e650","src/macros.rs":"c35b4f4fbb4781dadf70a952649cedf4f4e29b3b571c8bbfa58e9f6ad4071423","src/month.rs":"aab1a041bb5b69a0c21fa7ef37e3f8a9fe6f3c05bb8432339bbf67d59773fc5d","src/offset_date_time.rs":"f528ec252117159cdf69881de4fd6ec8914b70b3492a380ebbc4a188d5326645","src/parsing/combinator/mod.rs":"e49d14f7d0c38a847d9f5f2e63d466464641d365f1d39c48d1a455ebe6632ec5","src/parsing/combinator/rfc/iso8601.rs":"af40a366ebcdf577e5c16e75331d7e8d4ded26afa88ea9deba0615449fe10fb1","src/parsing/combinator/rfc/mod.rs":"f30b75d248f5ae92c27646d504703f5489185afb76c998cc4375437b3d15c822","src/parsing/combinator/rfc/rfc2234.rs":"08e2813c6d40c0dae881875fe0417ae06886c73679256587e33186e46b3c3bae","src/parsing/combinator/rfc/rfc2822.rs":"6c1f4d2c352aeb79c6d1b49bae6105c472859ce057a030a4cb0aa28b2853cf93","src/parsing/component.rs":"c4d24849e3f8fc14651056996c55f7e5a5ab342f64377c3bb223437c12acb620","src/parsing/iso8601.rs":"38ea74f81388e8beba1f94e01c3b372f566d0a06b9879b21c009aa818c81bbc9","src/parsing/mod.rs":"9f4e580bc88993c7ddefa184bbcb5b34723158d2f303d90b13def2d8f9d808a1","src/parsing/parsable.rs":"9227330b7341b5b76b9beab6aff23b6a1dcb0e91120065a5bec16b3f88d4d0ec","src/parsing/parsed.rs":"17ac85ca457f723ab28719e6a84dc49acc600a4a72cdf86410b187969a5f22db","src/parsing/shim.rs":"46efc374bc3129e28936a850143fff8e42aafe10c69ebbb904195aaeca26adc9","src/primitive_date_time.rs":"d0c4caf3ddb4eca2acd519bf188aab3f58d92249a412aa44ceb34542fc6b23d5","src/quickcheck.rs":"aa7e5417c70d7a99046b6af6974108ebed41c676b80b7f67cf7f3153d4cdd72f","src/rand.rs":"dd7228d1008246d33f2dee3f81e2a66ff12c257d4e89aa468903fe32bc7038c4","src/serde/iso8601.rs":"9c7a856213b95d2d7d7bd6a244aea36de03fca92ebfd2c32dea9a9bb11e1730b","src/serde/mod.rs":"7d8ab3dfb84b3e98f52a428dba0c2542e5b3e76082f551310db0006ef0a4fd64","src/serde/rfc2822.rs":"c3d577f4fcb9b70c5b7127d343bcd4d8449732f68fba333ef2c6013daa6e2ece","src/serde/rfc3339.rs":"4811b3e304ccce4e22803ee7e4a3466d0f3ecc3b4076ca74c9cca2506971eb0d","src/serde/timestamp/microseconds.rs":"7b8a0f6e455ddb6c50ed4a8473ea68cf9aacb31af36ccc058b68fa3bb5f3246d","src/serde/timestamp/milliseconds.rs":"df995f05f340f0429697269aa152a39b0beca45e1b4d8e60f4a6bb27f09a4d88","src/serde/timestamp/milliseconds_i64.rs":"9debcd18cc50bef9c935d25c6edb2827a0f6bb19b426c326349925ae38466e6f","src/serde/timestamp/mod.rs":"8c8349e0e9833480667a3fc7dc31c7b67610467ea36ce0fb24f5a47a2ebb1da5","src/serde/timestamp/nanoseconds.rs":"a46b1e60e8b19792a26ebdab33cba53db95cb13e3c4d9675a17b1491e9fb2940","src/serde/visitor.rs":"0b6bc76b88eb486b783d16c42a8f3af65c610fc8ffa07dd294dbfe0163f6e0b4","src/sys/local_offset_at/imp.rs":"4b6e57f02566364270ac9b7e1540290a5658a296f7e911f988264d103e420326","src/sys/local_offset_at/mod.rs":"0090b833161f0e69dd150bd8fdb599f2a4095475afbd5f7441ae6a363c6a4cea","src/sys/local_offset_at/unix.rs":"bb21dbe063889ceb409f54eee74d54690dc62b8ba840929581d6e827ca291f77","src/sys/local_offset_at/wasm_js.rs":"7cdacf5548a89a00265764ef07c1abb2ea1a3211f1ec720932b066f1d18b2f20","src/sys/local_offset_at/windows.rs":"90c16515d7ac29961bd0b8af92e38c7999f260bfd3438c9935fee65e8c0cc1e9","src/sys/mod.rs":"5e5649775aff43afa68d3ba0ca193273fd412e2de50e532828d7de65a1327f44","src/sys/refresh_tz/imp.rs":"c5265e17bdf1d0e676e7f75ca3a39e84c5d19d24de3d7f37ab0ce0e0f001d3b9","src/sys/refresh_tz/mod.rs":"0399000db309480debdaea9a61f0fad044f6acc4e22f8f7c49d7ea9e2e4877ab","src/sys/refresh_tz/unix.rs":"7a36ccb9efd23d264727fbb4cffcb5de5ed249b8216bbf6389fe10db22a70d30","src/tests.rs":"4cf40de5c6ffd670b9672ead5b3f25137f8214b1a435d298bd16ce467e72b040","src/time.rs":"da5a1bd6ce70547b8351297a0588c460894148b815f5c2008d61ab4102fb963a","src/utc_date_time.rs":"4bf3d0a07de1b5421bbc72cdfe21a297c311672a5618fec92e0a822295224599","src/utc_offset.rs":"3a9cd709e25837362778c550204486d4b4e6b4ff37b30cd87b4084163d06ed26","src/util.rs":"ccbfa06d000c83d8acef73a4576350305e77a547bbc2c67415a46b65f2c8c7da","src/weekday.rs":"daa82e07fa1d5291b7ab13b5dbcc1375f6ba4f8267abfbfea4fab4dae063d324"},"package":"8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40"}
\ No newline at end of file diff --git a/vendor/time/Cargo.lock b/vendor/time/Cargo.lock deleted file mode 100644 index 27fa70c7..00000000 --- a/vendor/time/Cargo.lock +++ /dev/null @@ -1,926 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "aho-corasick" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" -dependencies = [ - "memchr", -] - -[[package]] -name = "anes" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" - -[[package]] -name = "anstyle" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" - -[[package]] -name = "autocfg" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" - -[[package]] -name = "bitflags" -version = "2.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" - -[[package]] -name = "bumpalo" -version = "3.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" - -[[package]] -name = "cast" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "ciborium" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e" -dependencies = [ - "ciborium-io", - "ciborium-ll", - "serde", -] - -[[package]] -name = "ciborium-io" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757" - -[[package]] -name = "ciborium-ll" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9" -dependencies = [ - "ciborium-io", - "half", -] - -[[package]] -name = "clap" -version = "4.4.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e578d6ec4194633722ccf9544794b71b1385c3c027efe0c55db226fc880865c" -dependencies = [ - "clap_builder", -] - -[[package]] -name = "clap_builder" -version = "4.4.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4df4df40ec50c46000231c914968278b1eb05098cf8f1b3a518a95030e71d1c7" -dependencies = [ - "anstyle", - "clap_lex", -] - -[[package]] -name = "clap_lex" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" - -[[package]] -name = "criterion" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2b12d017a929603d80db1831cd3a24082f8137ce19c69e6447f54f5fc8d692f" -dependencies = [ - "anes", - "cast", - "ciborium", - "clap", - "criterion-plot", - "is-terminal", - "itertools", - "num-traits", - "once_cell", - "oorandom", - "regex", - "serde", - "serde_derive", - "serde_json", - "tinytemplate", - "walkdir", -] - -[[package]] -name = "criterion-plot" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1" -dependencies = [ - "cast", - "itertools", -] - -[[package]] -name = "crunchy" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" - -[[package]] -name = "deranged" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28cfac68e08048ae1883171632c2aef3ebc555621ae56fbccce1cbf22dd7f058" -dependencies = [ - "powerfmt", - "quickcheck", - "rand 0.8.5", - "rand 0.9.0", - "serde", -] - -[[package]] -name = "either" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" - -[[package]] -name = "equivalent" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" - -[[package]] -name = "errno" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" -dependencies = [ - "libc", - "windows-sys", -] - -[[package]] -name = "getrandom" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" -dependencies = [ - "cfg-if", - "libc", - "wasi", -] - -[[package]] -name = "glob" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" - -[[package]] -name = "half" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc52e53916c08643f1b56ec082790d1e86a32e58dc5268f897f313fbae7b4872" -dependencies = [ - "cfg-if", - "crunchy", -] - -[[package]] -name = "hashbrown" -version = "0.15.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" - -[[package]] -name = "hermit-abi" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d3d0e0f38255e7fa3cf31335b3a56f05febd18025f4db5ef7a0cfb4f8da651f" - -[[package]] -name = "indexmap" -version = "2.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c9c992b02b5b4c94ea26e32fe5bccb7aa7d9f390ab5c1221ff895bc7ea8b652" -dependencies = [ - "equivalent", - "hashbrown", -] - -[[package]] -name = "is-terminal" -version = "0.4.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bad00257d07be169d870ab665980b06cdb366d792ad690bf2e76876dc503455" -dependencies = [ - "hermit-abi", - "rustix", - "windows-sys", -] - -[[package]] -name = "itertools" -version = "0.10.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" -dependencies = [ - "either", -] - -[[package]] -name = "itoa" -version = "1.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" - -[[package]] -name = "js-sys" -version = "0.3.67" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a1d36f1235bc969acba30b7f5990b864423a6068a10f7c90ae8f0112e3a59d1" -dependencies = [ - "wasm-bindgen", -] - -[[package]] -name = "libc" -version = "0.2.152" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7" - -[[package]] -name = "linux-raw-sys" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" - -[[package]] -name = "log" -version = "0.4.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" - -[[package]] -name = "memchr" -version = "2.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" - -[[package]] -name = "num-conv" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" - -[[package]] -name = "num-traits" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" -dependencies = [ - "autocfg", -] - -[[package]] -name = "num_threads" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44" -dependencies = [ - "libc", -] - -[[package]] -name = "once_cell" -version = "1.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" - -[[package]] -name = "oorandom" -version = "11.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" - -[[package]] -name = "powerfmt" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" - -[[package]] -name = "ppv-lite86" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" - -[[package]] -name = "proc-macro2" -version = "1.0.93" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "quickcheck" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "588f6378e4dd99458b60ec275b4477add41ce4fa9f64dcba6f15adccb19b50d6" -dependencies = [ - "rand 0.8.5", -] - -[[package]] -name = "quickcheck_macros" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b22a693222d716a9587786f37ac3f6b4faedb5b80c23914e7303ff5a1d8016e9" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "quote" -version = "1.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha", - "rand_core 0.6.4", -] - -[[package]] -name = "rand" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94" -dependencies = [ - "rand_core 0.9.3", - "zerocopy", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core 0.6.4", -] - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom", -] - -[[package]] -name = "rand_core" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" - -[[package]] -name = "regex" -version = "1.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" -dependencies = [ - "aho-corasick", - "memchr", - "regex-automata", - "regex-syntax", -] - -[[package]] -name = "regex-automata" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" - -[[package]] -name = "relative-path" -version = "1.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba39f3699c378cd8970968dcbff9c43159ea4cfbd88d43c00b22f2ef10a435d2" - -[[package]] -name = "rstest" -version = "0.23.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a2c585be59b6b5dd66a9d2084aa1d8bd52fbdb806eafdeffb52791147862035" -dependencies = [ - "rstest_macros", - "rustc_version", -] - -[[package]] -name = "rstest_macros" -version = "0.23.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "825ea780781b15345a146be27eaefb05085e337e869bff01b4306a4fd4a9ad5a" -dependencies = [ - "cfg-if", - "glob", - "proc-macro2", - "quote", - "regex", - "relative-path", - "rustc_version", - "syn 2.0.96", - "unicode-ident", -] - -[[package]] -name = "rstest_reuse" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3a8fb4672e840a587a66fc577a5491375df51ddb88f2a2c2a792598c326fe14" -dependencies = [ - "quote", - "rand 0.8.5", - "syn 2.0.96", -] - -[[package]] -name = "rustc_version" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" -dependencies = [ - "semver", -] - -[[package]] -name = "rustix" -version = "0.38.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "322394588aaf33c24007e8bb3238ee3e4c5c09c084ab32bc73890b99ff326bca" -dependencies = [ - "bitflags", - "errno", - "libc", - "linux-raw-sys", - "windows-sys", -] - -[[package]] -name = "ryu" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" - -[[package]] -name = "same-file" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "semver" -version = "1.0.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97ed7a9823b74f99c7742f5336af7be5ecd3eeafcb1507d1fa93347b1d589b0" - -[[package]] -name = "serde" -version = "1.0.217" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.217" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.96", -] - -[[package]] -name = "serde_json" -version = "1.0.137" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "930cfb6e6abf99298aaad7d29abbef7a9999a9a8806a40088f55f0dcec03146b" -dependencies = [ - "itoa", - "memchr", - "ryu", - "serde", -] - -[[package]] -name = "serde_spanned" -version = "0.6.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" -dependencies = [ - "serde", -] - -[[package]] -name = "serde_test" -version = "1.0.176" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a2f49ace1498612d14f7e0b8245519584db8299541dfe31a06374a828d620ab" -dependencies = [ - "serde", -] - -[[package]] -name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.96" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5d0adab1ae378d7f53bdebc67a39f1f151407ef230f0ce2883572f5d8985c80" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "target-triple" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42a4d50cdb458045afc8131fd91b64904da29548bcb63c7236e0844936c13078" - -[[package]] -name = "termcolor" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "time" -version = "0.3.41" -dependencies = [ - "criterion", - "deranged", - "itoa", - "js-sys", - "libc", - "num-conv", - "num_threads", - "powerfmt", - "quickcheck", - "quickcheck_macros", - "rand 0.8.5", - "rstest", - "rstest_reuse", - "serde", - "serde_json", - "serde_test", - "time-core", - "time-macros", - "trybuild", -] - -[[package]] -name = "time-core" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c" - -[[package]] -name = "time-macros" -version = "0.2.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3526739392ec93fd8b359c8e98514cb3e8e021beb4e5f597b00a0221f8ed8a49" -dependencies = [ - "num-conv", - "time-core", -] - -[[package]] -name = "tinytemplate" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" -dependencies = [ - "serde", - "serde_json", -] - -[[package]] -name = "toml" -version = "0.8.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" -dependencies = [ - "serde", - "serde_spanned", - "toml_datetime", - "toml_edit", -] - -[[package]] -name = "toml_datetime" -version = "0.6.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" -dependencies = [ - "serde", -] - -[[package]] -name = "toml_edit" -version = "0.22.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" -dependencies = [ - "indexmap", - "serde", - "serde_spanned", - "toml_datetime", - "winnow", -] - -[[package]] -name = "trybuild" -version = "1.0.102" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f14b5c02a137632f68194ec657ecb92304138948e8957c932127eb1b58c23be" -dependencies = [ - "glob", - "serde", - "serde_derive", - "serde_json", - "target-triple", - "termcolor", - "toml", -] - -[[package]] -name = "unicode-ident" -version = "1.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" - -[[package]] -name = "walkdir" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" -dependencies = [ - "same-file", - "winapi-util", -] - -[[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" - -[[package]] -name = "wasm-bindgen" -version = "0.2.90" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1223296a201415c7fad14792dbefaace9bd52b62d33453ade1c5b5f07555406" -dependencies = [ - "cfg-if", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.90" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcdc935b63408d58a32f8cc9738a0bffd8f05cc7c002086c6ef20b7312ad9dcd" -dependencies = [ - "bumpalo", - "log", - "once_cell", - "proc-macro2", - "quote", - "syn 2.0.96", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.90" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e4c238561b2d428924c49815533a8b9121c664599558a5d9ec51f8a1740a999" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.90" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bae1abb6806dc1ad9e560ed242107c0f6c84335f1749dd4e8ddb012ebd5e25a7" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.96", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.90" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d91413b1c31d7539ba5ef2451af3f0b833a005eb27a631cec32bc0635a8602b" - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-util" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" -dependencies = [ - "winapi", -] - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "windows-sys" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets", -] - -[[package]] -name = "windows-targets" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" -dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" - -[[package]] -name = "winnow" -version = "0.6.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8d71a593cc5c42ad7876e2c1fda56f314f3754c084128833e64f1345ff8a03a" -dependencies = [ - "memchr", -] - -[[package]] -name = "zerocopy" -version = "0.8.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd97444d05a4328b90e75e503a34bad781f14e28a823ad3557f0750df1ebcbc6" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.8.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6352c01d0edd5db859a63e2605f4ea3183ddbd15e2c4a9e7d32184df75e4f154" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.96", -] diff --git a/vendor/time/Cargo.toml b/vendor/time/Cargo.toml deleted file mode 100644 index fdffe750..00000000 --- a/vendor/time/Cargo.toml +++ /dev/null @@ -1,298 +0,0 @@ -# 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 are reading this file be aware that the original Cargo.toml -# will likely look very different (and much more reasonable). -# See Cargo.toml.orig for the original contents. - -[package] -edition = "2021" -rust-version = "1.67.1" -name = "time" -version = "0.3.41" -authors = [ - "Jacob Pratt <open-source@jhpratt.dev>", - "Time contributors", -] -build = false -include = [ - "src/**/*", - "LICENSE-*", - "README.md", -] -autolib = false -autobins = false -autoexamples = false -autotests = false -autobenches = false -description = "Date and time library. Fully interoperable with the standard library. Mostly compatible with #![no_std]." -homepage = "https://time-rs.github.io" -readme = "README.md" -keywords = [ - "date", - "time", - "calendar", - "duration", -] -categories = [ - "date-and-time", - "no-std", - "parser-implementations", - "value-formatting", -] -license = "MIT OR Apache-2.0" -repository = "https://github.com/time-rs/time" - -[package.metadata.docs.rs] -all-features = true -rustdoc-args = ["--generate-link-to-definition"] -targets = ["x86_64-unknown-linux-gnu"] - -[features] -alloc = ["serde?/alloc"] -default = ["std"] -formatting = [ - "dep:itoa", - "std", - "time-macros?/formatting", -] -large-dates = ["time-macros?/large-dates"] -local-offset = [ - "std", - "dep:libc", - "dep:num_threads", -] -macros = ["dep:time-macros"] -parsing = ["time-macros?/parsing"] -quickcheck = [ - "dep:quickcheck", - "alloc", - "deranged/quickcheck", -] -rand = [ - "dep:rand", - "deranged/rand", -] -serde = [ - "dep:serde", - "time-macros?/serde", - "deranged/serde", -] -serde-human-readable = [ - "serde", - "formatting", - "parsing", -] -serde-well-known = [ - "serde", - "formatting", - "parsing", -] -std = [ - "alloc", - "deranged/std", -] -wasm-bindgen = ["dep:js-sys"] - -[lib] -name = "time" -path = "src/lib.rs" -bench = false - -[dependencies.deranged] -version = "0.4.0" -features = ["powerfmt"] -default-features = false - -[dependencies.itoa] -version = "1.0.1" -optional = true - -[dependencies.num-conv] -version = "0.1.0" - -[dependencies.powerfmt] -version = "0.2.0" -default-features = false - -[dependencies.quickcheck] -version = "1.0.3" -optional = true -default-features = false - -[dependencies.rand] -version = "0.8.4" -optional = true -default-features = false - -[dependencies.serde] -version = "1.0.184" -optional = true -default-features = false - -[dependencies.time-core] -version = "=0.1.4" - -[dependencies.time-macros] -version = "=0.2.22" -optional = true - -[dev-dependencies.num-conv] -version = "0.1.0" - -[dev-dependencies.quickcheck_macros] -version = "1.0.0" - -[dev-dependencies.rand] -version = "0.8.4" -default-features = false - -[dev-dependencies.rstest] -version = "0.23.0" -default-features = false - -[dev-dependencies.rstest_reuse] -version = "0.7.0" - -[dev-dependencies.serde] -version = "1.0.184" -features = ["derive"] -default-features = false - -[dev-dependencies.serde_json] -version = "1.0.68" - -[dev-dependencies.serde_test] -version = "1.0.126" - -[dev-dependencies.time-macros] -version = "=0.2.22" - -[target."cfg(__ui_tests)".dev-dependencies.trybuild] -version = "1.0.102" - -[target.'cfg(all(target_family = "wasm", not(any(target_os = "emscripten", target_os = "wasi"))))'.dependencies.js-sys] -version = "0.3.58" -optional = true - -[target."cfg(bench)".dev-dependencies.criterion] -version = "0.5.1" -default-features = false - -[target.'cfg(target_family = "unix")'.dependencies.libc] -version = "0.2.98" -optional = true - -[target.'cfg(target_family = "unix")'.dependencies.num_threads] -version = "0.1.2" -optional = true - -[lints.clippy] -alloc-instead-of-core = "deny" -as-underscore = "warn" -dbg-macro = "warn" -decimal-literal-representation = "warn" -explicit-auto-deref = "warn" -get-unwrap = "warn" -manual-let-else = "warn" -missing-docs-in-private-items = "warn" -missing-enforced-import-renames = "warn" -obfuscated-if-else = "warn" -print-stdout = "warn" -semicolon-outside-block = "warn" -std-instead-of-core = "deny" -todo = "warn" -undocumented-unsafe-blocks = "deny" -unimplemented = "warn" -uninlined-format-args = "warn" -unnested-or-patterns = "warn" -unwrap-in-result = "warn" -unwrap-used = "warn" -use-debug = "warn" - -[lints.clippy.all] -level = "warn" -priority = -1 - -[lints.clippy.nursery] -level = "warn" -priority = -1 - -[lints.clippy.option-if-let-else] -level = "allow" -priority = 1 - -[lints.clippy.redundant-pub-crate] -level = "allow" -priority = 1 - -[lints.clippy.uninhabited-references] -level = "allow" -priority = 1 - -[lints.rust] -ambiguous-glob-reexports = "deny" -clashing-extern-declarations = "deny" -const-item-mutation = "deny" -dangling-pointers-from-temporaries = "deny" -deref-nullptr = "deny" -drop-bounds = "deny" -future-incompatible = "deny" -hidden-glob-reexports = "deny" -improper-ctypes = "deny" -improper-ctypes-definitions = "deny" -invalid-from-utf8 = "deny" -invalid-macro-export-arguments = "deny" -invalid-nan-comparisons = "deny" -invalid-reference-casting = "deny" -invalid-value = "deny" -keyword-idents = "warn" -let-underscore = "warn" -macro-use-extern-crate = "warn" -meta-variable-misuse = "warn" -missing-abi = "warn" -missing-copy-implementations = "warn" -missing-debug-implementations = "warn" -missing-docs = "warn" -named-arguments-used-positionally = "deny" -non-ascii-idents = "deny" -noop-method-call = "warn" -opaque-hidden-inferred-bound = "deny" -overlapping-range-endpoints = "deny" -single-use-lifetimes = "warn" -suspicious-double-ref-op = "deny" -trivial-casts = "warn" -trivial-numeric-casts = "warn" -unconditional-recursion = "deny" -unnameable-test-items = "deny" -unreachable-pub = "warn" -unsafe-op-in-unsafe-fn = "deny" -unstable-syntax-pre-expansion = "deny" -unused-import-braces = "warn" -unused-lifetimes = "warn" -unused-qualifications = "warn" -variant-size-differences = "warn" - -[lints.rust.unexpected_cfgs] -level = "deny" -priority = 0 -check-cfg = [ - "cfg(__ui_tests)", - "cfg(bench)", -] - -[lints.rust.unstable-name-collisions] -level = "allow" -priority = 1 - -[lints.rust.unused] -level = "warn" -priority = -1 - -[lints.rustdoc] -private-doc-tests = "warn" -unescaped-backticks = "warn" diff --git a/vendor/time/LICENSE-Apache b/vendor/time/LICENSE-Apache deleted file mode 100644 index f433b1a5..00000000 --- a/vendor/time/LICENSE-Apache +++ /dev/null @@ -1,177 +0,0 @@ - - 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 diff --git a/vendor/time/LICENSE-MIT b/vendor/time/LICENSE-MIT deleted file mode 100644 index 663cb2a1..00000000 --- a/vendor/time/LICENSE-MIT +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) Jacob Pratt et al. - -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/vendor/time/README.md b/vendor/time/README.md deleted file mode 100644 index 22192563..00000000 --- a/vendor/time/README.md +++ /dev/null @@ -1,51 +0,0 @@ -# time - -[](https://www.whatrustisit.com) -[](https://crates.io/crates/time) -[](https://github.com/time-rs/time/actions) -[](https://codecov.io/gh/time-rs/time) - -Documentation: - -- [latest release](https://docs.rs/time) -- [main branch](https://time-rs.github.io/api/time) -- [book](https://time-rs.github.io/book) - -## Minimum Rust version policy - -`time` is guaranteed to compile with the latest stable release of Rust in addition to the two prior -minor releases. For example, if the latest stable Rust release is 1.70, then `time` is guaranteed to -compile with Rust 1.68, 1.69, and 1.70. - -The minimum supported Rust version may be increased to one of the aforementioned versions if doing -so provides the end user a benefit. However, the minimum supported Rust version may also be bumped -to a version four minor releases prior to the most recent stable release if doing so improves code -quality or maintainability. - -For interoperability with third-party crates, it is guaranteed that there exists a version of that -crate that supports the minimum supported Rust version of `time`. This does not mean that the latest -version of the third-party crate supports the minimum supported Rust version of `time`. - -## Contributing - -Contributions are always welcome! If you have an idea, it's best to float it by me before working on -it to ensure no effort is wasted. If there's already an open issue for it, knock yourself out. -Internal documentation can be viewed [here](https://time-rs.github.io/internal-api/time). - -If you have any questions, feel free to use [Discussions]. Don't hesitate to ask questions — that's -what I'm here for! - -[Discussions]: https://github.com/time-rs/time/discussions - -## License - -This project is licensed under either of - -- [Apache License, Version 2.0](https://github.com/time-rs/time/blob/main/LICENSE-Apache) -- [MIT license](https://github.com/time-rs/time/blob/main/LICENSE-MIT) - -at your option. - -Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in -time by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any -additional terms or conditions. diff --git a/vendor/time/src/date.rs b/vendor/time/src/date.rs deleted file mode 100644 index 3772c2da..00000000 --- a/vendor/time/src/date.rs +++ /dev/null @@ -1,1490 +0,0 @@ -//! The [`Date`] struct and its associated `impl`s. - -#[cfg(feature = "formatting")] -use alloc::string::String; -use core::num::{NonZeroI32, NonZeroU8}; -use core::ops::{Add, Sub}; -use core::time::Duration as StdDuration; -use core::{cmp, fmt}; -#[cfg(feature = "formatting")] -use std::io; - -use deranged::RangedI32; -use num_conv::prelude::*; -use powerfmt::ext::FormatterExt; -use powerfmt::smart_display::{self, FormatterOptions, Metadata, SmartDisplay}; - -use crate::convert::*; -use crate::ext::DigitCount; -#[cfg(feature = "formatting")] -use crate::formatting::Formattable; -use crate::internal_macros::{ - const_try, const_try_opt, div_floor, ensure_ranged, expect_opt, impl_add_assign, - impl_sub_assign, -}; -#[cfg(feature = "parsing")] -use crate::parsing::Parsable; -use crate::util::{days_in_year, is_leap_year, weeks_in_year}; -use crate::{error, Duration, Month, PrimitiveDateTime, Time, Weekday}; - -type Year = RangedI32<MIN_YEAR, MAX_YEAR>; - -/// The minimum valid year. -pub(crate) const MIN_YEAR: i32 = if cfg!(feature = "large-dates") { - -999_999 -} else { - -9999 -}; -/// The maximum valid year. -pub(crate) const MAX_YEAR: i32 = if cfg!(feature = "large-dates") { - 999_999 -} else { - 9999 -}; - -/// Date in the proleptic Gregorian calendar. -/// -/// By default, years between ±9999 inclusive are representable. This can be expanded to ±999,999 -/// inclusive by enabling the `large-dates` crate feature. Doing so has performance implications -/// and introduces some ambiguities when parsing. -#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] -pub struct Date { - /// Bitpacked field containing the year, ordinal, and whether the year is a leap year. - // | x | xxxxxxxxxxxxxxxxxxxxx | x | xxxxxxxxx | - // | 1 bit | 21 bits | 1 bit | 9 bits | - // | unassigned | year | is leap year? | ordinal | - // The year is 15 bits when `large-dates` is not enabled. - value: NonZeroI32, -} - -impl Date { - /// The minimum valid `Date`. - /// - /// The value of this may vary depending on the feature flags enabled. - // Safety: `ordinal` is not zero. - #[allow(clippy::undocumented_unsafe_blocks)] - pub const MIN: Self = unsafe { Self::__from_ordinal_date_unchecked(MIN_YEAR, 1) }; - - /// The maximum valid `Date`. - /// - /// The value of this may vary depending on the feature flags enabled. - // Safety: `ordinal` is not zero. - #[allow(clippy::undocumented_unsafe_blocks)] - pub const MAX: Self = - unsafe { Self::__from_ordinal_date_unchecked(MAX_YEAR, days_in_year(MAX_YEAR)) }; - - /// Construct a `Date` from its internal representation, the validity of which must be - /// guaranteed by the caller. - /// - /// # Safety - /// - /// - `ordinal` must be non-zero and at most the number of days in `year` - /// - `is_leap_year` must be `true` if and only if `year` is a leap year - const unsafe fn from_parts(year: i32, is_leap_year: bool, ordinal: u16) -> Self { - debug_assert!(year >= MIN_YEAR); - debug_assert!(year <= MAX_YEAR); - debug_assert!(ordinal != 0); - debug_assert!(ordinal <= days_in_year(year)); - debug_assert!(crate::util::is_leap_year(year) == is_leap_year); - - Self { - // Safety: `ordinal` is not zero. - value: unsafe { - NonZeroI32::new_unchecked( - (year << 10) | ((is_leap_year as i32) << 9) | ordinal as i32, - ) - }, - } - } - - /// Construct a `Date` from the year and ordinal values, the validity of which must be - /// guaranteed by the caller. - /// - /// # Safety - /// - /// `ordinal` must be non-zero and at most the number of days in `year`. `year` should be in the - /// range `MIN_YEAR..=MAX_YEAR`, but this is not a safety invariant. - #[doc(hidden)] - pub const unsafe fn __from_ordinal_date_unchecked(year: i32, ordinal: u16) -> Self { - // Safety: The caller must guarantee that `ordinal` is not zero. - unsafe { Self::from_parts(year, is_leap_year(year), ordinal) } - } - - /// Attempt to create a `Date` from the year, month, and day. - /// - /// ```rust - /// # use time::{Date, Month}; - /// assert!(Date::from_calendar_date(2019, Month::January, 1).is_ok()); - /// assert!(Date::from_calendar_date(2019, Month::December, 31).is_ok()); - /// ``` - /// - /// ```rust - /// # use time::{Date, Month}; - /// assert!(Date::from_calendar_date(2019, Month::February, 29).is_err()); // 2019 isn't a leap year. - /// ``` - pub const fn from_calendar_date( - year: i32, - month: Month, - day: u8, - ) -> Result<Self, error::ComponentRange> { - /// Cumulative days through the beginning of a month in both common and leap years. - const DAYS_CUMULATIVE_COMMON_LEAP: [[u16; 12]; 2] = [ - [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334], - [0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335], - ]; - - ensure_ranged!(Year: year); - match day { - 1..=28 => {} - 29..=31 if day <= month.length(year) => {} - _ => { - return Err(error::ComponentRange { - name: "day", - minimum: 1, - maximum: month.length(year) as i64, - value: day as i64, - conditional_message: Some("for the given month and year"), - }); - } - } - - // Safety: `ordinal` is not zero. - Ok(unsafe { - Self::__from_ordinal_date_unchecked( - year, - DAYS_CUMULATIVE_COMMON_LEAP[is_leap_year(year) as usize][month as usize - 1] - + day as u16, - ) - }) - } - - /// Attempt to create a `Date` from the year and ordinal day number. - /// - /// ```rust - /// # use time::Date; - /// assert!(Date::from_ordinal_date(2019, 1).is_ok()); - /// assert!(Date::from_ordinal_date(2019, 365).is_ok()); - /// ``` - /// - /// ```rust - /// # use time::Date; - /// assert!(Date::from_ordinal_date(2019, 366).is_err()); // 2019 isn't a leap year. - /// ``` - pub const fn from_ordinal_date(year: i32, ordinal: u16) -> Result<Self, error::ComponentRange> { - ensure_ranged!(Year: year); - match ordinal { - 1..=365 => {} - 366 if is_leap_year(year) => {} - _ => { - return Err(error::ComponentRange { - name: "ordinal", - minimum: 1, - maximum: days_in_year(year) as i64, - value: ordinal as i64, - conditional_message: Some("for the given year"), - }); - } - } - - // Safety: `ordinal` is not zero. - Ok(unsafe { Self::__from_ordinal_date_unchecked(year, ordinal) }) - } - - /// Attempt to create a `Date` from the ISO year, week, and weekday. - /// - /// ```rust - /// # use time::{Date, Weekday::*}; - /// assert!(Date::from_iso_week_date(2019, 1, Monday).is_ok()); - /// assert!(Date::from_iso_week_date(2019, 1, Tuesday).is_ok()); - /// assert!(Date::from_iso_week_date(2020, 53, Friday).is_ok()); - /// ``` - /// - /// ```rust - /// # use time::{Date, Weekday::*}; - /// assert!(Date::from_iso_week_date(2019, 53, Monday).is_err()); // 2019 doesn't have 53 weeks. - /// ``` - pub const fn from_iso_week_date( - year: i32, - week: u8, - weekday: Weekday, - ) -> Result<Self, error::ComponentRange> { - ensure_ranged!(Year: year); - match week { - 1..=52 => {} - 53 if week <= weeks_in_year(year) => {} - _ => { - return Err(error::ComponentRange { - name: "week", - minimum: 1, - maximum: weeks_in_year(year) as i64, - value: week as i64, - conditional_message: Some("for the given year"), - }); - } - } - - let adj_year = year - 1; - let raw = 365 * adj_year + div_floor!(adj_year, 4) - div_floor!(adj_year, 100) - + div_floor!(adj_year, 400); - let jan_4 = match (raw % 7) as i8 { - -6 | 1 => 8, - -5 | 2 => 9, - -4 | 3 => 10, - -3 | 4 => 4, - -2 | 5 => 5, - -1 | 6 => 6, - _ => 7, - }; - let ordinal = week as i16 * 7 + weekday.number_from_monday() as i16 - jan_4; - - Ok(if ordinal <= 0 { - // Safety: `ordinal` is not zero. - unsafe { - Self::__from_ordinal_date_unchecked( - year - 1, - (ordinal as u16).wrapping_add(days_in_year(year - 1)), - ) - } - } else if ordinal > days_in_year(year) as i16 { - // Safety: `ordinal` is not zero. - unsafe { - Self::__from_ordinal_date_unchecked(year + 1, ordinal as u16 - days_in_year(year)) - } - } else { - // Safety: `ordinal` is not zero. - unsafe { Self::__from_ordinal_date_unchecked(year, ordinal as u16) } - }) - } - - /// Create a `Date` from the Julian day. - /// - /// The algorithm to perform this conversion is derived from one provided by Peter Baum; it is - /// freely available [here](https://www.researchgate.net/publication/316558298_Date_Algorithms). - /// - /// ```rust - /// # use time::Date; - /// # use time_macros::date; - /// assert_eq!(Date::from_julian_day(0), Ok(date!(-4713 - 11 - 24))); - /// assert_eq!(Date::from_julian_day(2_451_545), Ok(date!(2000-01-01))); - /// assert_eq!(Date::from_julian_day(2_458_485), Ok(date!(2019-01-01))); - /// assert_eq!(Date::from_julian_day(2_458_849), Ok(date!(2019-12-31))); - /// ``` - #[doc(alias = "from_julian_date")] - pub const fn from_julian_day(julian_day: i32) -> Result<Self, error::ComponentRange> { - type JulianDay = RangedI32<{ Date::MIN.to_julian_day() }, { Date::MAX.to_julian_day() }>; - ensure_ranged!(JulianDay: julian_day); - // Safety: The Julian day number is in range. - Ok(unsafe { Self::from_julian_day_unchecked(julian_day) }) - } - - /// Create a `Date` from the Julian day. - /// - /// # Safety - /// - /// The provided Julian day number must be between `Date::MIN.to_julian_day()` and - /// `Date::MAX.to_julian_day()` inclusive. - pub(crate) const unsafe fn from_julian_day_unchecked(julian_day: i32) -> Self { - debug_assert!(julian_day >= Self::MIN.to_julian_day()); - debug_assert!(julian_day <= Self::MAX.to_julian_day()); - - const S: i32 = 2_500; - const K: i32 = 719_468 + 146_097 * S; - const L: i32 = 400 * S; - - let julian_day = julian_day - 2_440_588; - let n = (julian_day + K) as u32; - - let n_1 = 4 * n + 3; - let c = n_1 / 146_097; - let n_c = n_1 % 146_097 / 4; - - let n_2 = 4 * n_c + 3; - let p_2 = 2_939_745 * n_2 as u64; - let z = (p_2 >> 32) as u32; - let n_y = p_2 as u32 / 2_939_745 / 4; - let y = 100 * c + z; - - let j = n_y >= 306; - let y_g = y as i32 - L + j as i32; - - let is_leap_year = is_leap_year(y_g); - let ordinal = if j { - n_y - 305 - } else { - n_y + 60 + is_leap_year as u32 - }; - - // Safety: `ordinal` is not zero and `is_leap_year` is correct, so long as the Julian day - // number is in range. - unsafe { Self::from_parts(y_g, is_leap_year, ordinal as u16) } - } - - /// Whether `is_leap_year(self.year())` is `true`. - /// - /// This method is optimized to take advantage of the fact that the value is pre-computed upon - /// construction and stored in the bitpacked struct. - const fn is_in_leap_year(self) -> bool { - (self.value.get() >> 9) & 1 == 1 - } - - /// Get the year of the date. - /// - /// ```rust - /// # use time_macros::date; - /// assert_eq!(date!(2019-01-01).year(), 2019); - /// assert_eq!(date!(2019-12-31).year(), 2019); - /// assert_eq!(date!(2020-01-01).year(), 2020); - /// ``` - pub const fn year(self) -> i32 { - self.value.get() >> 10 - } - - /// Get the month. - /// - /// ```rust - /// # use time::Month; - /// # use time_macros::date; - /// assert_eq!(date!(2019-01-01).month(), Month::January); - /// assert_eq!(date!(2019-12-31).month(), Month::December); - /// ``` - pub const fn month(self) -> Month { - let ordinal = self.ordinal() as u32; - let jan_feb_len = 59 + self.is_in_leap_year() as u32; - - let (month_adj, ordinal_adj) = if ordinal <= jan_feb_len { - (0, 0) - } else { - (2, jan_feb_len) - }; - - let ordinal = ordinal - ordinal_adj; - let month = ((ordinal * 268 + 8031) >> 13) + month_adj; - - // Safety: `month` is guaranteed to be between 1 and 12 inclusive. - unsafe { - match Month::from_number(NonZeroU8::new_unchecked(month as u8)) { - Ok(month) => month, - Err(_) => core::hint::unreachable_unchecked(), - } - } - } - - /// Get the day of the month. - /// - /// The returned value will always be in the range `1..=31`. - /// - /// ```rust - /// # use time_macros::date; - /// assert_eq!(date!(2019-01-01).day(), 1); - /// assert_eq!(date!(2019-12-31).day(), 31); - /// ``` - pub const fn day(self) -> u8 { - let ordinal = self.ordinal() as u32; - let jan_feb_len = 59 + self.is_in_leap_year() as u32; - - let ordinal_adj = if ordinal <= jan_feb_len { - 0 - } else { - jan_feb_len - }; - - let ordinal = ordinal - ordinal_adj; - let month = (ordinal * 268 + 8031) >> 13; - let days_in_preceding_months = (month * 3917 - 3866) >> 7; - (ordinal - days_in_preceding_months) as u8 - } - - /// Get the day of the year. - /// - /// The returned value will always be in the range `1..=366` (`1..=365` for common years). - /// - /// ```rust - /// # use time_macros::date; - /// assert_eq!(date!(2019-01-01).ordinal(), 1); - /// assert_eq!(date!(2019-12-31).ordinal(), 365); - /// ``` - pub const fn ordinal(self) -> u16 { - (self.value.get() & 0x1FF) as u16 - } - - /// Get the ISO 8601 year and week number. - pub(crate) const fn iso_year_week(self) -> (i32, u8) { - let (year, ordinal) = self.to_ordinal_date(); - - match ((ordinal + 10 - self.weekday().number_from_monday() as u16) / 7) as u8 { - 0 => (year - 1, weeks_in_year(year - 1)), - 53 if weeks_in_year(year) == 52 => (year + 1, 1), - week => (year, week), - } - } - - /// Get the ISO week number. - /// - /// The returned value will always be in the range `1..=53`. - /// - /// ```rust - /// # use time_macros::date; - /// assert_eq!(date!(2019-01-01).iso_week(), 1); - /// assert_eq!(date!(2019-10-04).iso_week(), 40); - /// assert_eq!(date!(2020-01-01).iso_week(), 1); - /// assert_eq!(date!(2020-12-31).iso_week(), 53); - /// assert_eq!(date!(2021-01-01).iso_week(), 53); - /// ``` - pub const fn iso_week(self) -> u8 { - self.iso_year_week().1 - } - - /// Get the week number where week 1 begins on the first Sunday. - /// - /// The returned value will always be in the range `0..=53`. - /// - /// ```rust - /// # use time_macros::date; - /// assert_eq!(date!(2019-01-01).sunday_based_week(), 0); - /// assert_eq!(date!(2020-01-01).sunday_based_week(), 0); - /// assert_eq!(date!(2020-12-31).sunday_based_week(), 52); - /// assert_eq!(date!(2021-01-01).sunday_based_week(), 0); - /// ``` - pub const fn sunday_based_week(self) -> u8 { - ((self.ordinal() as i16 - self.weekday().number_days_from_sunday() as i16 + 6) / 7) as u8 - } - - /// Get the week number where week 1 begins on the first Monday. - /// - /// The returned value will always be in the range `0..=53`. - /// - /// ```rust - /// # use time_macros::date; - /// assert_eq!(date!(2019-01-01).monday_based_week(), 0); - /// assert_eq!(date!(2020-01-01).monday_based_week(), 0); - /// assert_eq!(date!(2020-12-31).monday_based_week(), 52); - /// assert_eq!(date!(2021-01-01).monday_based_week(), 0); - /// ``` - pub const fn monday_based_week(self) -> u8 { - ((self.ordinal() as i16 - self.weekday().number_days_from_monday() as i16 + 6) / 7) as u8 - } - - /// Get the year, month, and day. - /// - /// ```rust - /// # use time::Month; - /// # use time_macros::date; - /// assert_eq!( - /// date!(2019-01-01).to_calendar_date(), - /// (2019, Month::January, 1) - /// ); - /// ``` - pub const fn to_calendar_date(self) -> (i32, Month, u8) { - let (year, ordinal) = self.to_ordinal_date(); - let ordinal = ordinal as u32; - let jan_feb_len = 59 + self.is_in_leap_year() as u32; - - let (month_adj, ordinal_adj) = if ordinal <= jan_feb_len { - (0, 0) - } else { - (2, jan_feb_len) - }; - - let ordinal = ordinal - ordinal_adj; - let month = (ordinal * 268 + 8031) >> 13; - let days_in_preceding_months = (month * 3917 - 3866) >> 7; - let day = ordinal - days_in_preceding_months; - let month = month + month_adj; - - ( - year, - // Safety: `month` is guaranteed to be between 1 and 12 inclusive. - unsafe { - match Month::from_number(NonZeroU8::new_unchecked(month as u8)) { - Ok(month) => month, - Err(_) => core::hint::unreachable_unchecked(), - } - }, - day as u8, - ) - } - - /// Get the year and ordinal day number. - /// - /// ```rust - /// # use time_macros::date; - /// assert_eq!(date!(2019-01-01).to_ordinal_date(), (2019, 1)); - /// ``` - pub const fn to_ordinal_date(self) -> (i32, u16) { - (self.year(), self.ordinal()) - } - - /// Get the ISO 8601 year, week number, and weekday. - /// - /// ```rust - /// # use time::Weekday::*; - /// # use time_macros::date; - /// assert_eq!(date!(2019-01-01).to_iso_week_date(), (2019, 1, Tuesday)); - /// assert_eq!(date!(2019-10-04).to_iso_week_date(), (2019, 40, Friday)); - /// assert_eq!(date!(2020-01-01).to_iso_week_date(), (2020, 1, Wednesday)); - /// assert_eq!(date!(2020-12-31).to_iso_week_date(), (2020, 53, Thursday)); - /// assert_eq!(date!(2021-01-01).to_iso_week_date(), (2020, 53, Friday)); - /// ``` - pub const fn to_iso_week_date(self) -> (i32, u8, Weekday) { - let (year, ordinal) = self.to_ordinal_date(); - let weekday = self.weekday(); - - match ((ordinal + 10 - weekday.number_from_monday() as u16) / 7) as u8 { - 0 => (year - 1, weeks_in_year(year - 1), weekday), - 53 if weeks_in_year(year) == 52 => (year + 1, 1, weekday), - week => (year, week, weekday), - } - } - - /// Get the weekday. - /// - /// ```rust - /// # use time::Weekday::*; - /// # use time_macros::date; - /// assert_eq!(date!(2019-01-01).weekday(), Tuesday); - /// assert_eq!(date!(2019-02-01).weekday(), Friday); - /// assert_eq!(date!(2019-03-01).weekday(), Friday); - /// assert_eq!(date!(2019-04-01).weekday(), Monday); - /// assert_eq!(date!(2019-05-01).weekday(), Wednesday); - /// assert_eq!(date!(2019-06-01).weekday(), Saturday); - /// assert_eq!(date!(2019-07-01).weekday(), Monday); - /// assert_eq!(date!(2019-08-01).weekday(), Thursday); - /// assert_eq!(date!(2019-09-01).weekday(), Sunday); - /// assert_eq!(date!(2019-10-01).weekday(), Tuesday); - /// assert_eq!(date!(2019-11-01).weekday(), Friday); - /// assert_eq!(date!(2019-12-01).weekday(), Sunday); - /// ``` - pub const fn weekday(self) -> Weekday { - match self.to_julian_day() % 7 { - -6 | 1 => Weekday::Tuesday, - -5 | 2 => Weekday::Wednesday, - -4 | 3 => Weekday::Thursday, - -3 | 4 => Weekday::Friday, - -2 | 5 => Weekday::Saturday, - -1 | 6 => Weekday::Sunday, - val => { - debug_assert!(val == 0); - Weekday::Monday - } - } - } - - /// Get the next calendar date. - /// - /// ```rust - /// # use time::Date; - /// # use time_macros::date; - /// assert_eq!(date!(2019-01-01).next_day(), Some(date!(2019-01-02))); - /// assert_eq!(date!(2019-01-31).next_day(), Some(date!(2019-02-01))); - /// assert_eq!(date!(2019-12-31).next_day(), Some(date!(2020-01-01))); - /// assert_eq!(Date::MAX.next_day(), None); - /// ``` - pub const fn next_day(self) -> Option<Self> { - if self.ordinal() == 366 || (self.ordinal() == 365 && !self.is_in_leap_year()) { - if self.value.get() == Self::MAX.value.get() { - None - } else { - // Safety: `ordinal` is not zero. - unsafe { Some(Self::__from_ordinal_date_unchecked(self.year() + 1, 1)) } - } - } else { - Some(Self { - // Safety: `ordinal` is not zero. - value: unsafe { NonZeroI32::new_unchecked(self.value.get() + 1) }, - }) - } - } - - /// Get the previous calendar date. - /// - /// ```rust - /// # use time::Date; - /// # use time_macros::date; - /// assert_eq!(date!(2019-01-02).previous_day(), Some(date!(2019-01-01))); - /// assert_eq!(date!(2019-02-01).previous_day(), Some(date!(2019-01-31))); - /// assert_eq!(date!(2020-01-01).previous_day(), Some(date!(2019-12-31))); - /// assert_eq!(Date::MIN.previous_day(), None); - /// ``` - pub const fn previous_day(self) -> Option<Self> { - if self.ordinal() != 1 { - Some(Self { - // Safety: `ordinal` is not zero. - value: unsafe { NonZeroI32::new_unchecked(self.value.get() - 1) }, - }) - } else if self.value.get() == Self::MIN.value.get() { - None - } else { - // Safety: `ordinal` is not zero. - Some(unsafe { - Self::__from_ordinal_date_unchecked(self.year() - 1, days_in_year(self.year() - 1)) - }) - } - } - - /// Calculates the first occurrence of a weekday that is strictly later than a given `Date`. - /// - /// # Panics - /// Panics if an overflow occurred. - /// - /// # Examples - /// ``` - /// # use time::Weekday; - /// # use time_macros::date; - /// assert_eq!( - /// date!(2023-06-28).next_occurrence(Weekday::Monday), - /// date!(2023-07-03) - /// ); - /// assert_eq!( - /// date!(2023-06-19).next_occurrence(Weekday::Monday), - /// date!(2023-06-26) - /// ); - /// ``` - pub const fn next_occurrence(self, weekday: Weekday) -> Self { - expect_opt!( - self.checked_next_occurrence(weekday), - "overflow calculating the next occurrence of a weekday" - ) - } - - /// Calculates the first occurrence of a weekday that is strictly earlier than a given `Date`. - /// - /// # Panics - /// Panics if an overflow occurred. - /// - /// # Examples - /// ``` - /// # use time::Weekday; - /// # use time_macros::date; - /// assert_eq!( - /// date!(2023-06-28).prev_occurrence(Weekday::Monday), - /// date!(2023-06-26) - /// ); - /// assert_eq!( - /// date!(2023-06-19).prev_occurrence(Weekday::Monday), - /// date!(2023-06-12) - /// ); - /// ``` - pub const fn prev_occurrence(self, weekday: Weekday) -> Self { - expect_opt!( - self.checked_prev_occurrence(weekday), - "overflow calculating the previous occurrence of a weekday" - ) - } - - /// Calculates the `n`th occurrence of a weekday that is strictly later than a given `Date`. - /// - /// # Panics - /// Panics if an overflow occurred or if `n == 0`. - /// - /// # Examples - /// ``` - /// # use time::Weekday; - /// # use time_macros::date; - /// assert_eq!( - /// date!(2023-06-25).nth_next_occurrence(Weekday::Monday, 5), - /// date!(2023-07-24) - /// ); - /// assert_eq!( - /// date!(2023-06-26).nth_next_occurrence(Weekday::Monday, 5), - /// date!(2023-07-31) - /// ); - /// ``` - pub const fn nth_next_occurrence(self, weekday: Weekday, n: u8) -> Self { - expect_opt!( - self.checked_nth_next_occurrence(weekday, n), - "overflow calculating the next occurrence of a weekday" - ) - } - - /// Calculates the `n`th occurrence of a weekday that is strictly earlier than a given `Date`. - /// - /// # Panics - /// Panics if an overflow occurred or if `n == 0`. - /// - /// # Examples - /// ``` - /// # use time::Weekday; - /// # use time_macros::date; - /// assert_eq!( - /// date!(2023-06-27).nth_prev_occurrence(Weekday::Monday, 3), - /// date!(2023-06-12) - /// ); - /// assert_eq!( - /// date!(2023-06-26).nth_prev_occurrence(Weekday::Monday, 3), - /// date!(2023-06-05) - /// ); - /// ``` - pub const fn nth_prev_occurrence(self, weekday: Weekday, n: u8) -> Self { - expect_opt!( - self.checked_nth_prev_occurrence(weekday, n), - "overflow calculating the previous occurrence of a weekday" - ) - } - - /// Get the Julian day for the date. - /// - /// ```rust - /// # use time_macros::date; - /// assert_eq!(date!(-4713 - 11 - 24).to_julian_day(), 0); - /// assert_eq!(date!(2000-01-01).to_julian_day(), 2_451_545); - /// assert_eq!(date!(2019-01-01).to_julian_day(), 2_458_485); - /// assert_eq!(date!(2019-12-31).to_julian_day(), 2_458_849); - /// ``` - pub const fn to_julian_day(self) -> i32 { - let (year, ordinal) = self.to_ordinal_date(); - - // The algorithm requires a non-negative year. Add the lowest value to make it so. This is - // adjusted for at the end with the final subtraction. - let adj_year = year + 999_999; - let century = adj_year / 100; - - let days_before_year = (1461 * adj_year as i64 / 4) as i32 - century + century / 4; - days_before_year + ordinal as i32 - 363_521_075 - } - - /// Computes `self + duration`, returning `None` if an overflow occurred. - /// - /// ```rust - /// # use time::{Date, ext::NumericalDuration}; - /// # use time_macros::date; - /// assert_eq!(Date::MAX.checked_add(1.days()), None); - /// assert_eq!(Date::MIN.checked_add((-2).days()), None); - /// assert_eq!( - /// date!(2020-12-31).checked_add(2.days()), - /// Some(date!(2021-01-02)) - /// ); - /// ``` - /// - /// # Note - /// - /// This function only takes whole days into account. - /// - /// ```rust - /// # use time::{Date, ext::NumericalDuration}; - /// # use time_macros::date; - /// assert_eq!(Date::MAX.checked_add(23.hours()), Some(Date::MAX)); - /// assert_eq!(Date::MIN.checked_add((-23).hours()), Some(Date::MIN)); - /// assert_eq!( - /// date!(2020-12-31).checked_add(23.hours()), - /// Some(date!(2020-12-31)) - /// ); - /// assert_eq!( - /// date!(2020-12-31).checked_add(47.hours()), - /// Some(date!(2021-01-01)) - /// ); - /// ``` - pub const fn checked_add(self, duration: Duration) -> Option<Self> { - let whole_days = duration.whole_days(); - if whole_days < i32::MIN as i64 || whole_days > i32::MAX as i64 { - return None; - } - - let julian_day = const_try_opt!(self.to_julian_day().checked_add(whole_days as i32)); - if let Ok(date) = Self::from_julian_day(julian_day) { - Some(date) - } else { - None - } - } - - /// Computes `self + duration`, returning `None` if an overflow occurred. - /// - /// ```rust - /// # use time::{Date, ext::NumericalStdDuration}; - /// # use time_macros::date; - /// assert_eq!(Date::MAX.checked_add_std(1.std_days()), None); - /// assert_eq!( - /// date!(2020-12-31).checked_add_std(2.std_days()), - /// Some(date!(2021-01-02)) - /// ); - /// ``` - /// - /// # Note - /// - /// This function only takes whole days into account. - /// - /// ```rust - /// # use time::{Date, ext::NumericalStdDuration}; - /// # use time_macros::date; - /// assert_eq!(Date::MAX.checked_add_std(23.std_hours()), Some(Date::MAX)); - /// assert_eq!( - /// date!(2020-12-31).checked_add_std(23.std_hours()), - /// Some(date!(2020-12-31)) - /// ); - /// assert_eq!( - /// date!(2020-12-31).checked_add_std(47.std_hours()), - /// Some(date!(2021-01-01)) - /// ); - /// ``` - pub const fn checked_add_std(self, duration: StdDuration) -> Option<Self> { - let whole_days = duration.as_secs() / Second::per(Day) as u64; - if whole_days > i32::MAX as u64 { - return None; - } - - let julian_day = const_try_opt!(self.to_julian_day().checked_add(whole_days as i32)); - if let Ok(date) = Self::from_julian_day(julian_day) { - Some(date) - } else { - None - } - } - - /// Computes `self - duration`, returning `None` if an overflow occurred. - /// - /// ``` - /// # use time::{Date, ext::NumericalDuration}; - /// # use time_macros::date; - /// assert_eq!(Date::MAX.checked_sub((-2).days()), None); - /// assert_eq!(Date::MIN.checked_sub(1.days()), None); - /// assert_eq!( - /// date!(2020-12-31).checked_sub(2.days()), - /// Some(date!(2020-12-29)) - /// ); - /// ``` - /// - /// # Note - /// - /// This function only takes whole days into account. - /// - /// ``` - /// # use time::{Date, ext::NumericalDuration}; - /// # use time_macros::date; - /// assert_eq!(Date::MAX.checked_sub((-23).hours()), Some(Date::MAX)); - /// assert_eq!(Date::MIN.checked_sub(23.hours()), Some(Date::MIN)); - /// assert_eq!( - /// date!(2020-12-31).checked_sub(23.hours()), - /// Some(date!(2020-12-31)) - /// ); - /// assert_eq!( - /// date!(2020-12-31).checked_sub(47.hours()), - /// Some(date!(2020-12-30)) - /// ); - /// ``` - pub const fn checked_sub(self, duration: Duration) -> Option<Self> { - let whole_days = duration.whole_days(); - if whole_days < i32::MIN as i64 || whole_days > i32::MAX as i64 { - return None; - } - - let julian_day = const_try_opt!(self.to_julian_day().checked_sub(whole_days as i32)); - if let Ok(date) = Self::from_julian_day(julian_day) { - Some(date) - } else { - None - } - } - - /// Computes `self - duration`, returning `None` if an overflow occurred. - /// - /// ``` - /// # use time::{Date, ext::NumericalStdDuration}; - /// # use time_macros::date; - /// assert_eq!(Date::MIN.checked_sub_std(1.std_days()), None); - /// assert_eq!( - /// date!(2020-12-31).checked_sub_std(2.std_days()), - /// Some(date!(2020-12-29)) - /// ); - /// ``` - /// - /// # Note - /// - /// This function only takes whole days into account. - /// - /// ``` - /// # use time::{Date, ext::NumericalStdDuration}; - /// # use time_macros::date; - /// assert_eq!(Date::MIN.checked_sub_std(23.std_hours()), Some(Date::MIN)); - /// assert_eq!( - /// date!(2020-12-31).checked_sub_std(23.std_hours()), - /// Some(date!(2020-12-31)) - /// ); - /// assert_eq!( - /// date!(2020-12-31).checked_sub_std(47.std_hours()), - /// Some(date!(2020-12-30)) - /// ); - /// ``` - pub const fn checked_sub_std(self, duration: StdDuration) -> Option<Self> { - let whole_days = duration.as_secs() / Second::per(Day) as u64; - if whole_days > i32::MAX as u64 { - return None; - } - - let julian_day = const_try_opt!(self.to_julian_day().checked_sub(whole_days as i32)); - if let Ok(date) = Self::from_julian_day(julian_day) { - Some(date) - } else { - None - } - } - - /// Calculates the first occurrence of a weekday that is strictly later than a given `Date`. - /// Returns `None` if an overflow occurred. - pub(crate) const fn checked_next_occurrence(self, weekday: Weekday) -> Option<Self> { - let day_diff = match weekday as i8 - self.weekday() as i8 { - 1 | -6 => 1, - 2 | -5 => 2, - 3 | -4 => 3, - 4 | -3 => 4, - 5 | -2 => 5, - 6 | -1 => 6, - val => { - debug_assert!(val == 0); - 7 - } - }; - - self.checked_add(Duration::days(day_diff)) - } - - /// Calculates the first occurrence of a weekday that is strictly earlier than a given `Date`. - /// Returns `None` if an overflow occurred. - pub(crate) const fn checked_prev_occurrence(self, weekday: Weekday) -> Option<Self> { - let day_diff = match weekday as i8 - self.weekday() as i8 { - 1 | -6 => 6, - 2 | -5 => 5, - 3 | -4 => 4, - 4 | -3 => 3, - 5 | -2 => 2, - 6 | -1 => 1, - val => { - debug_assert!(val == 0); - 7 - } - }; - - self.checked_sub(Duration::days(day_diff)) - } - - /// Calculates the `n`th occurrence of a weekday that is strictly later than a given `Date`. - /// Returns `None` if an overflow occurred or if `n == 0`. - pub(crate) const fn checked_nth_next_occurrence(self, weekday: Weekday, n: u8) -> Option<Self> { - if n == 0 { - return None; - } - - const_try_opt!(self.checked_next_occurrence(weekday)) - .checked_add(Duration::weeks(n as i64 - 1)) - } - - /// Calculates the `n`th occurrence of a weekday that is strictly earlier than a given `Date`. - /// Returns `None` if an overflow occurred or if `n == 0`. - pub(crate) const fn checked_nth_prev_occurrence(self, weekday: Weekday, n: u8) -> Option<Self> { - if n == 0 { - return None; - } - - const_try_opt!(self.checked_prev_occurrence(weekday)) - .checked_sub(Duration::weeks(n as i64 - 1)) - } - - /// Computes `self + duration`, saturating value on overflow. - /// - /// ```rust - /// # use time::{Date, ext::NumericalDuration}; - /// # use time_macros::date; - /// assert_eq!(Date::MAX.saturating_add(1.days()), Date::MAX); - /// assert_eq!(Date::MIN.saturating_add((-2).days()), Date::MIN); - /// assert_eq!( - /// date!(2020-12-31).saturating_add(2.days()), - /// date!(2021-01-02) - /// ); - /// ``` - /// - /// # Note - /// - /// This function only takes whole days into account. - /// - /// ```rust - /// # use time::ext::NumericalDuration; - /// # use time_macros::date; - /// assert_eq!( - /// date!(2020-12-31).saturating_add(23.hours()), - /// date!(2020-12-31) - /// ); - /// assert_eq!( - /// date!(2020-12-31).saturating_add(47.hours()), - /// date!(2021-01-01) - /// ); - /// ``` - pub const fn saturating_add(self, duration: Duration) -> Self { - if let Some(datetime) = self.checked_add(duration) { - datetime - } else if duration.is_negative() { - Self::MIN - } else { - debug_assert!(duration.is_positive()); - Self::MAX - } - } - - /// Computes `self - duration`, saturating value on overflow. - /// - /// ``` - /// # use time::{Date, ext::NumericalDuration}; - /// # use time_macros::date; - /// assert_eq!(Date::MAX.saturating_sub((-2).days()), Date::MAX); - /// assert_eq!(Date::MIN.saturating_sub(1.days()), Date::MIN); - /// assert_eq!( - /// date!(2020-12-31).saturating_sub(2.days()), - /// date!(2020-12-29) - /// ); - /// ``` - /// - /// # Note - /// - /// This function only takes whole days into account. - /// - /// ``` - /// # use time::ext::NumericalDuration; - /// # use time_macros::date; - /// assert_eq!( - /// date!(2020-12-31).saturating_sub(23.hours()), - /// date!(2020-12-31) - /// ); - /// assert_eq!( - /// date!(2020-12-31).saturating_sub(47.hours()), - /// date!(2020-12-30) - /// ); - /// ``` - pub const fn saturating_sub(self, duration: Duration) -> Self { - if let Some(datetime) = self.checked_sub(duration) { - datetime - } else if duration.is_negative() { - Self::MAX - } else { - debug_assert!(duration.is_positive()); - Self::MIN - } - } - - /// Replace the year. The month and day will be unchanged. - /// - /// ```rust - /// # use time_macros::date; - /// assert_eq!( - /// date!(2022-02-18).replace_year(2019), - /// Ok(date!(2019-02-18)) - /// ); - /// assert!(date!(2022-02-18).replace_year(-1_000_000_000).is_err()); // -1_000_000_000 isn't a valid year - /// assert!(date!(2022-02-18).replace_year(1_000_000_000).is_err()); // 1_000_000_000 isn't a valid year - /// ``` - #[must_use = "This method does not mutate the original `Date`."] - pub const fn replace_year(self, year: i32) -> Result<Self, error::ComponentRange> { - ensure_ranged!(Year: year); - - let ordinal = self.ordinal(); - - // Dates in January and February are unaffected by leap years. - if ordinal <= 59 { - // Safety: `ordinal` is not zero. - return Ok(unsafe { Self::__from_ordinal_date_unchecked(year, ordinal) }); - } - - match (self.is_in_leap_year(), is_leap_year(year)) { - (false, false) | (true, true) => { - // Safety: `ordinal` is not zero. - Ok(unsafe { Self::__from_ordinal_date_unchecked(year, ordinal) }) - } - // February 29 does not exist in common years. - (true, false) if ordinal == 60 => Err(error::ComponentRange { - name: "day", - value: 29, - minimum: 1, - maximum: 28, - conditional_message: Some("for the given month and year"), - }), - // We're going from a common year to a leap year. Shift dates in March and later by - // one day. - // Safety: `ordinal` is not zero. - (false, true) => Ok(unsafe { Self::__from_ordinal_date_unchecked(year, ordinal + 1) }), - // We're going from a leap year to a common year. Shift dates in January and - // February by one day. - // Safety: `ordinal` is not zero. - (true, false) => Ok(unsafe { Self::__from_ordinal_date_unchecked(year, ordinal - 1) }), - } - } - - /// Replace the month of the year. - /// - /// ```rust - /// # use time_macros::date; - /// # use time::Month; - /// assert_eq!( - /// date!(2022-02-18).replace_month(Month::January), - /// Ok(date!(2022-01-18)) - /// ); - /// assert!(date!(2022-01-30) - /// .replace_month(Month::February) - /// .is_err()); // 30 isn't a valid day in February - /// ``` - #[must_use = "This method does not mutate the original `Date`."] - pub const fn replace_month(self, month: Month) -> Result<Self, error::ComponentRange> { - let (year, _, day) = self.to_calendar_date(); - Self::from_calendar_date(year, month, day) - } - - /// Replace the day of the month. - /// - /// ```rust - /// # use time_macros::date; - /// assert_eq!(date!(2022-02-18).replace_day(1), Ok(date!(2022-02-01))); - /// assert!(date!(2022-02-18).replace_day(0).is_err()); // 0 isn't a valid day - /// assert!(date!(2022-02-18).replace_day(30).is_err()); // 30 isn't a valid day in February - /// ``` - #[must_use = "This method does not mutate the original `Date`."] - pub const fn replace_day(self, day: u8) -> Result<Self, error::ComponentRange> { - match day { - 1..=28 => {} - 29..=31 if day <= self.month().length(self.year()) => {} - _ => { - return Err(error::ComponentRange { - name: "day", - minimum: 1, - maximum: self.month().length(self.year()) as i64, - value: day as i64, - conditional_message: Some("for the given month and year"), - }); - } - } - - // Safety: `ordinal` is not zero. - Ok(unsafe { - Self::__from_ordinal_date_unchecked( - self.year(), - (self.ordinal() as i16 - self.day() as i16 + day as i16) as u16, - ) - }) - } - - /// Replace the day of the year. - /// - /// ```rust - /// # use time_macros::date; - /// assert_eq!(date!(2022-049).replace_ordinal(1), Ok(date!(2022-001))); - /// assert!(date!(2022-049).replace_ordinal(0).is_err()); // 0 isn't a valid ordinal - /// assert!(date!(2022-049).replace_ordinal(366).is_err()); // 2022 isn't a leap year - /// ```` - #[must_use = "This method does not mutate the original `Date`."] - pub const fn replace_ordinal(self, ordinal: u16) -> Result<Self, error::ComponentRange> { - match ordinal { - 1..=365 => {} - 366 if self.is_in_leap_year() => {} - _ => { - return Err(error::ComponentRange { - name: "ordinal", - minimum: 1, - maximum: days_in_year(self.year()) as i64, - value: ordinal as i64, - conditional_message: Some("for the given year"), - }); - } - } - - // Safety: `ordinal` is in range. - Ok(unsafe { Self::__from_ordinal_date_unchecked(self.year(), ordinal) }) - } -} - -/// Methods to add a [`Time`] component, resulting in a [`PrimitiveDateTime`]. -impl Date { - /// Create a [`PrimitiveDateTime`] using the existing date. The [`Time`] component will be set - /// to midnight. - /// - /// ```rust - /// # use time_macros::{date, datetime}; - /// assert_eq!(date!(1970-01-01).midnight(), datetime!(1970-01-01 0:00)); - /// ``` - pub const fn midnight(self) -> PrimitiveDateTime { - PrimitiveDateTime::new(self, Time::MIDNIGHT) - } - - /// Create a [`PrimitiveDateTime`] using the existing date and the provided [`Time`]. - /// - /// ```rust - /// # use time_macros::{date, datetime, time}; - /// assert_eq!( - /// date!(1970-01-01).with_time(time!(0:00)), - /// datetime!(1970-01-01 0:00), - /// ); - /// ``` - pub const fn with_time(self, time: Time) -> PrimitiveDateTime { - PrimitiveDateTime::new(self, time) - } - - /// Attempt to create a [`PrimitiveDateTime`] using the existing date and the provided time. - /// - /// ```rust - /// # use time_macros::date; - /// assert!(date!(1970-01-01).with_hms(0, 0, 0).is_ok()); - /// assert!(date!(1970-01-01).with_hms(24, 0, 0).is_err()); - /// ``` - pub const fn with_hms( - self, - hour: u8, - minute: u8, - second: u8, - ) -> Result<PrimitiveDateTime, error::ComponentRange> { - Ok(PrimitiveDateTime::new( - self, - const_try!(Time::from_hms(hour, minute, second)), - )) - } - - /// Attempt to create a [`PrimitiveDateTime`] using the existing date and the provided time. - /// - /// ```rust - /// # use time_macros::date; - /// assert!(date!(1970-01-01).with_hms_milli(0, 0, 0, 0).is_ok()); - /// assert!(date!(1970-01-01).with_hms_milli(24, 0, 0, 0).is_err()); - /// ``` - pub const fn with_hms_milli( - self, - hour: u8, - minute: u8, - second: u8, - millisecond: u16, - ) -> Result<PrimitiveDateTime, error::ComponentRange> { - Ok(PrimitiveDateTime::new( - self, - const_try!(Time::from_hms_milli(hour, minute, second, millisecond)), - )) - } - - /// Attempt to create a [`PrimitiveDateTime`] using the existing date and the provided time. - /// - /// ```rust - /// # use time_macros::date; - /// assert!(date!(1970-01-01).with_hms_micro(0, 0, 0, 0).is_ok()); - /// assert!(date!(1970-01-01).with_hms_micro(24, 0, 0, 0).is_err()); - /// ``` - pub const fn with_hms_micro( - self, - hour: u8, - minute: u8, - second: u8, - microsecond: u32, - ) -> Result<PrimitiveDateTime, error::ComponentRange> { - Ok(PrimitiveDateTime::new( - self, - const_try!(Time::from_hms_micro(hour, minute, second, microsecond)), - )) - } - - /// Attempt to create a [`PrimitiveDateTime`] using the existing date and the provided time. - /// - /// ```rust - /// # use time_macros::date; - /// assert!(date!(1970-01-01).with_hms_nano(0, 0, 0, 0).is_ok()); - /// assert!(date!(1970-01-01).with_hms_nano(24, 0, 0, 0).is_err()); - /// ``` - pub const fn with_hms_nano( - self, - hour: u8, - minute: u8, - second: u8, - nanosecond: u32, - ) -> Result<PrimitiveDateTime, error::ComponentRange> { - Ok(PrimitiveDateTime::new( - self, - const_try!(Time::from_hms_nano(hour, minute, second, nanosecond)), - )) - } -} - -#[cfg(feature = "formatting")] -impl Date { - /// Format the `Date` using the provided [format description](crate::format_description). - pub fn format_into( - self, - output: &mut (impl io::Write + ?Sized), - format: &(impl Formattable + ?Sized), - ) -> Result<usize, error::Format> { - format.format_into(output, Some(self), None, None) - } - - /// Format the `Date` using the provided [format description](crate::format_description). - /// - /// ```rust - /// # use time::{format_description}; - /// # use time_macros::date; - /// let format = format_description::parse("[year]-[month]-[day]")?; - /// assert_eq!(date!(2020-01-02).format(&format)?, "2020-01-02"); - /// # Ok::<_, time::Error>(()) - /// ``` - pub fn format(self, format: &(impl Formattable + ?Sized)) -> Result<String, error::Format> { - format.format(Some(self), None, None) - } -} - -#[cfg(feature = "parsing")] -impl Date { - /// Parse a `Date` from the input using the provided [format - /// description](crate::format_description). - /// - /// ```rust - /// # use time::Date; - /// # use time_macros::{date, format_description}; - /// let format = format_description!("[year]-[month]-[day]"); - /// assert_eq!(Date::parse("2020-01-02", &format)?, date!(2020-01-02)); - /// # Ok::<_, time::Error>(()) - /// ``` - pub fn parse( - input: &str, - description: &(impl Parsable + ?Sized), - ) -> Result<Self, error::Parse> { - description.parse_date(input.as_bytes()) - } -} - -mod private { - #[non_exhaustive] - #[derive(Debug, Clone, Copy)] - pub struct DateMetadata { - /// The width of the year component, including the sign. - pub(super) year_width: u8, - /// Whether the sign should be displayed. - pub(super) display_sign: bool, - pub(super) year: i32, - pub(super) month: u8, - pub(super) day: u8, - } -} -use private::DateMetadata; - -impl SmartDisplay for Date { - type Metadata = DateMetadata; - - fn metadata(&self, _: FormatterOptions) -> Metadata<Self> { - let (year, month, day) = self.to_calendar_date(); - - // There is a minimum of four digits for any year. - let mut year_width = cmp::max(year.unsigned_abs().num_digits(), 4); - let display_sign = if !(0..10_000).contains(&year) { - // An extra character is required for the sign. - year_width += 1; - true - } else { - false - }; - - let formatted_width = year_width.extend::<usize>() - + smart_display::padded_width_of!( - "-", - u8::from(month) => width(2), - "-", - day => width(2), - ); - - Metadata::new( - formatted_width, - self, - DateMetadata { - year_width, - display_sign, - year, - month: u8::from(month), - day, - }, - ) - } - - fn fmt_with_metadata( - &self, - f: &mut fmt::Formatter<'_>, - metadata: Metadata<Self>, - ) -> fmt::Result { - let DateMetadata { - year_width, - display_sign, - year, - month, - day, - } = *metadata; - let year_width = year_width.extend(); - - if display_sign { - f.pad_with_width( - metadata.unpadded_width(), - format_args!("{year:+0year_width$}-{month:02}-{day:02}"), - ) - } else { - f.pad_with_width( - metadata.unpadded_width(), - format_args!("{year:0year_width$}-{month:02}-{day:02}"), - ) - } - } -} - -impl fmt::Display for Date { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - SmartDisplay::fmt(self, f) - } -} - -impl fmt::Debug for Date { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { - fmt::Display::fmt(self, f) - } -} - -impl Add<Duration> for Date { - type Output = Self; - - /// # Panics - /// - /// This may panic if an overflow occurs. - fn add(self, duration: Duration) -> Self::Output { - self.checked_add(duration) - .expect("overflow adding duration to date") - } -} - -impl Add<StdDuration> for Date { - type Output = Self; - - /// # Panics - /// - /// This may panic if an overflow occurs. - fn add(self, duration: StdDuration) -> Self::Output { - self.checked_add_std(duration) - .expect("overflow adding duration to date") - } -} - -impl_add_assign!(Date: Duration, StdDuration); - -impl Sub<Duration> for Date { - type Output = Self; - - /// # Panics - /// - /// This may panic if an overflow occurs. - fn sub(self, duration: Duration) -> Self::Output { - self.checked_sub(duration) - .expect("overflow subtracting duration from date") - } -} - -impl Sub<StdDuration> for Date { - type Output = Self; - - /// # Panics - /// - /// This may panic if an overflow occurs. - fn sub(self, duration: StdDuration) -> Self::Output { - self.checked_sub_std(duration) - .expect("overflow subtracting duration from date") - } -} - -impl_sub_assign!(Date: Duration, StdDuration); - -impl Sub for Date { - type Output = Duration; - - fn sub(self, other: Self) -> Self::Output { - Duration::days((self.to_julian_day() - other.to_julian_day()).extend()) - } -} diff --git a/vendor/time/src/duration.rs b/vendor/time/src/duration.rs deleted file mode 100644 index b86bfe7c..00000000 --- a/vendor/time/src/duration.rs +++ /dev/null @@ -1,1598 +0,0 @@ -//! The [`Duration`] struct and its associated `impl`s. - -use core::cmp::Ordering; -use core::fmt; -use core::iter::Sum; -use core::ops::{Add, AddAssign, Div, Mul, Neg, Sub, SubAssign}; -use core::time::Duration as StdDuration; -#[cfg(feature = "std")] -use std::time::SystemTime; - -use deranged::RangedI32; -use num_conv::prelude::*; - -use crate::convert::*; -use crate::error; -use crate::internal_macros::{ - const_try_opt, expect_opt, impl_add_assign, impl_div_assign, impl_mul_assign, impl_sub_assign, -}; -#[cfg(feature = "std")] -#[allow(deprecated)] -use crate::Instant; - -/// By explicitly inserting this enum where padding is expected, the compiler is able to better -/// perform niche value optimization. -#[repr(u32)] -#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] -pub(crate) enum Padding { - #[allow(clippy::missing_docs_in_private_items)] - Optimize, -} - -/// The type of the `nanosecond` field of `Duration`. -type Nanoseconds = - RangedI32<{ -(Nanosecond::per(Second) as i32 - 1) }, { Nanosecond::per(Second) as i32 - 1 }>; - -/// A span of time with nanosecond precision. -/// -/// Each `Duration` is composed of a whole number of seconds and a fractional part represented in -/// nanoseconds. -/// -/// This implementation allows for negative durations, unlike [`core::time::Duration`]. -#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] -pub struct Duration { - /// Number of whole seconds. - seconds: i64, - /// Number of nanoseconds within the second. The sign always matches the `seconds` field. - // Sign must match that of `seconds` (though this is not a safety requirement). - nanoseconds: Nanoseconds, - padding: Padding, -} - -impl fmt::Debug for Duration { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("Duration") - .field("seconds", &self.seconds) - .field("nanoseconds", &self.nanoseconds) - .finish() - } -} - -impl Default for Duration { - fn default() -> Self { - Self { - seconds: 0, - nanoseconds: Nanoseconds::new_static::<0>(), - padding: Padding::Optimize, - } - } -} - -/// This is adapted from the [`std` implementation][std], which uses mostly bit -/// operations to ensure the highest precision: -/// -/// Changes from `std` are marked and explained below. -/// -/// [std]: https://github.com/rust-lang/rust/blob/3a37c2f0523c87147b64f1b8099fc9df22e8c53e/library/core/src/time.rs#L1262-L1340 -#[rustfmt::skip] // Skip `rustfmt` because it reformats the arguments of the macro weirdly. -macro_rules! try_from_secs { - ( - secs = $secs: expr, - mantissa_bits = $mant_bits: literal, - exponent_bits = $exp_bits: literal, - offset = $offset: literal, - bits_ty = $bits_ty:ty, - bits_ty_signed = $bits_ty_signed:ty, - double_ty = $double_ty:ty, - float_ty = $float_ty:ty, - is_nan = $is_nan:expr, - is_overflow = $is_overflow:expr, - ) => {{ - 'value: { - const MIN_EXP: i16 = 1 - (1i16 << $exp_bits) / 2; - const MANT_MASK: $bits_ty = (1 << $mant_bits) - 1; - const EXP_MASK: $bits_ty = (1 << $exp_bits) - 1; - - // Change from std: No error check for negative values necessary. - - let bits = $secs.to_bits(); - let mant = (bits & MANT_MASK) | (MANT_MASK + 1); - let exp = ((bits >> $mant_bits) & EXP_MASK) as i16 + MIN_EXP; - - let (secs, nanos) = if exp < -31 { - // the input represents less than 1ns and can not be rounded to it - (0u64, 0u32) - } else if exp < 0 { - // the input is less than 1 second - let t = <$double_ty>::from(mant) << ($offset + exp); - let nanos_offset = $mant_bits + $offset; - let nanos_tmp = u128::from(Nanosecond::per(Second)) * u128::from(t); - let nanos = (nanos_tmp >> nanos_offset) as u32; - - let rem_mask = (1 << nanos_offset) - 1; - let rem_msb_mask = 1 << (nanos_offset - 1); - let rem = nanos_tmp & rem_mask; - let is_tie = rem == rem_msb_mask; - let is_even = (nanos & 1) == 0; - let rem_msb = nanos_tmp & rem_msb_mask == 0; - let add_ns = !(rem_msb || (is_even && is_tie)); - - // f32 does not have enough precision to trigger the second branch - // since it can not represent numbers between 0.999_999_940_395 and 1.0. - let nanos = nanos + add_ns as u32; - if ($mant_bits == 23) || (nanos != Nanosecond::per(Second)) { - (0, nanos) - } else { - (1, 0) - } - } else if exp < $mant_bits { - let secs = u64::from(mant >> ($mant_bits - exp)); - let t = <$double_ty>::from((mant << exp) & MANT_MASK); - let nanos_offset = $mant_bits; - let nanos_tmp = <$double_ty>::from(Nanosecond::per(Second)) * t; - let nanos = (nanos_tmp >> nanos_offset) as u32; - - let rem_mask = (1 << nanos_offset) - 1; - let rem_msb_mask = 1 << (nanos_offset - 1); - let rem = nanos_tmp & rem_mask; - let is_tie = rem == rem_msb_mask; - let is_even = (nanos & 1) == 0; - let rem_msb = nanos_tmp & rem_msb_mask == 0; - let add_ns = !(rem_msb || (is_even && is_tie)); - - // f32 does not have enough precision to trigger the second branch. - // For example, it can not represent numbers between 1.999_999_880... - // and 2.0. Bigger values result in even smaller precision of the - // fractional part. - let nanos = nanos + add_ns as u32; - if ($mant_bits == 23) || (nanos != Nanosecond::per(Second)) { - (secs, nanos) - } else { - (secs + 1, 0) - } - } else if exp < 63 { - // Change from std: The exponent here is 63 instead of 64, - // because i64::MAX + 1 is 2^63. - - // the input has no fractional part - let secs = u64::from(mant) << (exp - $mant_bits); - (secs, 0) - } else if bits == (i64::MIN as $float_ty).to_bits() { - // Change from std: Signed integers are asymmetrical in that - // iN::MIN is -iN::MAX - 1. So for example i8 covers the - // following numbers -128..=127. The check above (exp < 63) - // doesn't cover i64::MIN as that is -2^63, so we have this - // additional case to handle the asymmetry of iN::MIN. - break 'value Self::new_ranged_unchecked(i64::MIN, Nanoseconds::new_static::<0>()); - } else if $secs.is_nan() { - // Change from std: std doesn't differentiate between the error - // cases. - $is_nan - } else { - $is_overflow - }; - - // Change from std: All the code is mostly unmodified in that it - // simply calculates an unsigned integer. Here we extract the sign - // bit and assign it to the number. We basically manually do two's - // complement here, we could also use an if and just negate the - // numbers based on the sign, but it turns out to be quite a bit - // slower. - let mask = (bits as $bits_ty_signed) >> ($mant_bits + $exp_bits); - #[allow(trivial_numeric_casts)] - let secs_signed = ((secs as i64) ^ (mask as i64)) - (mask as i64); - #[allow(trivial_numeric_casts)] - let nanos_signed = ((nanos as i32) ^ (mask as i32)) - (mask as i32); - // Safety: `nanos_signed` is in range. - unsafe { Self::new_unchecked(secs_signed, nanos_signed) } - } - }}; -} - -impl Duration { - /// Equivalent to `0.seconds()`. - /// - /// ```rust - /// # use time::{Duration, ext::NumericalDuration}; - /// assert_eq!(Duration::ZERO, 0.seconds()); - /// ``` - pub const ZERO: Self = Self::seconds(0); - - /// Equivalent to `1.nanoseconds()`. - /// - /// ```rust - /// # use time::{Duration, ext::NumericalDuration}; - /// assert_eq!(Duration::NANOSECOND, 1.nanoseconds()); - /// ``` - pub const NANOSECOND: Self = Self::nanoseconds(1); - - /// Equivalent to `1.microseconds()`. - /// - /// ```rust - /// # use time::{Duration, ext::NumericalDuration}; - /// assert_eq!(Duration::MICROSECOND, 1.microseconds()); - /// ``` - pub const MICROSECOND: Self = Self::microseconds(1); - - /// Equivalent to `1.milliseconds()`. - /// - /// ```rust - /// # use time::{Duration, ext::NumericalDuration}; - /// assert_eq!(Duration::MILLISECOND, 1.milliseconds()); - /// ``` - pub const MILLISECOND: Self = Self::milliseconds(1); - - /// Equivalent to `1.seconds()`. - /// - /// ```rust - /// # use time::{Duration, ext::NumericalDuration}; - /// assert_eq!(Duration::SECOND, 1.seconds()); - /// ``` - pub const SECOND: Self = Self::seconds(1); - - /// Equivalent to `1.minutes()`. - /// - /// ```rust - /// # use time::{Duration, ext::NumericalDuration}; - /// assert_eq!(Duration::MINUTE, 1.minutes()); - /// ``` - pub const MINUTE: Self = Self::minutes(1); - - /// Equivalent to `1.hours()`. - /// - /// ```rust - /// # use time::{Duration, ext::NumericalDuration}; - /// assert_eq!(Duration::HOUR, 1.hours()); - /// ``` - pub const HOUR: Self = Self::hours(1); - - /// Equivalent to `1.days()`. - /// - /// ```rust - /// # use time::{Duration, ext::NumericalDuration}; - /// assert_eq!(Duration::DAY, 1.days()); - /// ``` - pub const DAY: Self = Self::days(1); - - /// Equivalent to `1.weeks()`. - /// - /// ```rust - /// # use time::{Duration, ext::NumericalDuration}; - /// assert_eq!(Duration::WEEK, 1.weeks()); - /// ``` - pub const WEEK: Self = Self::weeks(1); - - /// The minimum possible duration. Adding any negative duration to this will cause an overflow. - pub const MIN: Self = Self::new_ranged(i64::MIN, Nanoseconds::MIN); - - /// The maximum possible duration. Adding any positive duration to this will cause an overflow. - pub const MAX: Self = Self::new_ranged(i64::MAX, Nanoseconds::MAX); - - /// Check if a duration is exactly zero. - /// - /// ```rust - /// # use time::ext::NumericalDuration; - /// assert!(0.seconds().is_zero()); - /// assert!(!1.nanoseconds().is_zero()); - /// ``` - pub const fn is_zero(self) -> bool { - self.seconds == 0 && self.nanoseconds.get() == 0 - } - - /// Check if a duration is negative. - /// - /// ```rust - /// # use time::ext::NumericalDuration; - /// assert!((-1).seconds().is_negative()); - /// assert!(!0.seconds().is_negative()); - /// assert!(!1.seconds().is_negative()); - /// ``` - pub const fn is_negative(self) -> bool { - self.seconds < 0 || self.nanoseconds.get() < 0 - } - - /// Check if a duration is positive. - /// - /// ```rust - /// # use time::ext::NumericalDuration; - /// assert!(1.seconds().is_positive()); - /// assert!(!0.seconds().is_positive()); - /// assert!(!(-1).seconds().is_positive()); - /// ``` - pub const fn is_positive(self) -> bool { - self.seconds > 0 || self.nanoseconds.get() > 0 - } - - /// Get the absolute value of the duration. - /// - /// This method saturates the returned value if it would otherwise overflow. - /// - /// ```rust - /// # use time::ext::NumericalDuration; - /// assert_eq!(1.seconds().abs(), 1.seconds()); - /// assert_eq!(0.seconds().abs(), 0.seconds()); - /// assert_eq!((-1).seconds().abs(), 1.seconds()); - /// ``` - pub const fn abs(self) -> Self { - match self.seconds.checked_abs() { - Some(seconds) => Self::new_ranged_unchecked(seconds, self.nanoseconds.abs()), - None => Self::MAX, - } - } - - /// Convert the existing `Duration` to a `std::time::Duration` and its sign. This returns a - /// [`std::time::Duration`] and does not saturate the returned value (unlike [`Duration::abs`]). - /// - /// ```rust - /// # use time::ext::{NumericalDuration, NumericalStdDuration}; - /// assert_eq!(1.seconds().unsigned_abs(), 1.std_seconds()); - /// assert_eq!(0.seconds().unsigned_abs(), 0.std_seconds()); - /// assert_eq!((-1).seconds().unsigned_abs(), 1.std_seconds()); - /// ``` - pub const fn unsigned_abs(self) -> StdDuration { - StdDuration::new( - self.seconds.unsigned_abs(), - self.nanoseconds.get().unsigned_abs(), - ) - } - - /// Create a new `Duration` without checking the validity of the components. - /// - /// # Safety - /// - /// - `nanoseconds` must be in the range `-999_999_999..=999_999_999`. - /// - /// While the sign of `nanoseconds` is required to be the same as the sign of `seconds`, this is - /// not a safety invariant. - pub(crate) const unsafe fn new_unchecked(seconds: i64, nanoseconds: i32) -> Self { - Self::new_ranged_unchecked( - seconds, - // Safety: The caller must uphold the safety invariants. - unsafe { Nanoseconds::new_unchecked(nanoseconds) }, - ) - } - - /// Create a new `Duration` without checking the validity of the components. - pub(crate) const fn new_ranged_unchecked(seconds: i64, nanoseconds: Nanoseconds) -> Self { - if seconds < 0 { - debug_assert!(nanoseconds.get() <= 0); - } else if seconds > 0 { - debug_assert!(nanoseconds.get() >= 0); - } - - Self { - seconds, - nanoseconds, - padding: Padding::Optimize, - } - } - - /// Create a new `Duration` with the provided seconds and nanoseconds. If nanoseconds is at - /// least ±10<sup>9</sup>, it will wrap to the number of seconds. - /// - /// ```rust - /// # use time::{Duration, ext::NumericalDuration}; - /// assert_eq!(Duration::new(1, 0), 1.seconds()); - /// assert_eq!(Duration::new(-1, 0), (-1).seconds()); - /// assert_eq!(Duration::new(1, 2_000_000_000), 3.seconds()); - /// ``` - /// - /// # Panics - /// - /// This may panic if an overflow occurs. - pub const fn new(mut seconds: i64, mut nanoseconds: i32) -> Self { - seconds = expect_opt!( - seconds.checked_add(nanoseconds as i64 / Nanosecond::per(Second) as i64), - "overflow constructing `time::Duration`" - ); - nanoseconds %= Nanosecond::per(Second) as i32; - - if seconds > 0 && nanoseconds < 0 { - // `seconds` cannot overflow here because it is positive. - seconds -= 1; - nanoseconds += Nanosecond::per(Second) as i32; - } else if seconds < 0 && nanoseconds > 0 { - // `seconds` cannot overflow here because it is negative. - seconds += 1; - nanoseconds -= Nanosecond::per(Second) as i32; - } - - // Safety: `nanoseconds` is in range due to the modulus above. - unsafe { Self::new_unchecked(seconds, nanoseconds) } - } - - /// Create a new `Duration` with the provided seconds and nanoseconds. - pub(crate) const fn new_ranged(mut seconds: i64, mut nanoseconds: Nanoseconds) -> Self { - if seconds > 0 && nanoseconds.get() < 0 { - // `seconds` cannot overflow here because it is positive. - seconds -= 1; - // Safety: `nanoseconds` is negative with a maximum of 999,999,999, so adding a billion - // to it is guaranteed to result in an in-range value. - nanoseconds = unsafe { - Nanoseconds::new_unchecked(nanoseconds.get() + Nanosecond::per(Second) as i32) - }; - } else if seconds < 0 && nanoseconds.get() > 0 { - // `seconds` cannot overflow here because it is negative. - seconds += 1; - // Safety: `nanoseconds` is positive with a minimum of -999,999,999, so subtracting a - // billion from it is guaranteed to result in an in-range value. - nanoseconds = unsafe { - Nanoseconds::new_unchecked(nanoseconds.get() - Nanosecond::per(Second) as i32) - }; - } - - Self::new_ranged_unchecked(seconds, nanoseconds) - } - - /// Create a new `Duration` with the given number of weeks. Equivalent to - /// `Duration::seconds(weeks * 604_800)`. - /// - /// ```rust - /// # use time::{Duration, ext::NumericalDuration}; - /// assert_eq!(Duration::weeks(1), 604_800.seconds()); - /// ``` - /// - /// # Panics - /// - /// This may panic if an overflow occurs. - pub const fn weeks(weeks: i64) -> Self { - Self::seconds(expect_opt!( - weeks.checked_mul(Second::per(Week) as i64), - "overflow constructing `time::Duration`" - )) - } - - /// Create a new `Duration` with the given number of days. Equivalent to - /// `Duration::seconds(days * 86_400)`. - /// - /// ```rust - /// # use time::{Duration, ext::NumericalDuration}; - /// assert_eq!(Duration::days(1), 86_400.seconds()); - /// ``` - /// - /// # Panics - /// - /// This may panic if an overflow occurs. - pub const fn days(days: i64) -> Self { - Self::seconds(expect_opt!( - days.checked_mul(Second::per(Day) as i64), - "overflow constructing `time::Duration`" - )) - } - - /// Create a new `Duration` with the given number of hours. Equivalent to - /// `Duration::seconds(hours * 3_600)`. - /// - /// ```rust - /// # use time::{Duration, ext::NumericalDuration}; - /// assert_eq!(Duration::hours(1), 3_600.seconds()); - /// ``` - /// - /// # Panics - /// - /// This may panic if an overflow occurs. - pub const fn hours(hours: i64) -> Self { - Self::seconds(expect_opt!( - hours.checked_mul(Second::per(Hour) as i64), - "overflow constructing `time::Duration`" - )) - } - - /// Create a new `Duration` with the given number of minutes. Equivalent to - /// `Duration::seconds(minutes * 60)`. - /// - /// ```rust - /// # use time::{Duration, ext::NumericalDuration}; - /// assert_eq!(Duration::minutes(1), 60.seconds()); - /// ``` - /// - /// # Panics - /// - /// This may panic if an overflow occurs. - pub const fn minutes(minutes: i64) -> Self { - Self::seconds(expect_opt!( - minutes.checked_mul(Second::per(Minute) as i64), - "overflow constructing `time::Duration`" - )) - } - - /// Create a new `Duration` with the given number of seconds. - /// - /// ```rust - /// # use time::{Duration, ext::NumericalDuration}; - /// assert_eq!(Duration::seconds(1), 1_000.milliseconds()); - /// ``` - pub const fn seconds(seconds: i64) -> Self { - Self::new_ranged_unchecked(seconds, Nanoseconds::new_static::<0>()) - } - - /// Creates a new `Duration` from the specified number of seconds represented as `f64`. - /// - /// ```rust - /// # use time::{Duration, ext::NumericalDuration}; - /// assert_eq!(Duration::seconds_f64(0.5), 0.5.seconds()); - /// assert_eq!(Duration::seconds_f64(-0.5), (-0.5).seconds()); - /// ``` - pub fn seconds_f64(seconds: f64) -> Self { - try_from_secs!( - secs = seconds, - mantissa_bits = 52, - exponent_bits = 11, - offset = 44, - bits_ty = u64, - bits_ty_signed = i64, - double_ty = u128, - float_ty = f64, - is_nan = crate::expect_failed("passed NaN to `time::Duration::seconds_f64`"), - is_overflow = crate::expect_failed("overflow constructing `time::Duration`"), - ) - } - - /// Creates a new `Duration` from the specified number of seconds represented as `f32`. - /// - /// ```rust - /// # use time::{Duration, ext::NumericalDuration}; - /// assert_eq!(Duration::seconds_f32(0.5), 0.5.seconds()); - /// assert_eq!(Duration::seconds_f32(-0.5), (-0.5).seconds()); - /// ``` - pub fn seconds_f32(seconds: f32) -> Self { - try_from_secs!( - secs = seconds, - mantissa_bits = 23, - exponent_bits = 8, - offset = 41, - bits_ty = u32, - bits_ty_signed = i32, - double_ty = u64, - float_ty = f32, - is_nan = crate::expect_failed("passed NaN to `time::Duration::seconds_f32`"), - is_overflow = crate::expect_failed("overflow constructing `time::Duration`"), - ) - } - - /// Creates a new `Duration` from the specified number of seconds - /// represented as `f64`. Any values that are out of bounds are saturated at - /// the minimum or maximum respectively. `NaN` gets turned into a `Duration` - /// of 0 seconds. - /// - /// ```rust - /// # use time::{Duration, ext::NumericalDuration}; - /// assert_eq!(Duration::saturating_seconds_f64(0.5), 0.5.seconds()); - /// assert_eq!(Duration::saturating_seconds_f64(-0.5), (-0.5).seconds()); - /// assert_eq!( - /// Duration::saturating_seconds_f64(f64::NAN), - /// Duration::new(0, 0), - /// ); - /// assert_eq!( - /// Duration::saturating_seconds_f64(f64::NEG_INFINITY), - /// Duration::MIN, - /// ); - /// assert_eq!( - /// Duration::saturating_seconds_f64(f64::INFINITY), - /// Duration::MAX, - /// ); - /// ``` - pub fn saturating_seconds_f64(seconds: f64) -> Self { - try_from_secs!( - secs = seconds, - mantissa_bits = 52, - exponent_bits = 11, - offset = 44, - bits_ty = u64, - bits_ty_signed = i64, - double_ty = u128, - float_ty = f64, - is_nan = return Self::ZERO, - is_overflow = return if seconds < 0.0 { Self::MIN } else { Self::MAX }, - ) - } - - /// Creates a new `Duration` from the specified number of seconds - /// represented as `f32`. Any values that are out of bounds are saturated at - /// the minimum or maximum respectively. `NaN` gets turned into a `Duration` - /// of 0 seconds. - /// - /// ```rust - /// # use time::{Duration, ext::NumericalDuration}; - /// assert_eq!(Duration::saturating_seconds_f32(0.5), 0.5.seconds()); - /// assert_eq!(Duration::saturating_seconds_f32(-0.5), (-0.5).seconds()); - /// assert_eq!( - /// Duration::saturating_seconds_f32(f32::NAN), - /// Duration::new(0, 0), - /// ); - /// assert_eq!( - /// Duration::saturating_seconds_f32(f32::NEG_INFINITY), - /// Duration::MIN, - /// ); - /// assert_eq!( - /// Duration::saturating_seconds_f32(f32::INFINITY), - /// Duration::MAX, - /// ); - /// ``` - pub fn saturating_seconds_f32(seconds: f32) -> Self { - try_from_secs!( - secs = seconds, - mantissa_bits = 23, - exponent_bits = 8, - offset = 41, - bits_ty = u32, - bits_ty_signed = i32, - double_ty = u64, - float_ty = f32, - is_nan = return Self::ZERO, - is_overflow = return if seconds < 0.0 { Self::MIN } else { Self::MAX }, - ) - } - - /// Creates a new `Duration` from the specified number of seconds - /// represented as `f64`. Returns `None` if the `Duration` can't be - /// represented. - /// - /// ```rust - /// # use time::{Duration, ext::NumericalDuration}; - /// assert_eq!(Duration::checked_seconds_f64(0.5), Some(0.5.seconds())); - /// assert_eq!(Duration::checked_seconds_f64(-0.5), Some((-0.5).seconds())); - /// assert_eq!(Duration::checked_seconds_f64(f64::NAN), None); - /// assert_eq!(Duration::checked_seconds_f64(f64::NEG_INFINITY), None); - /// assert_eq!(Duration::checked_seconds_f64(f64::INFINITY), None); - /// ``` - pub fn checked_seconds_f64(seconds: f64) -> Option<Self> { - Some(try_from_secs!( - secs = seconds, - mantissa_bits = 52, - exponent_bits = 11, - offset = 44, - bits_ty = u64, - bits_ty_signed = i64, - double_ty = u128, - float_ty = f64, - is_nan = return None, - is_overflow = return None, - )) - } - - /// Creates a new `Duration` from the specified number of seconds - /// represented as `f32`. Returns `None` if the `Duration` can't be - /// represented. - /// - /// ```rust - /// # use time::{Duration, ext::NumericalDuration}; - /// assert_eq!(Duration::checked_seconds_f32(0.5), Some(0.5.seconds())); - /// assert_eq!(Duration::checked_seconds_f32(-0.5), Some((-0.5).seconds())); - /// assert_eq!(Duration::checked_seconds_f32(f32::NAN), None); - /// assert_eq!(Duration::checked_seconds_f32(f32::NEG_INFINITY), None); - /// assert_eq!(Duration::checked_seconds_f32(f32::INFINITY), None); - /// ``` - pub fn checked_seconds_f32(seconds: f32) -> Option<Self> { - Some(try_from_secs!( - secs = seconds, - mantissa_bits = 23, - exponent_bits = 8, - offset = 41, - bits_ty = u32, - bits_ty_signed = i32, - double_ty = u64, - float_ty = f32, - is_nan = return None, - is_overflow = return None, - )) - } - - /// Create a new `Duration` with the given number of milliseconds. - /// - /// ```rust - /// # use time::{Duration, ext::NumericalDuration}; - /// assert_eq!(Duration::milliseconds(1), 1_000.microseconds()); - /// assert_eq!(Duration::milliseconds(-1), (-1_000).microseconds()); - /// ``` - pub const fn milliseconds(milliseconds: i64) -> Self { - // Safety: `nanoseconds` is guaranteed to be in range because of the modulus. - unsafe { - Self::new_unchecked( - milliseconds / Millisecond::per(Second) as i64, - (milliseconds % Millisecond::per(Second) as i64 - * Nanosecond::per(Millisecond) as i64) as i32, - ) - } - } - - /// Create a new `Duration` with the given number of microseconds. - /// - /// ```rust - /// # use time::{Duration, ext::NumericalDuration}; - /// assert_eq!(Duration::microseconds(1), 1_000.nanoseconds()); - /// assert_eq!(Duration::microseconds(-1), (-1_000).nanoseconds()); - /// ``` - pub const fn microseconds(microseconds: i64) -> Self { - // Safety: `nanoseconds` is guaranteed to be in range because of the modulus. - unsafe { - Self::new_unchecked( - microseconds / Microsecond::per(Second) as i64, - (microseconds % Microsecond::per(Second) as i64 - * Nanosecond::per(Microsecond) as i64) as i32, - ) - } - } - - /// Create a new `Duration` with the given number of nanoseconds. - /// - /// ```rust - /// # use time::{Duration, ext::NumericalDuration}; - /// assert_eq!(Duration::nanoseconds(1), 1.microseconds() / 1_000); - /// assert_eq!(Duration::nanoseconds(-1), (-1).microseconds() / 1_000); - /// ``` - pub const fn nanoseconds(nanoseconds: i64) -> Self { - // Safety: `nanoseconds` is guaranteed to be in range because of the modulus. - unsafe { - Self::new_unchecked( - nanoseconds / Nanosecond::per(Second) as i64, - (nanoseconds % Nanosecond::per(Second) as i64) as i32, - ) - } - } - - /// Create a new `Duration` with the given number of nanoseconds. - /// - /// As the input range cannot be fully mapped to the output, this should only be used where it's - /// known to result in a valid value. - pub(crate) const fn nanoseconds_i128(nanoseconds: i128) -> Self { - let seconds = nanoseconds / Nanosecond::per(Second) as i128; - let nanoseconds = nanoseconds % Nanosecond::per(Second) as i128; - - if seconds > i64::MAX as i128 || seconds < i64::MIN as i128 { - crate::expect_failed("overflow constructing `time::Duration`"); - } - - // Safety: `nanoseconds` is guaranteed to be in range because of the modulus above. - unsafe { Self::new_unchecked(seconds as i64, nanoseconds as i32) } - } - - /// Get the number of whole weeks in the duration. - /// - /// ```rust - /// # use time::ext::NumericalDuration; - /// assert_eq!(1.weeks().whole_weeks(), 1); - /// assert_eq!((-1).weeks().whole_weeks(), -1); - /// assert_eq!(6.days().whole_weeks(), 0); - /// assert_eq!((-6).days().whole_weeks(), 0); - /// ``` - pub const fn whole_weeks(self) -> i64 { - self.whole_seconds() / Second::per(Week) as i64 - } - - /// Get the number of whole days in the duration. - /// - /// ```rust - /// # use time::ext::NumericalDuration; - /// assert_eq!(1.days().whole_days(), 1); - /// assert_eq!((-1).days().whole_days(), -1); - /// assert_eq!(23.hours().whole_days(), 0); - /// assert_eq!((-23).hours().whole_days(), 0); - /// ``` - pub const fn whole_days(self) -> i64 { - self.whole_seconds() / Second::per(Day) as i64 - } - - /// Get the number of whole hours in the duration. - /// - /// ```rust - /// # use time::ext::NumericalDuration; - /// assert_eq!(1.hours().whole_hours(), 1); - /// assert_eq!((-1).hours().whole_hours(), -1); - /// assert_eq!(59.minutes().whole_hours(), 0); - /// assert_eq!((-59).minutes().whole_hours(), 0); - /// ``` - pub const fn whole_hours(self) -> i64 { - self.whole_seconds() / Second::per(Hour) as i64 - } - - /// Get the number of whole minutes in the duration. - /// - /// ```rust - /// # use time::ext::NumericalDuration; - /// assert_eq!(1.minutes().whole_minutes(), 1); - /// assert_eq!((-1).minutes().whole_minutes(), -1); - /// assert_eq!(59.seconds().whole_minutes(), 0); - /// assert_eq!((-59).seconds().whole_minutes(), 0); - /// ``` - pub const fn whole_minutes(self) -> i64 { - self.whole_seconds() / Second::per(Minute) as i64 - } - - /// Get the number of whole seconds in the duration. - /// - /// ```rust - /// # use time::ext::NumericalDuration; - /// assert_eq!(1.seconds().whole_seconds(), 1); - /// assert_eq!((-1).seconds().whole_seconds(), -1); - /// assert_eq!(1.minutes().whole_seconds(), 60); - /// assert_eq!((-1).minutes().whole_seconds(), -60); - /// ``` - pub const fn whole_seconds(self) -> i64 { - self.seconds - } - - /// Get the number of fractional seconds in the duration. - /// - /// ```rust - /// # use time::ext::NumericalDuration; - /// assert_eq!(1.5.seconds().as_seconds_f64(), 1.5); - /// assert_eq!((-1.5).seconds().as_seconds_f64(), -1.5); - /// ``` - pub fn as_seconds_f64(self) -> f64 { - self.seconds as f64 + self.nanoseconds.get() as f64 / Nanosecond::per(Second) as f64 - } - - /// Get the number of fractional seconds in the duration. - /// - /// ```rust - /// # use time::ext::NumericalDuration; - /// assert_eq!(1.5.seconds().as_seconds_f32(), 1.5); - /// assert_eq!((-1.5).seconds().as_seconds_f32(), -1.5); - /// ``` - pub fn as_seconds_f32(self) -> f32 { - self.seconds as f32 + self.nanoseconds.get() as f32 / Nanosecond::per(Second) as f32 - } - - /// Get the number of whole milliseconds in the duration. - /// - /// ```rust - /// # use time::ext::NumericalDuration; - /// assert_eq!(1.seconds().whole_milliseconds(), 1_000); - /// assert_eq!((-1).seconds().whole_milliseconds(), -1_000); - /// assert_eq!(1.milliseconds().whole_milliseconds(), 1); - /// assert_eq!((-1).milliseconds().whole_milliseconds(), -1); - /// ``` - pub const fn whole_milliseconds(self) -> i128 { - self.seconds as i128 * Millisecond::per(Second) as i128 - + self.nanoseconds.get() as i128 / Nanosecond::per(Millisecond) as i128 - } - - /// Get the number of milliseconds past the number of whole seconds. - /// - /// Always in the range `-999..=999`. - /// - /// ```rust - /// # use time::ext::NumericalDuration; - /// assert_eq!(1.4.seconds().subsec_milliseconds(), 400); - /// assert_eq!((-1.4).seconds().subsec_milliseconds(), -400); - /// ``` - // Allow the lint, as the value is guaranteed to be less than 1000. - pub const fn subsec_milliseconds(self) -> i16 { - (self.nanoseconds.get() / Nanosecond::per(Millisecond) as i32) as i16 - } - - /// Get the number of whole microseconds in the duration. - /// - /// ```rust - /// # use time::ext::NumericalDuration; - /// assert_eq!(1.milliseconds().whole_microseconds(), 1_000); - /// assert_eq!((-1).milliseconds().whole_microseconds(), -1_000); - /// assert_eq!(1.microseconds().whole_microseconds(), 1); - /// assert_eq!((-1).microseconds().whole_microseconds(), -1); - /// ``` - pub const fn whole_microseconds(self) -> i128 { - self.seconds as i128 * Microsecond::per(Second) as i128 - + self.nanoseconds.get() as i128 / Nanosecond::per(Microsecond) as i128 - } - - /// Get the number of microseconds past the number of whole seconds. - /// - /// Always in the range `-999_999..=999_999`. - /// - /// ```rust - /// # use time::ext::NumericalDuration; - /// assert_eq!(1.0004.seconds().subsec_microseconds(), 400); - /// assert_eq!((-1.0004).seconds().subsec_microseconds(), -400); - /// ``` - pub const fn subsec_microseconds(self) -> i32 { - self.nanoseconds.get() / Nanosecond::per(Microsecond) as i32 - } - - /// Get the number of nanoseconds in the duration. - /// - /// ```rust - /// # use time::ext::NumericalDuration; - /// assert_eq!(1.microseconds().whole_nanoseconds(), 1_000); - /// assert_eq!((-1).microseconds().whole_nanoseconds(), -1_000); - /// assert_eq!(1.nanoseconds().whole_nanoseconds(), 1); - /// assert_eq!((-1).nanoseconds().whole_nanoseconds(), -1); - /// ``` - pub const fn whole_nanoseconds(self) -> i128 { - self.seconds as i128 * Nanosecond::per(Second) as i128 + self.nanoseconds.get() as i128 - } - - /// Get the number of nanoseconds past the number of whole seconds. - /// - /// The returned value will always be in the range `-999_999_999..=999_999_999`. - /// - /// ```rust - /// # use time::ext::NumericalDuration; - /// assert_eq!(1.000_000_400.seconds().subsec_nanoseconds(), 400); - /// assert_eq!((-1.000_000_400).seconds().subsec_nanoseconds(), -400); - /// ``` - pub const fn subsec_nanoseconds(self) -> i32 { - self.nanoseconds.get() - } - - /// Get the number of nanoseconds past the number of whole seconds. - #[cfg(feature = "quickcheck")] - pub(crate) const fn subsec_nanoseconds_ranged(self) -> Nanoseconds { - self.nanoseconds - } - - /// Computes `self + rhs`, returning `None` if an overflow occurred. - /// - /// ```rust - /// # use time::{Duration, ext::NumericalDuration}; - /// assert_eq!(5.seconds().checked_add(5.seconds()), Some(10.seconds())); - /// assert_eq!(Duration::MAX.checked_add(1.nanoseconds()), None); - /// assert_eq!((-5).seconds().checked_add(5.seconds()), Some(0.seconds())); - /// ``` - pub const fn checked_add(self, rhs: Self) -> Option<Self> { - let mut seconds = const_try_opt!(self.seconds.checked_add(rhs.seconds)); - let mut nanoseconds = self.nanoseconds.get() + rhs.nanoseconds.get(); - - if nanoseconds >= Nanosecond::per(Second) as i32 || seconds < 0 && nanoseconds > 0 { - nanoseconds -= Nanosecond::per(Second) as i32; - seconds = const_try_opt!(seconds.checked_add(1)); - } else if nanoseconds <= -(Nanosecond::per(Second) as i32) || seconds > 0 && nanoseconds < 0 - { - nanoseconds += Nanosecond::per(Second) as i32; - seconds = const_try_opt!(seconds.checked_sub(1)); - } - - // Safety: `nanoseconds` is guaranteed to be in range because of the overflow handling. - unsafe { Some(Self::new_unchecked(seconds, nanoseconds)) } - } - - /// Computes `self - rhs`, returning `None` if an overflow occurred. - /// - /// ```rust - /// # use time::{Duration, ext::NumericalDuration}; - /// assert_eq!(5.seconds().checked_sub(5.seconds()), Some(Duration::ZERO)); - /// assert_eq!(Duration::MIN.checked_sub(1.nanoseconds()), None); - /// assert_eq!(5.seconds().checked_sub(10.seconds()), Some((-5).seconds())); - /// ``` - pub const fn checked_sub(self, rhs: Self) -> Option<Self> { - let mut seconds = const_try_opt!(self.seconds.checked_sub(rhs.seconds)); - let mut nanoseconds = self.nanoseconds.get() - rhs.nanoseconds.get(); - - if nanoseconds >= Nanosecond::per(Second) as i32 || seconds < 0 && nanoseconds > 0 { - nanoseconds -= Nanosecond::per(Second) as i32; - seconds = const_try_opt!(seconds.checked_add(1)); - } else if nanoseconds <= -(Nanosecond::per(Second) as i32) || seconds > 0 && nanoseconds < 0 - { - nanoseconds += Nanosecond::per(Second) as i32; - seconds = const_try_opt!(seconds.checked_sub(1)); - } - - // Safety: `nanoseconds` is guaranteed to be in range because of the overflow handling. - unsafe { Some(Self::new_unchecked(seconds, nanoseconds)) } - } - - /// Computes `self * rhs`, returning `None` if an overflow occurred. - /// - /// ```rust - /// # use time::{Duration, ext::NumericalDuration}; - /// assert_eq!(5.seconds().checked_mul(2), Some(10.seconds())); - /// assert_eq!(5.seconds().checked_mul(-2), Some((-10).seconds())); - /// assert_eq!(5.seconds().checked_mul(0), Some(0.seconds())); - /// assert_eq!(Duration::MAX.checked_mul(2), None); - /// assert_eq!(Duration::MIN.checked_mul(2), None); - /// ``` - pub const fn checked_mul(self, rhs: i32) -> Option<Self> { - // Multiply nanoseconds as i64, because it cannot overflow that way. - let total_nanos = self.nanoseconds.get() as i64 * rhs as i64; - let extra_secs = total_nanos / Nanosecond::per(Second) as i64; - let nanoseconds = (total_nanos % Nanosecond::per(Second) as i64) as i32; - let seconds = const_try_opt!( - const_try_opt!(self.seconds.checked_mul(rhs as i64)).checked_add(extra_secs) - ); - - // Safety: `nanoseconds` is guaranteed to be in range because of the modulus above. - unsafe { Some(Self::new_unchecked(seconds, nanoseconds)) } - } - - /// Computes `self / rhs`, returning `None` if `rhs == 0` or if the result would overflow. - /// - /// ```rust - /// # use time::ext::NumericalDuration; - /// assert_eq!(10.seconds().checked_div(2), Some(5.seconds())); - /// assert_eq!(10.seconds().checked_div(-2), Some((-5).seconds())); - /// assert_eq!(1.seconds().checked_div(0), None); - /// ``` - pub const fn checked_div(self, rhs: i32) -> Option<Self> { - let (secs, extra_secs) = ( - const_try_opt!(self.seconds.checked_div(rhs as i64)), - self.seconds % (rhs as i64), - ); - let (mut nanos, extra_nanos) = (self.nanoseconds.get() / rhs, self.nanoseconds.get() % rhs); - nanos += ((extra_secs * (Nanosecond::per(Second) as i64) + extra_nanos as i64) - / (rhs as i64)) as i32; - - // Safety: `nanoseconds` is in range. - unsafe { Some(Self::new_unchecked(secs, nanos)) } - } - - /// Computes `-self`, returning `None` if the result would overflow. - /// - /// ```rust - /// # use time::ext::NumericalDuration; - /// # use time::Duration; - /// assert_eq!(5.seconds().checked_neg(), Some((-5).seconds())); - /// assert_eq!(Duration::MIN.checked_neg(), None); - /// ``` - pub const fn checked_neg(self) -> Option<Self> { - if self.seconds == i64::MIN { - None - } else { - Some(Self::new_ranged_unchecked( - -self.seconds, - self.nanoseconds.neg(), - )) - } - } - - /// Computes `self + rhs`, saturating if an overflow occurred. - /// - /// ```rust - /// # use time::{Duration, ext::NumericalDuration}; - /// assert_eq!(5.seconds().saturating_add(5.seconds()), 10.seconds()); - /// assert_eq!(Duration::MAX.saturating_add(1.nanoseconds()), Duration::MAX); - /// assert_eq!( - /// Duration::MIN.saturating_add((-1).nanoseconds()), - /// Duration::MIN - /// ); - /// assert_eq!((-5).seconds().saturating_add(5.seconds()), Duration::ZERO); - /// ``` - pub const fn saturating_add(self, rhs: Self) -> Self { - let (mut seconds, overflow) = self.seconds.overflowing_add(rhs.seconds); - if overflow { - if self.seconds > 0 { - return Self::MAX; - } - return Self::MIN; - } - let mut nanoseconds = self.nanoseconds.get() + rhs.nanoseconds.get(); - - if nanoseconds >= Nanosecond::per(Second) as i32 || seconds < 0 && nanoseconds > 0 { - nanoseconds -= Nanosecond::per(Second) as i32; - seconds = match seconds.checked_add(1) { - Some(seconds) => seconds, - None => return Self::MAX, - }; - } else if nanoseconds <= -(Nanosecond::per(Second) as i32) || seconds > 0 && nanoseconds < 0 - { - nanoseconds += Nanosecond::per(Second) as i32; - seconds = match seconds.checked_sub(1) { - Some(seconds) => seconds, - None => return Self::MIN, - }; - } - - // Safety: `nanoseconds` is guaranteed to be in range because of the overflow handling. - unsafe { Self::new_unchecked(seconds, nanoseconds) } - } - - /// Computes `self - rhs`, saturating if an overflow occurred. - /// - /// ```rust - /// # use time::{Duration, ext::NumericalDuration}; - /// assert_eq!(5.seconds().saturating_sub(5.seconds()), Duration::ZERO); - /// assert_eq!(Duration::MIN.saturating_sub(1.nanoseconds()), Duration::MIN); - /// assert_eq!( - /// Duration::MAX.saturating_sub((-1).nanoseconds()), - /// Duration::MAX - /// ); - /// assert_eq!(5.seconds().saturating_sub(10.seconds()), (-5).seconds()); - /// ``` - pub const fn saturating_sub(self, rhs: Self) -> Self { - let (mut seconds, overflow) = self.seconds.overflowing_sub(rhs.seconds); - if overflow { - if self.seconds > 0 { - return Self::MAX; - } - return Self::MIN; - } - let mut nanoseconds = self.nanoseconds.get() - rhs.nanoseconds.get(); - - if nanoseconds >= Nanosecond::per(Second) as i32 || seconds < 0 && nanoseconds > 0 { - nanoseconds -= Nanosecond::per(Second) as i32; - seconds = match seconds.checked_add(1) { - Some(seconds) => seconds, - None => return Self::MAX, - }; - } else if nanoseconds <= -(Nanosecond::per(Second) as i32) || seconds > 0 && nanoseconds < 0 - { - nanoseconds += Nanosecond::per(Second) as i32; - seconds = match seconds.checked_sub(1) { - Some(seconds) => seconds, - None => return Self::MIN, - }; - } - - // Safety: `nanoseconds` is guaranteed to be in range because of the overflow handling. - unsafe { Self::new_unchecked(seconds, nanoseconds) } - } - - /// Computes `self * rhs`, saturating if an overflow occurred. - /// - /// ```rust - /// # use time::{Duration, ext::NumericalDuration}; - /// assert_eq!(5.seconds().saturating_mul(2), 10.seconds()); - /// assert_eq!(5.seconds().saturating_mul(-2), (-10).seconds()); - /// assert_eq!(5.seconds().saturating_mul(0), Duration::ZERO); - /// assert_eq!(Duration::MAX.saturating_mul(2), Duration::MAX); - /// assert_eq!(Duration::MIN.saturating_mul(2), Duration::MIN); - /// assert_eq!(Duration::MAX.saturating_mul(-2), Duration::MIN); - /// assert_eq!(Duration::MIN.saturating_mul(-2), Duration::MAX); - /// ``` - pub const fn saturating_mul(self, rhs: i32) -> Self { - // Multiply nanoseconds as i64, because it cannot overflow that way. - let total_nanos = self.nanoseconds.get() as i64 * rhs as i64; - let extra_secs = total_nanos / Nanosecond::per(Second) as i64; - let nanoseconds = (total_nanos % Nanosecond::per(Second) as i64) as i32; - let (seconds, overflow1) = self.seconds.overflowing_mul(rhs as i64); - if overflow1 { - if self.seconds > 0 && rhs > 0 || self.seconds < 0 && rhs < 0 { - return Self::MAX; - } - return Self::MIN; - } - let (seconds, overflow2) = seconds.overflowing_add(extra_secs); - if overflow2 { - if self.seconds > 0 && rhs > 0 { - return Self::MAX; - } - return Self::MIN; - } - - // Safety: `nanoseconds` is guaranteed to be in range because of to the modulus above. - unsafe { Self::new_unchecked(seconds, nanoseconds) } - } - - /// Runs a closure, returning the duration of time it took to run. The return value of the - /// closure is provided in the second part of the tuple. - #[doc(hidden)] - #[cfg(feature = "std")] - #[deprecated( - since = "0.3.32", - note = "extremely limited use case, not intended for benchmarking" - )] - #[allow(deprecated)] - pub fn time_fn<T>(f: impl FnOnce() -> T) -> (Self, T) { - let start = Instant::now(); - let return_value = f(); - let end = Instant::now(); - - (end - start, return_value) - } -} - -/// The format returned by this implementation is not stable and must not be relied upon. -/// -/// By default this produces an exact, full-precision printout of the duration. -/// For a concise, rounded printout instead, you can use the `.N` format specifier: -/// -/// ``` -/// # use time::Duration; -/// # -/// let duration = Duration::new(123456, 789011223); -/// println!("{duration:.3}"); -/// ``` -/// -/// For the purposes of this implementation, a day is exactly 24 hours and a minute is exactly 60 -/// seconds. -impl fmt::Display for Duration { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - if self.is_negative() { - f.write_str("-")?; - } - - if let Some(_precision) = f.precision() { - // Concise, rounded representation. - - if self.is_zero() { - // Write a zero value with the requested precision. - return (0.).fmt(f).and_then(|_| f.write_str("s")); - } - - /// Format the first item that produces a value greater than 1 and then break. - macro_rules! item { - ($name:literal, $value:expr) => { - let value = $value; - if value >= 1.0 { - return value.fmt(f).and_then(|_| f.write_str($name)); - } - }; - } - - // Even if this produces a de-normal float, because we're rounding we don't really care. - let seconds = self.unsigned_abs().as_secs_f64(); - - item!("d", seconds / Second::per(Day) as f64); - item!("h", seconds / Second::per(Hour) as f64); - item!("m", seconds / Second::per(Minute) as f64); - item!("s", seconds); - item!("ms", seconds * Millisecond::per(Second) as f64); - item!("µs", seconds * Microsecond::per(Second) as f64); - item!("ns", seconds * Nanosecond::per(Second) as f64); - } else { - // Precise, but verbose representation. - - if self.is_zero() { - return f.write_str("0s"); - } - - /// Format a single item. - macro_rules! item { - ($name:literal, $value:expr) => { - match $value { - 0 => Ok(()), - value => value.fmt(f).and_then(|_| f.write_str($name)), - } - }; - } - - let seconds = self.seconds.unsigned_abs(); - let nanoseconds = self.nanoseconds.get().unsigned_abs(); - - item!("d", seconds / Second::per(Day).extend::<u64>())?; - item!( - "h", - seconds / Second::per(Hour).extend::<u64>() % Hour::per(Day).extend::<u64>() - )?; - item!( - "m", - seconds / Second::per(Minute).extend::<u64>() % Minute::per(Hour).extend::<u64>() - )?; - item!("s", seconds % Second::per(Minute).extend::<u64>())?; - item!("ms", nanoseconds / Nanosecond::per(Millisecond))?; - item!( - "µs", - nanoseconds / Nanosecond::per(Microsecond).extend::<u32>() - % Microsecond::per(Millisecond).extend::<u32>() - )?; - item!( - "ns", - nanoseconds % Nanosecond::per(Microsecond).extend::<u32>() - )?; - } - - Ok(()) - } -} - -impl TryFrom<StdDuration> for Duration { - type Error = error::ConversionRange; - - fn try_from(original: StdDuration) -> Result<Self, error::ConversionRange> { - Ok(Self::new( - original - .as_secs() - .try_into() - .map_err(|_| error::ConversionRange)?, - original.subsec_nanos().cast_signed(), - )) - } -} - -impl TryFrom<Duration> for StdDuration { - type Error = error::ConversionRange; - - fn try_from(duration: Duration) -> Result<Self, error::ConversionRange> { - Ok(Self::new( - duration - .seconds - .try_into() - .map_err(|_| error::ConversionRange)?, - duration - .nanoseconds - .get() - .try_into() - .map_err(|_| error::ConversionRange)?, - )) - } -} - -impl Add for Duration { - type Output = Self; - - /// # Panics - /// - /// This may panic if an overflow occurs. - fn add(self, rhs: Self) -> Self::Output { - self.checked_add(rhs) - .expect("overflow when adding durations") - } -} - -impl Add<StdDuration> for Duration { - type Output = Self; - - /// # Panics - /// - /// This may panic if an overflow occurs. - fn add(self, std_duration: StdDuration) -> Self::Output { - self + Self::try_from(std_duration) - .expect("overflow converting `std::time::Duration` to `time::Duration`") - } -} - -impl Add<Duration> for StdDuration { - type Output = Duration; - - fn add(self, rhs: Duration) -> Self::Output { - rhs + self - } -} - -impl_add_assign!(Duration: Self, StdDuration); - -impl AddAssign<Duration> for StdDuration { - /// # Panics - /// - /// This may panic if the resulting addition cannot be represented. - fn add_assign(&mut self, rhs: Duration) { - *self = (*self + rhs).try_into().expect( - "Cannot represent a resulting duration in std. Try `let x = x + rhs;`, which will \ - change the type.", - ); - } -} - -impl Neg for Duration { - type Output = Self; - - fn neg(self) -> Self::Output { - self.checked_neg().expect("overflow when negating duration") - } -} - -impl Sub for Duration { - type Output = Self; - - /// # Panics - /// - /// This may panic if an overflow occurs. - fn sub(self, rhs: Self) -> Self::Output { - self.checked_sub(rhs) - .expect("overflow when subtracting durations") - } -} - -impl Sub<StdDuration> for Duration { - type Output = Self; - - /// # Panics - /// - /// This may panic if an overflow occurs. - fn sub(self, rhs: StdDuration) -> Self::Output { - self - Self::try_from(rhs) - .expect("overflow converting `std::time::Duration` to `time::Duration`") - } -} - -impl Sub<Duration> for StdDuration { - type Output = Duration; - - /// # Panics - /// - /// This may panic if an overflow occurs. - fn sub(self, rhs: Duration) -> Self::Output { - Duration::try_from(self) - .expect("overflow converting `std::time::Duration` to `time::Duration`") - - rhs - } -} - -impl_sub_assign!(Duration: Self, StdDuration); - -impl SubAssign<Duration> for StdDuration { - /// # Panics - /// - /// This may panic if the resulting subtraction can not be represented. - fn sub_assign(&mut self, rhs: Duration) { - *self = (*self - rhs).try_into().expect( - "Cannot represent a resulting duration in std. Try `let x = x - rhs;`, which will \ - change the type.", - ); - } -} - -/// Implement `Mul` (reflexively) and `Div` for `Duration` for various types. -macro_rules! duration_mul_div_int { - ($($type:ty),+) => {$( - impl Mul<$type> for Duration { - type Output = Self; - - fn mul(self, rhs: $type) -> Self::Output { - Self::nanoseconds_i128( - self.whole_nanoseconds() - .checked_mul(rhs.cast_signed().extend::<i128>()) - .expect("overflow when multiplying duration") - ) - } - } - - impl Mul<Duration> for $type { - type Output = Duration; - - fn mul(self, rhs: Duration) -> Self::Output { - rhs * self - } - } - - impl Div<$type> for Duration { - type Output = Self; - - fn div(self, rhs: $type) -> Self::Output { - Self::nanoseconds_i128( - self.whole_nanoseconds() / rhs.cast_signed().extend::<i128>() - ) - } - } - )+}; -} -duration_mul_div_int![i8, i16, i32, u8, u16, u32]; - -impl Mul<f32> for Duration { - type Output = Self; - - fn mul(self, rhs: f32) -> Self::Output { - Self::seconds_f32(self.as_seconds_f32() * rhs) - } -} - -impl Mul<Duration> for f32 { - type Output = Duration; - - fn mul(self, rhs: Duration) -> Self::Output { - rhs * self - } -} - -impl Mul<f64> for Duration { - type Output = Self; - - fn mul(self, rhs: f64) -> Self::Output { - Self::seconds_f64(self.as_seconds_f64() * rhs) - } -} - -impl Mul<Duration> for f64 { - type Output = Duration; - - fn mul(self, rhs: Duration) -> Self::Output { - rhs * self - } -} - -impl_mul_assign!(Duration: i8, i16, i32, u8, u16, u32, f32, f64); - -impl Div<f32> for Duration { - type Output = Self; - - fn div(self, rhs: f32) -> Self::Output { - Self::seconds_f32(self.as_seconds_f32() / rhs) - } -} - -impl Div<f64> for Duration { - type Output = Self; - - fn div(self, rhs: f64) -> Self::Output { - Self::seconds_f64(self.as_seconds_f64() / rhs) - } -} - -impl_div_assign!(Duration: i8, i16, i32, u8, u16, u32, f32, f64); - -impl Div for Duration { - type Output = f64; - - fn div(self, rhs: Self) -> Self::Output { - self.as_seconds_f64() / rhs.as_seconds_f64() - } -} - -impl Div<StdDuration> for Duration { - type Output = f64; - - fn div(self, rhs: StdDuration) -> Self::Output { - self.as_seconds_f64() / rhs.as_secs_f64() - } -} - -impl Div<Duration> for StdDuration { - type Output = f64; - - fn div(self, rhs: Duration) -> Self::Output { - self.as_secs_f64() / rhs.as_seconds_f64() - } -} - -impl PartialEq<StdDuration> for Duration { - fn eq(&self, rhs: &StdDuration) -> bool { - Ok(*self) == Self::try_from(*rhs) - } -} - -impl PartialEq<Duration> for StdDuration { - fn eq(&self, rhs: &Duration) -> bool { - rhs == self - } -} - -impl PartialOrd<StdDuration> for Duration { - fn partial_cmp(&self, rhs: &StdDuration) -> Option<Ordering> { - if rhs.as_secs() > i64::MAX.cast_unsigned() { - return Some(Ordering::Less); - } - - Some( - self.seconds - .cmp(&rhs.as_secs().cast_signed()) - .then_with(|| { - self.nanoseconds - .get() - .cmp(&rhs.subsec_nanos().cast_signed()) - }), - ) - } -} - -impl PartialOrd<Duration> for StdDuration { - fn partial_cmp(&self, rhs: &Duration) -> Option<Ordering> { - rhs.partial_cmp(self).map(Ordering::reverse) - } -} - -impl Sum for Duration { - fn sum<I: Iterator<Item = Self>>(iter: I) -> Self { - iter.reduce(|a, b| a + b).unwrap_or_default() - } -} - -impl<'a> Sum<&'a Self> for Duration { - fn sum<I: Iterator<Item = &'a Self>>(iter: I) -> Self { - iter.copied().sum() - } -} - -#[cfg(feature = "std")] -impl Add<Duration> for SystemTime { - type Output = Self; - - fn add(self, duration: Duration) -> Self::Output { - if duration.is_zero() { - self - } else if duration.is_positive() { - self + duration.unsigned_abs() - } else { - debug_assert!(duration.is_negative()); - self - duration.unsigned_abs() - } - } -} - -impl_add_assign!(SystemTime: #[cfg(feature = "std")] Duration); - -#[cfg(feature = "std")] -impl Sub<Duration> for SystemTime { - type Output = Self; - - fn sub(self, duration: Duration) -> Self::Output { - if duration.is_zero() { - self - } else if duration.is_positive() { - self - duration.unsigned_abs() - } else { - debug_assert!(duration.is_negative()); - self + duration.unsigned_abs() - } - } -} - -impl_sub_assign!(SystemTime: #[cfg(feature = "std")] Duration); diff --git a/vendor/time/src/error/component_range.rs b/vendor/time/src/error/component_range.rs deleted file mode 100644 index dc980234..00000000 --- a/vendor/time/src/error/component_range.rs +++ /dev/null @@ -1,114 +0,0 @@ -//! Component range error - -use core::{fmt, hash}; - -use crate::error; - -/// An error type indicating that a component provided to a method was out of range, causing a -/// failure. -// i64 is the narrowest type fitting all use cases. This eliminates the need for a type parameter. -#[derive(Debug, Clone, Copy, Eq)] -pub struct ComponentRange { - /// Name of the component. - pub(crate) name: &'static str, - /// Minimum allowed value, inclusive. - pub(crate) minimum: i64, - /// Maximum allowed value, inclusive. - pub(crate) maximum: i64, - /// Value that was provided. - pub(crate) value: i64, - /// The minimum and/or maximum value is conditional on the value of other - /// parameters. - pub(crate) conditional_message: Option<&'static str>, -} - -impl ComponentRange { - /// Obtain the name of the component whose value was out of range. - pub const fn name(self) -> &'static str { - self.name - } - - /// Whether the value's permitted range is conditional, i.e. whether an input with this - /// value could have succeeded if the values of other components were different. - pub const fn is_conditional(self) -> bool { - self.conditional_message.is_some() - } -} - -impl PartialEq for ComponentRange { - fn eq(&self, other: &Self) -> bool { - self.name == other.name - && self.minimum == other.minimum - && self.maximum == other.maximum - && self.value == other.value - // Skip the contents of the message when comparing for equality. - && self.conditional_message.is_some() == other.conditional_message.is_some() - } -} - -impl hash::Hash for ComponentRange { - fn hash<H: hash::Hasher>(&self, state: &mut H) { - self.name.hash(state); - self.minimum.hash(state); - self.maximum.hash(state); - self.value.hash(state); - // Skip the contents of the message when comparing for equality. - self.conditional_message.is_some().hash(state); - } -} - -impl fmt::Display for ComponentRange { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!( - f, - "{} must be in the range {}..={}", - self.name, self.minimum, self.maximum - )?; - - if let Some(message) = self.conditional_message { - write!(f, " {message}")?; - } - - Ok(()) - } -} - -impl From<ComponentRange> for crate::Error { - fn from(original: ComponentRange) -> Self { - Self::ComponentRange(original) - } -} - -impl TryFrom<crate::Error> for ComponentRange { - type Error = error::DifferentVariant; - - fn try_from(err: crate::Error) -> Result<Self, Self::Error> { - match err { - crate::Error::ComponentRange(err) => Ok(err), - _ => Err(error::DifferentVariant), - } - } -} - -/// **This trait implementation is deprecated and will be removed in a future breaking release.** -#[cfg(feature = "serde")] -impl serde::de::Expected for ComponentRange { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!( - f, - "a value in the range {}..={}", - self.minimum, self.maximum - ) - } -} - -#[cfg(feature = "serde")] -impl ComponentRange { - /// Convert the error to a deserialization error. - pub(crate) fn into_de_error<E: serde::de::Error>(self) -> E { - E::invalid_value(serde::de::Unexpected::Signed(self.value), &self) - } -} - -#[cfg(feature = "std")] -impl std::error::Error for ComponentRange {} diff --git a/vendor/time/src/error/conversion_range.rs b/vendor/time/src/error/conversion_range.rs deleted file mode 100644 index d6d9243e..00000000 --- a/vendor/time/src/error/conversion_range.rs +++ /dev/null @@ -1,36 +0,0 @@ -//! Conversion range error - -use core::fmt; - -use crate::error; - -/// An error type indicating that a conversion failed because the target type could not store the -/// initial value. -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub struct ConversionRange; - -impl fmt::Display for ConversionRange { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str("Source value is out of range for the target type") - } -} - -#[cfg(feature = "std")] -impl std::error::Error for ConversionRange {} - -impl From<ConversionRange> for crate::Error { - fn from(err: ConversionRange) -> Self { - Self::ConversionRange(err) - } -} - -impl TryFrom<crate::Error> for ConversionRange { - type Error = error::DifferentVariant; - - fn try_from(err: crate::Error) -> Result<Self, Self::Error> { - match err { - crate::Error::ConversionRange(err) => Ok(err), - _ => Err(error::DifferentVariant), - } - } -} diff --git a/vendor/time/src/error/different_variant.rs b/vendor/time/src/error/different_variant.rs deleted file mode 100644 index 22e21cb0..00000000 --- a/vendor/time/src/error/different_variant.rs +++ /dev/null @@ -1,34 +0,0 @@ -//! Different variant error - -use core::fmt; - -/// An error type indicating that a [`TryFrom`](core::convert::TryFrom) call failed because the -/// original value was of a different variant. -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub struct DifferentVariant; - -impl fmt::Display for DifferentVariant { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "value was of a different variant than required") - } -} - -#[cfg(feature = "std")] -impl std::error::Error for DifferentVariant {} - -impl From<DifferentVariant> for crate::Error { - fn from(err: DifferentVariant) -> Self { - Self::DifferentVariant(err) - } -} - -impl TryFrom<crate::Error> for DifferentVariant { - type Error = Self; - - fn try_from(err: crate::Error) -> Result<Self, Self::Error> { - match err { - crate::Error::DifferentVariant(err) => Ok(err), - _ => Err(Self), - } - } -} diff --git a/vendor/time/src/error/format.rs b/vendor/time/src/error/format.rs deleted file mode 100644 index 906a58c0..00000000 --- a/vendor/time/src/error/format.rs +++ /dev/null @@ -1,113 +0,0 @@ -//! Error formatting a struct - -use alloc::boxed::Box; -use core::fmt; -use std::io; - -use crate::error; - -/// An error occurred when formatting. -#[non_exhaustive] -#[derive(Debug)] -pub enum Format { - /// The type being formatted does not contain sufficient information to format a component. - #[non_exhaustive] - InsufficientTypeInformation, - /// The component named has a value that cannot be formatted into the requested format. - /// - /// This variant is only returned when using well-known formats. - InvalidComponent(&'static str), - /// A component provided was out of range. - ComponentRange(Box<error::ComponentRange>), - /// A value of `std::io::Error` was returned internally. - StdIo(io::Error), -} - -impl fmt::Display for Format { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - Self::InsufficientTypeInformation => f.write_str( - "The type being formatted does not contain sufficient information to format a \ - component.", - ), - Self::InvalidComponent(component) => write!( - f, - "The {component} component cannot be formatted into the requested format." - ), - Self::ComponentRange(err) => err.fmt(f), - Self::StdIo(err) => err.fmt(f), - } - } -} - -impl From<error::ComponentRange> for Format { - fn from(err: error::ComponentRange) -> Self { - Self::ComponentRange(Box::new(err)) - } -} - -impl From<io::Error> for Format { - fn from(err: io::Error) -> Self { - Self::StdIo(err) - } -} - -impl TryFrom<Format> for error::ComponentRange { - type Error = error::DifferentVariant; - - fn try_from(err: Format) -> Result<Self, Self::Error> { - match err { - Format::ComponentRange(err) => Ok(*err), - _ => Err(error::DifferentVariant), - } - } -} - -impl TryFrom<Format> for io::Error { - type Error = error::DifferentVariant; - - fn try_from(err: Format) -> Result<Self, Self::Error> { - match err { - Format::StdIo(err) => Ok(err), - _ => Err(error::DifferentVariant), - } - } -} - -#[cfg(feature = "std")] -impl std::error::Error for Format { - fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { - match self { - Self::InsufficientTypeInformation | Self::InvalidComponent(_) => None, - Self::ComponentRange(err) => Some(&**err), - Self::StdIo(err) => Some(err), - } - } -} - -impl From<Format> for crate::Error { - fn from(original: Format) -> Self { - Self::Format(original) - } -} - -impl TryFrom<crate::Error> for Format { - type Error = error::DifferentVariant; - - fn try_from(err: crate::Error) -> Result<Self, Self::Error> { - match err { - crate::Error::Format(err) => Ok(err), - _ => Err(error::DifferentVariant), - } - } -} - -#[cfg(feature = "serde")] -impl Format { - /// Obtain an error type for the serializer. - #[doc(hidden)] // Exposed only for the `declare_format_string` macro - pub fn into_invalid_serde_value<S: serde::Serializer>(self) -> S::Error { - use serde::ser::Error; - S::Error::custom(self) - } -} diff --git a/vendor/time/src/error/indeterminate_offset.rs b/vendor/time/src/error/indeterminate_offset.rs deleted file mode 100644 index d25d4164..00000000 --- a/vendor/time/src/error/indeterminate_offset.rs +++ /dev/null @@ -1,35 +0,0 @@ -//! Indeterminate offset - -use core::fmt; - -use crate::error; - -/// The system's UTC offset could not be determined at the given datetime. -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub struct IndeterminateOffset; - -impl fmt::Display for IndeterminateOffset { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str("The system's UTC offset could not be determined") - } -} - -#[cfg(feature = "std")] -impl std::error::Error for IndeterminateOffset {} - -impl From<IndeterminateOffset> for crate::Error { - fn from(err: IndeterminateOffset) -> Self { - Self::IndeterminateOffset(err) - } -} - -impl TryFrom<crate::Error> for IndeterminateOffset { - type Error = error::DifferentVariant; - - fn try_from(err: crate::Error) -> Result<Self, Self::Error> { - match err { - crate::Error::IndeterminateOffset(err) => Ok(err), - _ => Err(error::DifferentVariant), - } - } -} diff --git a/vendor/time/src/error/invalid_format_description.rs b/vendor/time/src/error/invalid_format_description.rs deleted file mode 100644 index 635fee75..00000000 --- a/vendor/time/src/error/invalid_format_description.rs +++ /dev/null @@ -1,132 +0,0 @@ -//! Invalid format description - -use alloc::string::String; -use core::fmt; - -use crate::error; - -/// The format description provided was not valid. -#[non_exhaustive] -#[derive(Debug, Clone, PartialEq, Eq)] -pub enum InvalidFormatDescription { - /// There was a bracket pair that was opened but not closed. - #[non_exhaustive] - UnclosedOpeningBracket { - /// The zero-based index of the opening bracket. - index: usize, - }, - /// A component name is not valid. - #[non_exhaustive] - InvalidComponentName { - /// The name of the invalid component name. - name: String, - /// The zero-based index the component name starts at. - index: usize, - }, - /// A modifier is not valid. - #[non_exhaustive] - InvalidModifier { - /// The value of the invalid modifier. - value: String, - /// The zero-based index the modifier starts at. - index: usize, - }, - /// A component name is missing. - #[non_exhaustive] - MissingComponentName { - /// The zero-based index where the component name should start. - index: usize, - }, - /// A required modifier is missing. - #[non_exhaustive] - MissingRequiredModifier { - /// The name of the modifier that is missing. - name: &'static str, - /// The zero-based index of the component. - index: usize, - }, - /// Something was expected, but not found. - #[non_exhaustive] - Expected { - /// What was expected to be present, but wasn't. - what: &'static str, - /// The zero-based index the item was expected to be found at. - index: usize, - }, - /// Certain behavior is not supported in the given context. - #[non_exhaustive] - NotSupported { - /// The behavior that is not supported. - what: &'static str, - /// The context in which the behavior is not supported. - context: &'static str, - /// The zero-based index the error occurred at. - index: usize, - }, -} - -impl From<InvalidFormatDescription> for crate::Error { - fn from(original: InvalidFormatDescription) -> Self { - Self::InvalidFormatDescription(original) - } -} - -impl TryFrom<crate::Error> for InvalidFormatDescription { - type Error = error::DifferentVariant; - - fn try_from(err: crate::Error) -> Result<Self, Self::Error> { - match err { - crate::Error::InvalidFormatDescription(err) => Ok(err), - _ => Err(error::DifferentVariant), - } - } -} - -impl fmt::Display for InvalidFormatDescription { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - use InvalidFormatDescription::*; - match self { - UnclosedOpeningBracket { index } => { - write!(f, "unclosed opening bracket at byte index {index}") - } - InvalidComponentName { name, index } => { - write!(f, "invalid component name `{name}` at byte index {index}") - } - InvalidModifier { value, index } => { - write!(f, "invalid modifier `{value}` at byte index {index}") - } - MissingComponentName { index } => { - write!(f, "missing component name at byte index {index}") - } - MissingRequiredModifier { name, index } => { - write!( - f, - "missing required modifier `{name}` for component at byte index {index}" - ) - } - Expected { - what: expected, - index, - } => { - write!(f, "expected {expected} at byte index {index}") - } - NotSupported { - what, - context, - index, - } => { - if context.is_empty() { - write!(f, "{what} is not supported at byte index {index}") - } else { - write!( - f, - "{what} is not supported in {context} at byte index {index}" - ) - } - } - } - } -} - -#[cfg(feature = "std")] -impl std::error::Error for InvalidFormatDescription {} diff --git a/vendor/time/src/error/invalid_variant.rs b/vendor/time/src/error/invalid_variant.rs deleted file mode 100644 index 396a749a..00000000 --- a/vendor/time/src/error/invalid_variant.rs +++ /dev/null @@ -1,34 +0,0 @@ -//! Invalid variant error - -use core::fmt; - -/// An error type indicating that a [`FromStr`](core::str::FromStr) call failed because the value -/// was not a valid variant. -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub struct InvalidVariant; - -impl fmt::Display for InvalidVariant { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "value was not a valid variant") - } -} - -#[cfg(feature = "std")] -impl std::error::Error for InvalidVariant {} - -impl From<InvalidVariant> for crate::Error { - fn from(err: InvalidVariant) -> Self { - Self::InvalidVariant(err) - } -} - -impl TryFrom<crate::Error> for InvalidVariant { - type Error = crate::error::DifferentVariant; - - fn try_from(err: crate::Error) -> Result<Self, Self::Error> { - match err { - crate::Error::InvalidVariant(err) => Ok(err), - _ => Err(crate::error::DifferentVariant), - } - } -} diff --git a/vendor/time/src/error/mod.rs b/vendor/time/src/error/mod.rs deleted file mode 100644 index 78b15380..00000000 --- a/vendor/time/src/error/mod.rs +++ /dev/null @@ -1,131 +0,0 @@ -//! Various error types returned by methods in the time crate. - -mod component_range; -mod conversion_range; -mod different_variant; -#[cfg(feature = "formatting")] -mod format; -#[cfg(feature = "local-offset")] -mod indeterminate_offset; -#[cfg(all(any(feature = "formatting", feature = "parsing"), feature = "alloc"))] -mod invalid_format_description; -mod invalid_variant; -#[cfg(feature = "parsing")] -mod parse; -#[cfg(feature = "parsing")] -mod parse_from_description; -#[cfg(feature = "parsing")] -mod try_from_parsed; - -#[cfg(feature = "parsing")] -use core::convert::Infallible; -use core::fmt; - -pub use component_range::ComponentRange; -pub use conversion_range::ConversionRange; -pub use different_variant::DifferentVariant; -#[cfg(feature = "formatting")] -pub use format::Format; -#[cfg(feature = "local-offset")] -pub use indeterminate_offset::IndeterminateOffset; -#[cfg(all(any(feature = "formatting", feature = "parsing"), feature = "alloc"))] -pub use invalid_format_description::InvalidFormatDescription; -pub use invalid_variant::InvalidVariant; -#[cfg(feature = "parsing")] -pub use parse::Parse; -#[cfg(feature = "parsing")] -pub use parse_from_description::ParseFromDescription; -#[cfg(feature = "parsing")] -pub use try_from_parsed::TryFromParsed; - -/// A unified error type for anything returned by a method in the time crate. -/// -/// This can be used when you either don't know or don't care about the exact error returned. -/// `Result<_, time::Error>` (or its alias `time::Result<_>`) will work in these situations. -#[non_exhaustive] -#[derive(Debug)] -pub enum Error { - #[allow(missing_docs)] - ConversionRange(ConversionRange), - #[allow(missing_docs)] - ComponentRange(ComponentRange), - #[cfg(feature = "local-offset")] - #[allow(missing_docs)] - IndeterminateOffset(IndeterminateOffset), - #[cfg(feature = "formatting")] - #[allow(missing_docs)] - Format(Format), - #[cfg(feature = "parsing")] - #[allow(missing_docs)] - ParseFromDescription(ParseFromDescription), - #[cfg(feature = "parsing")] - #[allow(missing_docs)] - #[non_exhaustive] - #[deprecated( - since = "0.3.28", - note = "no longer output. moved to the `ParseFromDescription` variant" - )] - UnexpectedTrailingCharacters { - #[doc(hidden)] - never: Infallible, - }, - #[cfg(feature = "parsing")] - #[allow(missing_docs)] - TryFromParsed(TryFromParsed), - #[cfg(all(any(feature = "formatting", feature = "parsing"), feature = "alloc"))] - #[allow(missing_docs)] - InvalidFormatDescription(InvalidFormatDescription), - #[allow(missing_docs)] - DifferentVariant(DifferentVariant), - #[allow(missing_docs)] - InvalidVariant(InvalidVariant), -} - -impl fmt::Display for Error { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - Self::ConversionRange(e) => e.fmt(f), - Self::ComponentRange(e) => e.fmt(f), - #[cfg(feature = "local-offset")] - Self::IndeterminateOffset(e) => e.fmt(f), - #[cfg(feature = "formatting")] - Self::Format(e) => e.fmt(f), - #[cfg(feature = "parsing")] - Self::ParseFromDescription(e) => e.fmt(f), - #[cfg(feature = "parsing")] - #[allow(deprecated)] - Self::UnexpectedTrailingCharacters { never } => match *never {}, - #[cfg(feature = "parsing")] - Self::TryFromParsed(e) => e.fmt(f), - #[cfg(all(any(feature = "formatting", feature = "parsing"), feature = "alloc"))] - Self::InvalidFormatDescription(e) => e.fmt(f), - Self::DifferentVariant(e) => e.fmt(f), - Self::InvalidVariant(e) => e.fmt(f), - } - } -} - -#[cfg(feature = "std")] -impl std::error::Error for Error { - fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { - match self { - Self::ConversionRange(err) => Some(err), - Self::ComponentRange(err) => Some(err), - #[cfg(feature = "local-offset")] - Self::IndeterminateOffset(err) => Some(err), - #[cfg(feature = "formatting")] - Self::Format(err) => Some(err), - #[cfg(feature = "parsing")] - Self::ParseFromDescription(err) => Some(err), - #[cfg(feature = "parsing")] - #[allow(deprecated)] - Self::UnexpectedTrailingCharacters { never } => match *never {}, - #[cfg(feature = "parsing")] - Self::TryFromParsed(err) => Some(err), - #[cfg(all(any(feature = "formatting", feature = "parsing"), feature = "alloc"))] - Self::InvalidFormatDescription(err) => Some(err), - Self::DifferentVariant(err) => Some(err), - Self::InvalidVariant(err) => Some(err), - } - } -} diff --git a/vendor/time/src/error/parse.rs b/vendor/time/src/error/parse.rs deleted file mode 100644 index ee3f87b7..00000000 --- a/vendor/time/src/error/parse.rs +++ /dev/null @@ -1,109 +0,0 @@ -//! Error that occurred at some stage of parsing - -use core::convert::Infallible; -use core::fmt; - -use crate::error::{self, ParseFromDescription, TryFromParsed}; - -/// An error that occurred at some stage of parsing. -#[non_exhaustive] -#[allow(variant_size_differences)] -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum Parse { - #[allow(missing_docs)] - TryFromParsed(TryFromParsed), - #[allow(missing_docs)] - ParseFromDescription(ParseFromDescription), - #[allow(missing_docs)] - #[non_exhaustive] - #[deprecated( - since = "0.3.28", - note = "no longer output. moved to the `ParseFromDescription` variant" - )] - UnexpectedTrailingCharacters { - #[doc(hidden)] - never: Infallible, - }, -} - -impl fmt::Display for Parse { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - Self::TryFromParsed(err) => err.fmt(f), - Self::ParseFromDescription(err) => err.fmt(f), - #[allow(deprecated)] - Self::UnexpectedTrailingCharacters { never } => match *never {}, - } - } -} - -#[cfg(feature = "std")] -impl std::error::Error for Parse { - fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { - match self { - Self::TryFromParsed(err) => Some(err), - Self::ParseFromDescription(err) => Some(err), - #[allow(deprecated)] - Self::UnexpectedTrailingCharacters { never } => match *never {}, - } - } -} - -impl From<TryFromParsed> for Parse { - fn from(err: TryFromParsed) -> Self { - Self::TryFromParsed(err) - } -} - -impl TryFrom<Parse> for TryFromParsed { - type Error = error::DifferentVariant; - - fn try_from(err: Parse) -> Result<Self, Self::Error> { - match err { - Parse::TryFromParsed(err) => Ok(err), - _ => Err(error::DifferentVariant), - } - } -} - -impl From<ParseFromDescription> for Parse { - fn from(err: ParseFromDescription) -> Self { - Self::ParseFromDescription(err) - } -} - -impl TryFrom<Parse> for ParseFromDescription { - type Error = error::DifferentVariant; - - fn try_from(err: Parse) -> Result<Self, Self::Error> { - match err { - Parse::ParseFromDescription(err) => Ok(err), - _ => Err(error::DifferentVariant), - } - } -} - -impl From<Parse> for crate::Error { - fn from(err: Parse) -> Self { - match err { - Parse::TryFromParsed(err) => Self::TryFromParsed(err), - Parse::ParseFromDescription(err) => Self::ParseFromDescription(err), - #[allow(deprecated)] - Parse::UnexpectedTrailingCharacters { never } => match never {}, - } - } -} - -impl TryFrom<crate::Error> for Parse { - type Error = error::DifferentVariant; - - fn try_from(err: crate::Error) -> Result<Self, Self::Error> { - match err { - crate::Error::ParseFromDescription(err) => Ok(Self::ParseFromDescription(err)), - #[allow(deprecated)] - crate::Error::UnexpectedTrailingCharacters { never } => match never {}, - crate::Error::TryFromParsed(err) => Ok(Self::TryFromParsed(err)), - _ => Err(error::DifferentVariant), - } - } -} diff --git a/vendor/time/src/error/parse_from_description.rs b/vendor/time/src/error/parse_from_description.rs deleted file mode 100644 index 40124dce..00000000 --- a/vendor/time/src/error/parse_from_description.rs +++ /dev/null @@ -1,53 +0,0 @@ -//! Error parsing an input into a [`Parsed`](crate::parsing::Parsed) struct - -use core::fmt; - -use crate::error; - -/// An error that occurred while parsing the input into a [`Parsed`](crate::parsing::Parsed) struct. -#[non_exhaustive] -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum ParseFromDescription { - /// A string literal was not what was expected. - #[non_exhaustive] - InvalidLiteral, - /// A dynamic component was not valid. - InvalidComponent(&'static str), - /// The input was expected to have ended, but there are characters that remain. - #[non_exhaustive] - UnexpectedTrailingCharacters, -} - -impl fmt::Display for ParseFromDescription { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - Self::InvalidLiteral => f.write_str("a character literal was not valid"), - Self::InvalidComponent(name) => { - write!(f, "the '{name}' component could not be parsed") - } - Self::UnexpectedTrailingCharacters => { - f.write_str("unexpected trailing characters; the end of input was expected") - } - } - } -} - -#[cfg(feature = "std")] -impl std::error::Error for ParseFromDescription {} - -impl From<ParseFromDescription> for crate::Error { - fn from(original: ParseFromDescription) -> Self { - Self::ParseFromDescription(original) - } -} - -impl TryFrom<crate::Error> for ParseFromDescription { - type Error = error::DifferentVariant; - - fn try_from(err: crate::Error) -> Result<Self, Self::Error> { - match err { - crate::Error::ParseFromDescription(err) => Ok(err), - _ => Err(error::DifferentVariant), - } - } -} diff --git a/vendor/time/src/error/try_from_parsed.rs b/vendor/time/src/error/try_from_parsed.rs deleted file mode 100644 index da8e6947..00000000 --- a/vendor/time/src/error/try_from_parsed.rs +++ /dev/null @@ -1,71 +0,0 @@ -//! Error converting a [`Parsed`](crate::parsing::Parsed) struct to another type - -use core::fmt; - -use crate::error; - -/// An error that occurred when converting a [`Parsed`](crate::parsing::Parsed) to another type. -#[non_exhaustive] -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum TryFromParsed { - /// The [`Parsed`](crate::parsing::Parsed) did not include enough information to construct the - /// type. - InsufficientInformation, - /// Some component contained an invalid value for the type. - ComponentRange(error::ComponentRange), -} - -impl fmt::Display for TryFromParsed { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - Self::InsufficientInformation => f.write_str( - "the `Parsed` struct did not include enough information to construct the type", - ), - Self::ComponentRange(err) => err.fmt(f), - } - } -} - -impl From<error::ComponentRange> for TryFromParsed { - fn from(v: error::ComponentRange) -> Self { - Self::ComponentRange(v) - } -} - -impl TryFrom<TryFromParsed> for error::ComponentRange { - type Error = error::DifferentVariant; - - fn try_from(err: TryFromParsed) -> Result<Self, Self::Error> { - match err { - TryFromParsed::ComponentRange(err) => Ok(err), - _ => Err(error::DifferentVariant), - } - } -} - -#[cfg(feature = "std")] -impl std::error::Error for TryFromParsed { - fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { - match self { - Self::InsufficientInformation => None, - Self::ComponentRange(err) => Some(err), - } - } -} - -impl From<TryFromParsed> for crate::Error { - fn from(original: TryFromParsed) -> Self { - Self::TryFromParsed(original) - } -} - -impl TryFrom<crate::Error> for TryFromParsed { - type Error = error::DifferentVariant; - - fn try_from(err: crate::Error) -> Result<Self, Self::Error> { - match err { - crate::Error::TryFromParsed(err) => Ok(err), - _ => Err(error::DifferentVariant), - } - } -} diff --git a/vendor/time/src/ext/digit_count.rs b/vendor/time/src/ext/digit_count.rs deleted file mode 100644 index fb42ce9e..00000000 --- a/vendor/time/src/ext/digit_count.rs +++ /dev/null @@ -1,26 +0,0 @@ -use num_conv::prelude::*; - -/// A trait that indicates the formatted width of the value can be determined. -/// -/// Note that this should not be implemented for any signed integers. This forces the caller to -/// write the sign if desired. -pub(crate) trait DigitCount { - /// The number of digits in the stringified value. - fn num_digits(self) -> u8; -} - -/// A macro to generate implementations of `DigitCount` for unsigned integers. -macro_rules! impl_digit_count { - ($($t:ty),* $(,)?) => { - $(impl DigitCount for $t { - fn num_digits(self) -> u8 { - match self.checked_ilog10() { - Some(n) => n.truncate::<u8>() + 1, - None => 1, - } - } - })* - }; -} - -impl_digit_count!(u8, u16, u32); diff --git a/vendor/time/src/ext/instant.rs b/vendor/time/src/ext/instant.rs deleted file mode 100644 index 313ad5b1..00000000 --- a/vendor/time/src/ext/instant.rs +++ /dev/null @@ -1,98 +0,0 @@ -use std::time::Instant as StdInstant; - -use crate::Duration; - -/// Sealed trait to prevent downstream implementations. -mod sealed { - /// A trait that cannot be implemented by downstream users. - pub trait Sealed: Sized {} - impl Sealed for std::time::Instant {} -} - -/// An extension trait for [`std::time::Instant`] that adds methods for -/// [`time::Duration`](Duration)s. -pub trait InstantExt: sealed::Sealed { - /// # Panics - /// - /// This function may panic if the resulting point in time cannot be represented by the - /// underlying data structure. See [`InstantExt::checked_add_signed`] for a non-panicking - /// version. - fn add_signed(self, duration: Duration) -> Self { - self.checked_add_signed(duration) - .expect("overflow when adding duration to instant") - } - - /// # Panics - /// - /// This function may panic if the resulting point in time cannot be represented by the - /// underlying data structure. See [`InstantExt::checked_sub_signed`] for a non-panicking - /// version. - fn sub_signed(self, duration: Duration) -> Self { - self.checked_sub_signed(duration) - .expect("overflow when subtracting duration from instant") - } - - /// Returns `Some(t)` where `t` is the time `self.checked_add_signed(duration)` if `t` can be - /// represented as `Instant` (which means it's inside the bounds of the underlying data - /// structure), `None` otherwise. - fn checked_add_signed(&self, duration: Duration) -> Option<Self>; - - /// Returns `Some(t)` where `t` is the time `self.checked_sub_signed(duration)` if `t` can be - /// represented as `Instant` (which means it's inside the bounds of the underlying data - /// structure), `None` otherwise. - fn checked_sub_signed(&self, duration: Duration) -> Option<Self>; - - /// Returns the amount of time elapsed from another instant to this one. This will be negative - /// if `earlier` is later than `self`. - /// - /// # Example - /// - /// ```rust - /// # use std::thread::sleep; - /// # use std::time::{Duration, Instant}; - /// # use time::ext::InstantExt; - /// let now = Instant::now(); - /// sleep(Duration::new(1, 0)); - /// let new_now = Instant::now(); - /// println!("{:?}", new_now.signed_duration_since(now)); // positive - /// println!("{:?}", now.signed_duration_since(new_now)); // negative - /// ``` - fn signed_duration_since(&self, earlier: Self) -> Duration; -} - -impl InstantExt for StdInstant { - fn checked_add_signed(&self, duration: Duration) -> Option<Self> { - if duration.is_positive() { - self.checked_add(duration.unsigned_abs()) - } else if duration.is_negative() { - self.checked_sub(duration.unsigned_abs()) - } else { - debug_assert!(duration.is_zero()); - Some(*self) - } - } - - fn checked_sub_signed(&self, duration: Duration) -> Option<Self> { - if duration.is_positive() { - self.checked_sub(duration.unsigned_abs()) - } else if duration.is_negative() { - self.checked_add(duration.unsigned_abs()) - } else { - debug_assert!(duration.is_zero()); - Some(*self) - } - } - - fn signed_duration_since(&self, earlier: Self) -> Duration { - if *self > earlier { - self.saturating_duration_since(earlier) - .try_into() - .unwrap_or(Duration::MAX) - } else { - earlier - .saturating_duration_since(*self) - .try_into() - .map_or(Duration::MIN, |d: Duration| -d) - } - } -} diff --git a/vendor/time/src/ext/mod.rs b/vendor/time/src/ext/mod.rs deleted file mode 100644 index 7cc2d0d9..00000000 --- a/vendor/time/src/ext/mod.rs +++ /dev/null @@ -1,13 +0,0 @@ -//! Extension traits. - -mod digit_count; -#[cfg(feature = "std")] -mod instant; -mod numerical_duration; -mod numerical_std_duration; - -pub(crate) use self::digit_count::DigitCount; -#[cfg(feature = "std")] -pub use self::instant::InstantExt; -pub use self::numerical_duration::NumericalDuration; -pub use self::numerical_std_duration::NumericalStdDuration; diff --git a/vendor/time/src/ext/numerical_duration.rs b/vendor/time/src/ext/numerical_duration.rs deleted file mode 100644 index a1e93cc4..00000000 --- a/vendor/time/src/ext/numerical_duration.rs +++ /dev/null @@ -1,140 +0,0 @@ -use crate::convert::*; -use crate::Duration; - -/// Sealed trait to prevent downstream implementations. -mod sealed { - /// A trait that cannot be implemented by downstream users. - pub trait Sealed {} - impl Sealed for i64 {} - impl Sealed for f64 {} -} - -/// Create [`Duration`]s from numeric literals. -/// -/// # Examples -/// -/// Basic construction of [`Duration`]s. -/// -/// ```rust -/// # use time::{Duration, ext::NumericalDuration}; -/// assert_eq!(5.nanoseconds(), Duration::nanoseconds(5)); -/// assert_eq!(5.microseconds(), Duration::microseconds(5)); -/// assert_eq!(5.milliseconds(), Duration::milliseconds(5)); -/// assert_eq!(5.seconds(), Duration::seconds(5)); -/// assert_eq!(5.minutes(), Duration::minutes(5)); -/// assert_eq!(5.hours(), Duration::hours(5)); -/// assert_eq!(5.days(), Duration::days(5)); -/// assert_eq!(5.weeks(), Duration::weeks(5)); -/// ``` -/// -/// Signed integers work as well! -/// -/// ```rust -/// # use time::{Duration, ext::NumericalDuration}; -/// assert_eq!((-5).nanoseconds(), Duration::nanoseconds(-5)); -/// assert_eq!((-5).microseconds(), Duration::microseconds(-5)); -/// assert_eq!((-5).milliseconds(), Duration::milliseconds(-5)); -/// assert_eq!((-5).seconds(), Duration::seconds(-5)); -/// assert_eq!((-5).minutes(), Duration::minutes(-5)); -/// assert_eq!((-5).hours(), Duration::hours(-5)); -/// assert_eq!((-5).days(), Duration::days(-5)); -/// assert_eq!((-5).weeks(), Duration::weeks(-5)); -/// ``` -/// -/// Just like any other [`Duration`], they can be added, subtracted, etc. -/// -/// ```rust -/// # use time::ext::NumericalDuration; -/// assert_eq!(2.seconds() + 500.milliseconds(), 2_500.milliseconds()); -/// assert_eq!(2.seconds() - 500.milliseconds(), 1_500.milliseconds()); -/// ``` -/// -/// When called on floating point values, any remainder of the floating point value will be -/// truncated. Keep in mind that floating point numbers are inherently imprecise and have -/// limited capacity. -pub trait NumericalDuration: sealed::Sealed { - /// Create a [`Duration`] from the number of nanoseconds. - fn nanoseconds(self) -> Duration; - /// Create a [`Duration`] from the number of microseconds. - fn microseconds(self) -> Duration; - /// Create a [`Duration`] from the number of milliseconds. - fn milliseconds(self) -> Duration; - /// Create a [`Duration`] from the number of seconds. - fn seconds(self) -> Duration; - /// Create a [`Duration`] from the number of minutes. - fn minutes(self) -> Duration; - /// Create a [`Duration`] from the number of hours. - fn hours(self) -> Duration; - /// Create a [`Duration`] from the number of days. - fn days(self) -> Duration; - /// Create a [`Duration`] from the number of weeks. - fn weeks(self) -> Duration; -} - -impl NumericalDuration for i64 { - fn nanoseconds(self) -> Duration { - Duration::nanoseconds(self) - } - - fn microseconds(self) -> Duration { - Duration::microseconds(self) - } - - fn milliseconds(self) -> Duration { - Duration::milliseconds(self) - } - - fn seconds(self) -> Duration { - Duration::seconds(self) - } - - fn minutes(self) -> Duration { - Duration::minutes(self) - } - - fn hours(self) -> Duration { - Duration::hours(self) - } - - fn days(self) -> Duration { - Duration::days(self) - } - - fn weeks(self) -> Duration { - Duration::weeks(self) - } -} - -impl NumericalDuration for f64 { - fn nanoseconds(self) -> Duration { - Duration::nanoseconds(self as i64) - } - - fn microseconds(self) -> Duration { - Duration::nanoseconds((self * Nanosecond::per(Microsecond) as Self) as i64) - } - - fn milliseconds(self) -> Duration { - Duration::nanoseconds((self * Nanosecond::per(Millisecond) as Self) as i64) - } - - fn seconds(self) -> Duration { - Duration::nanoseconds((self * Nanosecond::per(Second) as Self) as i64) - } - - fn minutes(self) -> Duration { - Duration::nanoseconds((self * Nanosecond::per(Minute) as Self) as i64) - } - - fn hours(self) -> Duration { - Duration::nanoseconds((self * Nanosecond::per(Hour) as Self) as i64) - } - - fn days(self) -> Duration { - Duration::nanoseconds((self * Nanosecond::per(Day) as Self) as i64) - } - - fn weeks(self) -> Duration { - Duration::nanoseconds((self * Nanosecond::per(Week) as Self) as i64) - } -} diff --git a/vendor/time/src/ext/numerical_std_duration.rs b/vendor/time/src/ext/numerical_std_duration.rs deleted file mode 100644 index d6bc7bab..00000000 --- a/vendor/time/src/ext/numerical_std_duration.rs +++ /dev/null @@ -1,192 +0,0 @@ -use core::time::Duration as StdDuration; - -use num_conv::prelude::*; - -use crate::convert::*; - -/// Sealed trait to prevent downstream implementations. -mod sealed { - /// A trait that cannot be implemented by downstream users. - pub trait Sealed {} - impl Sealed for u64 {} - impl Sealed for f64 {} -} - -/// Create [`std::time::Duration`]s from numeric literals. -/// -/// # Examples -/// -/// Basic construction of [`std::time::Duration`]s. -/// -/// ```rust -/// # use time::ext::NumericalStdDuration; -/// # use core::time::Duration; -/// assert_eq!(5.std_nanoseconds(), Duration::from_nanos(5)); -/// assert_eq!(5.std_microseconds(), Duration::from_micros(5)); -/// assert_eq!(5.std_milliseconds(), Duration::from_millis(5)); -/// assert_eq!(5.std_seconds(), Duration::from_secs(5)); -/// assert_eq!(5.std_minutes(), Duration::from_secs(5 * 60)); -/// assert_eq!(5.std_hours(), Duration::from_secs(5 * 3_600)); -/// assert_eq!(5.std_days(), Duration::from_secs(5 * 86_400)); -/// assert_eq!(5.std_weeks(), Duration::from_secs(5 * 604_800)); -/// ``` -/// -/// Just like any other [`std::time::Duration`], they can be added, subtracted, etc. -/// -/// ```rust -/// # use time::ext::NumericalStdDuration; -/// assert_eq!( -/// 2.std_seconds() + 500.std_milliseconds(), -/// 2_500.std_milliseconds() -/// ); -/// assert_eq!( -/// 2.std_seconds() - 500.std_milliseconds(), -/// 1_500.std_milliseconds() -/// ); -/// ``` -/// -/// When called on floating point values, any remainder of the floating point value will be -/// truncated. Keep in mind that floating point numbers are inherently imprecise and have -/// limited capacity. -pub trait NumericalStdDuration: sealed::Sealed { - /// Create a [`std::time::Duration`] from the number of nanoseconds. - fn std_nanoseconds(self) -> StdDuration; - /// Create a [`std::time::Duration`] from the number of microseconds. - fn std_microseconds(self) -> StdDuration; - /// Create a [`std::time::Duration`] from the number of milliseconds. - fn std_milliseconds(self) -> StdDuration; - /// Create a [`std::time::Duration`] from the number of seconds. - fn std_seconds(self) -> StdDuration; - /// Create a [`std::time::Duration`] from the number of minutes. - fn std_minutes(self) -> StdDuration; - /// Create a [`std::time::Duration`] from the number of hours. - fn std_hours(self) -> StdDuration; - /// Create a [`std::time::Duration`] from the number of days. - fn std_days(self) -> StdDuration; - /// Create a [`std::time::Duration`] from the number of weeks. - fn std_weeks(self) -> StdDuration; -} - -impl NumericalStdDuration for u64 { - fn std_nanoseconds(self) -> StdDuration { - StdDuration::from_nanos(self) - } - - fn std_microseconds(self) -> StdDuration { - StdDuration::from_micros(self) - } - - fn std_milliseconds(self) -> StdDuration { - StdDuration::from_millis(self) - } - - fn std_seconds(self) -> StdDuration { - StdDuration::from_secs(self) - } - - /// # Panics - /// - /// This may panic if an overflow occurs. - fn std_minutes(self) -> StdDuration { - StdDuration::from_secs( - self.checked_mul(Second::per(Minute).extend()) - .expect("overflow constructing `time::Duration`"), - ) - } - - /// # Panics - /// - /// This may panic if an overflow occurs. - fn std_hours(self) -> StdDuration { - StdDuration::from_secs( - self.checked_mul(Second::per(Hour).extend()) - .expect("overflow constructing `time::Duration`"), - ) - } - - /// # Panics - /// - /// This may panic if an overflow occurs. - fn std_days(self) -> StdDuration { - StdDuration::from_secs( - self.checked_mul(Second::per(Day).extend()) - .expect("overflow constructing `time::Duration`"), - ) - } - - /// # Panics - /// - /// This may panic if an overflow occurs. - fn std_weeks(self) -> StdDuration { - StdDuration::from_secs( - self.checked_mul(Second::per(Week).extend()) - .expect("overflow constructing `time::Duration`"), - ) - } -} - -impl NumericalStdDuration for f64 { - /// # Panics - /// - /// This will panic if self is negative. - fn std_nanoseconds(self) -> StdDuration { - assert!(self >= 0.); - StdDuration::from_nanos(self as u64) - } - - /// # Panics - /// - /// This will panic if self is negative. - fn std_microseconds(self) -> StdDuration { - assert!(self >= 0.); - StdDuration::from_nanos((self * Nanosecond::per(Microsecond) as Self) as u64) - } - - /// # Panics - /// - /// This will panic if self is negative. - fn std_milliseconds(self) -> StdDuration { - assert!(self >= 0.); - StdDuration::from_nanos((self * Nanosecond::per(Millisecond) as Self) as u64) - } - - /// # Panics - /// - /// This will panic if self is negative. - fn std_seconds(self) -> StdDuration { - assert!(self >= 0.); - StdDuration::from_nanos((self * Nanosecond::per(Second) as Self) as u64) - } - - /// # Panics - /// - /// This will panic if self is negative. - fn std_minutes(self) -> StdDuration { - assert!(self >= 0.); - StdDuration::from_nanos((self * Nanosecond::per(Minute) as Self) as u64) - } - - /// # Panics - /// - /// This will panic if self is negative. - fn std_hours(self) -> StdDuration { - assert!(self >= 0.); - StdDuration::from_nanos((self * Nanosecond::per(Hour) as Self) as u64) - } - - /// # Panics - /// - /// This will panic if self is negative. - fn std_days(self) -> StdDuration { - assert!(self >= 0.); - StdDuration::from_nanos((self * Nanosecond::per(Day) as Self) as u64) - } - - /// # Panics - /// - /// This will panic if self is negative. - fn std_weeks(self) -> StdDuration { - assert!(self >= 0.); - StdDuration::from_nanos((self * Nanosecond::per(Week) as Self) as u64) - } -} diff --git a/vendor/time/src/format_description/borrowed_format_item.rs b/vendor/time/src/format_description/borrowed_format_item.rs deleted file mode 100644 index 2e97efd4..00000000 --- a/vendor/time/src/format_description/borrowed_format_item.rs +++ /dev/null @@ -1,106 +0,0 @@ -//! A format item with borrowed data. - -#[cfg(feature = "alloc")] -use alloc::string::String; -#[cfg(feature = "alloc")] -use core::fmt; - -use crate::error; -use crate::format_description::Component; - -/// A complete description of how to format and parse a type. -#[non_exhaustive] -#[cfg_attr(not(feature = "alloc"), derive(Debug))] -#[derive(Clone, PartialEq, Eq)] -pub enum BorrowedFormatItem<'a> { - /// Bytes that are formatted as-is. - /// - /// **Note**: These bytes **should** be UTF-8, but are not required to be. The value is passed - /// through `String::from_utf8_lossy` when necessary. - Literal(&'a [u8]), - /// A minimal representation of a single non-literal item. - Component(Component), - /// A series of literals or components that collectively form a partial or complete - /// description. - Compound(&'a [Self]), - /// A `FormatItem` that may or may not be present when parsing. If parsing fails, there - /// will be no effect on the resulting `struct`. - /// - /// This variant has no effect on formatting, as the value is guaranteed to be present. - Optional(&'a Self), - /// A series of `FormatItem`s where, when parsing, the first successful parse is used. When - /// formatting, the first element of the slice is used. An empty slice is a no-op when - /// formatting or parsing. - First(&'a [Self]), -} - -#[cfg(feature = "alloc")] -impl fmt::Debug for BorrowedFormatItem<'_> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - Self::Literal(literal) => f.write_str(&String::from_utf8_lossy(literal)), - Self::Component(component) => component.fmt(f), - Self::Compound(compound) => compound.fmt(f), - Self::Optional(item) => f.debug_tuple("Optional").field(item).finish(), - Self::First(items) => f.debug_tuple("First").field(items).finish(), - } - } -} - -impl From<Component> for BorrowedFormatItem<'_> { - fn from(component: Component) -> Self { - Self::Component(component) - } -} - -impl TryFrom<BorrowedFormatItem<'_>> for Component { - type Error = error::DifferentVariant; - - fn try_from(value: BorrowedFormatItem<'_>) -> Result<Self, Self::Error> { - match value { - BorrowedFormatItem::Component(component) => Ok(component), - _ => Err(error::DifferentVariant), - } - } -} - -impl<'a> From<&'a [BorrowedFormatItem<'_>]> for BorrowedFormatItem<'a> { - fn from(items: &'a [BorrowedFormatItem<'_>]) -> Self { - Self::Compound(items) - } -} - -impl<'a> TryFrom<BorrowedFormatItem<'a>> for &[BorrowedFormatItem<'a>] { - type Error = error::DifferentVariant; - - fn try_from(value: BorrowedFormatItem<'a>) -> Result<Self, Self::Error> { - match value { - BorrowedFormatItem::Compound(items) => Ok(items), - _ => Err(error::DifferentVariant), - } - } -} - -impl PartialEq<Component> for BorrowedFormatItem<'_> { - fn eq(&self, rhs: &Component) -> bool { - matches!(self, Self::Component(component) if component == rhs) - } -} - -impl PartialEq<BorrowedFormatItem<'_>> for Component { - fn eq(&self, rhs: &BorrowedFormatItem<'_>) -> bool { - rhs == self - } -} - -impl PartialEq<&[Self]> for BorrowedFormatItem<'_> { - fn eq(&self, rhs: &&[Self]) -> bool { - matches!(self, Self::Compound(compound) if compound == rhs) - } -} - -impl PartialEq<BorrowedFormatItem<'_>> for &[BorrowedFormatItem<'_>] { - fn eq(&self, rhs: &BorrowedFormatItem<'_>) -> bool { - rhs == self - } -} diff --git a/vendor/time/src/format_description/component.rs b/vendor/time/src/format_description/component.rs deleted file mode 100644 index 9119c090..00000000 --- a/vendor/time/src/format_description/component.rs +++ /dev/null @@ -1,44 +0,0 @@ -//! Part of a format description. - -use crate::format_description::modifier; - -/// A component of a larger format description. -#[non_exhaustive] -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum Component { - /// Day of the month. - Day(modifier::Day), - /// Month of the year. - Month(modifier::Month), - /// Ordinal day of the year. - Ordinal(modifier::Ordinal), - /// Day of the week. - Weekday(modifier::Weekday), - /// Week within the year. - WeekNumber(modifier::WeekNumber), - /// Year of the date. - Year(modifier::Year), - /// Hour of the day. - Hour(modifier::Hour), - /// Minute within the hour. - Minute(modifier::Minute), - /// AM/PM part of the time. - Period(modifier::Period), - /// Second within the minute. - Second(modifier::Second), - /// Subsecond within the second. - Subsecond(modifier::Subsecond), - /// Hour of the UTC offset. - OffsetHour(modifier::OffsetHour), - /// Minute within the hour of the UTC offset. - OffsetMinute(modifier::OffsetMinute), - /// Second within the minute of the UTC offset. - OffsetSecond(modifier::OffsetSecond), - /// A number of bytes to ignore when parsing. This has no effect on formatting. - Ignore(modifier::Ignore), - /// A Unix timestamp. - UnixTimestamp(modifier::UnixTimestamp), - /// The end of input. Parsing this component will fail if there is any input remaining. This - /// component neither affects formatting nor consumes any input when parsing. - End(modifier::End), -} diff --git a/vendor/time/src/format_description/mod.rs b/vendor/time/src/format_description/mod.rs deleted file mode 100644 index 9e7d5202..00000000 --- a/vendor/time/src/format_description/mod.rs +++ /dev/null @@ -1,41 +0,0 @@ -//! Description of how types should be formatted and parsed. -//! -//! The formatted value will be output to the provided writer. Format descriptions can be -//! [well-known](crate::format_description::well_known) or obtained by using the -//! [`format_description!`](crate::macros::format_description) macro or a function listed below. -//! -//! For examples, see the implementors of [Formattable](crate::formatting::Formattable), -//! e.g. [`well_known::Rfc3339`]. - -mod borrowed_format_item; -mod component; -pub mod modifier; -#[cfg(feature = "alloc")] -mod owned_format_item; -#[cfg(feature = "alloc")] -mod parse; - -pub use borrowed_format_item::BorrowedFormatItem; -#[doc(hidden)] -#[deprecated(since = "0.3.37", note = "use `BorrowedFormatItem` for clarity")] -pub use borrowed_format_item::BorrowedFormatItem as FormatItem; -#[cfg(feature = "alloc")] -pub use owned_format_item::OwnedFormatItem; - -pub use self::component::Component; -#[cfg(feature = "alloc")] -pub use self::parse::{ - parse, parse_borrowed, parse_owned, parse_strftime_borrowed, parse_strftime_owned, -}; - -/// Well-known formats, typically standards. -pub mod well_known { - pub mod iso8601; - mod rfc2822; - mod rfc3339; - - #[doc(inline)] - pub use iso8601::Iso8601; - pub use rfc2822::Rfc2822; - pub use rfc3339::Rfc3339; -} diff --git a/vendor/time/src/format_description/modifier.rs b/vendor/time/src/format_description/modifier.rs deleted file mode 100644 index 82fca805..00000000 --- a/vendor/time/src/format_description/modifier.rs +++ /dev/null @@ -1,434 +0,0 @@ -//! Various modifiers for components. - -use core::num::NonZeroU16; - -/// Day of the month. -#[non_exhaustive] -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub struct Day { - /// The padding to obtain the minimum width. - pub padding: Padding, -} - -/// The representation of a month. -#[non_exhaustive] -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum MonthRepr { - /// The number of the month (January is 1, December is 12). - Numerical, - /// The long form of the month name (e.g. "January"). - Long, - /// The short form of the month name (e.g. "Jan"). - Short, -} - -/// Month of the year. -#[non_exhaustive] -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub struct Month { - /// The padding to obtain the minimum width. - pub padding: Padding, - /// What form of representation should be used? - pub repr: MonthRepr, - /// Is the value case sensitive when parsing? - pub case_sensitive: bool, -} - -/// Ordinal day of the year. -#[non_exhaustive] -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub struct Ordinal { - /// The padding to obtain the minimum width. - pub padding: Padding, -} - -/// The representation used for the day of the week. -#[non_exhaustive] -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum WeekdayRepr { - /// The short form of the weekday (e.g. "Mon"). - Short, - /// The long form of the weekday (e.g. "Monday"). - Long, - /// A numerical representation using Sunday as the first day of the week. - /// - /// Sunday is either 0 or 1, depending on the other modifier's value. - Sunday, - /// A numerical representation using Monday as the first day of the week. - /// - /// Monday is either 0 or 1, depending on the other modifier's value. - Monday, -} - -/// Day of the week. -#[non_exhaustive] -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub struct Weekday { - /// What form of representation should be used? - pub repr: WeekdayRepr, - /// When using a numerical representation, should it be zero or one-indexed? - pub one_indexed: bool, - /// Is the value case sensitive when parsing? - pub case_sensitive: bool, -} - -/// The representation used for the week number. -#[non_exhaustive] -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum WeekNumberRepr { - /// Week 1 is the week that contains January 4. - Iso, - /// Week 1 begins on the first Sunday of the calendar year. - Sunday, - /// Week 1 begins on the first Monday of the calendar year. - Monday, -} - -/// Week within the year. -#[non_exhaustive] -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub struct WeekNumber { - /// The padding to obtain the minimum width. - pub padding: Padding, - /// What kind of representation should be used? - pub repr: WeekNumberRepr, -} - -/// The representation used for a year value. -#[non_exhaustive] -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum YearRepr { - /// The full value of the year. - Full, - /// All digits except the last two. Includes the sign, if any. - Century, - /// Only the last two digits of the year. - LastTwo, -} - -/// The range of years that are supported. -/// -/// This modifier has no effect when the year repr is [`LastTwo`](YearRepr::LastTwo). -#[non_exhaustive] -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum YearRange { - /// Years between -9999 and 9999 are supported. - Standard, - /// Years between -999_999 and 999_999 are supported, with the sign being required if the year - /// contains more than four digits. - /// - /// If the `large-dates` feature is not enabled, this variant is equivalent to `Standard`. - Extended, -} - -/// Year of the date. -#[non_exhaustive] -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub struct Year { - /// The padding to obtain the minimum width. - pub padding: Padding, - /// What kind of representation should be used? - pub repr: YearRepr, - /// What range of years is supported? - pub range: YearRange, - /// Whether the value is based on the ISO week number or the Gregorian calendar. - pub iso_week_based: bool, - /// Whether the `+` sign is present when a positive year contains fewer than five digits. - pub sign_is_mandatory: bool, -} - -/// Hour of the day. -#[non_exhaustive] -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub struct Hour { - /// The padding to obtain the minimum width. - pub padding: Padding, - /// Is the hour displayed using a 12 or 24-hour clock? - pub is_12_hour_clock: bool, -} - -/// Minute within the hour. -#[non_exhaustive] -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub struct Minute { - /// The padding to obtain the minimum width. - pub padding: Padding, -} - -/// AM/PM part of the time. -#[non_exhaustive] -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub struct Period { - /// Is the period uppercase or lowercase? - pub is_uppercase: bool, - /// Is the value case sensitive when parsing? - /// - /// Note that when `false`, the `is_uppercase` field has no effect on parsing behavior. - pub case_sensitive: bool, -} - -/// Second within the minute. -#[non_exhaustive] -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub struct Second { - /// The padding to obtain the minimum width. - pub padding: Padding, -} - -/// The number of digits present in a subsecond representation. -#[non_exhaustive] -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum SubsecondDigits { - /// Exactly one digit. - One, - /// Exactly two digits. - Two, - /// Exactly three digits. - Three, - /// Exactly four digits. - Four, - /// Exactly five digits. - Five, - /// Exactly six digits. - Six, - /// Exactly seven digits. - Seven, - /// Exactly eight digits. - Eight, - /// Exactly nine digits. - Nine, - /// Any number of digits (up to nine) that is at least one. When formatting, the minimum digits - /// necessary will be used. - OneOrMore, -} - -/// Subsecond within the second. -#[non_exhaustive] -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub struct Subsecond { - /// How many digits are present in the component? - pub digits: SubsecondDigits, -} - -/// Hour of the UTC offset. -#[non_exhaustive] -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub struct OffsetHour { - /// Whether the `+` sign is present on positive values. - pub sign_is_mandatory: bool, - /// The padding to obtain the minimum width. - pub padding: Padding, -} - -/// Minute within the hour of the UTC offset. -#[non_exhaustive] -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub struct OffsetMinute { - /// The padding to obtain the minimum width. - pub padding: Padding, -} - -/// Second within the minute of the UTC offset. -#[non_exhaustive] -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub struct OffsetSecond { - /// The padding to obtain the minimum width. - pub padding: Padding, -} - -/// Type of padding to ensure a minimum width. -#[non_exhaustive] -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum Padding { - /// A space character (` `) should be used as padding. - Space, - /// A zero character (`0`) should be used as padding. - Zero, - /// There is no padding. This can result in a width below the otherwise minimum number of - /// characters. - None, -} - -/// Ignore some number of bytes. -/// -/// This has no effect when formatting. -#[non_exhaustive] -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub struct Ignore { - /// The number of bytes to ignore. - pub count: NonZeroU16, -} - -// Needed as `Default` is deliberately not implemented for `Ignore`. The number of bytes to ignore -// must be explicitly provided. -impl Ignore { - /// Create an instance of `Ignore` with the provided number of bytes to ignore. - pub const fn count(count: NonZeroU16) -> Self { - Self { count } - } -} - -/// The precision of a Unix timestamp. -#[non_exhaustive] -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum UnixTimestampPrecision { - /// Seconds since the Unix epoch. - Second, - /// Milliseconds since the Unix epoch. - Millisecond, - /// Microseconds since the Unix epoch. - Microsecond, - /// Nanoseconds since the Unix epoch. - Nanosecond, -} - -/// A Unix timestamp. -#[non_exhaustive] -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub struct UnixTimestamp { - /// The precision of the timestamp. - pub precision: UnixTimestampPrecision, - /// Whether the `+` sign must be present for a non-negative timestamp. - pub sign_is_mandatory: bool, -} - -/// The end of input. -/// -/// There is currently not customization for this modifier. -#[non_exhaustive] -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub struct End; - -/// Generate the provided code if and only if `pub` is present. -macro_rules! if_pub { - (pub $(#[$attr:meta])*; $($x:tt)*) => { - $(#[$attr])* - /// - /// This function exists since [`Default::default()`] cannot be used in a `const` context. - /// It may be removed once that becomes possible. As the [`Default`] trait is in the - /// prelude, removing this function in the future will not cause any resolution failures for - /// the overwhelming majority of users; only users who use `#![no_implicit_prelude]` will be - /// affected. As such it will not be considered a breaking change. - $($x)* - }; - ($($_:tt)*) => {}; -} - -/// Implement `Default` for the given type. This also generates an inherent implementation of a -/// `default` method that is `const fn`, permitting the default value to be used in const contexts. -// Every modifier should use this macro rather than a derived `Default`. -macro_rules! impl_const_default { - ($($(#[$doc:meta])* $(@$pub:ident)? $type:ty => $default:expr;)*) => {$( - impl $type { - if_pub! { - $($pub)? - $(#[$doc])*; - pub const fn default() -> Self { - $default - } - } - } - - $(#[$doc])* - impl Default for $type { - fn default() -> Self { - $default - } - } - )*}; -} - -impl_const_default! { - /// Creates a modifier that indicates the value is [padded with zeroes](Padding::Zero). - @pub Day => Self { padding: Padding::Zero }; - /// Creates a modifier that indicates the value uses the - /// [`Numerical`](Self::Numerical) representation. - MonthRepr => Self::Numerical; - /// Creates an instance of this type that indicates the value uses the - /// [`Numerical`](MonthRepr::Numerical) representation, is [padded with zeroes](Padding::Zero), - /// and is case-sensitive when parsing. - @pub Month => Self { - padding: Padding::Zero, - repr: MonthRepr::Numerical, - case_sensitive: true, - }; - /// Creates a modifier that indicates the value is [padded with zeroes](Padding::Zero). - @pub Ordinal => Self { padding: Padding::Zero }; - /// Creates a modifier that indicates the value uses the [`Long`](Self::Long) representation. - WeekdayRepr => Self::Long; - /// Creates a modifier that indicates the value uses the [`Long`](WeekdayRepr::Long) - /// representation and is case-sensitive when parsing. If the representation is changed to a - /// numerical one, the instance defaults to one-based indexing. - @pub Weekday => Self { - repr: WeekdayRepr::Long, - one_indexed: true, - case_sensitive: true, - }; - /// Creates a modifier that indicates that the value uses the [`Iso`](Self::Iso) representation. - WeekNumberRepr => Self::Iso; - /// Creates a modifier that indicates that the value is [padded with zeroes](Padding::Zero) - /// and uses the [`Iso`](WeekNumberRepr::Iso) representation. - @pub WeekNumber => Self { - padding: Padding::Zero, - repr: WeekNumberRepr::Iso, - }; - /// Creates a modifier that indicates the value uses the [`Full`](Self::Full) representation. - YearRepr => Self::Full; - /// Creates a modifier that indicates the value uses the [`Extended`](Self::Extended) range. - YearRange => Self::Extended; - /// Creates a modifier that indicates the value uses the [`Full`](YearRepr::Full) - /// representation, is [padded with zeroes](Padding::Zero), uses the Gregorian calendar as its - /// base, and only includes the year's sign if necessary. - @pub Year => Self { - padding: Padding::Zero, - repr: YearRepr::Full, - range: YearRange::Extended, - iso_week_based: false, - sign_is_mandatory: false, - }; - /// Creates a modifier that indicates the value is [padded with zeroes](Padding::Zero) and - /// has the 24-hour representation. - @pub Hour => Self { - padding: Padding::Zero, - is_12_hour_clock: false, - }; - /// Creates a modifier that indicates the value is [padded with zeroes](Padding::Zero). - @pub Minute => Self { padding: Padding::Zero }; - /// Creates a modifier that indicates the value uses the upper-case representation and is - /// case-sensitive when parsing. - @pub Period => Self { - is_uppercase: true, - case_sensitive: true, - }; - /// Creates a modifier that indicates the value is [padded with zeroes](Padding::Zero). - @pub Second => Self { padding: Padding::Zero }; - /// Creates a modifier that indicates the stringified value contains [one or more - /// digits](Self::OneOrMore). - SubsecondDigits => Self::OneOrMore; - /// Creates a modifier that indicates the stringified value contains [one or more - /// digits](SubsecondDigits::OneOrMore). - @pub Subsecond => Self { digits: SubsecondDigits::OneOrMore }; - /// Creates a modifier that indicates the value only uses a sign for negative values and is - /// [padded with zeroes](Padding::Zero). - @pub OffsetHour => Self { - sign_is_mandatory: false, - padding: Padding::Zero, - }; - /// Creates a modifier that indicates the value is [padded with zeroes](Padding::Zero). - @pub OffsetMinute => Self { padding: Padding::Zero }; - /// Creates a modifier that indicates the value is [padded with zeroes](Padding::Zero). - @pub OffsetSecond => Self { padding: Padding::Zero }; - /// Creates a modifier that indicates the value is [padded with zeroes](Self::Zero). - Padding => Self::Zero; - /// Creates a modifier that indicates the value represents the [number of seconds](Self::Second) - /// since the Unix epoch. - UnixTimestampPrecision => Self::Second; - /// Creates a modifier that indicates the value represents the [number of - /// seconds](UnixTimestampPrecision::Second) since the Unix epoch. The sign is not mandatory. - @pub UnixTimestamp => Self { - precision: UnixTimestampPrecision::Second, - sign_is_mandatory: false, - }; - /// Creates a modifier used to represent the end of input. - @pub End => End; -} diff --git a/vendor/time/src/format_description/owned_format_item.rs b/vendor/time/src/format_description/owned_format_item.rs deleted file mode 100644 index 391e76f0..00000000 --- a/vendor/time/src/format_description/owned_format_item.rs +++ /dev/null @@ -1,158 +0,0 @@ -//! A format item with owned data. - -use alloc::boxed::Box; -use alloc::string::String; -use alloc::vec::Vec; -use core::fmt; - -use crate::error; -use crate::format_description::{BorrowedFormatItem, Component}; - -/// A complete description of how to format and parse a type. -#[non_exhaustive] -#[derive(Clone, PartialEq, Eq)] -pub enum OwnedFormatItem { - /// Bytes that are formatted as-is. - /// - /// **Note**: These bytes **should** be UTF-8, but are not required to be. The value is passed - /// through `String::from_utf8_lossy` when necessary. - Literal(Box<[u8]>), - /// A minimal representation of a single non-literal item. - Component(Component), - /// A series of literals or components that collectively form a partial or complete - /// description. - Compound(Box<[Self]>), - /// A `FormatItem` that may or may not be present when parsing. If parsing fails, there - /// will be no effect on the resulting `struct`. - /// - /// This variant has no effect on formatting, as the value is guaranteed to be present. - Optional(Box<Self>), - /// A series of `FormatItem`s where, when parsing, the first successful parse is used. When - /// formatting, the first element of the [`Vec`] is used. An empty [`Vec`] is a no-op when - /// formatting or parsing. - First(Box<[Self]>), -} - -impl fmt::Debug for OwnedFormatItem { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - Self::Literal(literal) => f.write_str(&String::from_utf8_lossy(literal)), - Self::Component(component) => component.fmt(f), - Self::Compound(compound) => compound.fmt(f), - Self::Optional(item) => f.debug_tuple("Optional").field(item).finish(), - Self::First(items) => f.debug_tuple("First").field(items).finish(), - } - } -} - -impl From<BorrowedFormatItem<'_>> for OwnedFormatItem { - fn from(item: BorrowedFormatItem<'_>) -> Self { - (&item).into() - } -} - -impl From<&BorrowedFormatItem<'_>> for OwnedFormatItem { - fn from(item: &BorrowedFormatItem<'_>) -> Self { - match item { - BorrowedFormatItem::Literal(literal) => { - Self::Literal(literal.to_vec().into_boxed_slice()) - } - BorrowedFormatItem::Component(component) => Self::Component(*component), - BorrowedFormatItem::Compound(compound) => Self::Compound( - compound - .iter() - .cloned() - .map(Into::into) - .collect::<Vec<_>>() - .into_boxed_slice(), - ), - BorrowedFormatItem::Optional(item) => Self::Optional(Box::new((*item).into())), - BorrowedFormatItem::First(items) => Self::First( - items - .iter() - .cloned() - .map(Into::into) - .collect::<Vec<_>>() - .into_boxed_slice(), - ), - } - } -} - -impl From<Vec<BorrowedFormatItem<'_>>> for OwnedFormatItem { - fn from(items: Vec<BorrowedFormatItem<'_>>) -> Self { - items.as_slice().into() - } -} - -impl<'a, T: AsRef<[BorrowedFormatItem<'a>]> + ?Sized> From<&T> for OwnedFormatItem { - fn from(items: &T) -> Self { - Self::Compound( - items - .as_ref() - .iter() - .cloned() - .map(Into::into) - .collect::<Vec<_>>() - .into_boxed_slice(), - ) - } -} - -impl From<Component> for OwnedFormatItem { - fn from(component: Component) -> Self { - Self::Component(component) - } -} - -impl TryFrom<OwnedFormatItem> for Component { - type Error = error::DifferentVariant; - - fn try_from(value: OwnedFormatItem) -> Result<Self, Self::Error> { - match value { - OwnedFormatItem::Component(component) => Ok(component), - _ => Err(error::DifferentVariant), - } - } -} - -impl From<Vec<Self>> for OwnedFormatItem { - fn from(items: Vec<Self>) -> Self { - Self::Compound(items.into_boxed_slice()) - } -} - -impl TryFrom<OwnedFormatItem> for Vec<OwnedFormatItem> { - type Error = error::DifferentVariant; - - fn try_from(value: OwnedFormatItem) -> Result<Self, Self::Error> { - match value { - OwnedFormatItem::Compound(items) => Ok(items.into_vec()), - _ => Err(error::DifferentVariant), - } - } -} - -impl PartialEq<Component> for OwnedFormatItem { - fn eq(&self, rhs: &Component) -> bool { - matches!(self, Self::Component(component) if component == rhs) - } -} - -impl PartialEq<OwnedFormatItem> for Component { - fn eq(&self, rhs: &OwnedFormatItem) -> bool { - rhs == self - } -} - -impl PartialEq<&[Self]> for OwnedFormatItem { - fn eq(&self, rhs: &&[Self]) -> bool { - matches!(self, Self::Compound(compound) if &&**compound == rhs) - } -} - -impl PartialEq<OwnedFormatItem> for &[OwnedFormatItem] { - fn eq(&self, rhs: &OwnedFormatItem) -> bool { - rhs == self - } -} diff --git a/vendor/time/src/format_description/parse/ast.rs b/vendor/time/src/format_description/parse/ast.rs deleted file mode 100644 index cf13de89..00000000 --- a/vendor/time/src/format_description/parse/ast.rs +++ /dev/null @@ -1,384 +0,0 @@ -//! AST for parsing format descriptions. - -use alloc::boxed::Box; -use alloc::string::String; -use alloc::vec::Vec; -use core::iter; - -use super::{lexer, unused, Error, Location, Spanned, SpannedValue, Unused}; -use crate::internal_macros::bug; - -/// One part of a complete format description. -pub(super) enum Item<'a> { - /// A literal string, formatted and parsed as-is. - /// - /// This should never be present inside a nested format description. - Literal(Spanned<&'a [u8]>), - /// A sequence of brackets. The first acts as the escape character. - /// - /// This should never be present if the lexer has `BACKSLASH_ESCAPE` set to `true`. - EscapedBracket { - /// The first bracket. - _first: Unused<Location>, - /// The second bracket. - _second: Unused<Location>, - }, - /// Part of a type, along with its modifiers. - Component { - /// Where the opening bracket was in the format string. - _opening_bracket: Unused<Location>, - /// Whitespace between the opening bracket and name. - _leading_whitespace: Unused<Option<Spanned<&'a [u8]>>>, - /// The name of the component. - name: Spanned<&'a [u8]>, - /// The modifiers for the component. - modifiers: Box<[Modifier<'a>]>, - /// Whitespace between the modifiers and closing bracket. - _trailing_whitespace: Unused<Option<Spanned<&'a [u8]>>>, - /// Where the closing bracket was in the format string. - _closing_bracket: Unused<Location>, - }, - /// An optional sequence of items. - Optional { - /// Where the opening bracket was in the format string. - opening_bracket: Location, - /// Whitespace between the opening bracket and "optional". - _leading_whitespace: Unused<Option<Spanned<&'a [u8]>>>, - /// The "optional" keyword. - _optional_kw: Unused<Spanned<&'a [u8]>>, - /// Whitespace between the "optional" keyword and the opening bracket. - _whitespace: Unused<Spanned<&'a [u8]>>, - /// The items within the optional sequence. - nested_format_description: NestedFormatDescription<'a>, - /// Where the closing bracket was in the format string. - closing_bracket: Location, - }, - /// The first matching parse of a sequence of items. - First { - /// Where the opening bracket was in the format string. - opening_bracket: Location, - /// Whitespace between the opening bracket and "first". - _leading_whitespace: Unused<Option<Spanned<&'a [u8]>>>, - /// The "first" keyword. - _first_kw: Unused<Spanned<&'a [u8]>>, - /// Whitespace between the "first" keyword and the opening bracket. - _whitespace: Unused<Spanned<&'a [u8]>>, - /// The sequences of items to try. - nested_format_descriptions: Box<[NestedFormatDescription<'a>]>, - /// Where the closing bracket was in the format string. - closing_bracket: Location, - }, -} - -/// A format description that is nested within another format description. -pub(super) struct NestedFormatDescription<'a> { - /// Where the opening bracket was in the format string. - pub(super) _opening_bracket: Unused<Location>, - /// The items within the nested format description. - pub(super) items: Box<[Item<'a>]>, - /// Where the closing bracket was in the format string. - pub(super) _closing_bracket: Unused<Location>, - /// Whitespace between the closing bracket and the next item. - pub(super) _trailing_whitespace: Unused<Option<Spanned<&'a [u8]>>>, -} - -/// A modifier for a component. -pub(super) struct Modifier<'a> { - /// Whitespace preceding the modifier. - pub(super) _leading_whitespace: Unused<Spanned<&'a [u8]>>, - /// The key of the modifier. - pub(super) key: Spanned<&'a [u8]>, - /// Where the colon of the modifier was in the format string. - pub(super) _colon: Unused<Location>, - /// The value of the modifier. - pub(super) value: Spanned<&'a [u8]>, -} - -/// Parse the provided tokens into an AST. -pub(super) fn parse< - 'item: 'iter, - 'iter, - I: Iterator<Item = Result<lexer::Token<'item>, Error>>, - const VERSION: usize, ->( - tokens: &'iter mut lexer::Lexed<I>, -) -> impl Iterator<Item = Result<Item<'item>, Error>> + 'iter { - validate_version!(VERSION); - parse_inner::<_, false, VERSION>(tokens) -} - -/// Parse the provided tokens into an AST. The const generic indicates whether the resulting -/// [`Item`] will be used directly or as part of a [`NestedFormatDescription`]. -fn parse_inner< - 'item, - I: Iterator<Item = Result<lexer::Token<'item>, Error>>, - const NESTED: bool, - const VERSION: usize, ->( - tokens: &mut lexer::Lexed<I>, -) -> impl Iterator<Item = Result<Item<'item>, Error>> + '_ { - validate_version!(VERSION); - iter::from_fn(move || { - if NESTED && tokens.peek_closing_bracket().is_some() { - return None; - } - - let next = match tokens.next()? { - Ok(token) => token, - Err(err) => return Some(Err(err)), - }; - - Some(match next { - lexer::Token::Literal(Spanned { value: _, span: _ }) if NESTED => { - bug!("literal should not be present in nested description") - } - lexer::Token::Literal(value) => Ok(Item::Literal(value)), - lexer::Token::Bracket { - kind: lexer::BracketKind::Opening, - location, - } => { - if version!(..=1) { - if let Some(second_location) = tokens.next_if_opening_bracket() { - Ok(Item::EscapedBracket { - _first: unused(location), - _second: unused(second_location), - }) - } else { - parse_component::<_, VERSION>(location, tokens) - } - } else { - parse_component::<_, VERSION>(location, tokens) - } - } - lexer::Token::Bracket { - kind: lexer::BracketKind::Closing, - location: _, - } if NESTED => { - bug!("closing bracket should be caught by the `if` statement") - } - lexer::Token::Bracket { - kind: lexer::BracketKind::Closing, - location: _, - } => { - bug!("closing bracket should have been consumed by `parse_component`") - } - lexer::Token::ComponentPart { - kind: _, // whitespace is significant in nested components - value, - } if NESTED => Ok(Item::Literal(value)), - lexer::Token::ComponentPart { kind: _, value: _ } => { - bug!("component part should have been consumed by `parse_component`") - } - }) - }) -} - -/// Parse a component. This assumes that the opening bracket has already been consumed. -fn parse_component< - 'a, - I: Iterator<Item = Result<lexer::Token<'a>, Error>>, - const VERSION: usize, ->( - opening_bracket: Location, - tokens: &mut lexer::Lexed<I>, -) -> Result<Item<'a>, Error> { - validate_version!(VERSION); - let leading_whitespace = tokens.next_if_whitespace(); - - let Some(name) = tokens.next_if_not_whitespace() else { - let span = match leading_whitespace { - Some(Spanned { value: _, span }) => span, - None => opening_bracket.to_self(), - }; - return Err(Error { - _inner: unused(span.error("expected component name")), - public: crate::error::InvalidFormatDescription::MissingComponentName { - index: span.start.byte as usize, - }, - }); - }; - - if *name == b"optional" { - let Some(whitespace) = tokens.next_if_whitespace() else { - return Err(Error { - _inner: unused(name.span.error("expected whitespace after `optional`")), - public: crate::error::InvalidFormatDescription::Expected { - what: "whitespace after `optional`", - index: name.span.end.byte as usize, - }, - }); - }; - - let nested = parse_nested::<_, VERSION>(whitespace.span.end, tokens)?; - - let Some(closing_bracket) = tokens.next_if_closing_bracket() else { - return Err(Error { - _inner: unused(opening_bracket.error("unclosed bracket")), - public: crate::error::InvalidFormatDescription::UnclosedOpeningBracket { - index: opening_bracket.byte as usize, - }, - }); - }; - - return Ok(Item::Optional { - opening_bracket, - _leading_whitespace: unused(leading_whitespace), - _optional_kw: unused(name), - _whitespace: unused(whitespace), - nested_format_description: nested, - closing_bracket, - }); - } - - if *name == b"first" { - let Some(whitespace) = tokens.next_if_whitespace() else { - return Err(Error { - _inner: unused(name.span.error("expected whitespace after `first`")), - public: crate::error::InvalidFormatDescription::Expected { - what: "whitespace after `first`", - index: name.span.end.byte as usize, - }, - }); - }; - - let mut nested_format_descriptions = Vec::new(); - while let Ok(description) = parse_nested::<_, VERSION>(whitespace.span.end, tokens) { - nested_format_descriptions.push(description); - } - - let Some(closing_bracket) = tokens.next_if_closing_bracket() else { - return Err(Error { - _inner: unused(opening_bracket.error("unclosed bracket")), - public: crate::error::InvalidFormatDescription::UnclosedOpeningBracket { - index: opening_bracket.byte as usize, - }, - }); - }; - - return Ok(Item::First { - opening_bracket, - _leading_whitespace: unused(leading_whitespace), - _first_kw: unused(name), - _whitespace: unused(whitespace), - nested_format_descriptions: nested_format_descriptions.into_boxed_slice(), - closing_bracket, - }); - } - - let mut modifiers = Vec::new(); - let trailing_whitespace = loop { - let Some(whitespace) = tokens.next_if_whitespace() else { - break None; - }; - - // This is not necessary for proper parsing, but provides a much better error when a nested - // description is used where it's not allowed. - if let Some(location) = tokens.next_if_opening_bracket() { - return Err(Error { - _inner: unused( - location - .to_self() - .error("modifier must be of the form `key:value`"), - ), - public: crate::error::InvalidFormatDescription::InvalidModifier { - value: String::from("["), - index: location.byte as usize, - }, - }); - } - - let Some(Spanned { value, span }) = tokens.next_if_not_whitespace() else { - break Some(whitespace); - }; - - let Some(colon_index) = value.iter().position(|&b| b == b':') else { - return Err(Error { - _inner: unused(span.error("modifier must be of the form `key:value`")), - public: crate::error::InvalidFormatDescription::InvalidModifier { - value: String::from_utf8_lossy(value).into_owned(), - index: span.start.byte as usize, - }, - }); - }; - let key = &value[..colon_index]; - let value = &value[colon_index + 1..]; - - if key.is_empty() { - return Err(Error { - _inner: unused(span.shrink_to_start().error("expected modifier key")), - public: crate::error::InvalidFormatDescription::InvalidModifier { - value: String::new(), - index: span.start.byte as usize, - }, - }); - } - if value.is_empty() { - return Err(Error { - _inner: unused(span.shrink_to_end().error("expected modifier value")), - public: crate::error::InvalidFormatDescription::InvalidModifier { - value: String::new(), - index: span.shrink_to_end().start.byte as usize, - }, - }); - } - - modifiers.push(Modifier { - _leading_whitespace: unused(whitespace), - key: key.spanned(span.shrink_to_before(colon_index as u32)), - _colon: unused(span.start.offset(colon_index as u32)), - value: value.spanned(span.shrink_to_after(colon_index as u32)), - }); - }; - - let Some(closing_bracket) = tokens.next_if_closing_bracket() else { - return Err(Error { - _inner: unused(opening_bracket.error("unclosed bracket")), - public: crate::error::InvalidFormatDescription::UnclosedOpeningBracket { - index: opening_bracket.byte as usize, - }, - }); - }; - - Ok(Item::Component { - _opening_bracket: unused(opening_bracket), - _leading_whitespace: unused(leading_whitespace), - name, - modifiers: modifiers.into_boxed_slice(), - _trailing_whitespace: unused(trailing_whitespace), - _closing_bracket: unused(closing_bracket), - }) -} - -/// Parse a nested format description. The location provided is the the most recent one consumed. -fn parse_nested<'a, I: Iterator<Item = Result<lexer::Token<'a>, Error>>, const VERSION: usize>( - last_location: Location, - tokens: &mut lexer::Lexed<I>, -) -> Result<NestedFormatDescription<'a>, Error> { - validate_version!(VERSION); - let Some(opening_bracket) = tokens.next_if_opening_bracket() else { - return Err(Error { - _inner: unused(last_location.error("expected opening bracket")), - public: crate::error::InvalidFormatDescription::Expected { - what: "opening bracket", - index: last_location.byte as usize, - }, - }); - }; - let items = parse_inner::<_, true, VERSION>(tokens).collect::<Result<_, _>>()?; - let Some(closing_bracket) = tokens.next_if_closing_bracket() else { - return Err(Error { - _inner: unused(opening_bracket.error("unclosed bracket")), - public: crate::error::InvalidFormatDescription::UnclosedOpeningBracket { - index: opening_bracket.byte as usize, - }, - }); - }; - let trailing_whitespace = tokens.next_if_whitespace(); - - Ok(NestedFormatDescription { - _opening_bracket: unused(opening_bracket), - items, - _closing_bracket: unused(closing_bracket), - _trailing_whitespace: unused(trailing_whitespace), - }) -} diff --git a/vendor/time/src/format_description/parse/format_item.rs b/vendor/time/src/format_description/parse/format_item.rs deleted file mode 100644 index d401daa5..00000000 --- a/vendor/time/src/format_description/parse/format_item.rs +++ /dev/null @@ -1,549 +0,0 @@ -//! Typed, validated representation of a parsed format description. - -use alloc::boxed::Box; -use alloc::string::String; -use core::num::NonZeroU16; -use core::str::{self, FromStr}; - -use super::{ast, unused, Error, Span, Spanned}; -use crate::internal_macros::bug; - -/// Parse an AST iterator into a sequence of format items. -pub(super) fn parse<'a>( - ast_items: impl Iterator<Item = Result<ast::Item<'a>, Error>>, -) -> impl Iterator<Item = Result<Item<'a>, Error>> { - ast_items.map(|ast_item| ast_item.and_then(Item::from_ast)) -} - -/// A description of how to format and parse one part of a type. -pub(super) enum Item<'a> { - /// A literal string. - Literal(&'a [u8]), - /// Part of a type, along with its modifiers. - Component(Component), - /// A sequence of optional items. - Optional { - /// The items themselves. - value: Box<[Self]>, - /// The span of the full sequence. - span: Span, - }, - /// The first matching parse of a sequence of format descriptions. - First { - /// The sequence of format descriptions. - value: Box<[Box<[Self]>]>, - /// The span of the full sequence. - span: Span, - }, -} - -impl Item<'_> { - /// Parse an AST item into a format item. - pub(super) fn from_ast(ast_item: ast::Item<'_>) -> Result<Item<'_>, Error> { - Ok(match ast_item { - ast::Item::Component { - _opening_bracket: _, - _leading_whitespace: _, - name, - modifiers, - _trailing_whitespace: _, - _closing_bracket: _, - } => Item::Component(component_from_ast(&name, &modifiers)?), - ast::Item::Literal(Spanned { value, span: _ }) => Item::Literal(value), - ast::Item::EscapedBracket { - _first: _, - _second: _, - } => Item::Literal(b"["), - ast::Item::Optional { - opening_bracket, - _leading_whitespace: _, - _optional_kw: _, - _whitespace: _, - nested_format_description, - closing_bracket, - } => { - let items = nested_format_description - .items - .into_vec() - .into_iter() - .map(Item::from_ast) - .collect::<Result<_, _>>()?; - Item::Optional { - value: items, - span: opening_bracket.to(closing_bracket), - } - } - ast::Item::First { - opening_bracket, - _leading_whitespace: _, - _first_kw: _, - _whitespace: _, - nested_format_descriptions, - closing_bracket, - } => { - let items = nested_format_descriptions - .into_vec() - .into_iter() - .map(|nested_format_description| { - nested_format_description - .items - .into_vec() - .into_iter() - .map(Item::from_ast) - .collect() - }) - .collect::<Result<_, _>>()?; - Item::First { - value: items, - span: opening_bracket.to(closing_bracket), - } - } - }) - } -} - -impl<'a> TryFrom<Item<'a>> for crate::format_description::BorrowedFormatItem<'a> { - type Error = Error; - - fn try_from(item: Item<'a>) -> Result<Self, Self::Error> { - match item { - Item::Literal(literal) => Ok(Self::Literal(literal)), - Item::Component(component) => Ok(Self::Component(component.into())), - Item::Optional { value: _, span } => Err(Error { - _inner: unused(span.error( - "optional items are not supported in runtime-parsed format descriptions", - )), - public: crate::error::InvalidFormatDescription::NotSupported { - what: "optional item", - context: "runtime-parsed format descriptions", - index: span.start.byte as usize, - }, - }), - Item::First { value: _, span } => Err(Error { - _inner: unused(span.error( - "'first' items are not supported in runtime-parsed format descriptions", - )), - public: crate::error::InvalidFormatDescription::NotSupported { - what: "'first' item", - context: "runtime-parsed format descriptions", - index: span.start.byte as usize, - }, - }), - } - } -} - -impl From<Item<'_>> for crate::format_description::OwnedFormatItem { - fn from(item: Item<'_>) -> Self { - match item { - Item::Literal(literal) => Self::Literal(literal.to_vec().into_boxed_slice()), - Item::Component(component) => Self::Component(component.into()), - Item::Optional { value, span: _ } => Self::Optional(Box::new(value.into())), - Item::First { value, span: _ } => { - Self::First(value.into_vec().into_iter().map(Into::into).collect()) - } - } - } -} - -impl<'a> From<Box<[Item<'a>]>> for crate::format_description::OwnedFormatItem { - fn from(items: Box<[Item<'a>]>) -> Self { - let items = items.into_vec(); - match <[_; 1]>::try_from(items) { - Ok([item]) => item.into(), - Err(vec) => Self::Compound(vec.into_iter().map(Into::into).collect()), - } - } -} - -/// Declare the `Component` struct. -macro_rules! component_definition { - (@if_required required then { $($then:tt)* } $(else { $($else:tt)* })?) => { $($then)* }; - (@if_required then { $($then:tt)* } $(else { $($else:tt)* })?) => { $($($else)*)? }; - (@if_from_str from_str then { $($then:tt)* } $(else { $($else:tt)* })?) => { $($then)* }; - (@if_from_str then { $($then:tt)* } $(else { $($else:tt)* })?) => { $($($else)*)? }; - - ($vis:vis enum $name:ident { - $($variant:ident = $parse_variant:literal {$( - $(#[$required:tt])? - $field:ident = $parse_field:literal: - Option<$(#[$from_str:tt])? $field_type:ty> - => $target_field:ident - ),* $(,)?}),* $(,)? - }) => { - $vis enum $name { - $($variant($variant),)* - } - - $($vis struct $variant { - $($field: Option<$field_type>),* - })* - - $(impl $variant { - /// Parse the component from the AST, given its modifiers. - fn with_modifiers( - modifiers: &[ast::Modifier<'_>], - _component_span: Span, - ) -> Result<Self, Error> - { - // rustc will complain if the modifier is empty. - #[allow(unused_mut)] - let mut this = Self { - $($field: None),* - }; - - for modifier in modifiers { - $(#[allow(clippy::string_lit_as_bytes)] - if modifier.key.eq_ignore_ascii_case($parse_field.as_bytes()) { - this.$field = component_definition!(@if_from_str $($from_str)? - then { - parse_from_modifier_value::<$field_type>(&modifier.value)? - } else { - <$field_type>::from_modifier_value(&modifier.value)? - }); - continue; - })* - return Err(Error { - _inner: unused(modifier.key.span.error("invalid modifier key")), - public: crate::error::InvalidFormatDescription::InvalidModifier { - value: String::from_utf8_lossy(*modifier.key).into_owned(), - index: modifier.key.span.start.byte as usize, - } - }); - } - - $(component_definition! { @if_required $($required)? then { - if this.$field.is_none() { - return Err(Error { - _inner: unused(_component_span.error("missing required modifier")), - public: - crate::error::InvalidFormatDescription::MissingRequiredModifier { - name: $parse_field, - index: _component_span.start.byte as usize, - } - }); - } - }})* - - Ok(this) - } - })* - - impl From<$name> for crate::format_description::Component { - fn from(component: $name) -> Self { - match component {$( - $name::$variant($variant { $($field),* }) => { - $crate::format_description::component::Component::$variant( - $crate::format_description::modifier::$variant {$( - $target_field: component_definition! { @if_required $($required)? - then { - match $field { - Some(value) => value.into(), - None => bug!("required modifier was not set"), - } - } else { - $field.unwrap_or_default().into() - } - } - ),*} - ) - } - )*} - } - } - - /// Parse a component from the AST, given its name and modifiers. - fn component_from_ast( - name: &Spanned<&[u8]>, - modifiers: &[ast::Modifier<'_>], - ) -> Result<Component, Error> { - $(#[allow(clippy::string_lit_as_bytes)] - if name.eq_ignore_ascii_case($parse_variant.as_bytes()) { - return Ok(Component::$variant($variant::with_modifiers(&modifiers, name.span)?)); - })* - Err(Error { - _inner: unused(name.span.error("invalid component")), - public: crate::error::InvalidFormatDescription::InvalidComponentName { - name: String::from_utf8_lossy(name).into_owned(), - index: name.span.start.byte as usize, - }, - }) - } - } -} - -// Keep in alphabetical order. -component_definition! { - pub(super) enum Component { - Day = "day" { - padding = "padding": Option<Padding> => padding, - }, - End = "end" {}, - Hour = "hour" { - padding = "padding": Option<Padding> => padding, - base = "repr": Option<HourBase> => is_12_hour_clock, - }, - Ignore = "ignore" { - #[required] - count = "count": Option<#[from_str] NonZeroU16> => count, - }, - Minute = "minute" { - padding = "padding": Option<Padding> => padding, - }, - Month = "month" { - padding = "padding": Option<Padding> => padding, - repr = "repr": Option<MonthRepr> => repr, - case_sensitive = "case_sensitive": Option<MonthCaseSensitive> => case_sensitive, - }, - OffsetHour = "offset_hour" { - sign_behavior = "sign": Option<SignBehavior> => sign_is_mandatory, - padding = "padding": Option<Padding> => padding, - }, - OffsetMinute = "offset_minute" { - padding = "padding": Option<Padding> => padding, - }, - OffsetSecond = "offset_second" { - padding = "padding": Option<Padding> => padding, - }, - Ordinal = "ordinal" { - padding = "padding": Option<Padding> => padding, - }, - Period = "period" { - case = "case": Option<PeriodCase> => is_uppercase, - case_sensitive = "case_sensitive": Option<PeriodCaseSensitive> => case_sensitive, - }, - Second = "second" { - padding = "padding": Option<Padding> => padding, - }, - Subsecond = "subsecond" { - digits = "digits": Option<SubsecondDigits> => digits, - }, - UnixTimestamp = "unix_timestamp" { - precision = "precision": Option<UnixTimestampPrecision> => precision, - sign_behavior = "sign": Option<SignBehavior> => sign_is_mandatory, - }, - Weekday = "weekday" { - repr = "repr": Option<WeekdayRepr> => repr, - one_indexed = "one_indexed": Option<WeekdayOneIndexed> => one_indexed, - case_sensitive = "case_sensitive": Option<WeekdayCaseSensitive> => case_sensitive, - }, - WeekNumber = "week_number" { - padding = "padding": Option<Padding> => padding, - repr = "repr": Option<WeekNumberRepr> => repr, - }, - Year = "year" { - padding = "padding": Option<Padding> => padding, - repr = "repr": Option<YearRepr> => repr, - range = "range": Option<YearRange> => range, - base = "base": Option<YearBase> => iso_week_based, - sign_behavior = "sign": Option<SignBehavior> => sign_is_mandatory, - }, - } -} - -/// Get the target type for a given enum. -macro_rules! target_ty { - ($name:ident $type:ty) => { - $type - }; - ($name:ident) => { - $crate::format_description::modifier::$name - }; -} - -/// Get the target value for a given enum. -macro_rules! target_value { - ($name:ident $variant:ident $value:expr) => { - $value - }; - ($name:ident $variant:ident) => { - $crate::format_description::modifier::$name::$variant - }; -} - -/// Declare the various modifiers. -/// -/// For the general case, ordinary syntax can be used. Note that you _must_ declare a default -/// variant. The only significant change is that the string representation of the variant must be -/// provided after the variant name. For example, `Numerical = b"numerical"` declares a variant -/// named `Numerical` with the string representation `b"numerical"`. This is the value that will be -/// used when parsing the modifier. The value is not case sensitive. -/// -/// If the type in the public API does not have the same name as the type in the internal -/// representation, then the former must be specified in parenthesis after the internal name. For -/// example, `HourBase(bool)` has an internal name "HourBase", but is represented as a boolean in -/// the public API. -/// -/// By default, the internal variant name is assumed to be the same as the public variant name. If -/// this is not the case, the qualified path to the variant must be specified in parenthesis after -/// the internal variant name. For example, `Twelve(true)` has an internal variant name "Twelve", -/// but is represented as `true` in the public API. -macro_rules! modifier { - ($( - enum $name:ident $(($target_ty:ty))? { - $( - $(#[$attr:meta])? - $variant:ident $(($target_value:expr))? = $parse_variant:literal - ),* $(,)? - } - )+) => {$( - #[derive(Default)] - enum $name { - $($(#[$attr])? $variant),* - } - - impl $name { - /// Parse the modifier from its string representation. - fn from_modifier_value(value: &Spanned<&[u8]>) -> Result<Option<Self>, Error> { - $(if value.eq_ignore_ascii_case($parse_variant) { - return Ok(Some(Self::$variant)); - })* - Err(Error { - _inner: unused(value.span.error("invalid modifier value")), - public: crate::error::InvalidFormatDescription::InvalidModifier { - value: String::from_utf8_lossy(value).into_owned(), - index: value.span.start.byte as usize, - }, - }) - } - } - - impl From<$name> for target_ty!($name $($target_ty)?) { - fn from(modifier: $name) -> Self { - match modifier { - $($name::$variant => target_value!($name $variant $($target_value)?)),* - } - } - } - )+}; -} - -// Keep in alphabetical order. -modifier! { - enum HourBase(bool) { - Twelve(true) = b"12", - #[default] - TwentyFour(false) = b"24", - } - - enum MonthCaseSensitive(bool) { - False(false) = b"false", - #[default] - True(true) = b"true", - } - - enum MonthRepr { - #[default] - Numerical = b"numerical", - Long = b"long", - Short = b"short", - } - - enum Padding { - Space = b"space", - #[default] - Zero = b"zero", - None = b"none", - } - - enum PeriodCase(bool) { - Lower(false) = b"lower", - #[default] - Upper(true) = b"upper", - } - - enum PeriodCaseSensitive(bool) { - False(false) = b"false", - #[default] - True(true) = b"true", - } - - enum SignBehavior(bool) { - #[default] - Automatic(false) = b"automatic", - Mandatory(true) = b"mandatory", - } - - enum SubsecondDigits { - One = b"1", - Two = b"2", - Three = b"3", - Four = b"4", - Five = b"5", - Six = b"6", - Seven = b"7", - Eight = b"8", - Nine = b"9", - #[default] - OneOrMore = b"1+", - } - - enum UnixTimestampPrecision { - #[default] - Second = b"second", - Millisecond = b"millisecond", - Microsecond = b"microsecond", - Nanosecond = b"nanosecond", - } - - enum WeekNumberRepr { - #[default] - Iso = b"iso", - Sunday = b"sunday", - Monday = b"monday", - } - - enum WeekdayCaseSensitive(bool) { - False(false) = b"false", - #[default] - True(true) = b"true", - } - - enum WeekdayOneIndexed(bool) { - False(false) = b"false", - #[default] - True(true) = b"true", - } - - enum WeekdayRepr { - Short = b"short", - #[default] - Long = b"long", - Sunday = b"sunday", - Monday = b"monday", - } - - enum YearBase(bool) { - #[default] - Calendar(false) = b"calendar", - IsoWeek(true) = b"iso_week", - } - - enum YearRepr { - #[default] - Full = b"full", - Century = b"century", - LastTwo = b"last_two", - } - - enum YearRange { - Standard = b"standard", - #[default] - Extended = b"extended", - } -} - -/// Parse a modifier value using `FromStr`. Requires the modifier value to be valid UTF-8. -fn parse_from_modifier_value<T: FromStr>(value: &Spanned<&[u8]>) -> Result<Option<T>, Error> { - str::from_utf8(value) - .ok() - .and_then(|val| val.parse::<T>().ok()) - .map(|val| Some(val)) - .ok_or_else(|| Error { - _inner: unused(value.span.error("invalid modifier value")), - public: crate::error::InvalidFormatDescription::InvalidModifier { - value: String::from_utf8_lossy(value).into_owned(), - index: value.span.start.byte as usize, - }, - }) -} diff --git a/vendor/time/src/format_description/parse/lexer.rs b/vendor/time/src/format_description/parse/lexer.rs deleted file mode 100644 index a63722e1..00000000 --- a/vendor/time/src/format_description/parse/lexer.rs +++ /dev/null @@ -1,284 +0,0 @@ -//! Lexer for parsing format descriptions. - -use core::iter; - -use super::{attach_location, unused, Error, Location, Spanned, SpannedValue}; - -/// An iterator over the lexed tokens. -pub(super) struct Lexed<I: Iterator> { - /// The internal iterator. - iter: iter::Peekable<I>, -} - -impl<I: Iterator> Iterator for Lexed<I> { - type Item = I::Item; - - fn next(&mut self) -> Option<Self::Item> { - self.iter.next() - } -} - -impl<'iter, 'token: 'iter, I: Iterator<Item = Result<Token<'token>, Error>> + 'iter> Lexed<I> { - /// Peek at the next item in the iterator. - pub(super) fn peek(&mut self) -> Option<&I::Item> { - self.iter.peek() - } - - /// Consume the next token if it is whitespace. - pub(super) fn next_if_whitespace(&mut self) -> Option<Spanned<&'token [u8]>> { - if let Some(&Ok(Token::ComponentPart { - kind: ComponentKind::Whitespace, - value, - })) = self.peek() - { - self.next(); // consume - Some(value) - } else { - None - } - } - - /// Consume the next token if it is a component item that is not whitespace. - pub(super) fn next_if_not_whitespace(&mut self) -> Option<Spanned<&'token [u8]>> { - if let Some(&Ok(Token::ComponentPart { - kind: ComponentKind::NotWhitespace, - value, - })) = self.peek() - { - self.next(); // consume - Some(value) - } else { - None - } - } - - /// Consume the next token if it is an opening bracket. - pub(super) fn next_if_opening_bracket(&mut self) -> Option<Location> { - if let Some(&Ok(Token::Bracket { - kind: BracketKind::Opening, - location, - })) = self.peek() - { - self.next(); // consume - Some(location) - } else { - None - } - } - - /// Peek at the next token if it is a closing bracket. - pub(super) fn peek_closing_bracket(&'iter mut self) -> Option<&'iter Location> { - if let Some(Ok(Token::Bracket { - kind: BracketKind::Closing, - location, - })) = self.peek() - { - Some(location) - } else { - None - } - } - - /// Consume the next token if it is a closing bracket. - pub(super) fn next_if_closing_bracket(&mut self) -> Option<Location> { - if let Some(&Ok(Token::Bracket { - kind: BracketKind::Closing, - location, - })) = self.peek() - { - self.next(); // consume - Some(location) - } else { - None - } - } -} - -/// A token emitted by the lexer. There is no semantic meaning at this stage. -pub(super) enum Token<'a> { - /// A literal string, formatted and parsed as-is. - Literal(Spanned<&'a [u8]>), - /// An opening or closing bracket. May or may not be the start or end of a component. - Bracket { - /// Whether the bracket is opening or closing. - kind: BracketKind, - /// Where the bracket was in the format string. - location: Location, - }, - /// One part of a component. This could be its name, a modifier, or whitespace. - ComponentPart { - /// Whether the part is whitespace or not. - kind: ComponentKind, - /// The part itself. - value: Spanned<&'a [u8]>, - }, -} - -/// What type of bracket is present. -pub(super) enum BracketKind { - /// An opening bracket: `[` - Opening, - /// A closing bracket: `]` - Closing, -} - -/// Indicates whether the component is whitespace or not. -pub(super) enum ComponentKind { - Whitespace, - NotWhitespace, -} - -/// Parse the string into a series of [`Token`]s. -/// -/// `VERSION` controls the version of the format description that is being parsed. Currently, this -/// must be 1 or 2. -/// -/// - When `VERSION` is 1, `[[` is the only escape sequence, resulting in a literal `[`. -/// - When `VERSION` is 2, all escape sequences begin with `\`. The only characters that may -/// currently follow are `\`, `[`, and `]`, all of which result in the literal character. All -/// other characters result in a lex error. -pub(super) fn lex<const VERSION: usize>( - mut input: &[u8], -) -> Lexed<impl Iterator<Item = Result<Token<'_>, Error>>> { - validate_version!(VERSION); - - let mut depth: u8 = 0; - let mut iter = attach_location(input.iter()).peekable(); - let mut second_bracket_location = None; - - let iter = iter::from_fn(move || { - // The flag is only set when version is zero. - if version!(..=1) { - // There is a flag set to emit the second half of an escaped bracket pair. - if let Some(location) = second_bracket_location.take() { - return Some(Ok(Token::Bracket { - kind: BracketKind::Opening, - location, - })); - } - } - - Some(Ok(match iter.next()? { - // possible escape sequence - (b'\\', backslash_loc) if version!(2..) => { - match iter.next() { - Some((b'\\' | b'[' | b']', char_loc)) => { - // The escaped character is emitted as-is. - let char = &input[1..2]; - input = &input[2..]; - if depth == 0 { - Token::Literal(char.spanned(backslash_loc.to(char_loc))) - } else { - Token::ComponentPart { - kind: ComponentKind::NotWhitespace, - value: char.spanned(backslash_loc.to(char_loc)), - } - } - } - Some((_, loc)) => { - return Some(Err(Error { - _inner: unused(loc.error("invalid escape sequence")), - public: crate::error::InvalidFormatDescription::Expected { - what: "valid escape sequence", - index: loc.byte as usize, - }, - })); - } - None => { - return Some(Err(Error { - _inner: unused(backslash_loc.error("unexpected end of input")), - public: crate::error::InvalidFormatDescription::Expected { - what: "valid escape sequence", - index: backslash_loc.byte as usize, - }, - })); - } - } - } - // potentially escaped opening bracket - (b'[', location) if version!(..=1) => { - if let Some((_, second_location)) = iter.next_if(|&(&byte, _)| byte == b'[') { - // Escaped bracket. Store the location of the second so we can emit it later. - second_bracket_location = Some(second_location); - input = &input[2..]; - } else { - // opening bracket - depth += 1; - input = &input[1..]; - } - - Token::Bracket { - kind: BracketKind::Opening, - location, - } - } - // opening bracket - (b'[', location) => { - depth += 1; - input = &input[1..]; - - Token::Bracket { - kind: BracketKind::Opening, - location, - } - } - // closing bracket - (b']', location) if depth > 0 => { - depth -= 1; - input = &input[1..]; - - Token::Bracket { - kind: BracketKind::Closing, - location, - } - } - // literal - (_, start_location) if depth == 0 => { - let mut bytes = 1; - let mut end_location = start_location; - - while let Some((_, location)) = - iter.next_if(|&(&byte, _)| !((version!(2..) && byte == b'\\') || byte == b'[')) - { - end_location = location; - bytes += 1; - } - - let value = &input[..bytes]; - input = &input[bytes..]; - - Token::Literal(value.spanned(start_location.to(end_location))) - } - // component part - (byte, start_location) => { - let mut bytes = 1; - let mut end_location = start_location; - let is_whitespace = byte.is_ascii_whitespace(); - - while let Some((_, location)) = iter.next_if(|&(byte, _)| { - !matches!(byte, b'\\' | b'[' | b']') - && is_whitespace == byte.is_ascii_whitespace() - }) { - end_location = location; - bytes += 1; - } - - let value = &input[..bytes]; - input = &input[bytes..]; - - Token::ComponentPart { - kind: if is_whitespace { - ComponentKind::Whitespace - } else { - ComponentKind::NotWhitespace - }, - value: value.spanned(start_location.to(end_location)), - } - } - })) - }); - - Lexed { - iter: iter.peekable(), - } -} diff --git a/vendor/time/src/format_description/parse/mod.rs b/vendor/time/src/format_description/parse/mod.rs deleted file mode 100644 index d058594d..00000000 --- a/vendor/time/src/format_description/parse/mod.rs +++ /dev/null @@ -1,262 +0,0 @@ -//! Parser for format descriptions. - -use alloc::boxed::Box; -use alloc::vec::Vec; - -pub use self::strftime::{parse_strftime_borrowed, parse_strftime_owned}; -use crate::{error, format_description}; - -/// A helper macro to make version restrictions simpler to read and write. -macro_rules! version { - ($range:expr) => { - $range.contains(&VERSION) - }; -} - -/// A helper macro to statically validate the version (when used as a const parameter). -macro_rules! validate_version { - ($version:ident) => { - let _ = $crate::format_description::parse::Version::<$version>::IS_VALID; - }; -} - -mod ast; -mod format_item; -mod lexer; -mod strftime; - -/// A struct that is used to ensure that the version is valid. -struct Version<const N: usize>; -impl<const N: usize> Version<N> { - /// A constant that panics if the version is not valid. This results in a post-monomorphization - /// error. - const IS_VALID: () = assert!(N >= 1 && N <= 2); -} - -/// Parse a sequence of items from the format description. -/// -/// The syntax for the format description can be found in [the -/// book](https://time-rs.github.io/book/api/format-description.html). -/// -/// This function exists for backward compatibility reasons. It is equivalent to calling -/// `parse_borrowed::<1>(s)`. In the future, this function will be deprecated in favor of -/// `parse_borrowed`. -pub fn parse( - s: &str, -) -> Result<Vec<format_description::BorrowedFormatItem<'_>>, error::InvalidFormatDescription> { - parse_borrowed::<1>(s) -} - -/// Parse a sequence of items from the format description. -/// -/// The syntax for the format description can be found in [the -/// book](https://time-rs.github.io/book/api/format-description.html). The version of the format -/// description is provided as the const parameter. **It is recommended to use version 2.** -pub fn parse_borrowed<const VERSION: usize>( - s: &str, -) -> Result<Vec<format_description::BorrowedFormatItem<'_>>, error::InvalidFormatDescription> { - validate_version!(VERSION); - let mut lexed = lexer::lex::<VERSION>(s.as_bytes()); - let ast = ast::parse::<_, VERSION>(&mut lexed); - let format_items = format_item::parse(ast); - Ok(format_items - .map(|res| res.and_then(TryInto::try_into)) - .collect::<Result<_, _>>()?) -} - -/// Parse a sequence of items from the format description. -/// -/// The syntax for the format description can be found in [the -/// book](https://time-rs.github.io/book/api/format-description.html). The version of the format -/// description is provided as the const parameter. -/// -/// Unlike [`parse`], this function returns [`OwnedFormatItem`], which owns its contents. This means -/// that there is no lifetime that needs to be handled. **It is recommended to use version 2.** -/// -/// [`OwnedFormatItem`]: crate::format_description::OwnedFormatItem -pub fn parse_owned<const VERSION: usize>( - s: &str, -) -> Result<format_description::OwnedFormatItem, error::InvalidFormatDescription> { - validate_version!(VERSION); - let mut lexed = lexer::lex::<VERSION>(s.as_bytes()); - let ast = ast::parse::<_, VERSION>(&mut lexed); - let format_items = format_item::parse(ast); - let items = format_items.collect::<Result<Box<_>, _>>()?; - Ok(items.into()) -} - -/// Attach [`Location`] information to each byte in the iterator. -fn attach_location<'item>( - iter: impl Iterator<Item = &'item u8>, -) -> impl Iterator<Item = (&'item u8, Location)> { - let mut byte_pos = 0; - - iter.map(move |byte| { - let location = Location { byte: byte_pos }; - byte_pos += 1; - (byte, location) - }) -} - -/// A location within a string. -#[derive(Clone, Copy)] -struct Location { - /// The zero-indexed byte of the string. - byte: u32, -} - -impl Location { - /// Create a new [`Span`] from `self` to `other`. - const fn to(self, end: Self) -> Span { - Span { start: self, end } - } - - /// Create a new [`Span`] consisting entirely of `self`. - const fn to_self(self) -> Span { - Span { - start: self, - end: self, - } - } - - /// Offset the location by the provided amount. - /// - /// Note that this assumes the resulting location is on the same line as the original location. - #[must_use = "this does not modify the original value"] - const fn offset(&self, offset: u32) -> Self { - Self { - byte: self.byte + offset, - } - } - - /// Create an error with the provided message at this location. - const fn error(self, message: &'static str) -> ErrorInner { - ErrorInner { - _message: message, - _span: Span { - start: self, - end: self, - }, - } - } -} - -/// A start and end point within a string. -#[derive(Clone, Copy)] -struct Span { - start: Location, - end: Location, -} - -impl Span { - /// Obtain a `Span` pointing at the start of the pre-existing span. - #[must_use = "this does not modify the original value"] - const fn shrink_to_start(&self) -> Self { - Self { - start: self.start, - end: self.start, - } - } - - /// Obtain a `Span` pointing at the end of the pre-existing span. - #[must_use = "this does not modify the original value"] - const fn shrink_to_end(&self) -> Self { - Self { - start: self.end, - end: self.end, - } - } - - /// Obtain a `Span` that ends before the provided position of the pre-existing span. - #[must_use = "this does not modify the original value"] - const fn shrink_to_before(&self, pos: u32) -> Self { - Self { - start: self.start, - end: Location { - byte: self.start.byte + pos - 1, - }, - } - } - - /// Obtain a `Span` that starts after provided position to the end of the pre-existing span. - #[must_use = "this does not modify the original value"] - const fn shrink_to_after(&self, pos: u32) -> Self { - Self { - start: Location { - byte: self.start.byte + pos + 1, - }, - end: self.end, - } - } - - /// Create an error with the provided message at this span. - const fn error(self, message: &'static str) -> ErrorInner { - ErrorInner { - _message: message, - _span: self, - } - } -} - -/// A value with an associated [`Span`]. -#[derive(Clone, Copy)] -struct Spanned<T> { - /// The value. - value: T, - /// Where the value was in the format string. - span: Span, -} - -impl<T> core::ops::Deref for Spanned<T> { - type Target = T; - - fn deref(&self) -> &Self::Target { - &self.value - } -} - -/// Helper trait to attach a [`Span`] to a value. -trait SpannedValue: Sized { - /// Attach a [`Span`] to a value. - fn spanned(self, span: Span) -> Spanned<Self>; -} - -impl<T> SpannedValue for T { - fn spanned(self, span: Span) -> Spanned<Self> { - Spanned { value: self, span } - } -} - -/// The internal error type. -struct ErrorInner { - /// The message displayed to the user. - _message: &'static str, - /// Where the error originated. - _span: Span, -} - -/// A complete error description. -struct Error { - /// The internal error. - _inner: Unused<ErrorInner>, - /// The error needed for interoperability with the rest of `time`. - public: error::InvalidFormatDescription, -} - -impl From<Error> for error::InvalidFormatDescription { - fn from(error: Error) -> Self { - error.public - } -} - -/// A value that may be used in the future, but currently is not. -/// -/// This struct exists so that data can semantically be passed around without _actually_ passing it -/// around. This way the data still exists if it is needed in the future. -// `PhantomData` is not used directly because we don't want to introduce any trait implementations. -struct Unused<T>(core::marker::PhantomData<T>); - -/// Indicate that a value is currently unused. -fn unused<T>(_: T) -> Unused<T> { - Unused(core::marker::PhantomData) -} diff --git a/vendor/time/src/format_description/parse/strftime.rs b/vendor/time/src/format_description/parse/strftime.rs deleted file mode 100644 index 5fcaf184..00000000 --- a/vendor/time/src/format_description/parse/strftime.rs +++ /dev/null @@ -1,487 +0,0 @@ -use alloc::string::String; -use alloc::vec::Vec; -use core::iter; - -use crate::error::InvalidFormatDescription; -use crate::format_description::parse::{ - attach_location, unused, Error, ErrorInner, Location, Spanned, SpannedValue, Unused, -}; -use crate::format_description::{self, modifier, BorrowedFormatItem, Component}; - -/// Parse a sequence of items from the [`strftime` format description][strftime docs]. -/// -/// The only heap allocation required is for the `Vec` itself. All components are bound to the -/// lifetime of the input. -/// -/// [strftime docs]: https://man7.org/linux/man-pages/man3/strftime.3.html -#[doc(alias = "parse_strptime_borrowed")] -pub fn parse_strftime_borrowed( - s: &str, -) -> Result<Vec<BorrowedFormatItem<'_>>, InvalidFormatDescription> { - let tokens = lex(s.as_bytes()); - let items = into_items(tokens).collect::<Result<_, _>>()?; - Ok(items) -} - -/// Parse a sequence of items from the [`strftime` format description][strftime docs]. -/// -/// This requires heap allocation for some owned items. -/// -/// [strftime docs]: https://man7.org/linux/man-pages/man3/strftime.3.html -#[doc(alias = "parse_strptime_owned")] -pub fn parse_strftime_owned( - s: &str, -) -> Result<format_description::OwnedFormatItem, InvalidFormatDescription> { - parse_strftime_borrowed(s).map(Into::into) -} - -#[derive(Debug, Clone, Copy, PartialEq)] -enum Padding { - /// The default padding for a numeric component. Indicated by no character. - Default, - /// Pad a numeric component with spaces. Indicated by an underscore. - Spaces, - /// Do not pad a numeric component. Indicated by a hyphen. - None, - /// Pad a numeric component with zeroes. Indicated by a zero. - Zeroes, -} - -enum Token<'a> { - Literal(Spanned<&'a [u8]>), - Component { - _percent: Unused<Location>, - padding: Spanned<Padding>, - component: Spanned<u8>, - }, -} - -fn lex(mut input: &[u8]) -> iter::Peekable<impl Iterator<Item = Result<Token<'_>, Error>>> { - let mut iter = attach_location(input.iter()).peekable(); - - iter::from_fn(move || { - Some(Ok(match iter.next()? { - (b'%', percent_loc) => match iter.next() { - Some((padding @ (b'_' | b'-' | b'0'), padding_loc)) => { - let padding = match padding { - b'_' => Padding::Spaces, - b'-' => Padding::None, - b'0' => Padding::Zeroes, - _ => unreachable!(), - }; - let (&component, component_loc) = iter.next()?; - input = &input[3..]; - Token::Component { - _percent: unused(percent_loc), - padding: padding.spanned(padding_loc.to_self()), - component: component.spanned(component_loc.to_self()), - } - } - Some((&component, component_loc)) => { - input = &input[2..]; - let span = component_loc.to_self(); - Token::Component { - _percent: unused(percent_loc), - padding: Padding::Default.spanned(span), - component: component.spanned(span), - } - } - None => { - return Some(Err(Error { - _inner: unused(percent_loc.error("unexpected end of input")), - public: InvalidFormatDescription::Expected { - what: "valid escape sequence", - index: percent_loc.byte as usize, - }, - })); - } - }, - (_, start_location) => { - let mut bytes = 1; - let mut end_location = start_location; - - while let Some((_, location)) = iter.next_if(|&(&byte, _)| byte != b'%') { - end_location = location; - bytes += 1; - } - - let value = &input[..bytes]; - input = &input[bytes..]; - - Token::Literal(value.spanned(start_location.to(end_location))) - } - })) - }) - .peekable() -} - -fn into_items<'iter, 'token: 'iter>( - mut tokens: iter::Peekable<impl Iterator<Item = Result<Token<'token>, Error>> + 'iter>, -) -> impl Iterator<Item = Result<BorrowedFormatItem<'token>, Error>> + 'iter { - iter::from_fn(move || { - let next = match tokens.next()? { - Ok(token) => token, - Err(err) => return Some(Err(err)), - }; - - Some(match next { - Token::Literal(spanned) => Ok(BorrowedFormatItem::Literal(*spanned)), - Token::Component { - _percent, - padding, - component, - } => parse_component(padding, component), - }) - }) -} - -fn parse_component( - padding: Spanned<Padding>, - component: Spanned<u8>, -) -> Result<BorrowedFormatItem<'static>, Error> { - let padding_or_default = |padding: Padding, default| match padding { - Padding::Default => default, - Padding::Spaces => modifier::Padding::Space, - Padding::None => modifier::Padding::None, - Padding::Zeroes => modifier::Padding::Zero, - }; - - /// Helper macro to create a component. - macro_rules! component { - ($name:ident { $($inner:tt)* }) => { - BorrowedFormatItem::Component(Component::$name(modifier::$name { - $($inner)* - })) - } - } - - Ok(match *component { - b'%' => BorrowedFormatItem::Literal(b"%"), - b'a' => component!(Weekday { - repr: modifier::WeekdayRepr::Short, - one_indexed: true, - case_sensitive: true, - }), - b'A' => component!(Weekday { - repr: modifier::WeekdayRepr::Long, - one_indexed: true, - case_sensitive: true, - }), - b'b' | b'h' => component!(Month { - repr: modifier::MonthRepr::Short, - padding: modifier::Padding::Zero, - case_sensitive: true, - }), - b'B' => component!(Month { - repr: modifier::MonthRepr::Long, - padding: modifier::Padding::Zero, - case_sensitive: true, - }), - b'c' => BorrowedFormatItem::Compound(&[ - component!(Weekday { - repr: modifier::WeekdayRepr::Short, - one_indexed: true, - case_sensitive: true, - }), - BorrowedFormatItem::Literal(b" "), - component!(Month { - repr: modifier::MonthRepr::Short, - padding: modifier::Padding::Zero, - case_sensitive: true, - }), - BorrowedFormatItem::Literal(b" "), - component!(Day { - padding: modifier::Padding::Space - }), - BorrowedFormatItem::Literal(b" "), - component!(Hour { - padding: modifier::Padding::Zero, - is_12_hour_clock: false, - }), - BorrowedFormatItem::Literal(b":"), - component!(Minute { - padding: modifier::Padding::Zero, - }), - BorrowedFormatItem::Literal(b":"), - component!(Second { - padding: modifier::Padding::Zero, - }), - BorrowedFormatItem::Literal(b" "), - component!(Year { - padding: modifier::Padding::Zero, - repr: modifier::YearRepr::Full, - range: modifier::YearRange::Extended, - iso_week_based: false, - sign_is_mandatory: false, - }), - ]), - b'C' => component!(Year { - padding: padding_or_default(*padding, modifier::Padding::Zero), - repr: modifier::YearRepr::Century, - range: modifier::YearRange::Extended, - iso_week_based: false, - sign_is_mandatory: false, - }), - b'd' => component!(Day { - padding: padding_or_default(*padding, modifier::Padding::Zero), - }), - b'D' => BorrowedFormatItem::Compound(&[ - component!(Month { - repr: modifier::MonthRepr::Numerical, - padding: modifier::Padding::Zero, - case_sensitive: true, - }), - BorrowedFormatItem::Literal(b"/"), - component!(Day { - padding: modifier::Padding::Zero, - }), - BorrowedFormatItem::Literal(b"/"), - component!(Year { - padding: modifier::Padding::Zero, - repr: modifier::YearRepr::LastTwo, - range: modifier::YearRange::Extended, - iso_week_based: false, - sign_is_mandatory: false, - }), - ]), - b'e' => component!(Day { - padding: padding_or_default(*padding, modifier::Padding::Space), - }), - b'F' => BorrowedFormatItem::Compound(&[ - component!(Year { - padding: modifier::Padding::Zero, - repr: modifier::YearRepr::Full, - range: modifier::YearRange::Extended, - iso_week_based: false, - sign_is_mandatory: false, - }), - BorrowedFormatItem::Literal(b"-"), - component!(Month { - padding: modifier::Padding::Zero, - repr: modifier::MonthRepr::Numerical, - case_sensitive: true, - }), - BorrowedFormatItem::Literal(b"-"), - component!(Day { - padding: modifier::Padding::Zero, - }), - ]), - b'g' => component!(Year { - padding: padding_or_default(*padding, modifier::Padding::Zero), - repr: modifier::YearRepr::LastTwo, - range: modifier::YearRange::Extended, - iso_week_based: true, - sign_is_mandatory: false, - }), - b'G' => component!(Year { - padding: modifier::Padding::Zero, - repr: modifier::YearRepr::Full, - range: modifier::YearRange::Extended, - iso_week_based: true, - sign_is_mandatory: false, - }), - b'H' => component!(Hour { - padding: padding_or_default(*padding, modifier::Padding::Zero), - is_12_hour_clock: false, - }), - b'I' => component!(Hour { - padding: padding_or_default(*padding, modifier::Padding::Zero), - is_12_hour_clock: true, - }), - b'j' => component!(Ordinal { - padding: padding_or_default(*padding, modifier::Padding::Zero), - }), - b'k' => component!(Hour { - padding: padding_or_default(*padding, modifier::Padding::Space), - is_12_hour_clock: false, - }), - b'l' => component!(Hour { - padding: padding_or_default(*padding, modifier::Padding::Space), - is_12_hour_clock: true, - }), - b'm' => component!(Month { - padding: padding_or_default(*padding, modifier::Padding::Zero), - repr: modifier::MonthRepr::Numerical, - case_sensitive: true, - }), - b'M' => component!(Minute { - padding: padding_or_default(*padding, modifier::Padding::Zero), - }), - b'n' => BorrowedFormatItem::Literal(b"\n"), - b'O' => { - return Err(Error { - _inner: unused(ErrorInner { - _message: "unsupported modifier", - _span: component.span, - }), - public: InvalidFormatDescription::NotSupported { - what: "modifier", - context: "", - index: component.span.start.byte as usize, - }, - }) - } - b'p' => component!(Period { - is_uppercase: true, - case_sensitive: true - }), - b'P' => component!(Period { - is_uppercase: false, - case_sensitive: true - }), - b'r' => BorrowedFormatItem::Compound(&[ - component!(Hour { - padding: modifier::Padding::Zero, - is_12_hour_clock: true, - }), - BorrowedFormatItem::Literal(b":"), - component!(Minute { - padding: modifier::Padding::Zero, - }), - BorrowedFormatItem::Literal(b":"), - component!(Second { - padding: modifier::Padding::Zero, - }), - BorrowedFormatItem::Literal(b" "), - component!(Period { - is_uppercase: true, - case_sensitive: true, - }), - ]), - b'R' => BorrowedFormatItem::Compound(&[ - component!(Hour { - padding: modifier::Padding::Zero, - is_12_hour_clock: false, - }), - BorrowedFormatItem::Literal(b":"), - component!(Minute { - padding: modifier::Padding::Zero, - }), - ]), - b's' => component!(UnixTimestamp { - precision: modifier::UnixTimestampPrecision::Second, - sign_is_mandatory: false, - }), - b'S' => component!(Second { - padding: padding_or_default(*padding, modifier::Padding::Zero), - }), - b't' => BorrowedFormatItem::Literal(b"\t"), - b'T' => BorrowedFormatItem::Compound(&[ - component!(Hour { - padding: modifier::Padding::Zero, - is_12_hour_clock: false, - }), - BorrowedFormatItem::Literal(b":"), - component!(Minute { - padding: modifier::Padding::Zero, - }), - BorrowedFormatItem::Literal(b":"), - component!(Second { - padding: modifier::Padding::Zero, - }), - ]), - b'u' => component!(Weekday { - repr: modifier::WeekdayRepr::Monday, - one_indexed: true, - case_sensitive: true, - }), - b'U' => component!(WeekNumber { - padding: padding_or_default(*padding, modifier::Padding::Zero), - repr: modifier::WeekNumberRepr::Sunday, - }), - b'V' => component!(WeekNumber { - padding: padding_or_default(*padding, modifier::Padding::Zero), - repr: modifier::WeekNumberRepr::Iso, - }), - b'w' => component!(Weekday { - repr: modifier::WeekdayRepr::Sunday, - one_indexed: true, - case_sensitive: true, - }), - b'W' => component!(WeekNumber { - padding: padding_or_default(*padding, modifier::Padding::Zero), - repr: modifier::WeekNumberRepr::Monday, - }), - b'x' => BorrowedFormatItem::Compound(&[ - component!(Month { - repr: modifier::MonthRepr::Numerical, - padding: modifier::Padding::Zero, - case_sensitive: true, - }), - BorrowedFormatItem::Literal(b"/"), - component!(Day { - padding: modifier::Padding::Zero - }), - BorrowedFormatItem::Literal(b"/"), - component!(Year { - padding: modifier::Padding::Zero, - repr: modifier::YearRepr::LastTwo, - range: modifier::YearRange::Extended, - iso_week_based: false, - sign_is_mandatory: false, - }), - ]), - b'X' => BorrowedFormatItem::Compound(&[ - component!(Hour { - padding: modifier::Padding::Zero, - is_12_hour_clock: false, - }), - BorrowedFormatItem::Literal(b":"), - component!(Minute { - padding: modifier::Padding::Zero, - }), - BorrowedFormatItem::Literal(b":"), - component!(Second { - padding: modifier::Padding::Zero, - }), - ]), - b'y' => component!(Year { - padding: padding_or_default(*padding, modifier::Padding::Zero), - repr: modifier::YearRepr::LastTwo, - range: modifier::YearRange::Extended, - iso_week_based: false, - sign_is_mandatory: false, - }), - b'Y' => component!(Year { - padding: modifier::Padding::Zero, - repr: modifier::YearRepr::Full, - range: modifier::YearRange::Extended, - iso_week_based: false, - sign_is_mandatory: false, - }), - b'z' => BorrowedFormatItem::Compound(&[ - component!(OffsetHour { - sign_is_mandatory: true, - padding: modifier::Padding::Zero, - }), - component!(OffsetMinute { - padding: modifier::Padding::Zero, - }), - ]), - b'Z' => { - return Err(Error { - _inner: unused(ErrorInner { - _message: "unsupported component", - _span: component.span, - }), - public: InvalidFormatDescription::NotSupported { - what: "component", - context: "", - index: component.span.start.byte as usize, - }, - }) - } - _ => { - return Err(Error { - _inner: unused(ErrorInner { - _message: "invalid component", - _span: component.span, - }), - public: InvalidFormatDescription::InvalidComponentName { - name: String::from_utf8_lossy(&[*component]).into_owned(), - index: component.span.start.byte as usize, - }, - }) - } - }) -} diff --git a/vendor/time/src/format_description/well_known/iso8601.rs b/vendor/time/src/format_description/well_known/iso8601.rs deleted file mode 100644 index 6b8ff2ab..00000000 --- a/vendor/time/src/format_description/well_known/iso8601.rs +++ /dev/null @@ -1,257 +0,0 @@ -//! The format described in ISO 8601. - -mod adt_hack; - -use core::num::NonZeroU8; - -#[doc(hidden, no_inline)] -pub use self::adt_hack::DoNotRelyOnWhatThisIs; -pub use self::adt_hack::EncodedConfig; - -/// The format described in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html). -/// -/// This implementation is of ISO 8601-1:2019. It may not be compatible with other versions. -/// -/// The const parameter `CONFIG` **must** be a value that was returned by [`Config::encode`]. -/// Passing any other value is **unspecified behavior**. -/// -/// Example: 1997-11-21T09:55:06.000000000-06:00 -/// -/// # Examples -#[cfg_attr(feature = "formatting", doc = "```rust")] -#[cfg_attr(not(feature = "formatting"), doc = "```rust,ignore")] -/// # use time::format_description::well_known::Iso8601; -/// # use time_macros::datetime; -/// assert_eq!( -/// datetime!(1997-11-12 9:55:06 -6:00).format(&Iso8601::DEFAULT)?, -/// "1997-11-12T09:55:06.000000000-06:00" -/// ); -/// # Ok::<_, time::Error>(()) -/// ``` -#[derive(Clone, Copy, PartialEq, Eq)] -pub struct Iso8601<const CONFIG: EncodedConfig = { Config::DEFAULT.encode() }>; - -impl<const CONFIG: EncodedConfig> core::fmt::Debug for Iso8601<CONFIG> { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - f.debug_struct("Iso8601") - .field("config", &Config::decode(CONFIG)) - .finish() - } -} - -/// Define associated constants for `Iso8601`. -macro_rules! define_assoc_consts { - ($($(#[$doc:meta])* $vis:vis const $const_name:ident = $format:expr;)*) => {$( - const $const_name: EncodedConfig = $format.encode(); - impl Iso8601<$const_name> { - $(#[$doc])* - $vis const $const_name: Self = Self; - } - )*}; -} - -define_assoc_consts! { - /// An [`Iso8601`] with the default configuration. - /// - /// The following is the default behavior: - /// - /// - The configuration can be used for both formatting and parsing. - /// - The date, time, and UTC offset are all formatted. - /// - Separators (such as `-` and `:`) are included. - /// - The year contains four digits, such that the year must be between 0 and 9999. - /// - The date uses the calendar format. - /// - The time has precision to the second and nine decimal digits. - /// - The UTC offset has precision to the minute. - /// - /// If you need different behavior, use another associated constant. For full customization, use - /// [`Config::DEFAULT`] and [`Config`]'s methods to create a custom configuration. - pub const DEFAULT = Config::DEFAULT; - /// An [`Iso8601`] that can only be used for parsing. Using this to format a value is - /// unspecified behavior. - pub const PARSING = Config::PARSING; - /// An [`Iso8601`] that handles only the date, but is otherwise the same as [`Config::DEFAULT`]. - pub const DATE = Config::DEFAULT.set_formatted_components(FormattedComponents::Date); - /// An [`Iso8601`] that handles only the time, but is otherwise the same as [`Config::DEFAULT`]. - pub const TIME = Config::DEFAULT.set_formatted_components(FormattedComponents::Time); - /// An [`Iso8601`] that handles only the UTC offset, but is otherwise the same as - /// [`Config::DEFAULT`]. - pub const OFFSET = Config::DEFAULT.set_formatted_components(FormattedComponents::Offset); - /// An [`Iso8601`] that handles the date and time, but is otherwise the same as - /// [`Config::DEFAULT`]. - pub const DATE_TIME = Config::DEFAULT.set_formatted_components(FormattedComponents::DateTime); - /// An [`Iso8601`] that handles the date, time, and UTC offset. This is the same as - /// [`Config::DEFAULT`]. - pub const DATE_TIME_OFFSET = Config::DEFAULT; - /// An [`Iso8601`] that handles the time and UTC offset, but is otherwise the same as - /// [`Config::DEFAULT`]. - pub const TIME_OFFSET = Config::DEFAULT - .set_formatted_components(FormattedComponents::TimeOffset); -} - -/// Which components to format. -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum FormattedComponents { - /// The configuration can only be used for parsing. Using this to format a value is - /// unspecified behavior. - None, - /// Format only the date. - Date, - /// Format only the time. - Time, - /// Format only the UTC offset. - Offset, - /// Format the date and time. - DateTime, - /// Format the date, time, and UTC offset. - DateTimeOffset, - /// Format the time and UTC offset. - TimeOffset, -} - -/// Which format to use for the date. -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum DateKind { - /// Use the year-month-day format. - Calendar, - /// Use the year-week-weekday format. - Week, - /// Use the week-ordinal format. - Ordinal, -} - -/// The precision and number of decimal digits present for the time. -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum TimePrecision { - /// Format the hour only. Minutes, seconds, and nanoseconds will be represented with the - /// specified number of decimal digits, if any. - Hour { - #[allow(missing_docs)] - decimal_digits: Option<NonZeroU8>, - }, - /// Format the hour and minute. Seconds and nanoseconds will be represented with the specified - /// number of decimal digits, if any. - Minute { - #[allow(missing_docs)] - decimal_digits: Option<NonZeroU8>, - }, - /// Format the hour, minute, and second. Nanoseconds will be represented with the specified - /// number of decimal digits, if any. - Second { - #[allow(missing_docs)] - decimal_digits: Option<NonZeroU8>, - }, -} - -/// The precision for the UTC offset. -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum OffsetPrecision { - /// Format only the offset hour. Requires the offset minute to be zero. - Hour, - /// Format both the offset hour and minute. - Minute, -} - -/// Configuration for [`Iso8601`]. -// This is only used as a const generic, so there's no need to have a number of implementations on -// it. -#[allow(missing_copy_implementations)] -#[doc(alias = "EncodedConfig")] // People will likely search for `EncodedConfig`, so show them this. -#[derive(Debug)] -pub struct Config { - /// Which components, if any, will be formatted. - pub(crate) formatted_components: FormattedComponents, - /// Whether the format contains separators (such as `-` or `:`). - pub(crate) use_separators: bool, - /// Whether the year is six digits. - pub(crate) year_is_six_digits: bool, - /// The format used for the date. - pub(crate) date_kind: DateKind, - /// The precision and number of decimal digits present for the time. - pub(crate) time_precision: TimePrecision, - /// The precision for the UTC offset. - pub(crate) offset_precision: OffsetPrecision, -} - -impl Config { - /// A configuration for the [`Iso8601`] format. - /// - /// The following is the default behavior: - /// - /// - The configuration can be used for both formatting and parsing. - /// - The date, time, and UTC offset are all formatted. - /// - Separators (such as `-` and `:`) are included. - /// - The year contains four digits, such that the year must be between 0 and 9999. - /// - The date uses the calendar format. - /// - The time has precision to the second and nine decimal digits. - /// - The UTC offset has precision to the minute. - /// - /// If you need different behavior, use the setter methods on this struct. - pub const DEFAULT: Self = Self { - formatted_components: FormattedComponents::DateTimeOffset, - use_separators: true, - year_is_six_digits: false, - date_kind: DateKind::Calendar, - time_precision: TimePrecision::Second { - decimal_digits: NonZeroU8::new(9), - }, - offset_precision: OffsetPrecision::Minute, - }; - - /// A configuration that can only be used for parsing. Using this to format a value is - /// unspecified behavior. - const PARSING: Self = Self { - formatted_components: FormattedComponents::None, - use_separators: false, - year_is_six_digits: false, - date_kind: DateKind::Calendar, - time_precision: TimePrecision::Hour { - decimal_digits: None, - }, - offset_precision: OffsetPrecision::Hour, - }; - - /// Set whether the format the date, time, and/or UTC offset. - pub const fn set_formatted_components(self, formatted_components: FormattedComponents) -> Self { - Self { - formatted_components, - ..self - } - } - - /// Set whether the format contains separators (such as `-` or `:`). - pub const fn set_use_separators(self, use_separators: bool) -> Self { - Self { - use_separators, - ..self - } - } - - /// Set whether the year is six digits. - pub const fn set_year_is_six_digits(self, year_is_six_digits: bool) -> Self { - Self { - year_is_six_digits, - ..self - } - } - - /// Set the format used for the date. - pub const fn set_date_kind(self, date_kind: DateKind) -> Self { - Self { date_kind, ..self } - } - - /// Set the precision and number of decimal digits present for the time. - pub const fn set_time_precision(self, time_precision: TimePrecision) -> Self { - Self { - time_precision, - ..self - } - } - - /// Set the precision for the UTC offset. - pub const fn set_offset_precision(self, offset_precision: OffsetPrecision) -> Self { - Self { - offset_precision, - ..self - } - } -} diff --git a/vendor/time/src/format_description/well_known/iso8601/adt_hack.rs b/vendor/time/src/format_description/well_known/iso8601/adt_hack.rs deleted file mode 100644 index 6d3daebb..00000000 --- a/vendor/time/src/format_description/well_known/iso8601/adt_hack.rs +++ /dev/null @@ -1,247 +0,0 @@ -//! Hackery to work around not being able to use ADTs in const generics on stable. - -use core::num::NonZeroU8; - -#[cfg(feature = "formatting")] -use super::Iso8601; -use super::{Config, DateKind, FormattedComponents as FC, OffsetPrecision, TimePrecision}; - -// This provides a way to include `EncodedConfig` in documentation without displaying the type it is -// aliased to. -#[doc(hidden)] -pub type DoNotRelyOnWhatThisIs = u128; - -/// An encoded [`Config`] that can be used as a const parameter to [`Iso8601`](super::Iso8601). -/// -/// The type this is aliased to must not be relied upon. It can change in any release without -/// notice. -pub type EncodedConfig = DoNotRelyOnWhatThisIs; - -#[cfg(feature = "formatting")] -impl<const CONFIG: EncodedConfig> Iso8601<CONFIG> { - /// The user-provided configuration for the ISO 8601 format. - const CONFIG: Config = Config::decode(CONFIG); - /// Whether the date should be formatted. - pub(crate) const FORMAT_DATE: bool = matches!( - Self::CONFIG.formatted_components, - FC::Date | FC::DateTime | FC::DateTimeOffset - ); - /// Whether the time should be formatted. - pub(crate) const FORMAT_TIME: bool = matches!( - Self::CONFIG.formatted_components, - FC::Time | FC::DateTime | FC::DateTimeOffset | FC::TimeOffset - ); - /// Whether the UTC offset should be formatted. - pub(crate) const FORMAT_OFFSET: bool = matches!( - Self::CONFIG.formatted_components, - FC::Offset | FC::DateTimeOffset | FC::TimeOffset - ); - /// Whether the year is six digits. - pub(crate) const YEAR_IS_SIX_DIGITS: bool = Self::CONFIG.year_is_six_digits; - /// Whether the format contains separators (such as `-` or `:`). - pub(crate) const USE_SEPARATORS: bool = Self::CONFIG.use_separators; - /// Which format to use for the date. - pub(crate) const DATE_KIND: DateKind = Self::CONFIG.date_kind; - /// The precision and number of decimal digits to use for the time. - pub(crate) const TIME_PRECISION: TimePrecision = Self::CONFIG.time_precision; - /// The precision for the UTC offset. - pub(crate) const OFFSET_PRECISION: OffsetPrecision = Self::CONFIG.offset_precision; -} - -impl Config { - /// Encode the configuration, permitting it to be used as a const parameter of [`Iso8601`]. - /// - /// The value returned by this method must only be used as a const parameter to [`Iso8601`]. Any - /// other usage is unspecified behavior. - pub const fn encode(&self) -> EncodedConfig { - let mut bytes = [0; EncodedConfig::BITS as usize / 8]; - - bytes[0] = match self.formatted_components { - FC::None => 0, - FC::Date => 1, - FC::Time => 2, - FC::Offset => 3, - FC::DateTime => 4, - FC::DateTimeOffset => 5, - FC::TimeOffset => 6, - }; - bytes[1] = self.use_separators as u8; - bytes[2] = self.year_is_six_digits as u8; - bytes[3] = match self.date_kind { - DateKind::Calendar => 0, - DateKind::Week => 1, - DateKind::Ordinal => 2, - }; - bytes[4] = match self.time_precision { - TimePrecision::Hour { .. } => 0, - TimePrecision::Minute { .. } => 1, - TimePrecision::Second { .. } => 2, - }; - bytes[5] = match self.time_precision { - TimePrecision::Hour { decimal_digits } - | TimePrecision::Minute { decimal_digits } - | TimePrecision::Second { decimal_digits } => match decimal_digits { - None => 0, - Some(decimal_digits) => decimal_digits.get(), - }, - }; - bytes[6] = match self.offset_precision { - OffsetPrecision::Hour => 0, - OffsetPrecision::Minute => 1, - }; - - EncodedConfig::from_be_bytes(bytes) - } - - /// Decode the configuration. The configuration must have been generated from - /// [`Config::encode`]. - pub(super) const fn decode(encoded: EncodedConfig) -> Self { - let bytes = encoded.to_be_bytes(); - - let formatted_components = match bytes[0] { - 0 => FC::None, - 1 => FC::Date, - 2 => FC::Time, - 3 => FC::Offset, - 4 => FC::DateTime, - 5 => FC::DateTimeOffset, - 6 => FC::TimeOffset, - _ => panic!("invalid configuration"), - }; - let use_separators = match bytes[1] { - 0 => false, - 1 => true, - _ => panic!("invalid configuration"), - }; - let year_is_six_digits = match bytes[2] { - 0 => false, - 1 => true, - _ => panic!("invalid configuration"), - }; - let date_kind = match bytes[3] { - 0 => DateKind::Calendar, - 1 => DateKind::Week, - 2 => DateKind::Ordinal, - _ => panic!("invalid configuration"), - }; - let time_precision = match bytes[4] { - 0 => TimePrecision::Hour { - decimal_digits: NonZeroU8::new(bytes[5]), - }, - 1 => TimePrecision::Minute { - decimal_digits: NonZeroU8::new(bytes[5]), - }, - 2 => TimePrecision::Second { - decimal_digits: NonZeroU8::new(bytes[5]), - }, - _ => panic!("invalid configuration"), - }; - let offset_precision = match bytes[6] { - 0 => OffsetPrecision::Hour, - 1 => OffsetPrecision::Minute, - _ => panic!("invalid configuration"), - }; - - // No `for` loops in `const fn`. - let mut idx = 7; // first unused byte - while idx < EncodedConfig::BITS as usize / 8 { - assert!(bytes[idx] == 0, "invalid configuration"); - idx += 1; - } - - Self { - formatted_components, - use_separators, - year_is_six_digits, - date_kind, - time_precision, - offset_precision, - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - - macro_rules! eq { - ($a:expr, $b:expr) => {{ - let a = $a; - let b = $b; - a.formatted_components == b.formatted_components - && a.use_separators == b.use_separators - && a.year_is_six_digits == b.year_is_six_digits - && a.date_kind == b.date_kind - && a.time_precision == b.time_precision - && a.offset_precision == b.offset_precision - }}; - } - - #[test] - fn encoding_roundtrip() { - macro_rules! assert_roundtrip { - ($config:expr) => { - let config = $config; - let encoded = config.encode(); - let decoded = Config::decode(encoded); - assert!(eq!(config, decoded)); - }; - } - - assert_roundtrip!(Config::DEFAULT); - assert_roundtrip!(Config::DEFAULT.set_formatted_components(FC::None)); - assert_roundtrip!(Config::DEFAULT.set_formatted_components(FC::Date)); - assert_roundtrip!(Config::DEFAULT.set_formatted_components(FC::Time)); - assert_roundtrip!(Config::DEFAULT.set_formatted_components(FC::Offset)); - assert_roundtrip!(Config::DEFAULT.set_formatted_components(FC::DateTime)); - assert_roundtrip!(Config::DEFAULT.set_formatted_components(FC::DateTimeOffset)); - assert_roundtrip!(Config::DEFAULT.set_formatted_components(FC::TimeOffset)); - assert_roundtrip!(Config::DEFAULT.set_use_separators(false)); - assert_roundtrip!(Config::DEFAULT.set_use_separators(true)); - assert_roundtrip!(Config::DEFAULT.set_year_is_six_digits(false)); - assert_roundtrip!(Config::DEFAULT.set_year_is_six_digits(true)); - assert_roundtrip!(Config::DEFAULT.set_date_kind(DateKind::Calendar)); - assert_roundtrip!(Config::DEFAULT.set_date_kind(DateKind::Week)); - assert_roundtrip!(Config::DEFAULT.set_date_kind(DateKind::Ordinal)); - assert_roundtrip!(Config::DEFAULT.set_time_precision(TimePrecision::Hour { - decimal_digits: None, - })); - assert_roundtrip!(Config::DEFAULT.set_time_precision(TimePrecision::Minute { - decimal_digits: None, - })); - assert_roundtrip!(Config::DEFAULT.set_time_precision(TimePrecision::Second { - decimal_digits: None, - })); - assert_roundtrip!(Config::DEFAULT.set_time_precision(TimePrecision::Hour { - decimal_digits: NonZeroU8::new(1), - })); - assert_roundtrip!(Config::DEFAULT.set_time_precision(TimePrecision::Minute { - decimal_digits: NonZeroU8::new(1), - })); - assert_roundtrip!(Config::DEFAULT.set_time_precision(TimePrecision::Second { - decimal_digits: NonZeroU8::new(1), - })); - assert_roundtrip!(Config::DEFAULT.set_offset_precision(OffsetPrecision::Hour)); - assert_roundtrip!(Config::DEFAULT.set_offset_precision(OffsetPrecision::Minute)); - } - - macro_rules! assert_decode_fail { - ($encoding:expr) => { - assert!(std::panic::catch_unwind(|| { - Config::decode($encoding); - }) - .is_err()); - }; - } - - #[test] - fn decode_fail() { - assert_decode_fail!(0x07_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00); - assert_decode_fail!(0x00_02_00_00_00_00_00_00_00_00_00_00_00_00_00_00); - assert_decode_fail!(0x00_00_02_00_00_00_00_00_00_00_00_00_00_00_00_00); - assert_decode_fail!(0x00_00_00_03_00_00_00_00_00_00_00_00_00_00_00_00); - assert_decode_fail!(0x00_00_00_00_03_00_00_00_00_00_00_00_00_00_00_00); - assert_decode_fail!(0x00_00_00_00_00_00_02_00_00_00_00_00_00_00_00_00); - assert_decode_fail!(0x00_00_00_00_00_00_00_01_00_00_00_00_00_00_00_00); - } -} diff --git a/vendor/time/src/format_description/well_known/rfc2822.rs b/vendor/time/src/format_description/well_known/rfc2822.rs deleted file mode 100644 index 3c890ab1..00000000 --- a/vendor/time/src/format_description/well_known/rfc2822.rs +++ /dev/null @@ -1,30 +0,0 @@ -//! The format described in RFC 2822. - -/// The format described in [RFC 2822](https://tools.ietf.org/html/rfc2822#section-3.3). -/// -/// Example: Fri, 21 Nov 1997 09:55:06 -0600 -/// -/// # Examples -#[cfg_attr(feature = "parsing", doc = "```rust")] -#[cfg_attr(not(feature = "parsing"), doc = "```rust,ignore")] -/// # use time::{format_description::well_known::Rfc2822, OffsetDateTime}; -/// use time_macros::datetime; -/// assert_eq!( -/// OffsetDateTime::parse("Sat, 12 Jun 1993 13:25:19 GMT", &Rfc2822)?, -/// datetime!(1993-06-12 13:25:19 +00:00) -/// ); -/// # Ok::<_, time::Error>(()) -/// ``` -/// -#[cfg_attr(feature = "formatting", doc = "```rust")] -#[cfg_attr(not(feature = "formatting"), doc = "```rust,ignore")] -/// # use time::format_description::well_known::Rfc2822; -/// # use time_macros::datetime; -/// assert_eq!( -/// datetime!(1997-11-21 09:55:06 -06:00).format(&Rfc2822)?, -/// "Fri, 21 Nov 1997 09:55:06 -0600" -/// ); -/// # Ok::<_, time::Error>(()) -/// ``` -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub struct Rfc2822; diff --git a/vendor/time/src/format_description/well_known/rfc3339.rs b/vendor/time/src/format_description/well_known/rfc3339.rs deleted file mode 100644 index f0873cba..00000000 --- a/vendor/time/src/format_description/well_known/rfc3339.rs +++ /dev/null @@ -1,30 +0,0 @@ -//! The format described in RFC 3339. - -/// The format described in [RFC 3339](https://tools.ietf.org/html/rfc3339#section-5.6). -/// -/// Format example: 1985-04-12T23:20:50.52Z -/// -/// # Examples -#[cfg_attr(feature = "parsing", doc = "```rust")] -#[cfg_attr(not(feature = "parsing"), doc = "```rust,ignore")] -/// # use time::{format_description::well_known::Rfc3339, OffsetDateTime}; -/// # use time_macros::datetime; -/// assert_eq!( -/// OffsetDateTime::parse("1985-04-12T23:20:50.52Z", &Rfc3339)?, -/// datetime!(1985-04-12 23:20:50.52 +00:00) -/// ); -/// # Ok::<_, time::Error>(()) -/// ``` -/// -#[cfg_attr(feature = "formatting", doc = "```rust")] -#[cfg_attr(not(feature = "formatting"), doc = "```rust,ignore")] -/// # use time::format_description::well_known::Rfc3339; -/// # use time_macros::datetime; -/// assert_eq!( -/// datetime!(1985-04-12 23:20:50.52 +00:00).format(&Rfc3339)?, -/// "1985-04-12T23:20:50.52Z" -/// ); -/// # Ok::<_, time::Error>(()) -/// ``` -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub struct Rfc3339; diff --git a/vendor/time/src/formatting/formattable.rs b/vendor/time/src/formatting/formattable.rs deleted file mode 100644 index 7d1ce031..00000000 --- a/vendor/time/src/formatting/formattable.rs +++ /dev/null @@ -1,312 +0,0 @@ -//! A trait that can be used to format an item from its components. - -use alloc::string::String; -use alloc::vec::Vec; -use core::ops::Deref; -use std::io; - -use num_conv::prelude::*; - -use crate::format_description::well_known::iso8601::EncodedConfig; -use crate::format_description::well_known::{Iso8601, Rfc2822, Rfc3339}; -use crate::format_description::{BorrowedFormatItem, OwnedFormatItem}; -use crate::formatting::{ - format_component, format_number_pad_zero, iso8601, write, MONTH_NAMES, WEEKDAY_NAMES, -}; -use crate::{error, Date, Time, UtcOffset}; - -/// A type that describes a format. -/// -/// Implementors of [`Formattable`] are [format descriptions](crate::format_description). -/// -/// [`Date::format`] and [`Time::format`] each use a format description to generate -/// a String from their data. See the respective methods for usage examples. -#[cfg_attr(docsrs, doc(notable_trait))] -pub trait Formattable: sealed::Sealed {} -impl Formattable for BorrowedFormatItem<'_> {} -impl Formattable for [BorrowedFormatItem<'_>] {} -impl Formattable for OwnedFormatItem {} -impl Formattable for [OwnedFormatItem] {} -impl Formattable for Rfc3339 {} -impl Formattable for Rfc2822 {} -impl<const CONFIG: EncodedConfig> Formattable for Iso8601<CONFIG> {} -impl<T: Deref> Formattable for T where T::Target: Formattable {} - -/// Seal the trait to prevent downstream users from implementing it. -mod sealed { - #[allow(clippy::wildcard_imports)] - use super::*; - - /// Format the item using a format description, the intended output, and the various components. - pub trait Sealed { - /// Format the item into the provided output, returning the number of bytes written. - fn format_into( - &self, - output: &mut (impl io::Write + ?Sized), - date: Option<Date>, - time: Option<Time>, - offset: Option<UtcOffset>, - ) -> Result<usize, error::Format>; - - /// Format the item directly to a `String`. - fn format( - &self, - date: Option<Date>, - time: Option<Time>, - offset: Option<UtcOffset>, - ) -> Result<String, error::Format> { - let mut buf = Vec::new(); - self.format_into(&mut buf, date, time, offset)?; - Ok(String::from_utf8_lossy(&buf).into_owned()) - } - } -} - -impl sealed::Sealed for BorrowedFormatItem<'_> { - fn format_into( - &self, - output: &mut (impl io::Write + ?Sized), - date: Option<Date>, - time: Option<Time>, - offset: Option<UtcOffset>, - ) -> Result<usize, error::Format> { - Ok(match *self { - Self::Literal(literal) => write(output, literal)?, - Self::Component(component) => format_component(output, component, date, time, offset)?, - Self::Compound(items) => items.format_into(output, date, time, offset)?, - Self::Optional(item) => item.format_into(output, date, time, offset)?, - Self::First(items) => match items { - [] => 0, - [item, ..] => item.format_into(output, date, time, offset)?, - }, - }) - } -} - -impl sealed::Sealed for [BorrowedFormatItem<'_>] { - fn format_into( - &self, - output: &mut (impl io::Write + ?Sized), - date: Option<Date>, - time: Option<Time>, - offset: Option<UtcOffset>, - ) -> Result<usize, error::Format> { - let mut bytes = 0; - for item in self.iter() { - bytes += item.format_into(output, date, time, offset)?; - } - Ok(bytes) - } -} - -impl sealed::Sealed for OwnedFormatItem { - fn format_into( - &self, - output: &mut (impl io::Write + ?Sized), - date: Option<Date>, - time: Option<Time>, - offset: Option<UtcOffset>, - ) -> Result<usize, error::Format> { - match self { - Self::Literal(literal) => Ok(write(output, literal)?), - Self::Component(component) => format_component(output, *component, date, time, offset), - Self::Compound(items) => items.format_into(output, date, time, offset), - Self::Optional(item) => item.format_into(output, date, time, offset), - Self::First(items) => match &**items { - [] => Ok(0), - [item, ..] => item.format_into(output, date, time, offset), - }, - } - } -} - -impl sealed::Sealed for [OwnedFormatItem] { - fn format_into( - &self, - output: &mut (impl io::Write + ?Sized), - date: Option<Date>, - time: Option<Time>, - offset: Option<UtcOffset>, - ) -> Result<usize, error::Format> { - let mut bytes = 0; - for item in self.iter() { - bytes += item.format_into(output, date, time, offset)?; - } - Ok(bytes) - } -} - -impl<T: Deref> sealed::Sealed for T -where - T::Target: sealed::Sealed, -{ - fn format_into( - &self, - output: &mut (impl io::Write + ?Sized), - date: Option<Date>, - time: Option<Time>, - offset: Option<UtcOffset>, - ) -> Result<usize, error::Format> { - self.deref().format_into(output, date, time, offset) - } -} - -impl sealed::Sealed for Rfc2822 { - fn format_into( - &self, - output: &mut (impl io::Write + ?Sized), - date: Option<Date>, - time: Option<Time>, - offset: Option<UtcOffset>, - ) -> Result<usize, error::Format> { - let date = date.ok_or(error::Format::InsufficientTypeInformation)?; - let time = time.ok_or(error::Format::InsufficientTypeInformation)?; - let offset = offset.ok_or(error::Format::InsufficientTypeInformation)?; - - let mut bytes = 0; - - let (year, month, day) = date.to_calendar_date(); - - if year < 1900 { - return Err(error::Format::InvalidComponent("year")); - } - if offset.seconds_past_minute() != 0 { - return Err(error::Format::InvalidComponent("offset_second")); - } - - bytes += write( - output, - &WEEKDAY_NAMES[date.weekday().number_days_from_monday().extend::<usize>()][..3], - )?; - bytes += write(output, b", ")?; - bytes += format_number_pad_zero::<2>(output, day)?; - bytes += write(output, b" ")?; - bytes += write( - output, - &MONTH_NAMES[u8::from(month).extend::<usize>() - 1][..3], - )?; - bytes += write(output, b" ")?; - bytes += format_number_pad_zero::<4>(output, year.cast_unsigned())?; - bytes += write(output, b" ")?; - bytes += format_number_pad_zero::<2>(output, time.hour())?; - bytes += write(output, b":")?; - bytes += format_number_pad_zero::<2>(output, time.minute())?; - bytes += write(output, b":")?; - bytes += format_number_pad_zero::<2>(output, time.second())?; - bytes += write(output, b" ")?; - bytes += write(output, if offset.is_negative() { b"-" } else { b"+" })?; - bytes += format_number_pad_zero::<2>(output, offset.whole_hours().unsigned_abs())?; - bytes += format_number_pad_zero::<2>(output, offset.minutes_past_hour().unsigned_abs())?; - - Ok(bytes) - } -} - -impl sealed::Sealed for Rfc3339 { - fn format_into( - &self, - output: &mut (impl io::Write + ?Sized), - date: Option<Date>, - time: Option<Time>, - offset: Option<UtcOffset>, - ) -> Result<usize, error::Format> { - let date = date.ok_or(error::Format::InsufficientTypeInformation)?; - let time = time.ok_or(error::Format::InsufficientTypeInformation)?; - let offset = offset.ok_or(error::Format::InsufficientTypeInformation)?; - - let mut bytes = 0; - - let year = date.year(); - - if !(0..10_000).contains(&year) { - return Err(error::Format::InvalidComponent("year")); - } - if offset.whole_hours().unsigned_abs() > 23 { - return Err(error::Format::InvalidComponent("offset_hour")); - } - if offset.seconds_past_minute() != 0 { - return Err(error::Format::InvalidComponent("offset_second")); - } - - bytes += format_number_pad_zero::<4>(output, year.cast_unsigned())?; - bytes += write(output, b"-")?; - bytes += format_number_pad_zero::<2>(output, u8::from(date.month()))?; - bytes += write(output, b"-")?; - bytes += format_number_pad_zero::<2>(output, date.day())?; - bytes += write(output, b"T")?; - bytes += format_number_pad_zero::<2>(output, time.hour())?; - bytes += write(output, b":")?; - bytes += format_number_pad_zero::<2>(output, time.minute())?; - bytes += write(output, b":")?; - bytes += format_number_pad_zero::<2>(output, time.second())?; - - if time.nanosecond() != 0 { - let nanos = time.nanosecond(); - bytes += write(output, b".")?; - bytes += if nanos % 10 != 0 { - format_number_pad_zero::<9>(output, nanos) - } else if (nanos / 10) % 10 != 0 { - format_number_pad_zero::<8>(output, nanos / 10) - } else if (nanos / 100) % 10 != 0 { - format_number_pad_zero::<7>(output, nanos / 100) - } else if (nanos / 1_000) % 10 != 0 { - format_number_pad_zero::<6>(output, nanos / 1_000) - } else if (nanos / 10_000) % 10 != 0 { - format_number_pad_zero::<5>(output, nanos / 10_000) - } else if (nanos / 100_000) % 10 != 0 { - format_number_pad_zero::<4>(output, nanos / 100_000) - } else if (nanos / 1_000_000) % 10 != 0 { - format_number_pad_zero::<3>(output, nanos / 1_000_000) - } else if (nanos / 10_000_000) % 10 != 0 { - format_number_pad_zero::<2>(output, nanos / 10_000_000) - } else { - format_number_pad_zero::<1>(output, nanos / 100_000_000) - }?; - } - - if offset == UtcOffset::UTC { - bytes += write(output, b"Z")?; - return Ok(bytes); - } - - bytes += write(output, if offset.is_negative() { b"-" } else { b"+" })?; - bytes += format_number_pad_zero::<2>(output, offset.whole_hours().unsigned_abs())?; - bytes += write(output, b":")?; - bytes += format_number_pad_zero::<2>(output, offset.minutes_past_hour().unsigned_abs())?; - - Ok(bytes) - } -} - -impl<const CONFIG: EncodedConfig> sealed::Sealed for Iso8601<CONFIG> { - fn format_into( - &self, - output: &mut (impl io::Write + ?Sized), - date: Option<Date>, - time: Option<Time>, - offset: Option<UtcOffset>, - ) -> Result<usize, error::Format> { - let mut bytes = 0; - - if Self::FORMAT_DATE { - let date = date.ok_or(error::Format::InsufficientTypeInformation)?; - bytes += iso8601::format_date::<CONFIG>(output, date)?; - } - if Self::FORMAT_TIME { - let time = time.ok_or(error::Format::InsufficientTypeInformation)?; - bytes += iso8601::format_time::<CONFIG>(output, time)?; - } - if Self::FORMAT_OFFSET { - let offset = offset.ok_or(error::Format::InsufficientTypeInformation)?; - bytes += iso8601::format_offset::<CONFIG>(output, offset)?; - } - - if bytes == 0 { - // The only reason there would be no bytes written is if the format was only for - // parsing. - panic!("attempted to format a parsing-only format description"); - } - - Ok(bytes) - } -} diff --git a/vendor/time/src/formatting/iso8601.rs b/vendor/time/src/formatting/iso8601.rs deleted file mode 100644 index a2d2affa..00000000 --- a/vendor/time/src/formatting/iso8601.rs +++ /dev/null @@ -1,142 +0,0 @@ -//! Helpers for implementing formatting for ISO 8601. - -use std::io; - -use num_conv::prelude::*; - -use crate::convert::*; -use crate::format_description::well_known::iso8601::{ - DateKind, EncodedConfig, OffsetPrecision, TimePrecision, -}; -use crate::format_description::well_known::Iso8601; -use crate::formatting::{format_float, format_number_pad_zero, write, write_if, write_if_else}; -use crate::{error, Date, Time, UtcOffset}; - -/// Format the date portion of ISO 8601. -pub(super) fn format_date<const CONFIG: EncodedConfig>( - output: &mut (impl io::Write + ?Sized), - date: Date, -) -> Result<usize, error::Format> { - let mut bytes = 0; - - match Iso8601::<CONFIG>::DATE_KIND { - DateKind::Calendar => { - let (year, month, day) = date.to_calendar_date(); - if Iso8601::<CONFIG>::YEAR_IS_SIX_DIGITS { - bytes += write_if_else(output, year < 0, b"-", b"+")?; - bytes += format_number_pad_zero::<6>(output, year.unsigned_abs())?; - } else if !(0..=9999).contains(&year) { - return Err(error::Format::InvalidComponent("year")); - } else { - bytes += format_number_pad_zero::<4>(output, year.cast_unsigned())?; - } - bytes += write_if(output, Iso8601::<CONFIG>::USE_SEPARATORS, b"-")?; - bytes += format_number_pad_zero::<2>(output, u8::from(month))?; - bytes += write_if(output, Iso8601::<CONFIG>::USE_SEPARATORS, b"-")?; - bytes += format_number_pad_zero::<2>(output, day)?; - } - DateKind::Week => { - let (year, week, day) = date.to_iso_week_date(); - if Iso8601::<CONFIG>::YEAR_IS_SIX_DIGITS { - bytes += write_if_else(output, year < 0, b"-", b"+")?; - bytes += format_number_pad_zero::<6>(output, year.unsigned_abs())?; - } else if !(0..=9999).contains(&year) { - return Err(error::Format::InvalidComponent("year")); - } else { - bytes += format_number_pad_zero::<4>(output, year.cast_unsigned())?; - } - bytes += write_if_else(output, Iso8601::<CONFIG>::USE_SEPARATORS, b"-W", b"W")?; - bytes += format_number_pad_zero::<2>(output, week)?; - bytes += write_if(output, Iso8601::<CONFIG>::USE_SEPARATORS, b"-")?; - bytes += format_number_pad_zero::<1>(output, day.number_from_monday())?; - } - DateKind::Ordinal => { - let (year, day) = date.to_ordinal_date(); - if Iso8601::<CONFIG>::YEAR_IS_SIX_DIGITS { - bytes += write_if_else(output, year < 0, b"-", b"+")?; - bytes += format_number_pad_zero::<6>(output, year.unsigned_abs())?; - } else if !(0..=9999).contains(&year) { - return Err(error::Format::InvalidComponent("year")); - } else { - bytes += format_number_pad_zero::<4>(output, year.cast_unsigned())?; - } - bytes += write_if(output, Iso8601::<CONFIG>::USE_SEPARATORS, b"-")?; - bytes += format_number_pad_zero::<3>(output, day)?; - } - } - - Ok(bytes) -} - -/// Format the time portion of ISO 8601. -pub(super) fn format_time<const CONFIG: EncodedConfig>( - output: &mut (impl io::Write + ?Sized), - time: Time, -) -> Result<usize, error::Format> { - let mut bytes = 0; - - // The "T" can only be omitted in extended format where there is no date being formatted. - bytes += write_if( - output, - Iso8601::<CONFIG>::USE_SEPARATORS || Iso8601::<CONFIG>::FORMAT_DATE, - b"T", - )?; - - let (hours, minutes, seconds, nanoseconds) = time.as_hms_nano(); - - match Iso8601::<CONFIG>::TIME_PRECISION { - TimePrecision::Hour { decimal_digits } => { - let hours = (hours as f64) - + (minutes as f64) / Minute::per(Hour) as f64 - + (seconds as f64) / Second::per(Hour) as f64 - + (nanoseconds as f64) / Nanosecond::per(Hour) as f64; - format_float(output, hours, 2, decimal_digits)?; - } - TimePrecision::Minute { decimal_digits } => { - bytes += format_number_pad_zero::<2>(output, hours)?; - bytes += write_if(output, Iso8601::<CONFIG>::USE_SEPARATORS, b":")?; - let minutes = (minutes as f64) - + (seconds as f64) / Second::per(Minute) as f64 - + (nanoseconds as f64) / Nanosecond::per(Minute) as f64; - bytes += format_float(output, minutes, 2, decimal_digits)?; - } - TimePrecision::Second { decimal_digits } => { - bytes += format_number_pad_zero::<2>(output, hours)?; - bytes += write_if(output, Iso8601::<CONFIG>::USE_SEPARATORS, b":")?; - bytes += format_number_pad_zero::<2>(output, minutes)?; - bytes += write_if(output, Iso8601::<CONFIG>::USE_SEPARATORS, b":")?; - let seconds = (seconds as f64) + (nanoseconds as f64) / Nanosecond::per(Second) as f64; - bytes += format_float(output, seconds, 2, decimal_digits)?; - } - } - - Ok(bytes) -} - -/// Format the UTC offset portion of ISO 8601. -pub(super) fn format_offset<const CONFIG: EncodedConfig>( - output: &mut (impl io::Write + ?Sized), - offset: UtcOffset, -) -> Result<usize, error::Format> { - if Iso8601::<CONFIG>::FORMAT_TIME && offset.is_utc() { - return Ok(write(output, b"Z")?); - } - - let mut bytes = 0; - - let (hours, minutes, seconds) = offset.as_hms(); - if seconds != 0 { - return Err(error::Format::InvalidComponent("offset_second")); - } - bytes += write_if_else(output, offset.is_negative(), b"-", b"+")?; - bytes += format_number_pad_zero::<2>(output, hours.unsigned_abs())?; - - if Iso8601::<CONFIG>::OFFSET_PRECISION == OffsetPrecision::Hour && minutes != 0 { - return Err(error::Format::InvalidComponent("offset_minute")); - } else if Iso8601::<CONFIG>::OFFSET_PRECISION == OffsetPrecision::Minute { - bytes += write_if(output, Iso8601::<CONFIG>::USE_SEPARATORS, b":")?; - bytes += format_number_pad_zero::<2>(output, minutes.unsigned_abs())?; - } - - Ok(bytes) -} diff --git a/vendor/time/src/formatting/mod.rs b/vendor/time/src/formatting/mod.rs deleted file mode 100644 index c3837107..00000000 --- a/vendor/time/src/formatting/mod.rs +++ /dev/null @@ -1,517 +0,0 @@ -//! Formatting for various types. - -pub(crate) mod formattable; -mod iso8601; - -use core::num::NonZeroU8; -use std::io; - -use num_conv::prelude::*; - -pub use self::formattable::Formattable; -use crate::convert::*; -use crate::ext::DigitCount; -use crate::format_description::{modifier, Component}; -use crate::{error, Date, OffsetDateTime, Time, UtcOffset}; - -const MONTH_NAMES: [&[u8]; 12] = [ - b"January", - b"February", - b"March", - b"April", - b"May", - b"June", - b"July", - b"August", - b"September", - b"October", - b"November", - b"December", -]; - -const WEEKDAY_NAMES: [&[u8]; 7] = [ - b"Monday", - b"Tuesday", - b"Wednesday", - b"Thursday", - b"Friday", - b"Saturday", - b"Sunday", -]; - -/// Write all bytes to the output, returning the number of bytes written. -pub(crate) fn write(output: &mut (impl io::Write + ?Sized), bytes: &[u8]) -> io::Result<usize> { - output.write_all(bytes)?; - Ok(bytes.len()) -} - -/// If `pred` is true, write all bytes to the output, returning the number of bytes written. -pub(crate) fn write_if( - output: &mut (impl io::Write + ?Sized), - pred: bool, - bytes: &[u8], -) -> io::Result<usize> { - if pred { - write(output, bytes) - } else { - Ok(0) - } -} - -/// If `pred` is true, write `true_bytes` to the output. Otherwise, write `false_bytes`. -pub(crate) fn write_if_else( - output: &mut (impl io::Write + ?Sized), - pred: bool, - true_bytes: &[u8], - false_bytes: &[u8], -) -> io::Result<usize> { - write(output, if pred { true_bytes } else { false_bytes }) -} - -/// Write the floating point number to the output, returning the number of bytes written. -/// -/// This method accepts the number of digits before and after the decimal. The value will be padded -/// with zeroes to the left if necessary. -pub(crate) fn format_float( - output: &mut (impl io::Write + ?Sized), - value: f64, - digits_before_decimal: u8, - digits_after_decimal: Option<NonZeroU8>, -) -> io::Result<usize> { - match digits_after_decimal { - Some(digits_after_decimal) => { - // Truncate the decimal points up to the precision - let trunc_num = 10_f64.powi(digits_after_decimal.get().cast_signed().extend()); - let value = f64::trunc(value * trunc_num) / trunc_num; - - let digits_after_decimal = digits_after_decimal.get().extend(); - let width = digits_before_decimal.extend::<usize>() + 1 + digits_after_decimal; - write!(output, "{value:0>width$.digits_after_decimal$}")?; - Ok(width) - } - None => { - let value = value.trunc() as u64; - let width = digits_before_decimal.extend(); - write!(output, "{value:0>width$}")?; - Ok(width) - } - } -} - -/// Format a number with the provided padding and width. -/// -/// The sign must be written by the caller. -pub(crate) fn format_number<const WIDTH: u8>( - output: &mut (impl io::Write + ?Sized), - value: impl itoa::Integer + DigitCount + Copy, - padding: modifier::Padding, -) -> Result<usize, io::Error> { - match padding { - modifier::Padding::Space => format_number_pad_space::<WIDTH>(output, value), - modifier::Padding::Zero => format_number_pad_zero::<WIDTH>(output, value), - modifier::Padding::None => format_number_pad_none(output, value), - } -} - -/// Format a number with the provided width and spaces as padding. -/// -/// The sign must be written by the caller. -pub(crate) fn format_number_pad_space<const WIDTH: u8>( - output: &mut (impl io::Write + ?Sized), - value: impl itoa::Integer + DigitCount + Copy, -) -> Result<usize, io::Error> { - let mut bytes = 0; - for _ in 0..(WIDTH.saturating_sub(value.num_digits())) { - bytes += write(output, b" ")?; - } - bytes += write(output, itoa::Buffer::new().format(value).as_bytes())?; - Ok(bytes) -} - -/// Format a number with the provided width and zeros as padding. -/// -/// The sign must be written by the caller. -pub(crate) fn format_number_pad_zero<const WIDTH: u8>( - output: &mut (impl io::Write + ?Sized), - value: impl itoa::Integer + DigitCount + Copy, -) -> Result<usize, io::Error> { - let mut bytes = 0; - for _ in 0..(WIDTH.saturating_sub(value.num_digits())) { - bytes += write(output, b"0")?; - } - bytes += write(output, itoa::Buffer::new().format(value).as_bytes())?; - Ok(bytes) -} - -/// Format a number with no padding. -/// -/// If the sign is mandatory, the sign must be written by the caller. -pub(crate) fn format_number_pad_none( - output: &mut (impl io::Write + ?Sized), - value: impl itoa::Integer + Copy, -) -> Result<usize, io::Error> { - write(output, itoa::Buffer::new().format(value).as_bytes()) -} - -/// Format the provided component into the designated output. An `Err` will be returned if the -/// component requires information that it does not provide or if the value cannot be output to the -/// stream. -pub(crate) fn format_component( - output: &mut (impl io::Write + ?Sized), - component: Component, - date: Option<Date>, - time: Option<Time>, - offset: Option<UtcOffset>, -) -> Result<usize, error::Format> { - use Component::*; - Ok(match (component, date, time, offset) { - (Day(modifier), Some(date), ..) => fmt_day(output, date, modifier)?, - (Month(modifier), Some(date), ..) => fmt_month(output, date, modifier)?, - (Ordinal(modifier), Some(date), ..) => fmt_ordinal(output, date, modifier)?, - (Weekday(modifier), Some(date), ..) => fmt_weekday(output, date, modifier)?, - (WeekNumber(modifier), Some(date), ..) => fmt_week_number(output, date, modifier)?, - (Year(modifier), Some(date), ..) => fmt_year(output, date, modifier)?, - (Hour(modifier), _, Some(time), _) => fmt_hour(output, time, modifier)?, - (Minute(modifier), _, Some(time), _) => fmt_minute(output, time, modifier)?, - (Period(modifier), _, Some(time), _) => fmt_period(output, time, modifier)?, - (Second(modifier), _, Some(time), _) => fmt_second(output, time, modifier)?, - (Subsecond(modifier), _, Some(time), _) => fmt_subsecond(output, time, modifier)?, - (OffsetHour(modifier), .., Some(offset)) => fmt_offset_hour(output, offset, modifier)?, - (OffsetMinute(modifier), .., Some(offset)) => fmt_offset_minute(output, offset, modifier)?, - (OffsetSecond(modifier), .., Some(offset)) => fmt_offset_second(output, offset, modifier)?, - (Ignore(_), ..) => 0, - (UnixTimestamp(modifier), Some(date), Some(time), Some(offset)) => { - fmt_unix_timestamp(output, date, time, offset, modifier)? - } - (End(modifier::End {}), ..) => 0, - - // This is functionally the same as a wildcard arm, but it will cause an error if a new - // component is added. This is to avoid a bug where a new component, the code compiles, and - // formatting fails. - // Allow unreachable patterns because some branches may be fully matched above. - #[allow(unreachable_patterns)] - ( - Day(_) | Month(_) | Ordinal(_) | Weekday(_) | WeekNumber(_) | Year(_) | Hour(_) - | Minute(_) | Period(_) | Second(_) | Subsecond(_) | OffsetHour(_) | OffsetMinute(_) - | OffsetSecond(_) | Ignore(_) | UnixTimestamp(_) | End(_), - .., - ) => return Err(error::Format::InsufficientTypeInformation), - }) -} - -/// Format the day into the designated output. -fn fmt_day( - output: &mut (impl io::Write + ?Sized), - date: Date, - modifier::Day { padding }: modifier::Day, -) -> Result<usize, io::Error> { - format_number::<2>(output, date.day(), padding) -} - -/// Format the month into the designated output. -fn fmt_month( - output: &mut (impl io::Write + ?Sized), - date: Date, - modifier::Month { - padding, - repr, - case_sensitive: _, // no effect on formatting - }: modifier::Month, -) -> Result<usize, io::Error> { - match repr { - modifier::MonthRepr::Numerical => { - format_number::<2>(output, u8::from(date.month()), padding) - } - modifier::MonthRepr::Long => write( - output, - MONTH_NAMES[u8::from(date.month()).extend::<usize>() - 1], - ), - modifier::MonthRepr::Short => write( - output, - &MONTH_NAMES[u8::from(date.month()).extend::<usize>() - 1][..3], - ), - } -} - -/// Format the ordinal into the designated output. -fn fmt_ordinal( - output: &mut (impl io::Write + ?Sized), - date: Date, - modifier::Ordinal { padding }: modifier::Ordinal, -) -> Result<usize, io::Error> { - format_number::<3>(output, date.ordinal(), padding) -} - -/// Format the weekday into the designated output. -fn fmt_weekday( - output: &mut (impl io::Write + ?Sized), - date: Date, - modifier::Weekday { - repr, - one_indexed, - case_sensitive: _, // no effect on formatting - }: modifier::Weekday, -) -> Result<usize, io::Error> { - match repr { - modifier::WeekdayRepr::Short => write( - output, - &WEEKDAY_NAMES[date.weekday().number_days_from_monday().extend::<usize>()][..3], - ), - modifier::WeekdayRepr::Long => write( - output, - WEEKDAY_NAMES[date.weekday().number_days_from_monday().extend::<usize>()], - ), - modifier::WeekdayRepr::Sunday => format_number::<1>( - output, - date.weekday().number_days_from_sunday() + u8::from(one_indexed), - modifier::Padding::None, - ), - modifier::WeekdayRepr::Monday => format_number::<1>( - output, - date.weekday().number_days_from_monday() + u8::from(one_indexed), - modifier::Padding::None, - ), - } -} - -/// Format the week number into the designated output. -fn fmt_week_number( - output: &mut (impl io::Write + ?Sized), - date: Date, - modifier::WeekNumber { padding, repr }: modifier::WeekNumber, -) -> Result<usize, io::Error> { - format_number::<2>( - output, - match repr { - modifier::WeekNumberRepr::Iso => date.iso_week(), - modifier::WeekNumberRepr::Sunday => date.sunday_based_week(), - modifier::WeekNumberRepr::Monday => date.monday_based_week(), - }, - padding, - ) -} - -/// Format the year into the designated output. -fn fmt_year( - output: &mut (impl io::Write + ?Sized), - date: Date, - modifier::Year { - padding, - repr, - range, - iso_week_based, - sign_is_mandatory, - }: modifier::Year, -) -> Result<usize, error::Format> { - let full_year = if iso_week_based { - date.iso_year_week().0 - } else { - date.year() - }; - let value = match repr { - modifier::YearRepr::Full => full_year, - modifier::YearRepr::Century => full_year / 100, - modifier::YearRepr::LastTwo => (full_year % 100).abs(), - }; - let format_number = if cfg!(feature = "large-dates") && range == modifier::YearRange::Extended { - match repr { - modifier::YearRepr::Full if value.abs() >= 100_000 => format_number::<6>, - modifier::YearRepr::Full if value.abs() >= 10_000 => format_number::<5>, - modifier::YearRepr::Full => format_number::<4>, - modifier::YearRepr::Century if value.abs() >= 1_000 => format_number::<4>, - modifier::YearRepr::Century if value.abs() >= 100 => format_number::<3>, - modifier::YearRepr::Century => format_number::<2>, - modifier::YearRepr::LastTwo => format_number::<2>, - } - } else { - match repr { - modifier::YearRepr::Full | modifier::YearRepr::Century if full_year.abs() >= 10_000 => { - return Err(error::ComponentRange { - name: "year", - minimum: -9999, - maximum: 9999, - value: full_year.extend(), - conditional_message: Some("when `range:standard` is used"), - } - .into()); - } - _ => {} - } - match repr { - modifier::YearRepr::Full => format_number::<4>, - modifier::YearRepr::Century => format_number::<2>, - modifier::YearRepr::LastTwo => format_number::<2>, - } - }; - let mut bytes = 0; - if repr != modifier::YearRepr::LastTwo { - if full_year < 0 { - bytes += write(output, b"-")?; - } else if sign_is_mandatory || cfg!(feature = "large-dates") && full_year >= 10_000 { - bytes += write(output, b"+")?; - } - } - bytes += format_number(output, value.unsigned_abs(), padding)?; - Ok(bytes) -} - -/// Format the hour into the designated output. -fn fmt_hour( - output: &mut (impl io::Write + ?Sized), - time: Time, - modifier::Hour { - padding, - is_12_hour_clock, - }: modifier::Hour, -) -> Result<usize, io::Error> { - let value = match (time.hour(), is_12_hour_clock) { - (hour, false) => hour, - (0 | 12, true) => 12, - (hour, true) if hour < 12 => hour, - (hour, true) => hour - 12, - }; - format_number::<2>(output, value, padding) -} - -/// Format the minute into the designated output. -fn fmt_minute( - output: &mut (impl io::Write + ?Sized), - time: Time, - modifier::Minute { padding }: modifier::Minute, -) -> Result<usize, io::Error> { - format_number::<2>(output, time.minute(), padding) -} - -/// Format the period into the designated output. -fn fmt_period( - output: &mut (impl io::Write + ?Sized), - time: Time, - modifier::Period { - is_uppercase, - case_sensitive: _, // no effect on formatting - }: modifier::Period, -) -> Result<usize, io::Error> { - match (time.hour() >= 12, is_uppercase) { - (false, false) => write(output, b"am"), - (false, true) => write(output, b"AM"), - (true, false) => write(output, b"pm"), - (true, true) => write(output, b"PM"), - } -} - -/// Format the second into the designated output. -fn fmt_second( - output: &mut (impl io::Write + ?Sized), - time: Time, - modifier::Second { padding }: modifier::Second, -) -> Result<usize, io::Error> { - format_number::<2>(output, time.second(), padding) -} - -/// Format the subsecond into the designated output. -fn fmt_subsecond( - output: &mut (impl io::Write + ?Sized), - time: Time, - modifier::Subsecond { digits }: modifier::Subsecond, -) -> Result<usize, io::Error> { - use modifier::SubsecondDigits::*; - let nanos = time.nanosecond(); - - if digits == Nine || (digits == OneOrMore && nanos % 10 != 0) { - format_number_pad_zero::<9>(output, nanos) - } else if digits == Eight || (digits == OneOrMore && (nanos / 10) % 10 != 0) { - format_number_pad_zero::<8>(output, nanos / 10) - } else if digits == Seven || (digits == OneOrMore && (nanos / 100) % 10 != 0) { - format_number_pad_zero::<7>(output, nanos / 100) - } else if digits == Six || (digits == OneOrMore && (nanos / 1_000) % 10 != 0) { - format_number_pad_zero::<6>(output, nanos / 1_000) - } else if digits == Five || (digits == OneOrMore && (nanos / 10_000) % 10 != 0) { - format_number_pad_zero::<5>(output, nanos / 10_000) - } else if digits == Four || (digits == OneOrMore && (nanos / 100_000) % 10 != 0) { - format_number_pad_zero::<4>(output, nanos / 100_000) - } else if digits == Three || (digits == OneOrMore && (nanos / 1_000_000) % 10 != 0) { - format_number_pad_zero::<3>(output, nanos / 1_000_000) - } else if digits == Two || (digits == OneOrMore && (nanos / 10_000_000) % 10 != 0) { - format_number_pad_zero::<2>(output, nanos / 10_000_000) - } else { - format_number_pad_zero::<1>(output, nanos / 100_000_000) - } -} - -/// Format the offset hour into the designated output. -fn fmt_offset_hour( - output: &mut (impl io::Write + ?Sized), - offset: UtcOffset, - modifier::OffsetHour { - padding, - sign_is_mandatory, - }: modifier::OffsetHour, -) -> Result<usize, io::Error> { - let mut bytes = 0; - if offset.is_negative() { - bytes += write(output, b"-")?; - } else if sign_is_mandatory { - bytes += write(output, b"+")?; - } - bytes += format_number::<2>(output, offset.whole_hours().unsigned_abs(), padding)?; - Ok(bytes) -} - -/// Format the offset minute into the designated output. -fn fmt_offset_minute( - output: &mut (impl io::Write + ?Sized), - offset: UtcOffset, - modifier::OffsetMinute { padding }: modifier::OffsetMinute, -) -> Result<usize, io::Error> { - format_number::<2>(output, offset.minutes_past_hour().unsigned_abs(), padding) -} - -/// Format the offset second into the designated output. -fn fmt_offset_second( - output: &mut (impl io::Write + ?Sized), - offset: UtcOffset, - modifier::OffsetSecond { padding }: modifier::OffsetSecond, -) -> Result<usize, io::Error> { - format_number::<2>(output, offset.seconds_past_minute().unsigned_abs(), padding) -} - -/// Format the Unix timestamp into the designated output. -fn fmt_unix_timestamp( - output: &mut (impl io::Write + ?Sized), - date: Date, - time: Time, - offset: UtcOffset, - modifier::UnixTimestamp { - precision, - sign_is_mandatory, - }: modifier::UnixTimestamp, -) -> Result<usize, io::Error> { - let date_time = OffsetDateTime::new_in_offset(date, time, offset).to_offset(UtcOffset::UTC); - - if date_time < OffsetDateTime::UNIX_EPOCH { - write(output, b"-")?; - } else if sign_is_mandatory { - write(output, b"+")?; - } - - match precision { - modifier::UnixTimestampPrecision::Second => { - format_number_pad_none(output, date_time.unix_timestamp().unsigned_abs()) - } - modifier::UnixTimestampPrecision::Millisecond => format_number_pad_none( - output, - (date_time.unix_timestamp_nanos() - / Nanosecond::per(Millisecond).cast_signed().extend::<i128>()) - .unsigned_abs(), - ), - modifier::UnixTimestampPrecision::Microsecond => format_number_pad_none( - output, - (date_time.unix_timestamp_nanos() - / Nanosecond::per(Microsecond).cast_signed().extend::<i128>()) - .unsigned_abs(), - ), - modifier::UnixTimestampPrecision::Nanosecond => { - format_number_pad_none(output, date_time.unix_timestamp_nanos().unsigned_abs()) - } - } -} diff --git a/vendor/time/src/hint.rs b/vendor/time/src/hint.rs deleted file mode 100644 index ded72d4c..00000000 --- a/vendor/time/src/hint.rs +++ /dev/null @@ -1,26 +0,0 @@ -//! Hints to the compiler that affects how code should be emitted or optimized. - -#![allow(dead_code)] // may be used in the future and has minimal overhead - -/// Indicate that a given branch is **not** likely to be taken, relatively speaking. -#[inline(always)] -#[cold] -pub(crate) const fn cold_path() {} - -/// Indicate that a given condition is likely to be true. -#[inline(always)] -pub(crate) const fn likely(b: bool) -> bool { - if !b { - cold_path(); - } - b -} - -/// Indicate that a given condition is likely to be false. -#[inline(always)] -pub(crate) const fn unlikely(b: bool) -> bool { - if b { - cold_path(); - } - b -} diff --git a/vendor/time/src/instant.rs b/vendor/time/src/instant.rs deleted file mode 100644 index 66264007..00000000 --- a/vendor/time/src/instant.rs +++ /dev/null @@ -1,287 +0,0 @@ -//! The [`Instant`] struct and its associated `impl`s. - -#![allow(deprecated)] - -use core::borrow::Borrow; -use core::cmp::{Ord, Ordering, PartialEq, PartialOrd}; -use core::ops::{Add, Sub}; -use core::time::Duration as StdDuration; -use std::time::Instant as StdInstant; - -use crate::internal_macros::{impl_add_assign, impl_sub_assign}; -use crate::Duration; - -/// A measurement of a monotonically non-decreasing clock. Opaque and useful only with [`Duration`]. -/// -/// Instants are always guaranteed to be no less than any previously measured instant when created, -/// and are often useful for tasks such as measuring benchmarks or timing how long an operation -/// takes. -/// -/// Note, however, that instants are not guaranteed to be **steady**. In other words, each tick of -/// the underlying clock may not be the same length (e.g. some seconds may be longer than others). -/// An instant may jump forwards or experience time dilation (slow down or speed up), but it will -/// never go backwards. -/// -/// Instants are opaque types that can only be compared to one another. There is no method to get -/// "the number of seconds" from an instant. Instead, it only allows measuring the duration between -/// two instants (or comparing two instants). -/// -/// This implementation allows for operations with signed [`Duration`]s, but is otherwise identical -/// to [`std::time::Instant`]. -#[doc(hidden)] -#[deprecated( - since = "0.3.35", - note = "import `std::time::Instant` and `time::ext::InstantExt` instead" -)] -#[repr(transparent)] -#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub struct Instant(pub StdInstant); - -impl Instant { - /// Returns an `Instant` corresponding to "now". - /// - /// ```rust - /// # #![allow(deprecated)] - /// # use time::Instant; - /// println!("{:?}", Instant::now()); - /// ``` - pub fn now() -> Self { - Self(StdInstant::now()) - } - - /// Returns the amount of time elapsed since this instant was created. The duration will always - /// be nonnegative if the instant is not synthetically created. - /// - /// ```rust - /// # #![allow(deprecated)] - /// # use time::{Instant, ext::{NumericalStdDuration, NumericalDuration}}; - /// # use std::thread; - /// let instant = Instant::now(); - /// thread::sleep(1.std_milliseconds()); - /// assert!(instant.elapsed() >= 1.milliseconds()); - /// ``` - pub fn elapsed(self) -> Duration { - Self::now() - self - } - - /// Returns `Some(t)` where `t` is the time `self + duration` if `t` can be represented as - /// `Instant` (which means it's inside the bounds of the underlying data structure), `None` - /// otherwise. - /// - /// ```rust - /// # #![allow(deprecated)] - /// # use time::{Instant, ext::NumericalDuration}; - /// let now = Instant::now(); - /// assert_eq!(now.checked_add(5.seconds()), Some(now + 5.seconds())); - /// assert_eq!(now.checked_add((-5).seconds()), Some(now + (-5).seconds())); - /// ``` - pub fn checked_add(self, duration: Duration) -> Option<Self> { - if duration.is_zero() { - Some(self) - } else if duration.is_positive() { - self.0.checked_add(duration.unsigned_abs()).map(Self) - } else { - debug_assert!(duration.is_negative()); - self.0.checked_sub(duration.unsigned_abs()).map(Self) - } - } - - /// Returns `Some(t)` where `t` is the time `self - duration` if `t` can be represented as - /// `Instant` (which means it's inside the bounds of the underlying data structure), `None` - /// otherwise. - /// - /// ```rust - /// # #![allow(deprecated)] - /// # use time::{Instant, ext::NumericalDuration}; - /// let now = Instant::now(); - /// assert_eq!(now.checked_sub(5.seconds()), Some(now - 5.seconds())); - /// assert_eq!(now.checked_sub((-5).seconds()), Some(now - (-5).seconds())); - /// ``` - pub fn checked_sub(self, duration: Duration) -> Option<Self> { - if duration.is_zero() { - Some(self) - } else if duration.is_positive() { - self.0.checked_sub(duration.unsigned_abs()).map(Self) - } else { - debug_assert!(duration.is_negative()); - self.0.checked_add(duration.unsigned_abs()).map(Self) - } - } - - /// Obtain the inner [`std::time::Instant`]. - /// - /// ```rust - /// # #![allow(deprecated)] - /// # use time::Instant; - /// let now = Instant::now(); - /// assert_eq!(now.into_inner(), now.0); - /// ``` - pub const fn into_inner(self) -> StdInstant { - self.0 - } -} - -impl From<StdInstant> for Instant { - fn from(instant: StdInstant) -> Self { - Self(instant) - } -} - -impl From<Instant> for StdInstant { - fn from(instant: Instant) -> Self { - instant.0 - } -} - -impl Sub for Instant { - type Output = Duration; - - /// # Panics - /// - /// This may panic if an overflow occurs. - fn sub(self, other: Self) -> Self::Output { - match self.0.cmp(&other.0) { - Ordering::Equal => Duration::ZERO, - Ordering::Greater => (self.0 - other.0) - .try_into() - .expect("overflow converting `std::time::Duration` to `time::Duration`"), - Ordering::Less => -Duration::try_from(other.0 - self.0) - .expect("overflow converting `std::time::Duration` to `time::Duration`"), - } - } -} - -impl Sub<StdInstant> for Instant { - type Output = Duration; - - fn sub(self, other: StdInstant) -> Self::Output { - self - Self(other) - } -} - -impl Sub<Instant> for StdInstant { - type Output = Duration; - - fn sub(self, other: Instant) -> Self::Output { - Instant(self) - other - } -} - -impl Add<Duration> for Instant { - type Output = Self; - - /// # Panics - /// - /// This function may panic if the resulting point in time cannot be represented by the - /// underlying data structure. - fn add(self, duration: Duration) -> Self::Output { - if duration.is_positive() { - Self(self.0 + duration.unsigned_abs()) - } else if duration.is_negative() { - #[allow(clippy::unchecked_duration_subtraction)] - Self(self.0 - duration.unsigned_abs()) - } else { - debug_assert!(duration.is_zero()); - self - } - } -} - -impl Add<Duration> for StdInstant { - type Output = Self; - - fn add(self, duration: Duration) -> Self::Output { - (Instant(self) + duration).0 - } -} - -impl Add<StdDuration> for Instant { - type Output = Self; - - fn add(self, duration: StdDuration) -> Self::Output { - Self(self.0 + duration) - } -} - -impl_add_assign!(Instant: Duration, StdDuration); -impl_add_assign!(StdInstant: Duration); - -impl Sub<Duration> for Instant { - type Output = Self; - - /// # Panics - /// - /// This function may panic if the resulting point in time cannot be represented by the - /// underlying data structure. - fn sub(self, duration: Duration) -> Self::Output { - if duration.is_positive() { - #[allow(clippy::unchecked_duration_subtraction)] - Self(self.0 - duration.unsigned_abs()) - } else if duration.is_negative() { - Self(self.0 + duration.unsigned_abs()) - } else { - debug_assert!(duration.is_zero()); - self - } - } -} - -impl Sub<Duration> for StdInstant { - type Output = Self; - - fn sub(self, duration: Duration) -> Self::Output { - (Instant(self) - duration).0 - } -} - -impl Sub<StdDuration> for Instant { - type Output = Self; - - /// # Panics - /// - /// This function may panic if the resulting point in time cannot be represented by the - /// underlying data structure. - fn sub(self, duration: StdDuration) -> Self::Output { - #[allow(clippy::unchecked_duration_subtraction)] - Self(self.0 - duration) - } -} - -impl_sub_assign!(Instant: Duration, StdDuration); -impl_sub_assign!(StdInstant: Duration); - -impl PartialEq<StdInstant> for Instant { - fn eq(&self, rhs: &StdInstant) -> bool { - self.0.eq(rhs) - } -} - -impl PartialEq<Instant> for StdInstant { - fn eq(&self, rhs: &Instant) -> bool { - self.eq(&rhs.0) - } -} - -impl PartialOrd<StdInstant> for Instant { - fn partial_cmp(&self, rhs: &StdInstant) -> Option<Ordering> { - self.0.partial_cmp(rhs) - } -} - -impl PartialOrd<Instant> for StdInstant { - fn partial_cmp(&self, rhs: &Instant) -> Option<Ordering> { - self.partial_cmp(&rhs.0) - } -} - -impl AsRef<StdInstant> for Instant { - fn as_ref(&self) -> &StdInstant { - &self.0 - } -} - -impl Borrow<StdInstant> for Instant { - fn borrow(&self) -> &StdInstant { - &self.0 - } -} diff --git a/vendor/time/src/internal_macros.rs b/vendor/time/src/internal_macros.rs deleted file mode 100644 index 74205ac4..00000000 --- a/vendor/time/src/internal_macros.rs +++ /dev/null @@ -1,209 +0,0 @@ -//! Macros for use within the library. They are not publicly available. - -/// Helper macro for easily implementing `OpAssign`. -macro_rules! __impl_assign { - ($sym:tt $op:ident $fn:ident $target:ty : $($(#[$attr:meta])* $t:ty),+) => {$( - #[allow(unused_qualifications)] - $(#[$attr])* - impl core::ops::$op<$t> for $target { - fn $fn(&mut self, rhs: $t) { - *self = *self $sym rhs; - } - } - )+}; -} - -/// Implement `AddAssign` for the provided types. -macro_rules! impl_add_assign { - ($target:ty : $($(#[$attr:meta])* $t:ty),+ $(,)?) => { - $crate::internal_macros::__impl_assign!( - + AddAssign add_assign $target : $($(#[$attr])* $t),+ - ); - }; -} - -/// Implement `SubAssign` for the provided types. -macro_rules! impl_sub_assign { - ($target:ty : $($(#[$attr:meta])* $t:ty),+ $(,)?) => { - $crate::internal_macros::__impl_assign!( - - SubAssign sub_assign $target : $($(#[$attr])* $t),+ - ); - }; -} - -/// Implement `MulAssign` for the provided types. -macro_rules! impl_mul_assign { - ($target:ty : $($(#[$attr:meta])* $t:ty),+ $(,)?) => { - $crate::internal_macros::__impl_assign!( - * MulAssign mul_assign $target : $($(#[$attr])* $t),+ - ); - }; -} - -/// Implement `DivAssign` for the provided types. -macro_rules! impl_div_assign { - ($target:ty : $($(#[$attr:meta])* $t:ty),+ $(,)?) => { - $crate::internal_macros::__impl_assign!( - / DivAssign div_assign $target : $($(#[$attr])* $t),+ - ); - }; -} - -/// Division of integers, rounding the resulting value towards negative infinity. -macro_rules! div_floor { - ($self:expr, $rhs:expr) => { - match ($self, $rhs) { - (this, rhs) => { - let d = this / rhs; - let r = this % rhs; - - // If the remainder is non-zero, we need to subtract one if the - // signs of self and rhs differ, as this means we rounded upwards - // instead of downwards. We do this branchlessly by creating a mask - // which is all-ones iff the signs differ, and 0 otherwise. Then by - // adding this mask (which corresponds to the signed value -1), we - // get our correction. - let correction = (this ^ rhs) >> ($crate::size_of_val(&this) * 8 - 1); - if r != 0 { - d + correction - } else { - d - } - } - } - }; -} - -/// Cascade an out-of-bounds value. -macro_rules! cascade { - (@ordinal ordinal) => {}; - (@year year) => {}; - - // Cascade an out-of-bounds value from "from" to "to". - ($from:ident in $min:literal.. $max:expr => $to:tt) => { - #[allow(unused_comparisons, unused_assignments)] - let min = $min; - let max = $max; - if $from >= max { - $from -= max - min; - $to += 1; - } else if $from < min { - $from += max - min; - $to -= 1; - } - }; - - // Special case the ordinal-to-year cascade, as it has different behavior. - ($ordinal:ident => $year:ident) => { - // We need to actually capture the idents. Without this, macro hygiene causes errors. - cascade!(@ordinal $ordinal); - cascade!(@year $year); - #[allow(unused_assignments)] - if $ordinal > crate::util::days_in_year($year) as i16 { - $ordinal -= crate::util::days_in_year($year) as i16; - $year += 1; - } else if $ordinal < 1 { - $year -= 1; - $ordinal += crate::util::days_in_year($year) as i16; - } - }; -} - -/// Constructs a ranged integer, returning a `ComponentRange` error if the value is out of range. -macro_rules! ensure_ranged { - ($type:ident : $value:ident) => { - match $type::new($value) { - Some(val) => val, - None => { - #[allow(trivial_numeric_casts)] - return Err(crate::error::ComponentRange { - name: stringify!($value), - minimum: $type::MIN.get() as i64, - maximum: $type::MAX.get() as i64, - value: $value as i64, - conditional_message: None, - }); - } - } - }; - - ($type:ident : $value:ident $(as $as_type:ident)? * $factor:expr) => { - match ($value $(as $as_type)?).checked_mul($factor) { - Some(val) => match $type::new(val) { - Some(val) => val, - None => { - #[allow(trivial_numeric_casts)] - return Err(crate::error::ComponentRange { - name: stringify!($value), - minimum: $type::MIN.get() as i64 / $factor as i64, - maximum: $type::MAX.get() as i64 / $factor as i64, - value: $value as i64, - conditional_message: None, - }); - } - }, - None => { - return Err(crate::error::ComponentRange { - name: stringify!($value), - minimum: $type::MIN.get() as i64 / $factor as i64, - maximum: $type::MAX.get() as i64 / $factor as i64, - value: $value as i64, - conditional_message: None, - }); - } - } - }; -} - -/// Try to unwrap an expression, returning if not possible. -/// -/// This is similar to the `?` operator, but does not perform `.into()`. Because of this, it is -/// usable in `const` contexts. -macro_rules! const_try { - ($e:expr) => { - match $e { - Ok(value) => value, - Err(error) => return Err(error), - } - }; -} - -/// Try to unwrap an expression, returning if not possible. -/// -/// This is similar to the `?` operator, but is usable in `const` contexts. -macro_rules! const_try_opt { - ($e:expr) => { - match $e { - Some(value) => value, - None => return None, - } - }; -} - -/// Try to unwrap an expression, panicking if not possible. -/// -/// This is similar to `$e.expect($message)`, but is usable in `const` contexts. -macro_rules! expect_opt { - ($e:expr, $message:literal) => { - match $e { - Some(value) => value, - None => crate::expect_failed($message), - } - }; -} - -/// `unreachable!()`, but better. -#[cfg(any(feature = "formatting", feature = "parsing"))] -macro_rules! bug { - () => { compile_error!("provide an error message to help fix a possible bug") }; - ($descr:literal $($rest:tt)?) => { - panic!(concat!("internal error: ", $descr) $($rest)?) - } -} - -#[cfg(any(feature = "formatting", feature = "parsing"))] -pub(crate) use bug; -pub(crate) use { - __impl_assign, cascade, const_try, const_try_opt, div_floor, ensure_ranged, expect_opt, - impl_add_assign, impl_div_assign, impl_mul_assign, impl_sub_assign, -}; diff --git a/vendor/time/src/interop/js_sys_date_offsetdatetime.rs b/vendor/time/src/interop/js_sys_date_offsetdatetime.rs deleted file mode 100644 index ecbd601e..00000000 --- a/vendor/time/src/interop/js_sys_date_offsetdatetime.rs +++ /dev/null @@ -1,27 +0,0 @@ -use num_conv::prelude::*; - -use crate::convert::*; -use crate::OffsetDateTime; - -impl From<js_sys::Date> for OffsetDateTime { - /// # Panics - /// - /// This may panic if the timestamp can not be represented. - fn from(js_date: js_sys::Date) -> Self { - // get_time() returns milliseconds - let timestamp_nanos = js_date.get_time() as i128 - * Nanosecond::per(Millisecond).cast_signed().extend::<i128>(); - Self::from_unix_timestamp_nanos(timestamp_nanos) - .expect("invalid timestamp: Timestamp cannot fit in range") - } -} - -impl From<OffsetDateTime> for js_sys::Date { - fn from(datetime: OffsetDateTime) -> Self { - // new Date() takes milliseconds - let timestamp = (datetime.unix_timestamp_nanos() - / Nanosecond::per(Millisecond).cast_signed().extend::<i128>()) - as f64; - Self::new(×tamp.into()) - } -} diff --git a/vendor/time/src/interop/js_sys_date_utcdatetime.rs b/vendor/time/src/interop/js_sys_date_utcdatetime.rs deleted file mode 100644 index e387c684..00000000 --- a/vendor/time/src/interop/js_sys_date_utcdatetime.rs +++ /dev/null @@ -1,26 +0,0 @@ -use num_conv::prelude::*; - -use crate::convert::*; -use crate::UtcDateTime; - -impl From<js_sys::Date> for UtcDateTime { - /// # Panics - /// - /// This may panic if the timestamp can not be represented. - fn from(js_date: js_sys::Date) -> Self { - // get_time() returns milliseconds - let timestamp_nanos = (js_date.get_time() * Nanosecond::per(Millisecond) as f64) as i128; - Self::from_unix_timestamp_nanos(timestamp_nanos) - .expect("invalid timestamp: Timestamp cannot fit in range") - } -} - -impl From<UtcDateTime> for js_sys::Date { - fn from(datetime: UtcDateTime) -> Self { - // new Date() takes milliseconds - let timestamp = (datetime.unix_timestamp_nanos() - / Nanosecond::per(Millisecond).cast_signed().extend::<i128>()) - as f64; - Self::new(×tamp.into()) - } -} diff --git a/vendor/time/src/interop/mod.rs b/vendor/time/src/interop/mod.rs deleted file mode 100644 index d562663c..00000000 --- a/vendor/time/src/interop/mod.rs +++ /dev/null @@ -1,28 +0,0 @@ -//! Comparison, arithmetic, and conversion between various types in `time` and the standard library. -//! -//! Currently, full interoperability is present between [`OffsetDateTime`](crate::OffsetDateTime), -//! [`UtcDateTime`](crate::UtcDateTime), and [`SystemTime`](std::time::SystemTime). Partial -//! interoperability is present with [`js_sys::Date`]. Note that -//! [`PrimitiveDateTime`](crate::PrimitiveDateTime) is not interoperable with any of these types due -//! to the lack of an associated UTC offset. - -// Module names should have the two types sorted in alphabetical order. This avoids any question -// of which type should be the "primary" type in the module name. - -#[cfg(all( - target_family = "wasm", - not(any(target_os = "emscripten", target_os = "wasi")), - feature = "wasm-bindgen" -))] -mod js_sys_date_offsetdatetime; -#[cfg(all( - target_family = "wasm", - not(any(target_os = "emscripten", target_os = "wasi")), - feature = "wasm-bindgen" -))] -mod js_sys_date_utcdatetime; -#[cfg(feature = "std")] -mod offsetdatetime_systemtime; -mod offsetdatetime_utcdatetime; -#[cfg(feature = "std")] -mod utcdatetime_systemtime; diff --git a/vendor/time/src/interop/offsetdatetime_systemtime.rs b/vendor/time/src/interop/offsetdatetime_systemtime.rs deleted file mode 100644 index 21a5d7f1..00000000 --- a/vendor/time/src/interop/offsetdatetime_systemtime.rs +++ /dev/null @@ -1,75 +0,0 @@ -use core::cmp::Ordering; -use core::ops::Sub; -use std::time::SystemTime; - -use crate::{Duration, OffsetDateTime}; - -impl Sub<SystemTime> for OffsetDateTime { - type Output = Duration; - - /// # Panics - /// - /// This may panic if an overflow occurs. - fn sub(self, rhs: SystemTime) -> Self::Output { - self - Self::from(rhs) - } -} - -impl Sub<OffsetDateTime> for SystemTime { - type Output = Duration; - - /// # Panics - /// - /// This may panic if an overflow occurs. - fn sub(self, rhs: OffsetDateTime) -> Self::Output { - OffsetDateTime::from(self) - rhs - } -} - -impl PartialEq<SystemTime> for OffsetDateTime { - fn eq(&self, rhs: &SystemTime) -> bool { - self == &Self::from(*rhs) - } -} - -impl PartialEq<OffsetDateTime> for SystemTime { - fn eq(&self, rhs: &OffsetDateTime) -> bool { - &OffsetDateTime::from(*self) == rhs - } -} - -impl PartialOrd<SystemTime> for OffsetDateTime { - fn partial_cmp(&self, other: &SystemTime) -> Option<Ordering> { - self.partial_cmp(&Self::from(*other)) - } -} - -impl PartialOrd<OffsetDateTime> for SystemTime { - fn partial_cmp(&self, other: &OffsetDateTime) -> Option<Ordering> { - OffsetDateTime::from(*self).partial_cmp(other) - } -} - -impl From<SystemTime> for OffsetDateTime { - fn from(system_time: SystemTime) -> Self { - match system_time.duration_since(SystemTime::UNIX_EPOCH) { - Ok(duration) => Self::UNIX_EPOCH + duration, - Err(err) => Self::UNIX_EPOCH - err.duration(), - } - } -} - -impl From<OffsetDateTime> for SystemTime { - fn from(datetime: OffsetDateTime) -> Self { - let duration = datetime - OffsetDateTime::UNIX_EPOCH; - - if duration.is_zero() { - Self::UNIX_EPOCH - } else if duration.is_positive() { - Self::UNIX_EPOCH + duration.unsigned_abs() - } else { - debug_assert!(duration.is_negative()); - Self::UNIX_EPOCH - duration.unsigned_abs() - } - } -} diff --git a/vendor/time/src/interop/offsetdatetime_utcdatetime.rs b/vendor/time/src/interop/offsetdatetime_utcdatetime.rs deleted file mode 100644 index 34a4887d..00000000 --- a/vendor/time/src/interop/offsetdatetime_utcdatetime.rs +++ /dev/null @@ -1,68 +0,0 @@ -use core::cmp::Ordering; -use core::ops::Sub; - -use crate::{Duration, OffsetDateTime, UtcDateTime}; - -impl Sub<OffsetDateTime> for UtcDateTime { - type Output = Duration; - - /// # Panics - /// - /// This may panic if an overflow occurs. - fn sub(self, rhs: OffsetDateTime) -> Self::Output { - OffsetDateTime::from(self) - rhs - } -} - -impl Sub<UtcDateTime> for OffsetDateTime { - type Output = Duration; - - /// # Panics - /// - /// This may panic if an overflow occurs. - fn sub(self, rhs: UtcDateTime) -> Self::Output { - self - Self::from(rhs) - } -} - -impl PartialEq<OffsetDateTime> for UtcDateTime { - fn eq(&self, other: &OffsetDateTime) -> bool { - OffsetDateTime::from(*self) == *other - } -} - -impl PartialEq<UtcDateTime> for OffsetDateTime { - fn eq(&self, other: &UtcDateTime) -> bool { - *self == Self::from(*other) - } -} - -impl PartialOrd<OffsetDateTime> for UtcDateTime { - fn partial_cmp(&self, other: &OffsetDateTime) -> Option<Ordering> { - OffsetDateTime::from(*self).partial_cmp(other) - } -} - -impl PartialOrd<UtcDateTime> for OffsetDateTime { - fn partial_cmp(&self, other: &UtcDateTime) -> Option<Ordering> { - self.partial_cmp(&Self::from(*other)) - } -} - -impl From<OffsetDateTime> for UtcDateTime { - /// # Panics - /// - /// This may panic if an overflow occurs. - fn from(datetime: OffsetDateTime) -> Self { - datetime.to_utc() - } -} - -impl From<UtcDateTime> for OffsetDateTime { - /// # Panics - /// - /// This may panic if an overflow occurs. - fn from(datetime: UtcDateTime) -> Self { - datetime.as_primitive().assume_utc() - } -} diff --git a/vendor/time/src/interop/utcdatetime_systemtime.rs b/vendor/time/src/interop/utcdatetime_systemtime.rs deleted file mode 100644 index 7cfb44e1..00000000 --- a/vendor/time/src/interop/utcdatetime_systemtime.rs +++ /dev/null @@ -1,75 +0,0 @@ -use core::cmp::Ordering; -use core::ops::Sub; -use std::time::SystemTime; - -use crate::{Duration, UtcDateTime}; - -impl Sub<SystemTime> for UtcDateTime { - type Output = Duration; - - /// # Panics - /// - /// This may panic if an overflow occurs. - fn sub(self, rhs: SystemTime) -> Self::Output { - self - Self::from(rhs) - } -} - -impl Sub<UtcDateTime> for SystemTime { - type Output = Duration; - - /// # Panics - /// - /// This may panic if an overflow occurs. - fn sub(self, rhs: UtcDateTime) -> Self::Output { - UtcDateTime::from(self) - rhs - } -} - -impl PartialEq<SystemTime> for UtcDateTime { - fn eq(&self, rhs: &SystemTime) -> bool { - self == &Self::from(*rhs) - } -} - -impl PartialEq<UtcDateTime> for SystemTime { - fn eq(&self, rhs: &UtcDateTime) -> bool { - &UtcDateTime::from(*self) == rhs - } -} - -impl PartialOrd<SystemTime> for UtcDateTime { - fn partial_cmp(&self, other: &SystemTime) -> Option<Ordering> { - self.partial_cmp(&Self::from(*other)) - } -} - -impl PartialOrd<UtcDateTime> for SystemTime { - fn partial_cmp(&self, other: &UtcDateTime) -> Option<Ordering> { - UtcDateTime::from(*self).partial_cmp(other) - } -} - -impl From<SystemTime> for UtcDateTime { - fn from(system_time: SystemTime) -> Self { - match system_time.duration_since(SystemTime::UNIX_EPOCH) { - Ok(duration) => Self::UNIX_EPOCH + duration, - Err(err) => Self::UNIX_EPOCH - err.duration(), - } - } -} - -impl From<UtcDateTime> for SystemTime { - fn from(datetime: UtcDateTime) -> Self { - let duration = datetime - UtcDateTime::UNIX_EPOCH; - - if duration.is_zero() { - Self::UNIX_EPOCH - } else if duration.is_positive() { - Self::UNIX_EPOCH + duration.unsigned_abs() - } else { - debug_assert!(duration.is_negative()); - Self::UNIX_EPOCH - duration.unsigned_abs() - } - } -} diff --git a/vendor/time/src/lib.rs b/vendor/time/src/lib.rs deleted file mode 100644 index d8765d17..00000000 --- a/vendor/time/src/lib.rs +++ /dev/null @@ -1,153 +0,0 @@ -//! # Feature flags -//! -//! This crate exposes a number of features. These can be enabled or disabled as shown -//! [in Cargo's documentation](https://doc.rust-lang.org/cargo/reference/features.html). Features -//! are _disabled_ by default unless otherwise noted. -//! -//! Reliance on a given feature is always indicated alongside the item definition. -//! -//! - `std` (_enabled by default, implicitly enables `alloc`_) -//! -//! This enables a number of features that depend on the standard library. -//! -//! - `alloc` (_enabled by default via `std`_) -//! -//! Enables a number of features that require the ability to dynamically allocate memory. -//! -//! - `macros` -//! -//! Enables macros that provide compile-time verification of values and intuitive syntax. -//! -//! - `formatting` (_implicitly enables `std`_) -//! -//! Enables formatting of most structs. -//! -//! - `parsing` -//! -//! Enables parsing of most structs. -//! -//! - `local-offset` (_implicitly enables `std`_) -//! -//! This feature enables a number of methods that allow obtaining the system's UTC offset. -//! -//! - `large-dates` -//! -//! By default, only years within the ±9999 range (inclusive) are supported. If you need support -//! for years outside this range, consider enabling this feature; the supported range will be -//! increased to ±999,999. -//! -//! Note that enabling this feature has some costs, as it means forgoing some optimizations. -//! Ambiguities may be introduced when parsing that would not otherwise exist. -//! -//! - `serde` -//! -//! Enables [serde](https://docs.rs/serde) support for all types. -//! -//! - `serde-human-readable` (_implicitly enables `serde`, `formatting`, and `parsing`_) -//! -//! Allows serde representations to use a human-readable format. This is determined by the -//! serializer, not the user. If this feature is not enabled or if the serializer requests a -//! non-human-readable format, a format optimized for binary representation will be used. -//! -//! Libraries should never enable this feature, as the decision of what format to use should be up -//! to the user. -//! -//! - `rand` -//! -//! Enables [rand](https://docs.rs/rand) support for all types. -//! -//! - `quickcheck` (_implicitly enables `alloc`_) -//! -//! Enables [quickcheck](https://docs.rs/quickcheck) support for all types. -//! -//! - `wasm-bindgen` -//! -//! Enables [wasm-bindgen](https://github.com/rustwasm/wasm-bindgen) support for converting -//! [JavaScript dates](https://rustwasm.github.io/wasm-bindgen/api/js_sys/struct.Date.html), as -//! well as obtaining the UTC offset from JavaScript. - -#![doc(html_playground_url = "https://play.rust-lang.org")] -#![cfg_attr(docsrs, feature(doc_auto_cfg, doc_notable_trait))] -#![no_std] -#![doc(html_favicon_url = "https://avatars0.githubusercontent.com/u/55999857")] -#![doc(html_logo_url = "https://avatars0.githubusercontent.com/u/55999857")] -#![doc(test(attr(deny(warnings))))] - -#[allow(unused_extern_crates)] -#[cfg(feature = "alloc")] -extern crate alloc; - -#[cfg(feature = "std")] -extern crate std; - -mod date; -mod duration; -pub mod error; -pub mod ext; -#[cfg(any(feature = "formatting", feature = "parsing"))] -pub mod format_description; -#[cfg(feature = "formatting")] -pub mod formatting; -mod hint; -#[cfg(feature = "std")] -mod instant; -mod internal_macros; -mod interop; -#[cfg(feature = "macros")] -pub mod macros; -mod month; -mod offset_date_time; -#[cfg(feature = "parsing")] -pub mod parsing; -mod primitive_date_time; -#[cfg(feature = "quickcheck")] -mod quickcheck; -#[cfg(feature = "rand")] -mod rand; -#[cfg(feature = "serde")] -pub mod serde; -mod sys; -#[cfg(test)] -mod tests; -mod time; -mod utc_date_time; -mod utc_offset; -pub mod util; -mod weekday; - -pub use time_core::convert; - -pub use crate::date::Date; -pub use crate::duration::Duration; -pub use crate::error::Error; -#[doc(hidden)] -#[cfg(feature = "std")] -#[allow(deprecated)] -pub use crate::instant::Instant; -pub use crate::month::Month; -pub use crate::offset_date_time::OffsetDateTime; -pub use crate::primitive_date_time::PrimitiveDateTime; -pub use crate::time::Time; -pub use crate::utc_date_time::UtcDateTime; -pub use crate::utc_offset::UtcOffset; -pub use crate::weekday::Weekday; - -/// An alias for [`std::result::Result`] with a generic error from the time crate. -pub type Result<T> = core::result::Result<T, Error>; - -/// This is a separate function to reduce the code size of `expect_opt!`. -#[inline(never)] -#[cold] -#[track_caller] -const fn expect_failed(message: &str) -> ! { - panic!("{}", message) -} - -/// Returns the size of the pointed-to value in bytes. -/// -/// This is a `const fn` in the standard library starting in Rust 1.85. When MSRV is at least that, -/// this can be removed. -#[allow(unused_qualifications)] // added to prelude after MSRV -const fn size_of_val<T>(_: &T) -> usize { - core::mem::size_of::<T>() -} diff --git a/vendor/time/src/macros.rs b/vendor/time/src/macros.rs deleted file mode 100644 index e9ca572e..00000000 --- a/vendor/time/src/macros.rs +++ /dev/null @@ -1,149 +0,0 @@ -//! Macros to construct statically known values. - -/// Construct a [`Date`](crate::Date) with a statically known value. -/// -/// The resulting expression can be used in `const` or `static` declarations. -/// -/// Three formats are supported: year-week-weekday, year-ordinal, and year-month-day. -/// -/// ```rust -/// # use time::{Date, Weekday::*, Month, macros::date}; -/// assert_eq!( -/// date!(2020 - W 01 - 3), -/// Date::from_iso_week_date(2020, 1, Wednesday)? -/// ); -/// assert_eq!(date!(2020-001), Date::from_ordinal_date(2020, 1)?); -/// assert_eq!( -/// date!(2020-01-01), -/// Date::from_calendar_date(2020, Month::January, 1)? -/// ); -/// # Ok::<_, time::Error>(()) -/// ``` -pub use time_macros::date; -/// Construct a [`PrimitiveDateTime`] or [`OffsetDateTime`] with a statically known value. -/// -/// The resulting expression can be used in `const` or `static` declarations. -/// -/// The syntax accepted by this macro is the same as [`date!`] and [`time!`], with an optional -/// [`offset!`], all space-separated. If an [`offset!`] is provided, the resulting value will -/// be an [`OffsetDateTime`]; otherwise it will be a [`PrimitiveDateTime`]. -/// -/// [`OffsetDateTime`]: crate::OffsetDateTime -/// [`PrimitiveDateTime`]: crate::PrimitiveDateTime -/// -/// ```rust -/// # use time::{Date, Month, macros::datetime, UtcOffset}; -/// assert_eq!( -/// datetime!(2020-01-01 0:00), -/// Date::from_calendar_date(2020, Month::January, 1)?.midnight() -/// ); -/// assert_eq!( -/// datetime!(2020-01-01 0:00 UTC), -/// Date::from_calendar_date(2020, Month::January, 1)?.midnight().assume_utc() -/// ); -/// assert_eq!( -/// datetime!(2020-01-01 0:00 -1), -/// Date::from_calendar_date(2020, Month::January, 1)?.midnight() -/// .assume_offset(UtcOffset::from_hms(-1, 0, 0)?) -/// ); -/// # Ok::<_, time::Error>(()) -/// ``` -pub use time_macros::datetime; -/// Equivalent of performing [`format_description::parse()`] at compile time. -/// -/// Using the macro instead of the function results in a static slice rather than a -/// [`Vec`](alloc::vec::Vec), such that it can be used in `#![no_alloc]` situations. -/// -/// The resulting expression can be used in `const` or `static` declarations, and implements -/// the sealed traits required for both formatting and parsing. -#[cfg_attr(feature = "alloc", doc = "```rust")] -#[cfg_attr(not(feature = "alloc"), doc = "```rust,ignore")] -/// # use time::{format_description, macros::format_description}; -/// assert_eq!( -/// format_description!("[hour]:[minute]:[second]"), -/// format_description::parse("[hour]:[minute]:[second]")? -/// ); -/// # Ok::<_, time::Error>(()) -/// ``` -/// -/// The syntax accepted by this macro is the same as [`format_description::parse()`], which can -/// be found in [the book](https://time-rs.github.io/book/api/format-description.html). -/// -/// [`format_description::parse()`]: crate::format_description::parse() -#[cfg(any(feature = "formatting", feature = "parsing"))] -pub use time_macros::format_description; -/// Construct a [`UtcOffset`](crate::UtcOffset) with a statically known value. -/// -/// The resulting expression can be used in `const` or `static` declarations. -/// -/// A sign and the hour must be provided; minutes and seconds default to zero. `UTC` (both -/// uppercase and lowercase) is also allowed. -/// -/// ```rust -/// # use time::{UtcOffset, macros::offset}; -/// assert_eq!(offset!(UTC), UtcOffset::from_hms(0, 0, 0)?); -/// assert_eq!(offset!(utc), UtcOffset::from_hms(0, 0, 0)?); -/// assert_eq!(offset!(+0), UtcOffset::from_hms(0, 0, 0)?); -/// assert_eq!(offset!(+1), UtcOffset::from_hms(1, 0, 0)?); -/// assert_eq!(offset!(-1), UtcOffset::from_hms(-1, 0, 0)?); -/// assert_eq!(offset!(+1:30), UtcOffset::from_hms(1, 30, 0)?); -/// assert_eq!(offset!(-1:30), UtcOffset::from_hms(-1, -30, 0)?); -/// assert_eq!(offset!(+1:30:59), UtcOffset::from_hms(1, 30, 59)?); -/// assert_eq!(offset!(-1:30:59), UtcOffset::from_hms(-1, -30, -59)?); -/// assert_eq!(offset!(+23:59:59), UtcOffset::from_hms(23, 59, 59)?); -/// assert_eq!(offset!(-23:59:59), UtcOffset::from_hms(-23, -59, -59)?); -/// # Ok::<_, time::Error>(()) -/// ``` -pub use time_macros::offset; -/// Construct a [`Time`](crate::Time) with a statically known value. -/// -/// The resulting expression can be used in `const` or `static` declarations. -/// -/// Hours and minutes must be provided, while seconds defaults to zero. AM/PM is allowed -/// (either uppercase or lowercase). Any number of subsecond digits may be provided (though any -/// past nine will be discarded). -/// -/// All components are validated at compile-time. An error will be raised if any value is -/// invalid. -/// -/// ```rust -/// # use time::{Time, macros::time}; -/// assert_eq!(time!(0:00), Time::from_hms(0, 0, 0)?); -/// assert_eq!(time!(1:02:03), Time::from_hms(1, 2, 3)?); -/// assert_eq!( -/// time!(1:02:03.004_005_006), -/// Time::from_hms_nano(1, 2, 3, 4_005_006)? -/// ); -/// assert_eq!(time!(12:00 am), Time::from_hms(0, 0, 0)?); -/// assert_eq!(time!(1:02:03 am), Time::from_hms(1, 2, 3)?); -/// assert_eq!( -/// time!(1:02:03.004_005_006 am), -/// Time::from_hms_nano(1, 2, 3, 4_005_006)? -/// ); -/// assert_eq!(time!(12 pm), Time::from_hms(12, 0, 0)?); -/// assert_eq!(time!(12:00 pm), Time::from_hms(12, 0, 0)?); -/// assert_eq!(time!(1:02:03 pm), Time::from_hms(13, 2, 3)?); -/// assert_eq!( -/// time!(1:02:03.004_005_006 pm), -/// Time::from_hms_nano(13, 2, 3, 4_005_006)? -/// ); -/// # Ok::<_, time::Error>(()) -/// ``` -pub use time_macros::time; -/// Construct a [`UtcDateTime`] with a statically known value. -/// -/// The resulting expression can be used in `const` or `static` declarations. -/// -/// The syntax accepted by this macro is the same as a space-separated [`date!`] and [`time!`]. -/// -/// [`UtcDateTime`]: crate::UtcDateTime -/// -/// ```rust -/// # use time::{Date, Month, macros::utc_datetime}; -/// assert_eq!( -/// utc_datetime!(2020-01-01 0:00), -/// Date::from_calendar_date(2020, Month::January, 1)?.midnight().as_utc() -/// ); -/// # Ok::<_, time::Error>(()) -/// ``` -pub use time_macros::utc_datetime; diff --git a/vendor/time/src/month.rs b/vendor/time/src/month.rs deleted file mode 100644 index 18bb091c..00000000 --- a/vendor/time/src/month.rs +++ /dev/null @@ -1,273 +0,0 @@ -//! The `Month` enum and its associated `impl`s. - -use core::fmt; -use core::num::NonZeroU8; -use core::str::FromStr; - -use powerfmt::smart_display::{FormatterOptions, Metadata, SmartDisplay}; - -use self::Month::*; -use crate::{error, util}; - -/// Months of the year. -#[repr(u8)] -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub enum Month { - #[allow(missing_docs)] - January = 1, - #[allow(missing_docs)] - February = 2, - #[allow(missing_docs)] - March = 3, - #[allow(missing_docs)] - April = 4, - #[allow(missing_docs)] - May = 5, - #[allow(missing_docs)] - June = 6, - #[allow(missing_docs)] - July = 7, - #[allow(missing_docs)] - August = 8, - #[allow(missing_docs)] - September = 9, - #[allow(missing_docs)] - October = 10, - #[allow(missing_docs)] - November = 11, - #[allow(missing_docs)] - December = 12, -} - -impl Month { - /// Create a `Month` from its numerical value. - pub(crate) const fn from_number(n: NonZeroU8) -> Result<Self, error::ComponentRange> { - match n.get() { - 1 => Ok(January), - 2 => Ok(February), - 3 => Ok(March), - 4 => Ok(April), - 5 => Ok(May), - 6 => Ok(June), - 7 => Ok(July), - 8 => Ok(August), - 9 => Ok(September), - 10 => Ok(October), - 11 => Ok(November), - 12 => Ok(December), - n => Err(error::ComponentRange { - name: "month", - minimum: 1, - maximum: 12, - value: n as i64, - conditional_message: None, - }), - } - } - - /// Get the number of days in the month of a given year. - /// - /// ```rust - /// # use time::Month; - /// assert_eq!(Month::February.length(2020), 29); - /// ``` - pub const fn length(self, year: i32) -> u8 { - util::days_in_month(self, year) - } - - /// Get the previous month. - /// - /// ```rust - /// # use time::Month; - /// assert_eq!(Month::January.previous(), Month::December); - /// ``` - pub const fn previous(self) -> Self { - match self { - January => December, - February => January, - March => February, - April => March, - May => April, - June => May, - July => June, - August => July, - September => August, - October => September, - November => October, - December => November, - } - } - - /// Get the next month. - /// - /// ```rust - /// # use time::Month; - /// assert_eq!(Month::January.next(), Month::February); - /// ``` - pub const fn next(self) -> Self { - match self { - January => February, - February => March, - March => April, - April => May, - May => June, - June => July, - July => August, - August => September, - September => October, - October => November, - November => December, - December => January, - } - } - - /// Get n-th next month. - /// - /// ```rust - /// # use time::Month; - /// assert_eq!(Month::January.nth_next(4), Month::May); - /// assert_eq!(Month::July.nth_next(9), Month::April); - /// ``` - pub const fn nth_next(self, n: u8) -> Self { - match (self as u8 - 1 + n % 12) % 12 { - 0 => January, - 1 => February, - 2 => March, - 3 => April, - 4 => May, - 5 => June, - 6 => July, - 7 => August, - 8 => September, - 9 => October, - 10 => November, - val => { - debug_assert!(val == 11); - December - } - } - } - - /// Get n-th previous month. - /// - /// ```rust - /// # use time::Month; - /// assert_eq!(Month::January.nth_prev(4), Month::September); - /// assert_eq!(Month::July.nth_prev(9), Month::October); - /// ``` - pub const fn nth_prev(self, n: u8) -> Self { - match self as i8 - 1 - (n % 12) as i8 { - 1 | -11 => February, - 2 | -10 => March, - 3 | -9 => April, - 4 | -8 => May, - 5 | -7 => June, - 6 | -6 => July, - 7 | -5 => August, - 8 | -4 => September, - 9 | -3 => October, - 10 | -2 => November, - 11 | -1 => December, - val => { - debug_assert!(val == 0); - January - } - } - } -} - -mod private { - #[non_exhaustive] - #[derive(Debug, Clone, Copy)] - pub struct MonthMetadata; -} -use private::MonthMetadata; - -impl SmartDisplay for Month { - type Metadata = MonthMetadata; - - fn metadata(&self, _: FormatterOptions) -> Metadata<Self> { - match self { - January => Metadata::new(7, self, MonthMetadata), - February => Metadata::new(8, self, MonthMetadata), - March => Metadata::new(5, self, MonthMetadata), - April => Metadata::new(5, self, MonthMetadata), - May => Metadata::new(3, self, MonthMetadata), - June => Metadata::new(4, self, MonthMetadata), - July => Metadata::new(4, self, MonthMetadata), - August => Metadata::new(6, self, MonthMetadata), - September => Metadata::new(9, self, MonthMetadata), - October => Metadata::new(7, self, MonthMetadata), - November => Metadata::new(8, self, MonthMetadata), - December => Metadata::new(8, self, MonthMetadata), - } - } - - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.pad(match self { - January => "January", - February => "February", - March => "March", - April => "April", - May => "May", - June => "June", - July => "July", - August => "August", - September => "September", - October => "October", - November => "November", - December => "December", - }) - } -} - -impl fmt::Display for Month { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - SmartDisplay::fmt(self, f) - } -} - -impl FromStr for Month { - type Err = error::InvalidVariant; - - fn from_str(s: &str) -> Result<Self, Self::Err> { - match s { - "January" => Ok(January), - "February" => Ok(February), - "March" => Ok(March), - "April" => Ok(April), - "May" => Ok(May), - "June" => Ok(June), - "July" => Ok(July), - "August" => Ok(August), - "September" => Ok(September), - "October" => Ok(October), - "November" => Ok(November), - "December" => Ok(December), - _ => Err(error::InvalidVariant), - } - } -} - -impl From<Month> for u8 { - fn from(month: Month) -> Self { - month as Self - } -} - -impl TryFrom<u8> for Month { - type Error = error::ComponentRange; - - fn try_from(value: u8) -> Result<Self, Self::Error> { - match NonZeroU8::new(value) { - Some(value) => Self::from_number(value), - None => Err(error::ComponentRange { - name: "month", - minimum: 1, - maximum: 12, - value: 0, - conditional_message: None, - }), - } - } -} diff --git a/vendor/time/src/offset_date_time.rs b/vendor/time/src/offset_date_time.rs deleted file mode 100644 index 274fad2b..00000000 --- a/vendor/time/src/offset_date_time.rs +++ /dev/null @@ -1,1511 +0,0 @@ -//! The [`OffsetDateTime`] struct and its associated `impl`s. - -#[cfg(feature = "formatting")] -use alloc::string::String; -use core::cmp::Ordering; -use core::fmt; -use core::hash::Hash; -use core::ops::{Add, AddAssign, Sub, SubAssign}; -use core::time::Duration as StdDuration; -#[cfg(feature = "formatting")] -use std::io; - -use deranged::RangedI64; -use num_conv::prelude::*; -use powerfmt::ext::FormatterExt as _; -use powerfmt::smart_display::{self, FormatterOptions, Metadata, SmartDisplay}; -use time_core::convert::*; - -use crate::date::{MAX_YEAR, MIN_YEAR}; -#[cfg(feature = "formatting")] -use crate::formatting::Formattable; -use crate::internal_macros::{ - cascade, const_try, const_try_opt, div_floor, ensure_ranged, expect_opt, -}; -#[cfg(feature = "parsing")] -use crate::parsing::Parsable; -use crate::{ - error, util, Date, Duration, Month, PrimitiveDateTime, Time, UtcDateTime, UtcOffset, Weekday, -}; - -/// The Julian day of the Unix epoch. -const UNIX_EPOCH_JULIAN_DAY: i32 = OffsetDateTime::UNIX_EPOCH.to_julian_day(); - -/// A [`PrimitiveDateTime`] with a [`UtcOffset`]. -/// -/// All comparisons are performed using the UTC time. -#[derive(Clone, Copy, Eq)] -pub struct OffsetDateTime { - local_date_time: PrimitiveDateTime, - offset: UtcOffset, -} - -impl PartialEq for OffsetDateTime { - fn eq(&self, other: &Self) -> bool { - self.to_offset_raw(UtcOffset::UTC) == other.to_offset_raw(UtcOffset::UTC) - } -} - -impl PartialOrd for OffsetDateTime { - fn partial_cmp(&self, other: &Self) -> Option<Ordering> { - Some(self.cmp(other)) - } -} - -impl Ord for OffsetDateTime { - fn cmp(&self, other: &Self) -> Ordering { - self.to_offset_raw(UtcOffset::UTC) - .cmp(&other.to_offset_raw(UtcOffset::UTC)) - } -} - -impl Hash for OffsetDateTime { - fn hash<H: core::hash::Hasher>(&self, state: &mut H) { - self.to_offset_raw(UtcOffset::UTC).hash(state); - } -} - -impl OffsetDateTime { - /// Midnight, 1 January, 1970 (UTC). - /// - /// ```rust - /// # use time::OffsetDateTime; - /// # use time_macros::datetime; - /// assert_eq!(OffsetDateTime::UNIX_EPOCH, datetime!(1970-01-01 0:00 UTC)); - /// ``` - pub const UNIX_EPOCH: Self = Self::new_in_offset( - // Safety: `ordinal` is not zero. - unsafe { Date::__from_ordinal_date_unchecked(1970, 1) }, - Time::MIDNIGHT, - UtcOffset::UTC, - ); - - /// Create a new `OffsetDateTime` with the current date and time in UTC. - /// - /// ```rust - /// # use time::OffsetDateTime; - /// # use time_macros::offset; - /// assert!(OffsetDateTime::now_utc().year() >= 2019); - /// assert_eq!(OffsetDateTime::now_utc().offset(), offset!(UTC)); - /// ``` - #[cfg(feature = "std")] - pub fn now_utc() -> Self { - #[cfg(all( - target_family = "wasm", - not(any(target_os = "emscripten", target_os = "wasi")), - feature = "wasm-bindgen" - ))] - { - js_sys::Date::new_0().into() - } - - #[cfg(not(all( - target_family = "wasm", - not(any(target_os = "emscripten", target_os = "wasi")), - feature = "wasm-bindgen" - )))] - std::time::SystemTime::now().into() - } - - /// Attempt to create a new `OffsetDateTime` with the current date and time in the local offset. - /// If the offset cannot be determined, an error is returned. - /// - /// ```rust - /// # use time::OffsetDateTime; - /// # if false { - /// assert!(OffsetDateTime::now_local().is_ok()); - /// # } - /// ``` - #[cfg(feature = "local-offset")] - pub fn now_local() -> Result<Self, error::IndeterminateOffset> { - let t = Self::now_utc(); - Ok(t.to_offset(UtcOffset::local_offset_at(t)?)) - } - - /// Create a new `OffsetDateTime` with the given [`Date`], [`Time`], and [`UtcOffset`]. - /// - /// ``` - /// # use time::{Date, Month, OffsetDateTime, Time, UtcOffset}; - /// # use time_macros::datetime; - /// let dt = OffsetDateTime::new_in_offset( - /// Date::from_calendar_date(2024, Month::January, 1)?, - /// Time::from_hms_nano(12, 59, 59, 500_000_000)?, - /// UtcOffset::from_hms(-5, 0, 0)?, - /// ); - /// assert_eq!(dt, datetime!(2024-01-01 12:59:59.5 -5)); - /// # Ok::<_, time::error::Error>(()) - /// ``` - pub const fn new_in_offset(date: Date, time: Time, offset: UtcOffset) -> Self { - Self { - local_date_time: date.with_time(time), - offset, - } - } - - /// Create a new `OffsetDateTime` with the given [`Date`] and [`Time`] in the UTC timezone. - /// - /// ``` - /// # use time::{Date, Month, OffsetDateTime, Time}; - /// # use time_macros::datetime; - /// let dt = OffsetDateTime::new_utc( - /// Date::from_calendar_date(2024, Month::January, 1)?, - /// Time::from_hms_nano(12, 59, 59, 500_000_000)?, - /// ); - /// assert_eq!(dt, datetime!(2024-01-01 12:59:59.5 UTC)); - /// # Ok::<_, time::error::Error>(()) - /// ``` - pub const fn new_utc(date: Date, time: Time) -> Self { - PrimitiveDateTime::new(date, time).assume_utc() - } - - /// Convert the `OffsetDateTime` from the current [`UtcOffset`] to the provided [`UtcOffset`]. - /// - /// ```rust - /// # use time_macros::{datetime, offset}; - /// assert_eq!( - /// datetime!(2000-01-01 0:00 UTC) - /// .to_offset(offset!(-1)) - /// .year(), - /// 1999, - /// ); - /// - /// // Let's see what time Sydney's new year's celebration is in New York and Los Angeles. - /// - /// // Construct midnight on new year's in Sydney. - /// let sydney = datetime!(2000-01-01 0:00 +11); - /// let new_york = sydney.to_offset(offset!(-5)); - /// let los_angeles = sydney.to_offset(offset!(-8)); - /// assert_eq!(sydney.hour(), 0); - /// assert_eq!(new_york.hour(), 8); - /// assert_eq!(los_angeles.hour(), 5); - /// ``` - /// - /// # Panics - /// - /// This method panics if the local date-time in the new offset is outside the supported range. - pub const fn to_offset(self, offset: UtcOffset) -> Self { - expect_opt!( - self.checked_to_offset(offset), - "local datetime out of valid range" - ) - } - - /// Convert the `OffsetDateTime` from the current [`UtcOffset`] to the provided [`UtcOffset`], - /// returning `None` if the date-time in the resulting offset is invalid. - /// - /// ```rust - /// # use time::PrimitiveDateTime; - /// # use time_macros::{datetime, offset}; - /// assert_eq!( - /// datetime!(2000-01-01 0:00 UTC) - /// .checked_to_offset(offset!(-1)) - /// .unwrap() - /// .year(), - /// 1999, - /// ); - /// assert_eq!( - /// PrimitiveDateTime::MAX - /// .assume_utc() - /// .checked_to_offset(offset!(+1)), - /// None, - /// ); - /// ``` - pub const fn checked_to_offset(self, offset: UtcOffset) -> Option<Self> { - if self.offset.whole_hours() == offset.whole_hours() - && self.offset.minutes_past_hour() == offset.minutes_past_hour() - && self.offset.seconds_past_minute() == offset.seconds_past_minute() - { - return Some(self.replace_offset(offset)); - } - - let (year, ordinal, time) = self.to_offset_raw(offset); - - if year > MAX_YEAR || year < MIN_YEAR { - return None; - } - - Some(Self::new_in_offset( - // Safety: `ordinal` is not zero. - unsafe { Date::__from_ordinal_date_unchecked(year, ordinal) }, - time, - offset, - )) - } - - /// Convert the `OffsetDateTime` from the current [`UtcOffset`] to UTC, returning a - /// [`UtcDateTime`]. - /// - /// ```rust - /// # use time_macros::datetime; - /// assert_eq!( - /// datetime!(2000-01-01 0:00 +1) - /// .to_utc() - /// .year(), - /// 1999, - /// ); - /// ``` - /// - /// # Panics - /// - /// This method panics if the UTC date-time is outside the supported range. - pub const fn to_utc(self) -> UtcDateTime { - self.to_offset(UtcOffset::UTC).local_date_time.as_utc() - } - - /// Convert the `OffsetDateTime` from the current [`UtcOffset`] to UTC, returning `None` if the - /// UTC date-time is invalid. Returns a [`UtcDateTime`]. - /// - /// ```rust - /// # use time_macros::datetime; - /// assert_eq!( - /// datetime!(2000-01-01 0:00 +1) - /// .checked_to_utc() - /// .unwrap() - /// .year(), - /// 1999, - /// ); - /// assert_eq!( - #[cfg_attr( - feature = "large-dates", - doc = " datetime!(+999999-12-31 23:59:59 -1).checked_to_utc()," - )] - #[cfg_attr( - not(feature = "large-dates"), - doc = " datetime!(9999-12-31 23:59:59 -1).checked_to_utc()," - )] - /// None, - /// ); - /// ``` - pub const fn checked_to_utc(self) -> Option<UtcDateTime> { - Some( - const_try_opt!(self.checked_to_offset(UtcOffset::UTC)) - .local_date_time - .as_utc(), - ) - } - - /// Equivalent to `.to_offset(UtcOffset::UTC)`, but returning the year, ordinal, and time. This - /// avoids constructing an invalid [`Date`] if the new value is out of range. - pub(crate) const fn to_offset_raw(self, offset: UtcOffset) -> (i32, u16, Time) { - let from = self.offset; - let to = offset; - - // Fast path for when no conversion is necessary. - if from.whole_hours() == to.whole_hours() - && from.minutes_past_hour() == to.minutes_past_hour() - && from.seconds_past_minute() == to.seconds_past_minute() - { - return (self.year(), self.ordinal(), self.time()); - } - - let mut second = self.second() as i16 - from.seconds_past_minute() as i16 - + to.seconds_past_minute() as i16; - let mut minute = - self.minute() as i16 - from.minutes_past_hour() as i16 + to.minutes_past_hour() as i16; - let mut hour = self.hour() as i8 - from.whole_hours() + to.whole_hours(); - let (mut year, ordinal) = self.to_ordinal_date(); - let mut ordinal = ordinal as i16; - - // Cascade the values twice. This is needed because the values are adjusted twice above. - cascade!(second in 0..Second::per(Minute) as i16 => minute); - cascade!(second in 0..Second::per(Minute) as i16 => minute); - cascade!(minute in 0..Minute::per(Hour) as i16 => hour); - cascade!(minute in 0..Minute::per(Hour) as i16 => hour); - cascade!(hour in 0..Hour::per(Day) as i8 => ordinal); - cascade!(hour in 0..Hour::per(Day) as i8 => ordinal); - cascade!(ordinal => year); - - debug_assert!(ordinal > 0); - debug_assert!(ordinal <= util::days_in_year(year) as i16); - - ( - year, - ordinal as u16, - // Safety: The cascades above ensure the values are in range. - unsafe { - Time::__from_hms_nanos_unchecked( - hour as u8, - minute as u8, - second as u8, - self.nanosecond(), - ) - }, - ) - } - - /// Create an `OffsetDateTime` from the provided Unix timestamp. Calling `.offset()` on the - /// resulting value is guaranteed to return UTC. - /// - /// ```rust - /// # use time::OffsetDateTime; - /// # use time_macros::datetime; - /// assert_eq!( - /// OffsetDateTime::from_unix_timestamp(0), - /// Ok(OffsetDateTime::UNIX_EPOCH), - /// ); - /// assert_eq!( - /// OffsetDateTime::from_unix_timestamp(1_546_300_800), - /// Ok(datetime!(2019-01-01 0:00 UTC)), - /// ); - /// ``` - /// - /// If you have a timestamp-nanosecond pair, you can use something along the lines of the - /// following: - /// - /// ```rust - /// # use time::{Duration, OffsetDateTime, ext::NumericalDuration}; - /// let (timestamp, nanos) = (1, 500_000_000); - /// assert_eq!( - /// OffsetDateTime::from_unix_timestamp(timestamp)? + Duration::nanoseconds(nanos), - /// OffsetDateTime::UNIX_EPOCH + 1.5.seconds() - /// ); - /// # Ok::<_, time::Error>(()) - /// ``` - pub const fn from_unix_timestamp(timestamp: i64) -> Result<Self, error::ComponentRange> { - type Timestamp = RangedI64< - { - OffsetDateTime::new_in_offset(Date::MIN, Time::MIDNIGHT, UtcOffset::UTC) - .unix_timestamp() - }, - { - OffsetDateTime::new_in_offset(Date::MAX, Time::MAX, UtcOffset::UTC).unix_timestamp() - }, - >; - ensure_ranged!(Timestamp: timestamp); - - // Use the unchecked method here, as the input validity has already been verified. - // Safety: The Julian day number is in range. - let date = unsafe { - Date::from_julian_day_unchecked( - UNIX_EPOCH_JULIAN_DAY + div_floor!(timestamp, Second::per(Day) as i64) as i32, - ) - }; - - let seconds_within_day = timestamp.rem_euclid(Second::per(Day) as i64); - // Safety: All values are in range. - let time = unsafe { - Time::__from_hms_nanos_unchecked( - (seconds_within_day / Second::per(Hour) as i64) as u8, - ((seconds_within_day % Second::per(Hour) as i64) / Minute::per(Hour) as i64) as u8, - (seconds_within_day % Second::per(Minute) as i64) as u8, - 0, - ) - }; - - Ok(Self::new_in_offset(date, time, UtcOffset::UTC)) - } - - /// Construct an `OffsetDateTime` from the provided Unix timestamp (in nanoseconds). Calling - /// `.offset()` on the resulting value is guaranteed to return UTC. - /// - /// ```rust - /// # use time::OffsetDateTime; - /// # use time_macros::datetime; - /// assert_eq!( - /// OffsetDateTime::from_unix_timestamp_nanos(0), - /// Ok(OffsetDateTime::UNIX_EPOCH), - /// ); - /// assert_eq!( - /// OffsetDateTime::from_unix_timestamp_nanos(1_546_300_800_000_000_000), - /// Ok(datetime!(2019-01-01 0:00 UTC)), - /// ); - /// ``` - pub const fn from_unix_timestamp_nanos(timestamp: i128) -> Result<Self, error::ComponentRange> { - let datetime = const_try!(Self::from_unix_timestamp(div_floor!( - timestamp, - Nanosecond::per(Second) as i128 - ) as i64)); - - Ok(Self::new_in_offset( - datetime.date(), - // Safety: `nanosecond` is in range due to `rem_euclid`. - unsafe { - Time::__from_hms_nanos_unchecked( - datetime.hour(), - datetime.minute(), - datetime.second(), - timestamp.rem_euclid(Nanosecond::per(Second) as i128) as u32, - ) - }, - UtcOffset::UTC, - )) - } - - /// Get the [`UtcOffset`]. - /// - /// ```rust - /// # use time_macros::{datetime, offset}; - /// assert_eq!(datetime!(2019-01-01 0:00 UTC).offset(), offset!(UTC)); - /// assert_eq!(datetime!(2019-01-01 0:00 +1).offset(), offset!(+1)); - /// ``` - pub const fn offset(self) -> UtcOffset { - self.offset - } - - /// Get the [Unix timestamp](https://en.wikipedia.org/wiki/Unix_time). - /// - /// ```rust - /// # use time_macros::datetime; - /// assert_eq!(datetime!(1970-01-01 0:00 UTC).unix_timestamp(), 0); - /// assert_eq!(datetime!(1970-01-01 0:00 -1).unix_timestamp(), 3_600); - /// ``` - pub const fn unix_timestamp(self) -> i64 { - let days = - (self.to_julian_day() as i64 - UNIX_EPOCH_JULIAN_DAY as i64) * Second::per(Day) as i64; - let hours = self.hour() as i64 * Second::per(Hour) as i64; - let minutes = self.minute() as i64 * Second::per(Minute) as i64; - let seconds = self.second() as i64; - let offset_seconds = self.offset.whole_seconds() as i64; - days + hours + minutes + seconds - offset_seconds - } - - /// Get the Unix timestamp in nanoseconds. - /// - /// ```rust - /// use time_macros::datetime; - /// assert_eq!(datetime!(1970-01-01 0:00 UTC).unix_timestamp_nanos(), 0); - /// assert_eq!( - /// datetime!(1970-01-01 0:00 -1).unix_timestamp_nanos(), - /// 3_600_000_000_000, - /// ); - /// ``` - pub const fn unix_timestamp_nanos(self) -> i128 { - self.unix_timestamp() as i128 * Nanosecond::per(Second) as i128 + self.nanosecond() as i128 - } - - /// Get the [`PrimitiveDateTime`] in the stored offset. - pub(crate) const fn date_time(self) -> PrimitiveDateTime { - self.local_date_time - } - - /// Get the [`Date`] in the stored offset. - /// - /// ```rust - /// # use time_macros::{date, datetime, offset}; - /// assert_eq!(datetime!(2019-01-01 0:00 UTC).date(), date!(2019-01-01)); - /// assert_eq!( - /// datetime!(2019-01-01 0:00 UTC) - /// .to_offset(offset!(-1)) - /// .date(), - /// date!(2018-12-31), - /// ); - /// ``` - pub const fn date(self) -> Date { - self.date_time().date() - } - - /// Get the [`Time`] in the stored offset. - /// - /// ```rust - /// # use time_macros::{datetime, offset, time}; - /// assert_eq!(datetime!(2019-01-01 0:00 UTC).time(), time!(0:00)); - /// assert_eq!( - /// datetime!(2019-01-01 0:00 UTC) - /// .to_offset(offset!(-1)) - /// .time(), - /// time!(23:00) - /// ); - /// ``` - pub const fn time(self) -> Time { - self.date_time().time() - } - - /// Get the year of the date in the stored offset. - /// - /// ```rust - /// # use time_macros::{datetime, offset}; - /// assert_eq!(datetime!(2019-01-01 0:00 UTC).year(), 2019); - /// assert_eq!( - /// datetime!(2019-12-31 23:00 UTC) - /// .to_offset(offset!(+1)) - /// .year(), - /// 2020, - /// ); - /// assert_eq!(datetime!(2020-01-01 0:00 UTC).year(), 2020); - /// ``` - pub const fn year(self) -> i32 { - self.date().year() - } - - /// Get the month of the date in the stored offset. - /// - /// ```rust - /// # use time::Month; - /// # use time_macros::{datetime, offset}; - /// assert_eq!(datetime!(2019-01-01 0:00 UTC).month(), Month::January); - /// assert_eq!( - /// datetime!(2019-12-31 23:00 UTC) - /// .to_offset(offset!(+1)) - /// .month(), - /// Month::January, - /// ); - /// ``` - pub const fn month(self) -> Month { - self.date().month() - } - - /// Get the day of the date in the stored offset. - /// - /// The returned value will always be in the range `1..=31`. - /// - /// ```rust - /// # use time_macros::{datetime, offset}; - /// assert_eq!(datetime!(2019-01-01 0:00 UTC).day(), 1); - /// assert_eq!( - /// datetime!(2019-12-31 23:00 UTC) - /// .to_offset(offset!(+1)) - /// .day(), - /// 1, - /// ); - /// ``` - pub const fn day(self) -> u8 { - self.date().day() - } - - /// Get the day of the year of the date in the stored offset. - /// - /// The returned value will always be in the range `1..=366`. - /// - /// ```rust - /// # use time_macros::{datetime, offset}; - /// assert_eq!(datetime!(2019-01-01 0:00 UTC).ordinal(), 1); - /// assert_eq!( - /// datetime!(2019-12-31 23:00 UTC) - /// .to_offset(offset!(+1)) - /// .ordinal(), - /// 1, - /// ); - /// ``` - pub const fn ordinal(self) -> u16 { - self.date().ordinal() - } - - /// Get the ISO week number of the date in the stored offset. - /// - /// The returned value will always be in the range `1..=53`. - /// - /// ```rust - /// # use time_macros::datetime; - /// assert_eq!(datetime!(2019-01-01 0:00 UTC).iso_week(), 1); - /// assert_eq!(datetime!(2020-01-01 0:00 UTC).iso_week(), 1); - /// assert_eq!(datetime!(2020-12-31 0:00 UTC).iso_week(), 53); - /// assert_eq!(datetime!(2021-01-01 0:00 UTC).iso_week(), 53); - /// ``` - pub const fn iso_week(self) -> u8 { - self.date().iso_week() - } - - /// Get the week number where week 1 begins on the first Sunday. - /// - /// The returned value will always be in the range `0..=53`. - /// - /// ```rust - /// # use time_macros::datetime; - /// assert_eq!(datetime!(2019-01-01 0:00 UTC).sunday_based_week(), 0); - /// assert_eq!(datetime!(2020-01-01 0:00 UTC).sunday_based_week(), 0); - /// assert_eq!(datetime!(2020-12-31 0:00 UTC).sunday_based_week(), 52); - /// assert_eq!(datetime!(2021-01-01 0:00 UTC).sunday_based_week(), 0); - /// ``` - pub const fn sunday_based_week(self) -> u8 { - self.date().sunday_based_week() - } - - /// Get the week number where week 1 begins on the first Monday. - /// - /// The returned value will always be in the range `0..=53`. - /// - /// ```rust - /// # use time_macros::datetime; - /// assert_eq!(datetime!(2019-01-01 0:00 UTC).monday_based_week(), 0); - /// assert_eq!(datetime!(2020-01-01 0:00 UTC).monday_based_week(), 0); - /// assert_eq!(datetime!(2020-12-31 0:00 UTC).monday_based_week(), 52); - /// assert_eq!(datetime!(2021-01-01 0:00 UTC).monday_based_week(), 0); - /// ``` - pub const fn monday_based_week(self) -> u8 { - self.date().monday_based_week() - } - - /// Get the year, month, and day. - /// - /// ```rust - /// # use time::Month; - /// # use time_macros::datetime; - /// assert_eq!( - /// datetime!(2019-01-01 0:00 UTC).to_calendar_date(), - /// (2019, Month::January, 1) - /// ); - /// ``` - pub const fn to_calendar_date(self) -> (i32, Month, u8) { - self.date().to_calendar_date() - } - - /// Get the year and ordinal day number. - /// - /// ```rust - /// # use time_macros::datetime; - /// assert_eq!( - /// datetime!(2019-01-01 0:00 UTC).to_ordinal_date(), - /// (2019, 1) - /// ); - /// ``` - pub const fn to_ordinal_date(self) -> (i32, u16) { - self.date().to_ordinal_date() - } - - /// Get the ISO 8601 year, week number, and weekday. - /// - /// ```rust - /// # use time::Weekday::*; - /// # use time_macros::datetime; - /// assert_eq!( - /// datetime!(2019-01-01 0:00 UTC).to_iso_week_date(), - /// (2019, 1, Tuesday) - /// ); - /// assert_eq!( - /// datetime!(2019-10-04 0:00 UTC).to_iso_week_date(), - /// (2019, 40, Friday) - /// ); - /// assert_eq!( - /// datetime!(2020-01-01 0:00 UTC).to_iso_week_date(), - /// (2020, 1, Wednesday) - /// ); - /// assert_eq!( - /// datetime!(2020-12-31 0:00 UTC).to_iso_week_date(), - /// (2020, 53, Thursday) - /// ); - /// assert_eq!( - /// datetime!(2021-01-01 0:00 UTC).to_iso_week_date(), - /// (2020, 53, Friday) - /// ); - /// ``` - pub const fn to_iso_week_date(self) -> (i32, u8, Weekday) { - self.date().to_iso_week_date() - } - - /// Get the weekday of the date in the stored offset. - /// - /// ```rust - /// # use time::Weekday::*; - /// # use time_macros::datetime; - /// assert_eq!(datetime!(2019-01-01 0:00 UTC).weekday(), Tuesday); - /// assert_eq!(datetime!(2019-02-01 0:00 UTC).weekday(), Friday); - /// assert_eq!(datetime!(2019-03-01 0:00 UTC).weekday(), Friday); - /// ``` - pub const fn weekday(self) -> Weekday { - self.date().weekday() - } - - /// Get the Julian day for the date. The time is not taken into account for this calculation. - /// - /// The algorithm to perform this conversion is derived from one provided by Peter Baum; it is - /// freely available [here](https://www.researchgate.net/publication/316558298_Date_Algorithms). - /// - /// ```rust - /// # use time_macros::datetime; - /// assert_eq!(datetime!(-4713-11-24 0:00 UTC).to_julian_day(), 0); - /// assert_eq!(datetime!(2000-01-01 0:00 UTC).to_julian_day(), 2_451_545); - /// assert_eq!(datetime!(2019-01-01 0:00 UTC).to_julian_day(), 2_458_485); - /// assert_eq!(datetime!(2019-12-31 0:00 UTC).to_julian_day(), 2_458_849); - /// ``` - pub const fn to_julian_day(self) -> i32 { - self.date().to_julian_day() - } - - /// Get the clock hour, minute, and second. - /// - /// ```rust - /// # use time_macros::datetime; - /// assert_eq!(datetime!(2020-01-01 0:00:00 UTC).to_hms(), (0, 0, 0)); - /// assert_eq!(datetime!(2020-01-01 23:59:59 UTC).to_hms(), (23, 59, 59)); - /// ``` - pub const fn to_hms(self) -> (u8, u8, u8) { - self.time().as_hms() - } - - /// Get the clock hour, minute, second, and millisecond. - /// - /// ```rust - /// # use time_macros::datetime; - /// assert_eq!( - /// datetime!(2020-01-01 0:00:00 UTC).to_hms_milli(), - /// (0, 0, 0, 0) - /// ); - /// assert_eq!( - /// datetime!(2020-01-01 23:59:59.999 UTC).to_hms_milli(), - /// (23, 59, 59, 999) - /// ); - /// ``` - pub const fn to_hms_milli(self) -> (u8, u8, u8, u16) { - self.time().as_hms_milli() - } - - /// Get the clock hour, minute, second, and microsecond. - /// - /// ```rust - /// # use time_macros::datetime; - /// assert_eq!( - /// datetime!(2020-01-01 0:00:00 UTC).to_hms_micro(), - /// (0, 0, 0, 0) - /// ); - /// assert_eq!( - /// datetime!(2020-01-01 23:59:59.999_999 UTC).to_hms_micro(), - /// (23, 59, 59, 999_999) - /// ); - /// ``` - pub const fn to_hms_micro(self) -> (u8, u8, u8, u32) { - self.time().as_hms_micro() - } - - /// Get the clock hour, minute, second, and nanosecond. - /// - /// ```rust - /// # use time_macros::datetime; - /// assert_eq!( - /// datetime!(2020-01-01 0:00:00 UTC).to_hms_nano(), - /// (0, 0, 0, 0) - /// ); - /// assert_eq!( - /// datetime!(2020-01-01 23:59:59.999_999_999 UTC).to_hms_nano(), - /// (23, 59, 59, 999_999_999) - /// ); - /// ``` - pub const fn to_hms_nano(self) -> (u8, u8, u8, u32) { - self.time().as_hms_nano() - } - - /// Get the clock hour in the stored offset. - /// - /// The returned value will always be in the range `0..24`. - /// - /// ```rust - /// # use time_macros::{datetime, offset}; - /// assert_eq!(datetime!(2019-01-01 0:00 UTC).hour(), 0); - /// assert_eq!( - /// datetime!(2019-01-01 23:59:59 UTC) - /// .to_offset(offset!(-2)) - /// .hour(), - /// 21, - /// ); - /// ``` - pub const fn hour(self) -> u8 { - self.time().hour() - } - - /// Get the minute within the hour in the stored offset. - /// - /// The returned value will always be in the range `0..60`. - /// - /// ```rust - /// # use time_macros::{datetime, offset}; - /// assert_eq!(datetime!(2019-01-01 0:00 UTC).minute(), 0); - /// assert_eq!( - /// datetime!(2019-01-01 23:59:59 UTC) - /// .to_offset(offset!(+0:30)) - /// .minute(), - /// 29, - /// ); - /// ``` - pub const fn minute(self) -> u8 { - self.time().minute() - } - - /// Get the second within the minute in the stored offset. - /// - /// The returned value will always be in the range `0..60`. - /// - /// ```rust - /// # use time_macros::{datetime, offset}; - /// assert_eq!(datetime!(2019-01-01 0:00 UTC).second(), 0); - /// assert_eq!( - /// datetime!(2019-01-01 23:59:59 UTC) - /// .to_offset(offset!(+0:00:30)) - /// .second(), - /// 29, - /// ); - /// ``` - pub const fn second(self) -> u8 { - self.time().second() - } - - // Because a `UtcOffset` is limited in resolution to one second, any subsecond value will not - // change when adjusting for the offset. - - /// Get the milliseconds within the second in the stored offset. - /// - /// The returned value will always be in the range `0..1_000`. - /// - /// ```rust - /// # use time_macros::datetime; - /// assert_eq!(datetime!(2019-01-01 0:00 UTC).millisecond(), 0); - /// assert_eq!(datetime!(2019-01-01 23:59:59.999 UTC).millisecond(), 999); - /// ``` - pub const fn millisecond(self) -> u16 { - self.time().millisecond() - } - - /// Get the microseconds within the second in the stored offset. - /// - /// The returned value will always be in the range `0..1_000_000`. - /// - /// ```rust - /// # use time_macros::datetime; - /// assert_eq!(datetime!(2019-01-01 0:00 UTC).microsecond(), 0); - /// assert_eq!( - /// datetime!(2019-01-01 23:59:59.999_999 UTC).microsecond(), - /// 999_999, - /// ); - /// ``` - pub const fn microsecond(self) -> u32 { - self.time().microsecond() - } - - /// Get the nanoseconds within the second in the stored offset. - /// - /// The returned value will always be in the range `0..1_000_000_000`. - /// - /// ```rust - /// # use time_macros::datetime; - /// assert_eq!(datetime!(2019-01-01 0:00 UTC).nanosecond(), 0); - /// assert_eq!( - /// datetime!(2019-01-01 23:59:59.999_999_999 UTC).nanosecond(), - /// 999_999_999, - /// ); - /// ``` - pub const fn nanosecond(self) -> u32 { - self.time().nanosecond() - } - - /// Computes `self + duration`, returning `None` if an overflow occurred. - /// - /// ``` - /// # use time::{Date, ext::NumericalDuration}; - /// # use time_macros::{datetime, offset}; - /// let datetime = Date::MIN.midnight().assume_offset(offset!(+10)); - /// assert_eq!(datetime.checked_add((-2).days()), None); - /// - /// let datetime = Date::MAX.midnight().assume_offset(offset!(+10)); - /// assert_eq!(datetime.checked_add(2.days()), None); - /// - /// assert_eq!( - /// datetime!(2019-11-25 15:30 +10).checked_add(27.hours()), - /// Some(datetime!(2019-11-26 18:30 +10)) - /// ); - /// ``` - pub const fn checked_add(self, duration: Duration) -> Option<Self> { - Some(const_try_opt!(self.date_time().checked_add(duration)).assume_offset(self.offset())) - } - - /// Computes `self - duration`, returning `None` if an overflow occurred. - /// - /// ``` - /// # use time::{Date, ext::NumericalDuration}; - /// # use time_macros::{datetime, offset}; - /// let datetime = Date::MIN.midnight().assume_offset(offset!(+10)); - /// assert_eq!(datetime.checked_sub(2.days()), None); - /// - /// let datetime = Date::MAX.midnight().assume_offset(offset!(+10)); - /// assert_eq!(datetime.checked_sub((-2).days()), None); - /// - /// assert_eq!( - /// datetime!(2019-11-25 15:30 +10).checked_sub(27.hours()), - /// Some(datetime!(2019-11-24 12:30 +10)) - /// ); - /// ``` - pub const fn checked_sub(self, duration: Duration) -> Option<Self> { - Some(const_try_opt!(self.date_time().checked_sub(duration)).assume_offset(self.offset())) - } - - /// Computes `self + duration`, saturating value on overflow. - /// - /// ``` - /// # use time::ext::NumericalDuration; - /// # use time_macros::datetime; - /// assert_eq!( - #[cfg_attr( - feature = "large-dates", - doc = " datetime!(-999999-01-01 0:00 +10).saturating_add((-2).days())," - )] - #[cfg_attr(feature = "large-dates", doc = " datetime!(-999999-01-01 0:00 +10)")] - #[cfg_attr( - not(feature = "large-dates"), - doc = " datetime!(-9999-01-01 0:00 +10).saturating_add((-2).days())," - )] - #[cfg_attr( - not(feature = "large-dates"), - doc = " datetime!(-9999-01-01 0:00 +10)" - )] - /// ); - /// - /// assert_eq!( - #[cfg_attr( - feature = "large-dates", - doc = " datetime!(+999999-12-31 23:59:59.999_999_999 +10).saturating_add(2.days())," - )] - #[cfg_attr( - feature = "large-dates", - doc = " datetime!(+999999-12-31 23:59:59.999_999_999 +10)" - )] - #[cfg_attr( - not(feature = "large-dates"), - doc = " datetime!(+9999-12-31 23:59:59.999_999_999 +10).saturating_add(2.days())," - )] - #[cfg_attr( - not(feature = "large-dates"), - doc = " datetime!(+9999-12-31 23:59:59.999_999_999 +10)" - )] - /// ); - /// - /// assert_eq!( - /// datetime!(2019-11-25 15:30 +10).saturating_add(27.hours()), - /// datetime!(2019-11-26 18:30 +10) - /// ); - /// ``` - pub const fn saturating_add(self, duration: Duration) -> Self { - if let Some(datetime) = self.checked_add(duration) { - datetime - } else if duration.is_negative() { - PrimitiveDateTime::MIN.assume_offset(self.offset()) - } else { - PrimitiveDateTime::MAX.assume_offset(self.offset()) - } - } - - /// Computes `self - duration`, saturating value on overflow. - /// - /// ``` - /// # use time::ext::NumericalDuration; - /// # use time_macros::datetime; - /// assert_eq!( - #[cfg_attr( - feature = "large-dates", - doc = " datetime!(-999999-01-01 0:00 +10).saturating_sub(2.days())," - )] - #[cfg_attr(feature = "large-dates", doc = " datetime!(-999999-01-01 0:00 +10)")] - #[cfg_attr( - not(feature = "large-dates"), - doc = " datetime!(-9999-01-01 0:00 +10).saturating_sub(2.days())," - )] - #[cfg_attr( - not(feature = "large-dates"), - doc = " datetime!(-9999-01-01 0:00 +10)" - )] - /// ); - /// - /// assert_eq!( - #[cfg_attr( - feature = "large-dates", - doc = " datetime!(+999999-12-31 23:59:59.999_999_999 +10).saturating_sub((-2).days())," - )] - #[cfg_attr( - feature = "large-dates", - doc = " datetime!(+999999-12-31 23:59:59.999_999_999 +10)" - )] - #[cfg_attr( - not(feature = "large-dates"), - doc = " datetime!(+9999-12-31 23:59:59.999_999_999 +10).saturating_sub((-2).days())," - )] - #[cfg_attr( - not(feature = "large-dates"), - doc = " datetime!(+9999-12-31 23:59:59.999_999_999 +10)" - )] - /// ); - /// - /// assert_eq!( - /// datetime!(2019-11-25 15:30 +10).saturating_sub(27.hours()), - /// datetime!(2019-11-24 12:30 +10) - /// ); - /// ``` - pub const fn saturating_sub(self, duration: Duration) -> Self { - if let Some(datetime) = self.checked_sub(duration) { - datetime - } else if duration.is_negative() { - PrimitiveDateTime::MAX.assume_offset(self.offset()) - } else { - PrimitiveDateTime::MIN.assume_offset(self.offset()) - } - } -} - -/// Methods that replace part of the `OffsetDateTime`. -impl OffsetDateTime { - /// Replace the time, which is assumed to be in the stored offset. The date and offset - /// components are unchanged. - /// - /// ```rust - /// # use time_macros::{datetime, time}; - /// assert_eq!( - /// datetime!(2020-01-01 5:00 UTC).replace_time(time!(12:00)), - /// datetime!(2020-01-01 12:00 UTC) - /// ); - /// assert_eq!( - /// datetime!(2020-01-01 12:00 -5).replace_time(time!(7:00)), - /// datetime!(2020-01-01 7:00 -5) - /// ); - /// assert_eq!( - /// datetime!(2020-01-01 0:00 +1).replace_time(time!(12:00)), - /// datetime!(2020-01-01 12:00 +1) - /// ); - /// ``` - #[must_use = "This method does not mutate the original `OffsetDateTime`."] - pub const fn replace_time(self, time: Time) -> Self { - Self::new_in_offset(self.date(), time, self.offset()) - } - - /// Replace the date, which is assumed to be in the stored offset. The time and offset - /// components are unchanged. - /// - /// ```rust - /// # use time_macros::{datetime, date}; - /// assert_eq!( - /// datetime!(2020-01-01 12:00 UTC).replace_date(date!(2020-01-30)), - /// datetime!(2020-01-30 12:00 UTC) - /// ); - /// assert_eq!( - /// datetime!(2020-01-01 0:00 +1).replace_date(date!(2020-01-30)), - /// datetime!(2020-01-30 0:00 +1) - /// ); - /// ``` - #[must_use = "This method does not mutate the original `OffsetDateTime`."] - pub const fn replace_date(self, date: Date) -> Self { - Self::new_in_offset(date, self.time(), self.offset()) - } - - /// Replace the date and time, which are assumed to be in the stored offset. The offset - /// component remains unchanged. - /// - /// ```rust - /// # use time_macros::datetime; - /// assert_eq!( - /// datetime!(2020-01-01 12:00 UTC).replace_date_time(datetime!(2020-01-30 16:00)), - /// datetime!(2020-01-30 16:00 UTC) - /// ); - /// assert_eq!( - /// datetime!(2020-01-01 12:00 +1).replace_date_time(datetime!(2020-01-30 0:00)), - /// datetime!(2020-01-30 0:00 +1) - /// ); - /// ``` - #[must_use = "This method does not mutate the original `OffsetDateTime`."] - pub const fn replace_date_time(self, date_time: PrimitiveDateTime) -> Self { - date_time.assume_offset(self.offset()) - } - - /// Replace the offset. The date and time components remain unchanged. - /// - /// ```rust - /// # use time_macros::{datetime, offset}; - /// assert_eq!( - /// datetime!(2020-01-01 0:00 UTC).replace_offset(offset!(-5)), - /// datetime!(2020-01-01 0:00 -5) - /// ); - /// ``` - #[must_use = "This method does not mutate the original `OffsetDateTime`."] - pub const fn replace_offset(self, offset: UtcOffset) -> Self { - self.date_time().assume_offset(offset) - } - - /// Replace the year. The month and day will be unchanged. - /// - /// ```rust - /// # use time_macros::datetime; - /// assert_eq!( - /// datetime!(2022-02-18 12:00 +01).replace_year(2019), - /// Ok(datetime!(2019-02-18 12:00 +01)) - /// ); - /// assert!(datetime!(2022-02-18 12:00 +01).replace_year(-1_000_000_000).is_err()); // -1_000_000_000 isn't a valid year - /// assert!(datetime!(2022-02-18 12:00 +01).replace_year(1_000_000_000).is_err()); // 1_000_000_000 isn't a valid year - /// ``` - #[must_use = "This method does not mutate the original `OffsetDateTime`."] - pub const fn replace_year(self, year: i32) -> Result<Self, error::ComponentRange> { - Ok(const_try!(self.date_time().replace_year(year)).assume_offset(self.offset())) - } - - /// Replace the month of the year. - /// - /// ```rust - /// # use time_macros::datetime; - /// # use time::Month; - /// assert_eq!( - /// datetime!(2022-02-18 12:00 +01).replace_month(Month::January), - /// Ok(datetime!(2022-01-18 12:00 +01)) - /// ); - /// assert!(datetime!(2022-01-30 12:00 +01).replace_month(Month::February).is_err()); // 30 isn't a valid day in February - /// ``` - #[must_use = "This method does not mutate the original `OffsetDateTime`."] - pub const fn replace_month(self, month: Month) -> Result<Self, error::ComponentRange> { - Ok(const_try!(self.date_time().replace_month(month)).assume_offset(self.offset())) - } - - /// Replace the day of the month. - /// - /// ```rust - /// # use time_macros::datetime; - /// assert_eq!( - /// datetime!(2022-02-18 12:00 +01).replace_day(1), - /// Ok(datetime!(2022-02-01 12:00 +01)) - /// ); - /// assert!(datetime!(2022-02-18 12:00 +01).replace_day(0).is_err()); // 00 isn't a valid day - /// assert!(datetime!(2022-02-18 12:00 +01).replace_day(30).is_err()); // 30 isn't a valid day in February - /// ``` - #[must_use = "This method does not mutate the original `OffsetDateTime`."] - pub const fn replace_day(self, day: u8) -> Result<Self, error::ComponentRange> { - Ok(const_try!(self.date_time().replace_day(day)).assume_offset(self.offset())) - } - - /// Replace the day of the year. - /// - /// ```rust - /// # use time_macros::datetime; - /// assert_eq!(datetime!(2022-049 12:00 +01).replace_ordinal(1), Ok(datetime!(2022-001 12:00 +01))); - /// assert!(datetime!(2022-049 12:00 +01).replace_ordinal(0).is_err()); // 0 isn't a valid ordinal - /// assert!(datetime!(2022-049 12:00 +01).replace_ordinal(366).is_err()); // 2022 isn't a leap year - /// ``` - #[must_use = "This method does not mutate the original `OffsetDateTime`."] - pub const fn replace_ordinal(self, ordinal: u16) -> Result<Self, error::ComponentRange> { - Ok(const_try!(self.date_time().replace_ordinal(ordinal)).assume_offset(self.offset())) - } - - /// Replace the clock hour. - /// - /// ```rust - /// # use time_macros::datetime; - /// assert_eq!( - /// datetime!(2022-02-18 01:02:03.004_005_006 +01).replace_hour(7), - /// Ok(datetime!(2022-02-18 07:02:03.004_005_006 +01)) - /// ); - /// assert!(datetime!(2022-02-18 01:02:03.004_005_006 +01).replace_hour(24).is_err()); // 24 isn't a valid hour - /// ``` - #[must_use = "This method does not mutate the original `OffsetDateTime`."] - pub const fn replace_hour(self, hour: u8) -> Result<Self, error::ComponentRange> { - Ok(const_try!(self.date_time().replace_hour(hour)).assume_offset(self.offset())) - } - - /// Replace the minutes within the hour. - /// - /// ```rust - /// # use time_macros::datetime; - /// assert_eq!( - /// datetime!(2022-02-18 01:02:03.004_005_006 +01).replace_minute(7), - /// Ok(datetime!(2022-02-18 01:07:03.004_005_006 +01)) - /// ); - /// assert!(datetime!(2022-02-18 01:02:03.004_005_006 +01).replace_minute(60).is_err()); // 60 isn't a valid minute - /// ``` - #[must_use = "This method does not mutate the original `OffsetDateTime`."] - pub const fn replace_minute(self, minute: u8) -> Result<Self, error::ComponentRange> { - Ok(const_try!(self.date_time().replace_minute(minute)).assume_offset(self.offset())) - } - - /// Replace the seconds within the minute. - /// - /// ```rust - /// # use time_macros::datetime; - /// assert_eq!( - /// datetime!(2022-02-18 01:02:03.004_005_006 +01).replace_second(7), - /// Ok(datetime!(2022-02-18 01:02:07.004_005_006 +01)) - /// ); - /// assert!(datetime!(2022-02-18 01:02:03.004_005_006 +01).replace_second(60).is_err()); // 60 isn't a valid second - /// ``` - #[must_use = "This method does not mutate the original `OffsetDateTime`."] - pub const fn replace_second(self, second: u8) -> Result<Self, error::ComponentRange> { - Ok(const_try!(self.date_time().replace_second(second)).assume_offset(self.offset())) - } - - /// Replace the milliseconds within the second. - /// - /// ```rust - /// # use time_macros::datetime; - /// assert_eq!( - /// datetime!(2022-02-18 01:02:03.004_005_006 +01).replace_millisecond(7), - /// Ok(datetime!(2022-02-18 01:02:03.007 +01)) - /// ); - /// assert!(datetime!(2022-02-18 01:02:03.004_005_006 +01).replace_millisecond(1_000).is_err()); // 1_000 isn't a valid millisecond - /// ``` - #[must_use = "This method does not mutate the original `OffsetDateTime`."] - pub const fn replace_millisecond( - self, - millisecond: u16, - ) -> Result<Self, error::ComponentRange> { - Ok( - const_try!(self.date_time().replace_millisecond(millisecond)) - .assume_offset(self.offset()), - ) - } - - /// Replace the microseconds within the second. - /// - /// ```rust - /// # use time_macros::datetime; - /// assert_eq!( - /// datetime!(2022-02-18 01:02:03.004_005_006 +01).replace_microsecond(7_008), - /// Ok(datetime!(2022-02-18 01:02:03.007_008 +01)) - /// ); - /// assert!(datetime!(2022-02-18 01:02:03.004_005_006 +01).replace_microsecond(1_000_000).is_err()); // 1_000_000 isn't a valid microsecond - /// ``` - #[must_use = "This method does not mutate the original `OffsetDateTime`."] - pub const fn replace_microsecond( - self, - microsecond: u32, - ) -> Result<Self, error::ComponentRange> { - Ok( - const_try!(self.date_time().replace_microsecond(microsecond)) - .assume_offset(self.offset()), - ) - } - - /// Replace the nanoseconds within the second. - /// - /// ```rust - /// # use time_macros::datetime; - /// assert_eq!( - /// datetime!(2022-02-18 01:02:03.004_005_006 +01).replace_nanosecond(7_008_009), - /// Ok(datetime!(2022-02-18 01:02:03.007_008_009 +01)) - /// ); - /// assert!(datetime!(2022-02-18 01:02:03.004_005_006 +01).replace_nanosecond(1_000_000_000).is_err()); // 1_000_000_000 isn't a valid nanosecond - /// ``` - #[must_use = "This method does not mutate the original `OffsetDateTime`."] - pub const fn replace_nanosecond(self, nanosecond: u32) -> Result<Self, error::ComponentRange> { - Ok( - const_try!(self.date_time().replace_nanosecond(nanosecond)) - .assume_offset(self.offset()), - ) - } -} - -#[cfg(feature = "formatting")] -impl OffsetDateTime { - /// Format the `OffsetDateTime` using the provided [format - /// description](crate::format_description). - pub fn format_into( - self, - output: &mut (impl io::Write + ?Sized), - format: &(impl Formattable + ?Sized), - ) -> Result<usize, error::Format> { - format.format_into( - output, - Some(self.date()), - Some(self.time()), - Some(self.offset()), - ) - } - - /// Format the `OffsetDateTime` using the provided [format - /// description](crate::format_description). - /// - /// ```rust - /// # use time::format_description; - /// # use time_macros::datetime; - /// let format = format_description::parse( - /// "[year]-[month]-[day] [hour]:[minute]:[second] [offset_hour \ - /// sign:mandatory]:[offset_minute]:[offset_second]", - /// )?; - /// assert_eq!( - /// datetime!(2020-01-02 03:04:05 +06:07:08).format(&format)?, - /// "2020-01-02 03:04:05 +06:07:08" - /// ); - /// # Ok::<_, time::Error>(()) - /// ``` - pub fn format(self, format: &(impl Formattable + ?Sized)) -> Result<String, error::Format> { - format.format(Some(self.date()), Some(self.time()), Some(self.offset())) - } -} - -#[cfg(feature = "parsing")] -impl OffsetDateTime { - /// Parse an `OffsetDateTime` from the input using the provided [format - /// description](crate::format_description). - /// - /// ```rust - /// # use time::OffsetDateTime; - /// # use time_macros::{datetime, format_description}; - /// let format = format_description!( - /// "[year]-[month]-[day] [hour]:[minute]:[second] [offset_hour \ - /// sign:mandatory]:[offset_minute]:[offset_second]" - /// ); - /// assert_eq!( - /// OffsetDateTime::parse("2020-01-02 03:04:05 +06:07:08", &format)?, - /// datetime!(2020-01-02 03:04:05 +06:07:08) - /// ); - /// # Ok::<_, time::Error>(()) - /// ``` - pub fn parse( - input: &str, - description: &(impl Parsable + ?Sized), - ) -> Result<Self, error::Parse> { - description.parse_offset_date_time(input.as_bytes()) - } - - /// A helper method to check if the `OffsetDateTime` is a valid representation of a leap second. - /// Leap seconds, when parsed, are represented as the preceding nanosecond. However, leap - /// seconds can only occur as the last second of a month UTC. - #[cfg(feature = "parsing")] - pub(crate) const fn is_valid_leap_second_stand_in(self) -> bool { - // This comparison doesn't need to be adjusted for the stored offset, so check it first for - // speed. - if self.nanosecond() != 999_999_999 { - return false; - } - - let (year, ordinal, time) = self.to_offset_raw(UtcOffset::UTC); - let Ok(date) = Date::from_ordinal_date(year, ordinal) else { - return false; - }; - - time.hour() == 23 - && time.minute() == 59 - && time.second() == 59 - && date.day() == date.month().length(year) - } -} - -impl SmartDisplay for OffsetDateTime { - type Metadata = (); - - fn metadata(&self, _: FormatterOptions) -> Metadata<Self> { - let width = - smart_display::padded_width_of!(self.date(), " ", self.time(), " ", self.offset()); - Metadata::new(width, self, ()) - } - - fn fmt_with_metadata( - &self, - f: &mut fmt::Formatter<'_>, - metadata: Metadata<Self>, - ) -> fmt::Result { - f.pad_with_width( - metadata.unpadded_width(), - format_args!("{} {} {}", self.date(), self.time(), self.offset()), - ) - } -} - -impl fmt::Display for OffsetDateTime { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - SmartDisplay::fmt(self, f) - } -} - -impl fmt::Debug for OffsetDateTime { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Display::fmt(self, f) - } -} - -impl Add<Duration> for OffsetDateTime { - type Output = Self; - - /// # Panics - /// - /// This may panic if an overflow occurs. - fn add(self, duration: Duration) -> Self::Output { - self.checked_add(duration) - .expect("resulting value is out of range") - } -} - -impl Add<StdDuration> for OffsetDateTime { - type Output = Self; - - /// # Panics - /// - /// This may panic if an overflow occurs. - fn add(self, duration: StdDuration) -> Self::Output { - let (is_next_day, time) = self.time().adjusting_add_std(duration); - - Self::new_in_offset( - if is_next_day { - (self.date() + duration) - .next_day() - .expect("resulting value is out of range") - } else { - self.date() + duration - }, - time, - self.offset, - ) - } -} - -impl AddAssign<Duration> for OffsetDateTime { - /// # Panics - /// - /// This may panic if an overflow occurs. - fn add_assign(&mut self, rhs: Duration) { - *self = *self + rhs; - } -} - -impl AddAssign<StdDuration> for OffsetDateTime { - /// # Panics - /// - /// This may panic if an overflow occurs. - fn add_assign(&mut self, rhs: StdDuration) { - *self = *self + rhs; - } -} - -impl Sub<Duration> for OffsetDateTime { - type Output = Self; - - /// # Panics - /// - /// This may panic if an overflow occurs. - fn sub(self, rhs: Duration) -> Self::Output { - self.checked_sub(rhs) - .expect("resulting value is out of range") - } -} - -impl Sub<StdDuration> for OffsetDateTime { - type Output = Self; - - /// # Panics - /// - /// This may panic if an overflow occurs. - fn sub(self, duration: StdDuration) -> Self::Output { - let (is_previous_day, time) = self.time().adjusting_sub_std(duration); - - Self::new_in_offset( - if is_previous_day { - (self.date() - duration) - .previous_day() - .expect("resulting value is out of range") - } else { - self.date() - duration - }, - time, - self.offset, - ) - } -} - -impl SubAssign<Duration> for OffsetDateTime { - /// # Panics - /// - /// This may panic if an overflow occurs. - fn sub_assign(&mut self, rhs: Duration) { - *self = *self - rhs; - } -} - -impl SubAssign<StdDuration> for OffsetDateTime { - /// # Panics - /// - /// This may panic if an overflow occurs. - fn sub_assign(&mut self, rhs: StdDuration) { - *self = *self - rhs; - } -} - -impl Sub for OffsetDateTime { - type Output = Duration; - - /// # Panics - /// - /// This may panic if an overflow occurs. - fn sub(self, rhs: Self) -> Self::Output { - let base = self.date_time() - rhs.date_time(); - let adjustment = Duration::seconds( - (self.offset.whole_seconds() - rhs.offset.whole_seconds()).extend::<i64>(), - ); - base - adjustment - } -} diff --git a/vendor/time/src/parsing/combinator/mod.rs b/vendor/time/src/parsing/combinator/mod.rs deleted file mode 100644 index e3e1df76..00000000 --- a/vendor/time/src/parsing/combinator/mod.rs +++ /dev/null @@ -1,194 +0,0 @@ -//! Implementations of the low-level parser combinators. - -pub(crate) mod rfc; - -use num_conv::prelude::*; - -use crate::format_description::modifier::Padding; -use crate::parsing::shim::{Integer, IntegerParseBytes}; -use crate::parsing::ParsedItem; - -/// Parse a "+" or "-" sign. Returns the ASCII byte representing the sign, if present. -pub(crate) const fn sign(input: &[u8]) -> Option<ParsedItem<'_, u8>> { - match input { - [sign @ (b'-' | b'+'), remaining @ ..] => Some(ParsedItem(remaining, *sign)), - _ => None, - } -} - -/// Consume the first matching item, returning its associated value. -pub(crate) fn first_match<'a, T>( - options: impl IntoIterator<Item = (&'a [u8], T)>, - case_sensitive: bool, -) -> impl FnMut(&'a [u8]) -> Option<ParsedItem<'a, T>> { - let mut options = options.into_iter(); - move |input| { - options.find_map(|(expected, t)| { - if case_sensitive { - Some(ParsedItem(input.strip_prefix(expected)?, t)) - } else { - let n = expected.len(); - if n <= input.len() { - let (head, tail) = input.split_at(n); - if head.eq_ignore_ascii_case(expected) { - return Some(ParsedItem(tail, t)); - } - } - None - } - }) - } -} - -/// Consume zero or more instances of the provided parser. The parser must return the unit value. -pub(crate) fn zero_or_more<'a, P: Fn(&'a [u8]) -> Option<ParsedItem<'a, ()>>>( - parser: P, -) -> impl FnMut(&'a [u8]) -> ParsedItem<'a, ()> { - move |mut input| { - while let Some(remaining) = parser(input) { - input = remaining.into_inner(); - } - ParsedItem(input, ()) - } -} - -/// Consume one of or more instances of the provided parser. The parser must produce the unit value. -pub(crate) fn one_or_more<'a, P: Fn(&'a [u8]) -> Option<ParsedItem<'a, ()>>>( - parser: P, -) -> impl Fn(&'a [u8]) -> Option<ParsedItem<'a, ()>> { - move |mut input| { - input = parser(input)?.into_inner(); - while let Some(remaining) = parser(input) { - input = remaining.into_inner(); - } - Some(ParsedItem(input, ())) - } -} - -/// Consume between `n` and `m` instances of the provided parser. -pub(crate) fn n_to_m< - 'a, - const N: u8, - const M: u8, - T, - P: Fn(&'a [u8]) -> Option<ParsedItem<'a, T>>, ->( - parser: P, -) -> impl Fn(&'a [u8]) -> Option<ParsedItem<'a, &'a [u8]>> { - debug_assert!(M >= N); - move |mut input| { - // We need to keep this to determine the total length eventually consumed. - let orig_input = input; - - // Mandatory - for _ in 0..N { - input = parser(input)?.0; - } - - // Optional - for _ in N..M { - match parser(input) { - Some(parsed) => input = parsed.0, - None => break, - } - } - - Some(ParsedItem( - input, - &orig_input[..(orig_input.len() - input.len())], - )) - } -} - -/// Consume between `n` and `m` digits, returning the numerical value. -pub(crate) fn n_to_m_digits<const N: u8, const M: u8, T: Integer>( - input: &[u8], -) -> Option<ParsedItem<'_, T>> { - debug_assert!(M >= N); - n_to_m::<N, M, _, _>(any_digit)(input)?.flat_map(|value| value.parse_bytes()) -} - -/// Consume exactly `n` digits, returning the numerical value. -pub(crate) fn exactly_n_digits<const N: u8, T: Integer>(input: &[u8]) -> Option<ParsedItem<'_, T>> { - n_to_m_digits::<N, N, _>(input) -} - -/// Consume exactly `n` digits, returning the numerical value. -pub(crate) fn exactly_n_digits_padded<'a, const N: u8, T: Integer>( - padding: Padding, -) -> impl Fn(&'a [u8]) -> Option<ParsedItem<'a, T>> { - n_to_m_digits_padded::<N, N, _>(padding) -} - -/// Consume between `n` and `m` digits, returning the numerical value. -pub(crate) fn n_to_m_digits_padded<'a, const N: u8, const M: u8, T: Integer>( - padding: Padding, -) -> impl Fn(&'a [u8]) -> Option<ParsedItem<'a, T>> { - debug_assert!(M >= N); - move |mut input| match padding { - Padding::None => n_to_m_digits::<1, M, _>(input), - Padding::Space => { - debug_assert!(N > 0); - - let mut orig_input = input; - for _ in 0..(N - 1) { - match ascii_char::<b' '>(input) { - Some(parsed) => input = parsed.0, - None => break, - } - } - let pad_width = (orig_input.len() - input.len()).truncate::<u8>(); - - orig_input = input; - for _ in 0..(N - pad_width) { - input = any_digit(input)?.0; - } - for _ in N..M { - match any_digit(input) { - Some(parsed) => input = parsed.0, - None => break, - } - } - - ParsedItem(input, &orig_input[..(orig_input.len() - input.len())]) - .flat_map(|value| value.parse_bytes()) - } - Padding::Zero => n_to_m_digits::<N, M, _>(input), - } -} - -/// Consume exactly one digit. -pub(crate) const fn any_digit(input: &[u8]) -> Option<ParsedItem<'_, u8>> { - match input { - [c, remaining @ ..] if c.is_ascii_digit() => Some(ParsedItem(remaining, *c)), - _ => None, - } -} - -/// Consume exactly one of the provided ASCII characters. -pub(crate) fn ascii_char<const CHAR: u8>(input: &[u8]) -> Option<ParsedItem<'_, ()>> { - debug_assert!(CHAR.is_ascii_graphic() || CHAR.is_ascii_whitespace()); - match input { - [c, remaining @ ..] if *c == CHAR => Some(ParsedItem(remaining, ())), - _ => None, - } -} - -/// Consume exactly one of the provided ASCII characters, case-insensitive. -pub(crate) fn ascii_char_ignore_case<const CHAR: u8>(input: &[u8]) -> Option<ParsedItem<'_, ()>> { - debug_assert!(CHAR.is_ascii_graphic() || CHAR.is_ascii_whitespace()); - match input { - [c, remaining @ ..] if c.eq_ignore_ascii_case(&CHAR) => Some(ParsedItem(remaining, ())), - _ => None, - } -} - -/// Optionally consume an input with a given parser. -pub(crate) fn opt<'a, T>( - parser: impl Fn(&'a [u8]) -> Option<ParsedItem<'a, T>>, -) -> impl Fn(&'a [u8]) -> ParsedItem<'a, Option<T>> { - move |input| match parser(input) { - Some(value) => value.map(Some), - None => ParsedItem(input, None), - } -} diff --git a/vendor/time/src/parsing/combinator/rfc/iso8601.rs b/vendor/time/src/parsing/combinator/rfc/iso8601.rs deleted file mode 100644 index 4a1ebc46..00000000 --- a/vendor/time/src/parsing/combinator/rfc/iso8601.rs +++ /dev/null @@ -1,177 +0,0 @@ -//! Rules defined in [ISO 8601]. -//! -//! [ISO 8601]: https://www.iso.org/iso-8601-date-and-time-format.html - -use core::num::{NonZeroU16, NonZeroU8}; - -use num_conv::prelude::*; - -use crate::parsing::combinator::{any_digit, ascii_char, exactly_n_digits, first_match, sign}; -use crate::parsing::ParsedItem; -use crate::{Month, Weekday}; - -/// What kind of format is being parsed. This is used to ensure each part of the format (date, time, -/// offset) is the same kind. -#[derive(Debug, Clone, Copy)] -pub(crate) enum ExtendedKind { - /// The basic format. - Basic, - /// The extended format. - Extended, - /// ¯\_(ツ)_/¯ - Unknown, -} - -impl ExtendedKind { - /// Is it possible that the format is extended? - pub(crate) const fn maybe_extended(self) -> bool { - matches!(self, Self::Extended | Self::Unknown) - } - - /// Is the format known for certain to be extended? - pub(crate) const fn is_extended(self) -> bool { - matches!(self, Self::Extended) - } - - /// If the kind is `Unknown`, make it `Basic`. Otherwise, do nothing. Returns `Some` if and only - /// if the kind is now `Basic`. - pub(crate) fn coerce_basic(&mut self) -> Option<()> { - match self { - Self::Basic => Some(()), - Self::Extended => None, - Self::Unknown => { - *self = Self::Basic; - Some(()) - } - } - } - - /// If the kind is `Unknown`, make it `Extended`. Otherwise, do nothing. Returns `Some` if and - /// only if the kind is now `Extended`. - pub(crate) fn coerce_extended(&mut self) -> Option<()> { - match self { - Self::Basic => None, - Self::Extended => Some(()), - Self::Unknown => { - *self = Self::Extended; - Some(()) - } - } - } -} - -/// Parse a possibly expanded year. -pub(crate) fn year(input: &[u8]) -> Option<ParsedItem<'_, i32>> { - Some(match sign(input) { - Some(ParsedItem(input, sign)) => exactly_n_digits::<6, u32>(input)?.map(|val| { - let val = val.cast_signed(); - if sign == b'-' { - -val - } else { - val - } - }), - None => exactly_n_digits::<4, u32>(input)?.map(|val| val.cast_signed()), - }) -} - -/// Parse a month. -pub(crate) fn month(input: &[u8]) -> Option<ParsedItem<'_, Month>> { - first_match( - [ - (b"01".as_slice(), Month::January), - (b"02".as_slice(), Month::February), - (b"03".as_slice(), Month::March), - (b"04".as_slice(), Month::April), - (b"05".as_slice(), Month::May), - (b"06".as_slice(), Month::June), - (b"07".as_slice(), Month::July), - (b"08".as_slice(), Month::August), - (b"09".as_slice(), Month::September), - (b"10".as_slice(), Month::October), - (b"11".as_slice(), Month::November), - (b"12".as_slice(), Month::December), - ], - true, - )(input) -} - -/// Parse a week number. -pub(crate) fn week(input: &[u8]) -> Option<ParsedItem<'_, NonZeroU8>> { - exactly_n_digits::<2, _>(input) -} - -/// Parse a day of the month. -pub(crate) fn day(input: &[u8]) -> Option<ParsedItem<'_, NonZeroU8>> { - exactly_n_digits::<2, _>(input) -} - -/// Parse a day of the week. -pub(crate) fn dayk(input: &[u8]) -> Option<ParsedItem<'_, Weekday>> { - first_match( - [ - (b"1".as_slice(), Weekday::Monday), - (b"2".as_slice(), Weekday::Tuesday), - (b"3".as_slice(), Weekday::Wednesday), - (b"4".as_slice(), Weekday::Thursday), - (b"5".as_slice(), Weekday::Friday), - (b"6".as_slice(), Weekday::Saturday), - (b"7".as_slice(), Weekday::Sunday), - ], - true, - )(input) -} - -/// Parse a day of the year. -pub(crate) fn dayo(input: &[u8]) -> Option<ParsedItem<'_, NonZeroU16>> { - exactly_n_digits::<3, _>(input) -} - -/// Parse the hour. -pub(crate) fn hour(input: &[u8]) -> Option<ParsedItem<'_, u8>> { - exactly_n_digits::<2, _>(input) -} - -/// Parse the minute. -pub(crate) fn min(input: &[u8]) -> Option<ParsedItem<'_, u8>> { - exactly_n_digits::<2, _>(input) -} - -/// Parse a floating point number as its integer and optional fractional parts. -/// -/// The number must have two digits before the decimal point. If a decimal point is present, at -/// least one digit must follow. -/// -/// The return type is a tuple of the integer part and optional fraction part. -pub(crate) fn float(input: &[u8]) -> Option<ParsedItem<'_, (u8, Option<f64>)>> { - // Two digits before the decimal. - let ParsedItem(input, integer_part) = match input { - [first_digit @ b'0'..=b'9', second_digit @ b'0'..=b'9', input @ ..] => { - ParsedItem(input, (first_digit - b'0') * 10 + (second_digit - b'0')) - } - _ => return None, - }; - - if let Some(ParsedItem(input, ())) = decimal_sign(input) { - // Mandatory post-decimal digit. - let ParsedItem(mut input, mut fractional_part) = - any_digit(input)?.map(|digit| ((digit - b'0') as f64) / 10.); - - let mut divisor = 10.; - // Any number of subsequent digits. - while let Some(ParsedItem(new_input, digit)) = any_digit(input) { - input = new_input; - divisor *= 10.; - fractional_part += (digit - b'0') as f64 / divisor; - } - - Some(ParsedItem(input, (integer_part, Some(fractional_part)))) - } else { - Some(ParsedItem(input, (integer_part, None))) - } -} - -/// Parse a "decimal sign", which is either a comma or a period. -fn decimal_sign(input: &[u8]) -> Option<ParsedItem<'_, ()>> { - ascii_char::<b'.'>(input).or_else(|| ascii_char::<b','>(input)) -} diff --git a/vendor/time/src/parsing/combinator/rfc/mod.rs b/vendor/time/src/parsing/combinator/rfc/mod.rs deleted file mode 100644 index 2974a4d5..00000000 --- a/vendor/time/src/parsing/combinator/rfc/mod.rs +++ /dev/null @@ -1,10 +0,0 @@ -//! Combinators for rules as defined in a standard. -//! -//! When applicable, these rules have been converted strictly following the ABNF syntax as specified -//! in [RFC 2234]. -//! -//! [RFC 2234]: https://datatracker.ietf.org/doc/html/rfc2234 - -pub(crate) mod iso8601; -pub(crate) mod rfc2234; -pub(crate) mod rfc2822; diff --git a/vendor/time/src/parsing/combinator/rfc/rfc2234.rs b/vendor/time/src/parsing/combinator/rfc/rfc2234.rs deleted file mode 100644 index 67534443..00000000 --- a/vendor/time/src/parsing/combinator/rfc/rfc2234.rs +++ /dev/null @@ -1,13 +0,0 @@ -//! Rules defined in [RFC 2234]. -//! -//! [RFC 2234]: https://datatracker.ietf.org/doc/html/rfc2234 - -use crate::parsing::ParsedItem; - -/// Consume exactly one space or tab. -pub(crate) const fn wsp(input: &[u8]) -> Option<ParsedItem<'_, ()>> { - match input { - [b' ' | b'\t', rest @ ..] => Some(ParsedItem(rest, ())), - _ => None, - } -} diff --git a/vendor/time/src/parsing/combinator/rfc/rfc2822.rs b/vendor/time/src/parsing/combinator/rfc/rfc2822.rs deleted file mode 100644 index 0e886ee4..00000000 --- a/vendor/time/src/parsing/combinator/rfc/rfc2822.rs +++ /dev/null @@ -1,108 +0,0 @@ -//! Rules defined in [RFC 2822]. -//! -//! [RFC 2822]: https://datatracker.ietf.org/doc/html/rfc2822 - -use crate::parsing::combinator::rfc::rfc2234::wsp; -use crate::parsing::combinator::{ascii_char, one_or_more, zero_or_more}; -use crate::parsing::ParsedItem; - -/// Consume the `fws` rule. -// The full rule is equivalent to /\r\n[ \t]+|[ \t]+(?:\r\n[ \t]+)*/ -pub(crate) fn fws(mut input: &[u8]) -> Option<ParsedItem<'_, ()>> { - if let [b'\r', b'\n', rest @ ..] = input { - one_or_more(wsp)(rest) - } else { - input = one_or_more(wsp)(input)?.into_inner(); - while let [b'\r', b'\n', rest @ ..] = input { - input = one_or_more(wsp)(rest)?.into_inner(); - } - Some(ParsedItem(input, ())) - } -} - -/// Consume the `cfws` rule. -// The full rule is equivalent to any combination of `fws` and `comment` so long as it is not empty. -pub(crate) fn cfws(input: &[u8]) -> Option<ParsedItem<'_, ()>> { - one_or_more(|input| fws(input).or_else(|| comment(input)))(input) -} - -/// Consume the `comment` rule. -fn comment(mut input: &[u8]) -> Option<ParsedItem<'_, ()>> { - input = ascii_char::<b'('>(input)?.into_inner(); - input = zero_or_more(fws)(input).into_inner(); - while let Some(rest) = ccontent(input) { - input = rest.into_inner(); - input = zero_or_more(fws)(input).into_inner(); - } - input = ascii_char::<b')'>(input)?.into_inner(); - - Some(ParsedItem(input, ())) -} - -/// Consume the `ccontent` rule. -fn ccontent(input: &[u8]) -> Option<ParsedItem<'_, ()>> { - ctext(input) - .or_else(|| quoted_pair(input)) - .or_else(|| comment(input)) -} - -/// Consume the `ctext` rule. -#[allow(clippy::unnecessary_lazy_evaluations)] // rust-lang/rust-clippy#8522 -fn ctext(input: &[u8]) -> Option<ParsedItem<'_, ()>> { - no_ws_ctl(input).or_else(|| match input { - [33..=39 | 42..=91 | 93..=126, rest @ ..] => Some(ParsedItem(rest, ())), - _ => None, - }) -} - -/// Consume the `quoted_pair` rule. -fn quoted_pair(mut input: &[u8]) -> Option<ParsedItem<'_, ()>> { - input = ascii_char::<b'\\'>(input)?.into_inner(); - input = text(input).into_inner(); - - // If nothing is parsed by `text`, this means by hit the `obs-text` rule and nothing matched. - // This is technically a success, and we used to check the `obs-qp` rule to ensure everything - // possible was consumed. After further analysis, it was determined that this check was - // unnecessary due to `obs-text` wholly subsuming `obs-qp` in this context. For this reason, if - // `text` fails to parse anything, we consider it a success without further consideration. - - Some(ParsedItem(input, ())) -} - -/// Consume the `no_ws_ctl` rule. -const fn no_ws_ctl(input: &[u8]) -> Option<ParsedItem<'_, ()>> { - match input { - [1..=8 | 11..=12 | 14..=31 | 127, rest @ ..] => Some(ParsedItem(rest, ())), - _ => None, - } -} - -/// Consume the `text` rule. -fn text<'a>(input: &'a [u8]) -> ParsedItem<'a, ()> { - let new_text = |input: &'a [u8]| match input { - [1..=9 | 11..=12 | 14..=127, rest @ ..] => Some(ParsedItem(rest, ())), - _ => None, - }; - - let obs_char = |input: &'a [u8]| match input { - // This is technically allowed, but consuming this would mean the rest of the string is - // eagerly consumed without consideration for where the comment actually ends. - [b')', ..] => None, - [0..=9 | 11..=12 | 14..=127, rest @ ..] => Some(rest), - _ => None, - }; - - let obs_text = |mut input| { - input = zero_or_more(ascii_char::<b'\n'>)(input).into_inner(); - input = zero_or_more(ascii_char::<b'\r'>)(input).into_inner(); - while let Some(rest) = obs_char(input) { - input = rest; - input = zero_or_more(ascii_char::<b'\n'>)(input).into_inner(); - input = zero_or_more(ascii_char::<b'\r'>)(input).into_inner(); - } - - ParsedItem(input, ()) - }; - - new_text(input).unwrap_or_else(|| obs_text(input)) -} diff --git a/vendor/time/src/parsing/component.rs b/vendor/time/src/parsing/component.rs deleted file mode 100644 index 79645704..00000000 --- a/vendor/time/src/parsing/component.rs +++ /dev/null @@ -1,379 +0,0 @@ -//! Parsing implementations for all [`Component`](crate::format_description::Component)s. - -use core::num::{NonZeroU16, NonZeroU8}; - -use num_conv::prelude::*; - -use crate::convert::*; -use crate::format_description::modifier; -use crate::parsing::combinator::{ - any_digit, exactly_n_digits, exactly_n_digits_padded, first_match, n_to_m_digits, - n_to_m_digits_padded, opt, sign, -}; -use crate::parsing::ParsedItem; -use crate::{Month, Weekday}; - -/// Parse the "year" component of a `Date`. -pub(crate) fn parse_year( - input: &[u8], - modifiers: modifier::Year, -) -> Option<ParsedItem<'_, (i32, bool)>> { - match modifiers.repr { - modifier::YearRepr::Full => { - let ParsedItem(input, sign) = opt(sign)(input); - - if let Some(sign) = sign { - let ParsedItem(input, year) = if cfg!(feature = "large-dates") - && modifiers.range == modifier::YearRange::Extended - { - n_to_m_digits_padded::<4, 6, u32>(modifiers.padding)(input)? - } else { - exactly_n_digits_padded::<4, u32>(modifiers.padding)(input)? - }; - - Some(if sign == b'-' { - ParsedItem(input, (-year.cast_signed(), true)) - } else { - ParsedItem(input, (year.cast_signed(), false)) - }) - } else if modifiers.sign_is_mandatory { - None - } else { - let ParsedItem(input, year) = - exactly_n_digits_padded::<4, u32>(modifiers.padding)(input)?; - Some(ParsedItem(input, (year.cast_signed(), false))) - } - } - modifier::YearRepr::Century => { - let ParsedItem(input, sign) = opt(sign)(input); - - if let Some(sign) = sign { - let ParsedItem(input, year) = if cfg!(feature = "large-dates") - && modifiers.range == modifier::YearRange::Extended - { - n_to_m_digits_padded::<2, 4, u32>(modifiers.padding)(input)? - } else { - exactly_n_digits_padded::<2, u32>(modifiers.padding)(input)? - }; - - Some(if sign == b'-' { - ParsedItem(input, (-year.cast_signed(), true)) - } else { - ParsedItem(input, (year.cast_signed(), false)) - }) - } else if modifiers.sign_is_mandatory { - None - } else { - let ParsedItem(input, year) = - n_to_m_digits_padded::<1, 2, u32>(modifiers.padding)(input)?; - Some(ParsedItem(input, (year.cast_signed(), false))) - } - } - modifier::YearRepr::LastTwo => Some( - exactly_n_digits_padded::<2, u32>(modifiers.padding)(input)? - .map(|v| (v.cast_signed(), false)), - ), - } -} - -/// Parse the "month" component of a `Date`. -pub(crate) fn parse_month( - input: &[u8], - modifiers: modifier::Month, -) -> Option<ParsedItem<'_, Month>> { - use Month::*; - let ParsedItem(remaining, value) = first_match( - match modifiers.repr { - modifier::MonthRepr::Numerical => { - return exactly_n_digits_padded::<2, _>(modifiers.padding)(input)? - .flat_map(|n| Month::from_number(n).ok()); - } - modifier::MonthRepr::Long => [ - (b"January".as_slice(), January), - (b"February".as_slice(), February), - (b"March".as_slice(), March), - (b"April".as_slice(), April), - (b"May".as_slice(), May), - (b"June".as_slice(), June), - (b"July".as_slice(), July), - (b"August".as_slice(), August), - (b"September".as_slice(), September), - (b"October".as_slice(), October), - (b"November".as_slice(), November), - (b"December".as_slice(), December), - ], - modifier::MonthRepr::Short => [ - (b"Jan".as_slice(), January), - (b"Feb".as_slice(), February), - (b"Mar".as_slice(), March), - (b"Apr".as_slice(), April), - (b"May".as_slice(), May), - (b"Jun".as_slice(), June), - (b"Jul".as_slice(), July), - (b"Aug".as_slice(), August), - (b"Sep".as_slice(), September), - (b"Oct".as_slice(), October), - (b"Nov".as_slice(), November), - (b"Dec".as_slice(), December), - ], - }, - modifiers.case_sensitive, - )(input)?; - Some(ParsedItem(remaining, value)) -} - -/// Parse the "week number" component of a `Date`. -pub(crate) fn parse_week_number( - input: &[u8], - modifiers: modifier::WeekNumber, -) -> Option<ParsedItem<'_, u8>> { - exactly_n_digits_padded::<2, _>(modifiers.padding)(input) -} - -/// Parse the "weekday" component of a `Date`. -pub(crate) fn parse_weekday( - input: &[u8], - modifiers: modifier::Weekday, -) -> Option<ParsedItem<'_, Weekday>> { - first_match( - match (modifiers.repr, modifiers.one_indexed) { - (modifier::WeekdayRepr::Short, _) => [ - (b"Mon".as_slice(), Weekday::Monday), - (b"Tue".as_slice(), Weekday::Tuesday), - (b"Wed".as_slice(), Weekday::Wednesday), - (b"Thu".as_slice(), Weekday::Thursday), - (b"Fri".as_slice(), Weekday::Friday), - (b"Sat".as_slice(), Weekday::Saturday), - (b"Sun".as_slice(), Weekday::Sunday), - ], - (modifier::WeekdayRepr::Long, _) => [ - (b"Monday".as_slice(), Weekday::Monday), - (b"Tuesday".as_slice(), Weekday::Tuesday), - (b"Wednesday".as_slice(), Weekday::Wednesday), - (b"Thursday".as_slice(), Weekday::Thursday), - (b"Friday".as_slice(), Weekday::Friday), - (b"Saturday".as_slice(), Weekday::Saturday), - (b"Sunday".as_slice(), Weekday::Sunday), - ], - (modifier::WeekdayRepr::Sunday, false) => [ - (b"1".as_slice(), Weekday::Monday), - (b"2".as_slice(), Weekday::Tuesday), - (b"3".as_slice(), Weekday::Wednesday), - (b"4".as_slice(), Weekday::Thursday), - (b"5".as_slice(), Weekday::Friday), - (b"6".as_slice(), Weekday::Saturday), - (b"0".as_slice(), Weekday::Sunday), - ], - (modifier::WeekdayRepr::Sunday, true) => [ - (b"2".as_slice(), Weekday::Monday), - (b"3".as_slice(), Weekday::Tuesday), - (b"4".as_slice(), Weekday::Wednesday), - (b"5".as_slice(), Weekday::Thursday), - (b"6".as_slice(), Weekday::Friday), - (b"7".as_slice(), Weekday::Saturday), - (b"1".as_slice(), Weekday::Sunday), - ], - (modifier::WeekdayRepr::Monday, false) => [ - (b"0".as_slice(), Weekday::Monday), - (b"1".as_slice(), Weekday::Tuesday), - (b"2".as_slice(), Weekday::Wednesday), - (b"3".as_slice(), Weekday::Thursday), - (b"4".as_slice(), Weekday::Friday), - (b"5".as_slice(), Weekday::Saturday), - (b"6".as_slice(), Weekday::Sunday), - ], - (modifier::WeekdayRepr::Monday, true) => [ - (b"1".as_slice(), Weekday::Monday), - (b"2".as_slice(), Weekday::Tuesday), - (b"3".as_slice(), Weekday::Wednesday), - (b"4".as_slice(), Weekday::Thursday), - (b"5".as_slice(), Weekday::Friday), - (b"6".as_slice(), Weekday::Saturday), - (b"7".as_slice(), Weekday::Sunday), - ], - }, - modifiers.case_sensitive, - )(input) -} - -/// Parse the "ordinal" component of a `Date`. -pub(crate) fn parse_ordinal( - input: &[u8], - modifiers: modifier::Ordinal, -) -> Option<ParsedItem<'_, NonZeroU16>> { - exactly_n_digits_padded::<3, _>(modifiers.padding)(input) -} - -/// Parse the "day" component of a `Date`. -pub(crate) fn parse_day( - input: &[u8], - modifiers: modifier::Day, -) -> Option<ParsedItem<'_, NonZeroU8>> { - exactly_n_digits_padded::<2, _>(modifiers.padding)(input) -} - -/// Indicate whether the hour is "am" or "pm". -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub(crate) enum Period { - #[allow(clippy::missing_docs_in_private_items)] - Am, - #[allow(clippy::missing_docs_in_private_items)] - Pm, -} - -/// Parse the "hour" component of a `Time`. -pub(crate) fn parse_hour(input: &[u8], modifiers: modifier::Hour) -> Option<ParsedItem<'_, u8>> { - exactly_n_digits_padded::<2, _>(modifiers.padding)(input) -} - -/// Parse the "minute" component of a `Time`. -pub(crate) fn parse_minute( - input: &[u8], - modifiers: modifier::Minute, -) -> Option<ParsedItem<'_, u8>> { - exactly_n_digits_padded::<2, _>(modifiers.padding)(input) -} - -/// Parse the "second" component of a `Time`. -pub(crate) fn parse_second( - input: &[u8], - modifiers: modifier::Second, -) -> Option<ParsedItem<'_, u8>> { - exactly_n_digits_padded::<2, _>(modifiers.padding)(input) -} - -/// Parse the "period" component of a `Time`. Required if the hour is on a 12-hour clock. -pub(crate) fn parse_period( - input: &[u8], - modifiers: modifier::Period, -) -> Option<ParsedItem<'_, Period>> { - first_match( - if modifiers.is_uppercase { - [ - (b"AM".as_slice(), Period::Am), - (b"PM".as_slice(), Period::Pm), - ] - } else { - [ - (b"am".as_slice(), Period::Am), - (b"pm".as_slice(), Period::Pm), - ] - }, - modifiers.case_sensitive, - )(input) -} - -/// Parse the "subsecond" component of a `Time`. -pub(crate) fn parse_subsecond( - input: &[u8], - modifiers: modifier::Subsecond, -) -> Option<ParsedItem<'_, u32>> { - use modifier::SubsecondDigits::*; - Some(match modifiers.digits { - One => exactly_n_digits::<1, u32>(input)?.map(|v| v * 100_000_000), - Two => exactly_n_digits::<2, u32>(input)?.map(|v| v * 10_000_000), - Three => exactly_n_digits::<3, u32>(input)?.map(|v| v * 1_000_000), - Four => exactly_n_digits::<4, u32>(input)?.map(|v| v * 100_000), - Five => exactly_n_digits::<5, u32>(input)?.map(|v| v * 10_000), - Six => exactly_n_digits::<6, u32>(input)?.map(|v| v * 1_000), - Seven => exactly_n_digits::<7, u32>(input)?.map(|v| v * 100), - Eight => exactly_n_digits::<8, u32>(input)?.map(|v| v * 10), - Nine => exactly_n_digits::<9, _>(input)?, - OneOrMore => { - let ParsedItem(mut input, mut value) = - any_digit(input)?.map(|v| (v - b'0').extend::<u32>() * 100_000_000); - - let mut multiplier = 10_000_000; - while let Some(ParsedItem(new_input, digit)) = any_digit(input) { - value += (digit - b'0').extend::<u32>() * multiplier; - input = new_input; - multiplier /= 10; - } - - ParsedItem(input, value) - } - }) -} - -/// Parse the "hour" component of a `UtcOffset`. -/// -/// Returns the value and whether the value is negative. This is used for when "-0" is parsed. -pub(crate) fn parse_offset_hour( - input: &[u8], - modifiers: modifier::OffsetHour, -) -> Option<ParsedItem<'_, (i8, bool)>> { - let ParsedItem(input, sign) = opt(sign)(input); - let ParsedItem(input, hour) = exactly_n_digits_padded::<2, u8>(modifiers.padding)(input)?; - match sign { - Some(b'-') => Some(ParsedItem(input, (-hour.cast_signed(), true))), - None if modifiers.sign_is_mandatory => None, - _ => Some(ParsedItem(input, (hour.cast_signed(), false))), - } -} - -/// Parse the "minute" component of a `UtcOffset`. -pub(crate) fn parse_offset_minute( - input: &[u8], - modifiers: modifier::OffsetMinute, -) -> Option<ParsedItem<'_, i8>> { - Some( - exactly_n_digits_padded::<2, u8>(modifiers.padding)(input)? - .map(|offset_minute| offset_minute.cast_signed()), - ) -} - -/// Parse the "second" component of a `UtcOffset`. -pub(crate) fn parse_offset_second( - input: &[u8], - modifiers: modifier::OffsetSecond, -) -> Option<ParsedItem<'_, i8>> { - Some( - exactly_n_digits_padded::<2, u8>(modifiers.padding)(input)? - .map(|offset_second| offset_second.cast_signed()), - ) -} - -/// Ignore the given number of bytes. -pub(crate) fn parse_ignore( - input: &[u8], - modifiers: modifier::Ignore, -) -> Option<ParsedItem<'_, ()>> { - let modifier::Ignore { count } = modifiers; - let input = input.get((count.get().extend())..)?; - Some(ParsedItem(input, ())) -} - -/// Parse the Unix timestamp component. -pub(crate) fn parse_unix_timestamp( - input: &[u8], - modifiers: modifier::UnixTimestamp, -) -> Option<ParsedItem<'_, i128>> { - let ParsedItem(input, sign) = opt(sign)(input); - let ParsedItem(input, nano_timestamp) = match modifiers.precision { - modifier::UnixTimestampPrecision::Second => n_to_m_digits::<1, 14, u128>(input)? - .map(|val| val * Nanosecond::per(Second).extend::<u128>()), - modifier::UnixTimestampPrecision::Millisecond => n_to_m_digits::<1, 17, u128>(input)? - .map(|val| val * Nanosecond::per(Millisecond).extend::<u128>()), - modifier::UnixTimestampPrecision::Microsecond => n_to_m_digits::<1, 20, u128>(input)? - .map(|val| val * Nanosecond::per(Microsecond).extend::<u128>()), - modifier::UnixTimestampPrecision::Nanosecond => n_to_m_digits::<1, 23, _>(input)?, - }; - - match sign { - Some(b'-') => Some(ParsedItem(input, -nano_timestamp.cast_signed())), - None if modifiers.sign_is_mandatory => None, - _ => Some(ParsedItem(input, nano_timestamp.cast_signed())), - } -} - -/// Parse the `end` component, which represents the end of input. If any input is remaining, `None` -/// is returned. -pub(crate) const fn parse_end(input: &[u8], end: modifier::End) -> Option<ParsedItem<'_, ()>> { - let modifier::End {} = end; - - if input.is_empty() { - Some(ParsedItem(input, ())) - } else { - None - } -} diff --git a/vendor/time/src/parsing/iso8601.rs b/vendor/time/src/parsing/iso8601.rs deleted file mode 100644 index a57d6274..00000000 --- a/vendor/time/src/parsing/iso8601.rs +++ /dev/null @@ -1,332 +0,0 @@ -//! Parse parts of an ISO 8601-formatted value. - -use num_conv::prelude::*; - -use crate::convert::*; -use crate::error; -use crate::error::ParseFromDescription::{InvalidComponent, InvalidLiteral}; -use crate::format_description::well_known::iso8601::EncodedConfig; -use crate::format_description::well_known::Iso8601; -use crate::parsing::combinator::rfc::iso8601::{ - day, dayk, dayo, float, hour, min, month, week, year, ExtendedKind, -}; -use crate::parsing::combinator::{ascii_char, sign}; -use crate::parsing::{Parsed, ParsedItem}; - -impl<const CONFIG: EncodedConfig> Iso8601<CONFIG> { - // Basic: [year][month][day] - // Extended: [year]["-"][month]["-"][day] - // Basic: [year][dayo] - // Extended: [year]["-"][dayo] - // Basic: [year]["W"][week][dayk] - // Extended: [year]["-"]["W"][week]["-"][dayk] - /// Parse a date in the basic or extended format. Reduced precision is permitted. - pub(crate) fn parse_date<'a>( - parsed: &'a mut Parsed, - extended_kind: &'a mut ExtendedKind, - ) -> impl FnMut(&[u8]) -> Result<&[u8], error::Parse> + 'a { - move |input| { - // Same for any acceptable format. - let ParsedItem(mut input, year) = year(input).ok_or(InvalidComponent("year"))?; - *extended_kind = match ascii_char::<b'-'>(input) { - Some(ParsedItem(new_input, ())) => { - input = new_input; - ExtendedKind::Extended - } - None => ExtendedKind::Basic, // no separator before mandatory month/ordinal/week - }; - - let parsed_month_day = (|| { - let ParsedItem(mut input, month) = month(input).ok_or(InvalidComponent("month"))?; - if extended_kind.is_extended() { - input = ascii_char::<b'-'>(input) - .ok_or(InvalidLiteral)? - .into_inner(); - } - let ParsedItem(input, day) = day(input).ok_or(InvalidComponent("day"))?; - Ok(ParsedItem(input, (month, day))) - })(); - let mut ret_error = match parsed_month_day { - Ok(ParsedItem(input, (month, day))) => { - *parsed = parsed - .with_year(year) - .ok_or(InvalidComponent("year"))? - .with_month(month) - .ok_or(InvalidComponent("month"))? - .with_day(day) - .ok_or(InvalidComponent("day"))?; - return Ok(input); - } - Err(err) => err, - }; - - // Don't check for `None`, as the error from year-month-day will always take priority. - if let Some(ParsedItem(input, ordinal)) = dayo(input) { - *parsed = parsed - .with_year(year) - .ok_or(InvalidComponent("year"))? - .with_ordinal(ordinal) - .ok_or(InvalidComponent("ordinal"))?; - return Ok(input); - } - - let parsed_week_weekday = (|| { - let input = ascii_char::<b'W'>(input) - .ok_or((false, InvalidLiteral))? - .into_inner(); - let ParsedItem(mut input, week) = - week(input).ok_or((true, InvalidComponent("week")))?; - if extended_kind.is_extended() { - input = ascii_char::<b'-'>(input) - .ok_or((true, InvalidLiteral))? - .into_inner(); - } - let ParsedItem(input, weekday) = - dayk(input).ok_or((true, InvalidComponent("weekday")))?; - Ok(ParsedItem(input, (week, weekday))) - })(); - match parsed_week_weekday { - Ok(ParsedItem(input, (week, weekday))) => { - *parsed = parsed - .with_iso_year(year) - .ok_or(InvalidComponent("year"))? - .with_iso_week_number(week) - .ok_or(InvalidComponent("week"))? - .with_weekday(weekday) - .ok_or(InvalidComponent("weekday"))?; - return Ok(input); - } - Err((false, _err)) => {} - // This error is more accurate than the one from year-month-day. - Err((true, err)) => ret_error = err, - } - - Err(ret_error.into()) - } - } - - // Basic: ["T"][hour][min][sec] - // Extended: ["T"][hour][":"][min][":"][sec] - // Reduced precision: components after [hour] (including their preceding separator) can be - // omitted. ["T"] can be omitted if there is no date present. - /// Parse a time in the basic or extended format. Reduced precision is permitted. - pub(crate) fn parse_time<'a>( - parsed: &'a mut Parsed, - extended_kind: &'a mut ExtendedKind, - date_is_present: bool, - ) -> impl FnMut(&[u8]) -> Result<&[u8], error::Parse> + 'a { - move |mut input| { - if date_is_present { - input = ascii_char::<b'T'>(input) - .ok_or(InvalidLiteral)? - .into_inner(); - } - - let ParsedItem(mut input, hour) = float(input).ok_or(InvalidComponent("hour"))?; - match hour { - (hour, None) => parsed.set_hour_24(hour).ok_or(InvalidComponent("hour"))?, - (hour, Some(fractional_part)) => { - *parsed = parsed - .with_hour_24(hour) - .ok_or(InvalidComponent("hour"))? - .with_minute((fractional_part * Second::per(Minute) as f64) as u8) - .ok_or(InvalidComponent("minute"))? - .with_second( - (fractional_part * Second::per(Hour) as f64 % Minute::per(Hour) as f64) - as u8, - ) - .ok_or(InvalidComponent("second"))? - .with_subsecond( - (fractional_part * Nanosecond::per(Hour) as f64 - % Nanosecond::per(Second) as f64) - as u32, - ) - .ok_or(InvalidComponent("subsecond"))?; - return Ok(input); - } - }; - - if let Some(ParsedItem(new_input, ())) = ascii_char::<b':'>(input) { - extended_kind - .coerce_extended() - .ok_or(InvalidComponent("minute"))?; - input = new_input; - }; - - let mut input = match float(input) { - Some(ParsedItem(input, (minute, None))) => { - extended_kind.coerce_basic(); - parsed - .set_minute(minute) - .ok_or(InvalidComponent("minute"))?; - input - } - Some(ParsedItem(input, (minute, Some(fractional_part)))) => { - // `None` is valid behavior, so don't error if this fails. - extended_kind.coerce_basic(); - *parsed = parsed - .with_minute(minute) - .ok_or(InvalidComponent("minute"))? - .with_second((fractional_part * Second::per(Minute) as f64) as u8) - .ok_or(InvalidComponent("second"))? - .with_subsecond( - (fractional_part * Nanosecond::per(Minute) as f64 - % Nanosecond::per(Second) as f64) - as u32, - ) - .ok_or(InvalidComponent("subsecond"))?; - return Ok(input); - } - // colon was present, so minutes are required - None if extended_kind.is_extended() => { - return Err(error::Parse::ParseFromDescription(InvalidComponent( - "minute", - ))); - } - None => { - // Missing components are assumed to be zero. - *parsed = parsed - .with_minute(0) - .ok_or(InvalidComponent("minute"))? - .with_second(0) - .ok_or(InvalidComponent("second"))? - .with_subsecond(0) - .ok_or(InvalidComponent("subsecond"))?; - return Ok(input); - } - }; - - if extended_kind.is_extended() { - match ascii_char::<b':'>(input) { - Some(ParsedItem(new_input, ())) => input = new_input, - None => { - *parsed = parsed - .with_second(0) - .ok_or(InvalidComponent("second"))? - .with_subsecond(0) - .ok_or(InvalidComponent("subsecond"))?; - return Ok(input); - } - } - } - - let (input, second, subsecond) = match float(input) { - Some(ParsedItem(input, (second, None))) => (input, second, 0), - Some(ParsedItem(input, (second, Some(fractional_part)))) => ( - input, - second, - round(fractional_part * Nanosecond::per(Second) as f64) as u32, - ), - None if extended_kind.is_extended() => { - return Err(error::Parse::ParseFromDescription(InvalidComponent( - "second", - ))); - } - // Missing components are assumed to be zero. - None => (input, 0, 0), - }; - *parsed = parsed - .with_second(second) - .ok_or(InvalidComponent("second"))? - .with_subsecond(subsecond) - .ok_or(InvalidComponent("subsecond"))?; - - Ok(input) - } - } - - // Basic: [±][hour][min] or ["Z"] - // Extended: [±][hour][":"][min] or ["Z"] - // Reduced precision: [±][hour] or ["Z"] - /// Parse a UTC offset in the basic or extended format. Reduced precision is supported. - pub(crate) fn parse_offset<'a>( - parsed: &'a mut Parsed, - extended_kind: &'a mut ExtendedKind, - ) -> impl FnMut(&[u8]) -> Result<&[u8], error::Parse> + 'a { - move |input| { - if let Some(ParsedItem(input, ())) = ascii_char::<b'Z'>(input) { - *parsed = parsed - .with_offset_hour(0) - .ok_or(InvalidComponent("offset hour"))? - .with_offset_minute_signed(0) - .ok_or(InvalidComponent("offset minute"))? - .with_offset_second_signed(0) - .ok_or(InvalidComponent("offset second"))?; - return Ok(input); - } - - let ParsedItem(input, sign) = sign(input).ok_or(InvalidComponent("offset hour"))?; - let mut input = hour(input) - .and_then(|parsed_item| { - parsed_item.consume_value(|hour| { - parsed.set_offset_hour(if sign == b'-' { - -hour.cast_signed() - } else { - hour.cast_signed() - }) - }) - }) - .ok_or(InvalidComponent("offset hour"))?; - - if extended_kind.maybe_extended() { - if let Some(ParsedItem(new_input, ())) = ascii_char::<b':'>(input) { - extended_kind - .coerce_extended() - .ok_or(InvalidComponent("offset minute"))?; - input = new_input; - }; - } - - match min(input) { - Some(ParsedItem(new_input, min)) => { - input = new_input; - parsed - .set_offset_minute_signed(if sign == b'-' { - -min.cast_signed() - } else { - min.cast_signed() - }) - .ok_or(InvalidComponent("offset minute"))?; - } - None => { - // Omitted offset minute is assumed to be zero. - parsed.set_offset_minute_signed(0); - } - } - - // If `:` was present, the format has already been set to extended. As such, this call - // will do nothing in that case. If there wasn't `:` but minutes were - // present, we know it's the basic format. Do not use `?` on the call, as - // returning `None` is valid behavior. - extended_kind.coerce_basic(); - - Ok(input) - } - } -} - -/// Round wrapper that uses hardware implementation if `std` is available, falling back to manual -/// implementation for `no_std` -fn round(value: f64) -> f64 { - #[cfg(feature = "std")] - { - value.round() - } - #[cfg(not(feature = "std"))] - { - round_impl(value) - } -} - -#[cfg(not(feature = "std"))] -#[allow(clippy::missing_docs_in_private_items)] -fn round_impl(value: f64) -> f64 { - debug_assert!(value.is_sign_positive() && !value.is_nan()); - - let f = value % 1.; - if f < 0.5 { - value - f - } else { - value - f + 1. - } -} diff --git a/vendor/time/src/parsing/mod.rs b/vendor/time/src/parsing/mod.rs deleted file mode 100644 index 34e92736..00000000 --- a/vendor/time/src/parsing/mod.rs +++ /dev/null @@ -1,57 +0,0 @@ -//! Parsing for various types. - -pub(crate) mod combinator; -pub(crate) mod component; -mod iso8601; -pub(crate) mod parsable; -mod parsed; -pub(crate) mod shim; - -pub use self::parsable::Parsable; -pub use self::parsed::Parsed; - -/// An item that has been parsed. Represented as a `(remaining, value)` pair. -#[derive(Debug)] -pub(crate) struct ParsedItem<'a, T>(pub(crate) &'a [u8], pub(crate) T); - -impl<'a, T> ParsedItem<'a, T> { - /// Map the value to a new value, preserving the remaining input. - pub(crate) fn map<U>(self, f: impl FnOnce(T) -> U) -> ParsedItem<'a, U> { - ParsedItem(self.0, f(self.1)) - } - - /// Map the value to a new, optional value, preserving the remaining input. - pub(crate) fn flat_map<U>(self, f: impl FnOnce(T) -> Option<U>) -> Option<ParsedItem<'a, U>> { - Some(ParsedItem(self.0, f(self.1)?)) - } - - /// Consume the stored value with the provided function. The remaining input is returned. - #[must_use = "this returns the remaining input"] - pub(crate) fn consume_value(self, f: impl FnOnce(T) -> Option<()>) -> Option<&'a [u8]> { - f(self.1)?; - Some(self.0) - } - - /// Filter the value with the provided function. If the function returns `false`, the value - /// is discarded and `None` is returned. Otherwise, the value is preserved and `Some(self)` is - /// returned. - pub(crate) fn filter(self, f: impl FnOnce(&T) -> bool) -> Option<Self> { - f(&self.1).then_some(self) - } -} - -impl<'a> ParsedItem<'a, ()> { - /// Discard the unit value, returning the remaining input. - #[must_use = "this returns the remaining input"] - pub(crate) const fn into_inner(self) -> &'a [u8] { - self.0 - } -} - -impl<'a> ParsedItem<'a, Option<()>> { - /// Discard the potential unit value, returning the remaining input. - #[must_use = "this returns the remaining input"] - pub(crate) const fn into_inner(self) -> &'a [u8] { - self.0 - } -} diff --git a/vendor/time/src/parsing/parsable.rs b/vendor/time/src/parsing/parsable.rs deleted file mode 100644 index c631c5fe..00000000 --- a/vendor/time/src/parsing/parsable.rs +++ /dev/null @@ -1,800 +0,0 @@ -//! A trait that can be used to parse an item from an input. - -use core::ops::Deref; - -use num_conv::prelude::*; - -use crate::error::TryFromParsed; -use crate::format_description::well_known::iso8601::EncodedConfig; -use crate::format_description::well_known::{Iso8601, Rfc2822, Rfc3339}; -use crate::format_description::BorrowedFormatItem; -#[cfg(feature = "alloc")] -use crate::format_description::OwnedFormatItem; -use crate::internal_macros::bug; -use crate::parsing::{Parsed, ParsedItem}; -use crate::{error, Date, Month, OffsetDateTime, Time, UtcOffset, Weekday}; - -/// A type that can be parsed. -#[cfg_attr(docsrs, doc(notable_trait))] -#[doc(alias = "Parseable")] -pub trait Parsable: sealed::Sealed {} -impl Parsable for BorrowedFormatItem<'_> {} -impl Parsable for [BorrowedFormatItem<'_>] {} -#[cfg(feature = "alloc")] -impl Parsable for OwnedFormatItem {} -#[cfg(feature = "alloc")] -impl Parsable for [OwnedFormatItem] {} -impl Parsable for Rfc2822 {} -impl Parsable for Rfc3339 {} -impl<const CONFIG: EncodedConfig> Parsable for Iso8601<CONFIG> {} -impl<T: Deref> Parsable for T where T::Target: Parsable {} - -/// Seal the trait to prevent downstream users from implementing it, while still allowing it to -/// exist in generic bounds. -mod sealed { - #[allow(clippy::wildcard_imports)] - use super::*; - use crate::{PrimitiveDateTime, UtcDateTime}; - - /// Parse the item using a format description and an input. - pub trait Sealed { - /// Parse the item into the provided [`Parsed`] struct. - /// - /// This method can be used to parse a single component without parsing the full value. - fn parse_into<'a>( - &self, - input: &'a [u8], - parsed: &mut Parsed, - ) -> Result<&'a [u8], error::Parse>; - - /// Parse the item into a new [`Parsed`] struct. - /// - /// This method can only be used to parse a complete value of a type. If any characters - /// remain after parsing, an error will be returned. - fn parse(&self, input: &[u8]) -> Result<Parsed, error::Parse> { - let mut parsed = Parsed::new(); - if self.parse_into(input, &mut parsed)?.is_empty() { - Ok(parsed) - } else { - Err(error::Parse::ParseFromDescription( - error::ParseFromDescription::UnexpectedTrailingCharacters, - )) - } - } - - /// Parse a [`Date`] from the format description. - fn parse_date(&self, input: &[u8]) -> Result<Date, error::Parse> { - Ok(self.parse(input)?.try_into()?) - } - - /// Parse a [`Time`] from the format description. - fn parse_time(&self, input: &[u8]) -> Result<Time, error::Parse> { - Ok(self.parse(input)?.try_into()?) - } - - /// Parse a [`UtcOffset`] from the format description. - fn parse_offset(&self, input: &[u8]) -> Result<UtcOffset, error::Parse> { - Ok(self.parse(input)?.try_into()?) - } - - /// Parse a [`PrimitiveDateTime`] from the format description. - fn parse_primitive_date_time( - &self, - input: &[u8], - ) -> Result<PrimitiveDateTime, error::Parse> { - Ok(self.parse(input)?.try_into()?) - } - - /// Parse a [`UtcDateTime`] from the format description. - fn parse_utc_date_time(&self, input: &[u8]) -> Result<UtcDateTime, error::Parse> { - Ok(self.parse(input)?.try_into()?) - } - - /// Parse a [`OffsetDateTime`] from the format description. - fn parse_offset_date_time(&self, input: &[u8]) -> Result<OffsetDateTime, error::Parse> { - Ok(self.parse(input)?.try_into()?) - } - } -} - -impl sealed::Sealed for BorrowedFormatItem<'_> { - fn parse_into<'a>( - &self, - input: &'a [u8], - parsed: &mut Parsed, - ) -> Result<&'a [u8], error::Parse> { - Ok(parsed.parse_item(input, self)?) - } -} - -impl sealed::Sealed for [BorrowedFormatItem<'_>] { - fn parse_into<'a>( - &self, - input: &'a [u8], - parsed: &mut Parsed, - ) -> Result<&'a [u8], error::Parse> { - Ok(parsed.parse_items(input, self)?) - } -} - -#[cfg(feature = "alloc")] -impl sealed::Sealed for OwnedFormatItem { - fn parse_into<'a>( - &self, - input: &'a [u8], - parsed: &mut Parsed, - ) -> Result<&'a [u8], error::Parse> { - Ok(parsed.parse_item(input, self)?) - } -} - -#[cfg(feature = "alloc")] -impl sealed::Sealed for [OwnedFormatItem] { - fn parse_into<'a>( - &self, - input: &'a [u8], - parsed: &mut Parsed, - ) -> Result<&'a [u8], error::Parse> { - Ok(parsed.parse_items(input, self)?) - } -} - -impl<T: Deref> sealed::Sealed for T -where - T::Target: sealed::Sealed, -{ - fn parse_into<'a>( - &self, - input: &'a [u8], - parsed: &mut Parsed, - ) -> Result<&'a [u8], error::Parse> { - self.deref().parse_into(input, parsed) - } -} - -impl sealed::Sealed for Rfc2822 { - fn parse_into<'a>( - &self, - input: &'a [u8], - parsed: &mut Parsed, - ) -> Result<&'a [u8], error::Parse> { - use crate::error::ParseFromDescription::{InvalidComponent, InvalidLiteral}; - use crate::parsing::combinator::rfc::rfc2822::{cfws, fws}; - use crate::parsing::combinator::{ - ascii_char, exactly_n_digits, first_match, n_to_m_digits, opt, sign, - }; - - let colon = ascii_char::<b':'>; - let comma = ascii_char::<b','>; - - let input = opt(cfws)(input).into_inner(); - let weekday = first_match( - [ - (b"Mon".as_slice(), Weekday::Monday), - (b"Tue".as_slice(), Weekday::Tuesday), - (b"Wed".as_slice(), Weekday::Wednesday), - (b"Thu".as_slice(), Weekday::Thursday), - (b"Fri".as_slice(), Weekday::Friday), - (b"Sat".as_slice(), Weekday::Saturday), - (b"Sun".as_slice(), Weekday::Sunday), - ], - false, - )(input); - let input = if let Some(item) = weekday { - let input = item - .consume_value(|value| parsed.set_weekday(value)) - .ok_or(InvalidComponent("weekday"))?; - let input = comma(input).ok_or(InvalidLiteral)?.into_inner(); - opt(cfws)(input).into_inner() - } else { - input - }; - let input = n_to_m_digits::<1, 2, _>(input) - .and_then(|item| item.consume_value(|value| parsed.set_day(value))) - .ok_or(InvalidComponent("day"))?; - let input = cfws(input).ok_or(InvalidLiteral)?.into_inner(); - let input = first_match( - [ - (b"Jan".as_slice(), Month::January), - (b"Feb".as_slice(), Month::February), - (b"Mar".as_slice(), Month::March), - (b"Apr".as_slice(), Month::April), - (b"May".as_slice(), Month::May), - (b"Jun".as_slice(), Month::June), - (b"Jul".as_slice(), Month::July), - (b"Aug".as_slice(), Month::August), - (b"Sep".as_slice(), Month::September), - (b"Oct".as_slice(), Month::October), - (b"Nov".as_slice(), Month::November), - (b"Dec".as_slice(), Month::December), - ], - false, - )(input) - .and_then(|item| item.consume_value(|value| parsed.set_month(value))) - .ok_or(InvalidComponent("month"))?; - let input = cfws(input).ok_or(InvalidLiteral)?.into_inner(); - let input = match exactly_n_digits::<4, u32>(input) { - Some(item) => { - let input = item - .flat_map(|year| if year >= 1900 { Some(year) } else { None }) - .and_then(|item| { - item.consume_value(|value| parsed.set_year(value.cast_signed())) - }) - .ok_or(InvalidComponent("year"))?; - fws(input).ok_or(InvalidLiteral)?.into_inner() - } - None => { - let input = exactly_n_digits::<2, u32>(input) - .and_then(|item| { - item.map(|year| if year < 50 { year + 2000 } else { year + 1900 }) - .map(|year| year.cast_signed()) - .consume_value(|value| parsed.set_year(value)) - }) - .ok_or(InvalidComponent("year"))?; - cfws(input).ok_or(InvalidLiteral)?.into_inner() - } - }; - - let input = exactly_n_digits::<2, _>(input) - .and_then(|item| item.consume_value(|value| parsed.set_hour_24(value))) - .ok_or(InvalidComponent("hour"))?; - let input = opt(cfws)(input).into_inner(); - let input = colon(input).ok_or(InvalidLiteral)?.into_inner(); - let input = opt(cfws)(input).into_inner(); - let input = exactly_n_digits::<2, _>(input) - .and_then(|item| item.consume_value(|value| parsed.set_minute(value))) - .ok_or(InvalidComponent("minute"))?; - - let input = if let Some(input) = colon(opt(cfws)(input).into_inner()) { - let input = input.into_inner(); // discard the colon - let input = opt(cfws)(input).into_inner(); - let input = exactly_n_digits::<2, _>(input) - .and_then(|item| item.consume_value(|value| parsed.set_second(value))) - .ok_or(InvalidComponent("second"))?; - cfws(input).ok_or(InvalidLiteral)?.into_inner() - } else { - cfws(input).ok_or(InvalidLiteral)?.into_inner() - }; - - // The RFC explicitly allows leap seconds. - parsed.leap_second_allowed = true; - - #[allow(clippy::unnecessary_lazy_evaluations)] // rust-lang/rust-clippy#8522 - let zone_literal = first_match( - [ - (b"UT".as_slice(), 0), - (b"GMT".as_slice(), 0), - (b"EST".as_slice(), -5), - (b"EDT".as_slice(), -4), - (b"CST".as_slice(), -6), - (b"CDT".as_slice(), -5), - (b"MST".as_slice(), -7), - (b"MDT".as_slice(), -6), - (b"PST".as_slice(), -8), - (b"PDT".as_slice(), -7), - ], - false, - )(input) - .or_else(|| match input { - [b'a'..=b'i' | b'k'..=b'z' | b'A'..=b'I' | b'K'..=b'Z', rest @ ..] => { - Some(ParsedItem(rest, 0)) - } - _ => None, - }); - if let Some(zone_literal) = zone_literal { - let input = zone_literal - .consume_value(|value| parsed.set_offset_hour(value)) - .ok_or(InvalidComponent("offset hour"))?; - parsed - .set_offset_minute_signed(0) - .ok_or(InvalidComponent("offset minute"))?; - parsed - .set_offset_second_signed(0) - .ok_or(InvalidComponent("offset second"))?; - return Ok(input); - } - - let ParsedItem(input, offset_sign) = sign(input).ok_or(InvalidComponent("offset hour"))?; - let input = exactly_n_digits::<2, u8>(input) - .and_then(|item| { - item.map(|offset_hour| { - if offset_sign == b'-' { - -offset_hour.cast_signed() - } else { - offset_hour.cast_signed() - } - }) - .consume_value(|value| parsed.set_offset_hour(value)) - }) - .ok_or(InvalidComponent("offset hour"))?; - let input = exactly_n_digits::<2, u8>(input) - .and_then(|item| { - item.consume_value(|value| parsed.set_offset_minute_signed(value.cast_signed())) - }) - .ok_or(InvalidComponent("offset minute"))?; - - let input = opt(cfws)(input).into_inner(); - - Ok(input) - } - - fn parse_offset_date_time(&self, input: &[u8]) -> Result<OffsetDateTime, error::Parse> { - use crate::error::ParseFromDescription::{InvalidComponent, InvalidLiteral}; - use crate::parsing::combinator::rfc::rfc2822::{cfws, fws}; - use crate::parsing::combinator::{ - ascii_char, exactly_n_digits, first_match, n_to_m_digits, opt, sign, - }; - - let colon = ascii_char::<b':'>; - let comma = ascii_char::<b','>; - - let input = opt(cfws)(input).into_inner(); - // This parses the weekday, but we don't actually use the value anywhere. Because of this, - // just return `()` to avoid unnecessary generated code. - let weekday = first_match( - [ - (b"Mon".as_slice(), ()), - (b"Tue".as_slice(), ()), - (b"Wed".as_slice(), ()), - (b"Thu".as_slice(), ()), - (b"Fri".as_slice(), ()), - (b"Sat".as_slice(), ()), - (b"Sun".as_slice(), ()), - ], - false, - )(input); - let input = if let Some(item) = weekday { - let input = item.into_inner(); - let input = comma(input).ok_or(InvalidLiteral)?.into_inner(); - opt(cfws)(input).into_inner() - } else { - input - }; - let ParsedItem(input, day) = - n_to_m_digits::<1, 2, _>(input).ok_or(InvalidComponent("day"))?; - let input = cfws(input).ok_or(InvalidLiteral)?.into_inner(); - let ParsedItem(input, month) = first_match( - [ - (b"Jan".as_slice(), Month::January), - (b"Feb".as_slice(), Month::February), - (b"Mar".as_slice(), Month::March), - (b"Apr".as_slice(), Month::April), - (b"May".as_slice(), Month::May), - (b"Jun".as_slice(), Month::June), - (b"Jul".as_slice(), Month::July), - (b"Aug".as_slice(), Month::August), - (b"Sep".as_slice(), Month::September), - (b"Oct".as_slice(), Month::October), - (b"Nov".as_slice(), Month::November), - (b"Dec".as_slice(), Month::December), - ], - false, - )(input) - .ok_or(InvalidComponent("month"))?; - let input = cfws(input).ok_or(InvalidLiteral)?.into_inner(); - let (input, year) = match exactly_n_digits::<4, u32>(input) { - Some(item) => { - let ParsedItem(input, year) = item - .flat_map(|year| if year >= 1900 { Some(year) } else { None }) - .ok_or(InvalidComponent("year"))?; - let input = fws(input).ok_or(InvalidLiteral)?.into_inner(); - (input, year) - } - None => { - let ParsedItem(input, year) = exactly_n_digits::<2, u32>(input) - .map(|item| item.map(|year| if year < 50 { year + 2000 } else { year + 1900 })) - .ok_or(InvalidComponent("year"))?; - let input = cfws(input).ok_or(InvalidLiteral)?.into_inner(); - (input, year) - } - }; - - let ParsedItem(input, hour) = - exactly_n_digits::<2, _>(input).ok_or(InvalidComponent("hour"))?; - let input = opt(cfws)(input).into_inner(); - let input = colon(input).ok_or(InvalidLiteral)?.into_inner(); - let input = opt(cfws)(input).into_inner(); - let ParsedItem(input, minute) = - exactly_n_digits::<2, _>(input).ok_or(InvalidComponent("minute"))?; - - let (input, mut second) = if let Some(input) = colon(opt(cfws)(input).into_inner()) { - let input = input.into_inner(); // discard the colon - let input = opt(cfws)(input).into_inner(); - let ParsedItem(input, second) = - exactly_n_digits::<2, _>(input).ok_or(InvalidComponent("second"))?; - let input = cfws(input).ok_or(InvalidLiteral)?.into_inner(); - (input, second) - } else { - (cfws(input).ok_or(InvalidLiteral)?.into_inner(), 0) - }; - - #[allow(clippy::unnecessary_lazy_evaluations)] // rust-lang/rust-clippy#8522 - let zone_literal = first_match( - [ - (b"UT".as_slice(), 0), - (b"GMT".as_slice(), 0), - (b"EST".as_slice(), -5), - (b"EDT".as_slice(), -4), - (b"CST".as_slice(), -6), - (b"CDT".as_slice(), -5), - (b"MST".as_slice(), -7), - (b"MDT".as_slice(), -6), - (b"PST".as_slice(), -8), - (b"PDT".as_slice(), -7), - ], - false, - )(input) - .or_else(|| match input { - [b'a'..=b'i' | b'k'..=b'z' | b'A'..=b'I' | b'K'..=b'Z', rest @ ..] => { - Some(ParsedItem(rest, 0)) - } - _ => None, - }); - - let (input, offset_hour, offset_minute) = if let Some(zone_literal) = zone_literal { - let ParsedItem(input, offset_hour) = zone_literal; - (input, offset_hour, 0) - } else { - let ParsedItem(input, offset_sign) = - sign(input).ok_or(InvalidComponent("offset hour"))?; - let ParsedItem(input, offset_hour) = exactly_n_digits::<2, u8>(input) - .map(|item| { - item.map(|offset_hour| { - if offset_sign == b'-' { - -offset_hour.cast_signed() - } else { - offset_hour.cast_signed() - } - }) - }) - .ok_or(InvalidComponent("offset hour"))?; - let ParsedItem(input, offset_minute) = - exactly_n_digits::<2, u8>(input).ok_or(InvalidComponent("offset minute"))?; - (input, offset_hour, offset_minute.cast_signed()) - }; - - let input = opt(cfws)(input).into_inner(); - - if !input.is_empty() { - return Err(error::Parse::ParseFromDescription( - error::ParseFromDescription::UnexpectedTrailingCharacters, - )); - } - - let mut nanosecond = 0; - let leap_second_input = if second == 60 { - second = 59; - nanosecond = 999_999_999; - true - } else { - false - }; - - let dt = (|| { - let date = Date::from_calendar_date(year.cast_signed(), month, day)?; - let time = Time::from_hms_nano(hour, minute, second, nanosecond)?; - let offset = UtcOffset::from_hms(offset_hour, offset_minute, 0)?; - Ok(OffsetDateTime::new_in_offset(date, time, offset)) - })() - .map_err(TryFromParsed::ComponentRange)?; - - if leap_second_input && !dt.is_valid_leap_second_stand_in() { - return Err(error::Parse::TryFromParsed(TryFromParsed::ComponentRange( - error::ComponentRange { - name: "second", - minimum: 0, - maximum: 59, - value: 60, - conditional_message: Some("because leap seconds are not supported"), - }, - ))); - } - - Ok(dt) - } -} - -impl sealed::Sealed for Rfc3339 { - fn parse_into<'a>( - &self, - input: &'a [u8], - parsed: &mut Parsed, - ) -> Result<&'a [u8], error::Parse> { - use crate::error::ParseFromDescription::{InvalidComponent, InvalidLiteral}; - use crate::parsing::combinator::{ - any_digit, ascii_char, ascii_char_ignore_case, exactly_n_digits, sign, - }; - - let dash = ascii_char::<b'-'>; - let colon = ascii_char::<b':'>; - - let input = exactly_n_digits::<4, u32>(input) - .and_then(|item| item.consume_value(|value| parsed.set_year(value.cast_signed()))) - .ok_or(InvalidComponent("year"))?; - let input = dash(input).ok_or(InvalidLiteral)?.into_inner(); - let input = exactly_n_digits::<2, _>(input) - .and_then(|item| item.flat_map(|value| Month::from_number(value).ok())) - .and_then(|item| item.consume_value(|value| parsed.set_month(value))) - .ok_or(InvalidComponent("month"))?; - let input = dash(input).ok_or(InvalidLiteral)?.into_inner(); - let input = exactly_n_digits::<2, _>(input) - .and_then(|item| item.consume_value(|value| parsed.set_day(value))) - .ok_or(InvalidComponent("day"))?; - - // RFC3339 allows any separator, not just `T`, not just `space`. - // cf. Section 5.6: Internet Date/Time Format: - // NOTE: ISO 8601 defines date and time separated by "T". - // Applications using this syntax may choose, for the sake of - // readability, to specify a full-date and full-time separated by - // (say) a space character. - // Specifically, rusqlite uses space separators. - let input = input.get(1..).ok_or(InvalidComponent("separator"))?; - - let input = exactly_n_digits::<2, _>(input) - .and_then(|item| item.consume_value(|value| parsed.set_hour_24(value))) - .ok_or(InvalidComponent("hour"))?; - let input = colon(input).ok_or(InvalidLiteral)?.into_inner(); - let input = exactly_n_digits::<2, _>(input) - .and_then(|item| item.consume_value(|value| parsed.set_minute(value))) - .ok_or(InvalidComponent("minute"))?; - let input = colon(input).ok_or(InvalidLiteral)?.into_inner(); - let input = exactly_n_digits::<2, _>(input) - .and_then(|item| item.consume_value(|value| parsed.set_second(value))) - .ok_or(InvalidComponent("second"))?; - let input = if let Some(ParsedItem(input, ())) = ascii_char::<b'.'>(input) { - let ParsedItem(mut input, mut value) = any_digit(input) - .ok_or(InvalidComponent("subsecond"))? - .map(|v| (v - b'0').extend::<u32>() * 100_000_000); - - let mut multiplier = 10_000_000; - while let Some(ParsedItem(new_input, digit)) = any_digit(input) { - value += (digit - b'0').extend::<u32>() * multiplier; - input = new_input; - multiplier /= 10; - } - - parsed - .set_subsecond(value) - .ok_or(InvalidComponent("subsecond"))?; - input - } else { - input - }; - - // The RFC explicitly allows leap seconds. - parsed.leap_second_allowed = true; - - if let Some(ParsedItem(input, ())) = ascii_char_ignore_case::<b'Z'>(input) { - parsed - .set_offset_hour(0) - .ok_or(InvalidComponent("offset hour"))?; - parsed - .set_offset_minute_signed(0) - .ok_or(InvalidComponent("offset minute"))?; - parsed - .set_offset_second_signed(0) - .ok_or(InvalidComponent("offset second"))?; - return Ok(input); - } - - let ParsedItem(input, offset_sign) = sign(input).ok_or(InvalidComponent("offset hour"))?; - let input = exactly_n_digits::<2, u8>(input) - .and_then(|item| { - item.filter(|&offset_hour| offset_hour <= 23)? - .map(|offset_hour| { - if offset_sign == b'-' { - -offset_hour.cast_signed() - } else { - offset_hour.cast_signed() - } - }) - .consume_value(|value| parsed.set_offset_hour(value)) - }) - .ok_or(InvalidComponent("offset hour"))?; - let input = colon(input).ok_or(InvalidLiteral)?.into_inner(); - let input = exactly_n_digits::<2, u8>(input) - .and_then(|item| { - item.map(|offset_minute| { - if offset_sign == b'-' { - -offset_minute.cast_signed() - } else { - offset_minute.cast_signed() - } - }) - .consume_value(|value| parsed.set_offset_minute_signed(value)) - }) - .ok_or(InvalidComponent("offset minute"))?; - - Ok(input) - } - - fn parse_offset_date_time(&self, input: &[u8]) -> Result<OffsetDateTime, error::Parse> { - use crate::error::ParseFromDescription::{InvalidComponent, InvalidLiteral}; - use crate::parsing::combinator::{ - any_digit, ascii_char, ascii_char_ignore_case, exactly_n_digits, sign, - }; - - let dash = ascii_char::<b'-'>; - let colon = ascii_char::<b':'>; - - let ParsedItem(input, year) = - exactly_n_digits::<4, u32>(input).ok_or(InvalidComponent("year"))?; - let input = dash(input).ok_or(InvalidLiteral)?.into_inner(); - let ParsedItem(input, month) = - exactly_n_digits::<2, _>(input).ok_or(InvalidComponent("month"))?; - let input = dash(input).ok_or(InvalidLiteral)?.into_inner(); - let ParsedItem(input, day) = - exactly_n_digits::<2, _>(input).ok_or(InvalidComponent("day"))?; - - // RFC3339 allows any separator, not just `T`, not just `space`. - // cf. Section 5.6: Internet Date/Time Format: - // NOTE: ISO 8601 defines date and time separated by "T". - // Applications using this syntax may choose, for the sake of - // readability, to specify a full-date and full-time separated by - // (say) a space character. - // Specifically, rusqlite uses space separators. - let input = input.get(1..).ok_or(InvalidComponent("separator"))?; - - let ParsedItem(input, hour) = - exactly_n_digits::<2, _>(input).ok_or(InvalidComponent("hour"))?; - let input = colon(input).ok_or(InvalidLiteral)?.into_inner(); - let ParsedItem(input, minute) = - exactly_n_digits::<2, _>(input).ok_or(InvalidComponent("minute"))?; - let input = colon(input).ok_or(InvalidLiteral)?.into_inner(); - let ParsedItem(input, mut second) = - exactly_n_digits::<2, _>(input).ok_or(InvalidComponent("second"))?; - let ParsedItem(input, mut nanosecond) = - if let Some(ParsedItem(input, ())) = ascii_char::<b'.'>(input) { - let ParsedItem(mut input, mut value) = any_digit(input) - .ok_or(InvalidComponent("subsecond"))? - .map(|v| (v - b'0').extend::<u32>() * 100_000_000); - - let mut multiplier = 10_000_000; - while let Some(ParsedItem(new_input, digit)) = any_digit(input) { - value += (digit - b'0').extend::<u32>() * multiplier; - input = new_input; - multiplier /= 10; - } - - ParsedItem(input, value) - } else { - ParsedItem(input, 0) - }; - let ParsedItem(input, offset) = { - if let Some(ParsedItem(input, ())) = ascii_char_ignore_case::<b'Z'>(input) { - ParsedItem(input, UtcOffset::UTC) - } else { - let ParsedItem(input, offset_sign) = - sign(input).ok_or(InvalidComponent("offset hour"))?; - let ParsedItem(input, offset_hour) = exactly_n_digits::<2, u8>(input) - .and_then(|parsed| parsed.filter(|&offset_hour| offset_hour <= 23)) - .ok_or(InvalidComponent("offset hour"))?; - let input = colon(input).ok_or(InvalidLiteral)?.into_inner(); - let ParsedItem(input, offset_minute) = - exactly_n_digits::<2, u8>(input).ok_or(InvalidComponent("offset minute"))?; - UtcOffset::from_hms( - if offset_sign == b'-' { - -offset_hour.cast_signed() - } else { - offset_hour.cast_signed() - }, - if offset_sign == b'-' { - -offset_minute.cast_signed() - } else { - offset_minute.cast_signed() - }, - 0, - ) - .map(|offset| ParsedItem(input, offset)) - .map_err(|mut err| { - // Provide the user a more accurate error. - if err.name == "hours" { - err.name = "offset hour"; - } else if err.name == "minutes" { - err.name = "offset minute"; - } - err - }) - .map_err(TryFromParsed::ComponentRange)? - } - }; - - if !input.is_empty() { - return Err(error::Parse::ParseFromDescription( - error::ParseFromDescription::UnexpectedTrailingCharacters, - )); - } - - // The RFC explicitly permits leap seconds. We don't currently support them, so treat it as - // the preceding nanosecond. However, leap seconds can only occur as the last second of the - // month UTC. - let leap_second_input = if second == 60 { - second = 59; - nanosecond = 999_999_999; - true - } else { - false - }; - - let date = Month::from_number(month) - .and_then(|month| Date::from_calendar_date(year.cast_signed(), month, day)) - .map_err(TryFromParsed::ComponentRange)?; - let time = Time::from_hms_nano(hour, minute, second, nanosecond) - .map_err(TryFromParsed::ComponentRange)?; - let dt = OffsetDateTime::new_in_offset(date, time, offset); - - if leap_second_input && !dt.is_valid_leap_second_stand_in() { - return Err(error::Parse::TryFromParsed(TryFromParsed::ComponentRange( - error::ComponentRange { - name: "second", - minimum: 0, - maximum: 59, - value: 60, - conditional_message: Some("because leap seconds are not supported"), - }, - ))); - } - - Ok(dt) - } -} - -impl<const CONFIG: EncodedConfig> sealed::Sealed for Iso8601<CONFIG> { - fn parse_into<'a>( - &self, - mut input: &'a [u8], - parsed: &mut Parsed, - ) -> Result<&'a [u8], error::Parse> { - use crate::parsing::combinator::rfc::iso8601::ExtendedKind; - - let mut extended_kind = ExtendedKind::Unknown; - let mut date_is_present = false; - let mut time_is_present = false; - let mut offset_is_present = false; - let mut first_error = None; - - parsed.leap_second_allowed = true; - - match Self::parse_date(parsed, &mut extended_kind)(input) { - Ok(new_input) => { - input = new_input; - date_is_present = true; - } - Err(err) => { - first_error.get_or_insert(err); - } - } - - match Self::parse_time(parsed, &mut extended_kind, date_is_present)(input) { - Ok(new_input) => { - input = new_input; - time_is_present = true; - } - Err(err) => { - first_error.get_or_insert(err); - } - } - - // If a date and offset are present, a time must be as well. - if !date_is_present || time_is_present { - match Self::parse_offset(parsed, &mut extended_kind)(input) { - Ok(new_input) => { - input = new_input; - offset_is_present = true; - } - Err(err) => { - first_error.get_or_insert(err); - } - } - } - - if !date_is_present && !time_is_present && !offset_is_present { - match first_error { - Some(err) => return Err(err), - None => bug!("an error should be present if no components were parsed"), - } - } - - Ok(input) - } -} diff --git a/vendor/time/src/parsing/parsed.rs b/vendor/time/src/parsing/parsed.rs deleted file mode 100644 index a6f00d9b..00000000 --- a/vendor/time/src/parsing/parsed.rs +++ /dev/null @@ -1,1118 +0,0 @@ -//! Information parsed from an input and format description. - -use core::num::{NonZeroU16, NonZeroU8}; - -use deranged::{ - OptionRangedI128, OptionRangedI16, OptionRangedI32, OptionRangedI8, OptionRangedU16, - OptionRangedU32, OptionRangedU8, RangedI128, RangedI16, RangedI32, RangedI8, RangedU16, - RangedU32, RangedU8, -}; -use num_conv::prelude::*; - -use crate::convert::{Day, Hour, Minute, Nanosecond, Second}; -use crate::date::{MAX_YEAR, MIN_YEAR}; -use crate::error::TryFromParsed::InsufficientInformation; -#[cfg(feature = "alloc")] -use crate::format_description::OwnedFormatItem; -use crate::format_description::{modifier, BorrowedFormatItem, Component}; -use crate::internal_macros::{bug, const_try_opt}; -use crate::parsing::component::{ - parse_day, parse_end, parse_hour, parse_ignore, parse_minute, parse_month, parse_offset_hour, - parse_offset_minute, parse_offset_second, parse_ordinal, parse_period, parse_second, - parse_subsecond, parse_unix_timestamp, parse_week_number, parse_weekday, parse_year, Period, -}; -use crate::parsing::ParsedItem; -use crate::{ - error, Date, Month, OffsetDateTime, PrimitiveDateTime, Time, UtcDateTime, UtcOffset, Weekday, -}; - -/// Sealed to prevent downstream implementations. -mod sealed { - use super::*; - - /// A trait to allow `parse_item` to be generic. - pub trait AnyFormatItem { - /// Parse a single item, returning the remaining input on success. - fn parse_item<'a>( - &self, - parsed: &mut Parsed, - input: &'a [u8], - ) -> Result<&'a [u8], error::ParseFromDescription>; - } -} - -impl sealed::AnyFormatItem for BorrowedFormatItem<'_> { - fn parse_item<'a>( - &self, - parsed: &mut Parsed, - input: &'a [u8], - ) -> Result<&'a [u8], error::ParseFromDescription> { - match self { - Self::Literal(literal) => Parsed::parse_literal(input, literal), - Self::Component(component) => parsed.parse_component(input, *component), - Self::Compound(compound) => parsed.parse_items(input, compound), - Self::Optional(item) => parsed.parse_item(input, *item).or(Ok(input)), - Self::First(items) => { - let mut first_err = None; - - for item in items.iter() { - match parsed.parse_item(input, item) { - Ok(remaining_input) => return Ok(remaining_input), - Err(err) if first_err.is_none() => first_err = Some(err), - Err(_) => {} - } - } - - match first_err { - Some(err) => Err(err), - // This location will be reached if the slice is empty, skipping the `for` loop. - // As this case is expected to be uncommon, there's no need to check up front. - None => Ok(input), - } - } - } - } -} - -#[cfg(feature = "alloc")] -impl sealed::AnyFormatItem for OwnedFormatItem { - fn parse_item<'a>( - &self, - parsed: &mut Parsed, - input: &'a [u8], - ) -> Result<&'a [u8], error::ParseFromDescription> { - match self { - Self::Literal(literal) => Parsed::parse_literal(input, literal), - Self::Component(component) => parsed.parse_component(input, *component), - Self::Compound(compound) => parsed.parse_items(input, compound), - Self::Optional(item) => parsed.parse_item(input, item.as_ref()).or(Ok(input)), - Self::First(items) => { - let mut first_err = None; - - for item in items.iter() { - match parsed.parse_item(input, item) { - Ok(remaining_input) => return Ok(remaining_input), - Err(err) if first_err.is_none() => first_err = Some(err), - Err(_) => {} - } - } - - match first_err { - Some(err) => Err(err), - // This location will be reached if the slice is empty, skipping the `for` loop. - // As this case is expected to be uncommon, there's no need to check up front. - None => Ok(input), - } - } - } - } -} - -/// All information parsed. -/// -/// This information is directly used to construct the final values. -/// -/// Most users will not need think about this struct in any way. It is public to allow for manual -/// control over values, in the instance that the default parser is insufficient. -#[derive(Debug, Clone, Copy)] -pub struct Parsed { - /// Calendar year. - year: OptionRangedI32<{ MIN_YEAR }, { MAX_YEAR }>, - /// All digits except the last two of the calendar year. - year_century: OptionRangedI16<{ (MIN_YEAR / 100) as i16 }, { (MAX_YEAR / 100) as i16 }>, - /// The last two digits of the calendar year. - year_last_two: OptionRangedU8<0, 99>, - /// Year of the [ISO week date](https://en.wikipedia.org/wiki/ISO_week_date). - iso_year: OptionRangedI32<{ MIN_YEAR }, { MAX_YEAR }>, - /// All digits except the last two of the ISO week year. - iso_year_century: OptionRangedI16<{ (MIN_YEAR / 100) as i16 }, { (MAX_YEAR / 100) as i16 }>, - /// The last two digits of the ISO week year. - iso_year_last_two: OptionRangedU8<0, 99>, - /// Month of the year. - month: Option<Month>, - /// Week of the year, where week one begins on the first Sunday of the calendar year. - sunday_week_number: OptionRangedU8<0, 53>, - /// Week of the year, where week one begins on the first Monday of the calendar year. - monday_week_number: OptionRangedU8<0, 53>, - /// Week of the year, where week one is the Monday-to-Sunday period containing January 4. - iso_week_number: OptionRangedU8<1, 53>, - /// Day of the week. - weekday: Option<Weekday>, - /// Day of the year. - ordinal: OptionRangedU16<1, 366>, - /// Day of the month. - day: OptionRangedU8<1, 31>, - /// Hour within the day. - hour_24: OptionRangedU8<0, { Hour::per(Day) - 1 }>, - /// Hour within the 12-hour period (midnight to noon or vice versa). This is typically used in - /// conjunction with AM/PM, which is indicated by the `hour_12_is_pm` field. - hour_12: OptionRangedU8<1, 12>, - /// Whether the `hour_12` field indicates a time that "PM". - hour_12_is_pm: Option<bool>, - /// Minute within the hour. - minute: OptionRangedU8<0, { Minute::per(Hour) - 1 }>, - /// Second within the minute. - // do not subtract one, as leap seconds may be allowed - second: OptionRangedU8<0, { Second::per(Minute) }>, - /// Nanosecond within the second. - subsecond: OptionRangedU32<0, { Nanosecond::per(Second) - 1 }>, - /// Whole hours of the UTC offset. - offset_hour: OptionRangedI8<-23, 23>, - /// Minutes within the hour of the UTC offset. - offset_minute: - OptionRangedI8<{ -((Minute::per(Hour) - 1) as i8) }, { (Minute::per(Hour) - 1) as i8 }>, - /// Seconds within the minute of the UTC offset. - offset_second: - OptionRangedI8<{ -((Second::per(Minute) - 1) as i8) }, { (Second::per(Minute) - 1) as i8 }>, - /// The Unix timestamp in nanoseconds. - unix_timestamp_nanos: OptionRangedI128< - { - OffsetDateTime::new_in_offset(Date::MIN, Time::MIDNIGHT, UtcOffset::UTC) - .unix_timestamp_nanos() - }, - { - OffsetDateTime::new_in_offset(Date::MAX, Time::MAX, UtcOffset::UTC) - .unix_timestamp_nanos() - }, - >, - /// Indicates whether the [`UtcOffset`] is negative. This information is obtained when parsing - /// the offset hour, but may not otherwise be stored due to "-0" being equivalent to "0". - offset_is_negative: bool, - /// Indicates whether the `year_century` component is negative. This information is obtained - /// when parsing, but may not otherwise be stored due to "-0" being equivalent to "0". - year_century_is_negative: bool, - /// Indicates whether the `iso_year_century` component is negative. This information is - /// obtained when parsing, but may not otherwise be stored due to "-0" being equivalent to "0". - iso_year_century_is_negative: bool, - /// Indicates whether a leap second is permitted to be parsed. This is required by some - /// well-known formats. - pub(super) leap_second_allowed: bool, -} - -impl Default for Parsed { - fn default() -> Self { - Self::new() - } -} - -impl Parsed { - /// Create a new instance of `Parsed` with no information known. - pub const fn new() -> Self { - Self { - year: OptionRangedI32::None, - year_century: OptionRangedI16::None, - year_last_two: OptionRangedU8::None, - iso_year: OptionRangedI32::None, - iso_year_century: OptionRangedI16::None, - iso_year_last_two: OptionRangedU8::None, - month: None, - sunday_week_number: OptionRangedU8::None, - monday_week_number: OptionRangedU8::None, - iso_week_number: OptionRangedU8::None, - weekday: None, - ordinal: OptionRangedU16::None, - day: OptionRangedU8::None, - hour_24: OptionRangedU8::None, - hour_12: OptionRangedU8::None, - hour_12_is_pm: None, - minute: OptionRangedU8::None, - second: OptionRangedU8::None, - subsecond: OptionRangedU32::None, - offset_hour: OptionRangedI8::None, - offset_minute: OptionRangedI8::None, - offset_second: OptionRangedI8::None, - unix_timestamp_nanos: OptionRangedI128::None, - offset_is_negative: false, - year_century_is_negative: false, - iso_year_century_is_negative: false, - leap_second_allowed: false, - } - } - - /// Parse a single [`BorrowedFormatItem`] or [`OwnedFormatItem`], mutating the struct. The - /// remaining input is returned as the `Ok` value. - /// - /// If a [`BorrowedFormatItem::Optional`] or [`OwnedFormatItem::Optional`] is passed, parsing - /// will not fail; the input will be returned as-is if the expected format is not present. - pub fn parse_item<'a>( - &mut self, - input: &'a [u8], - item: &impl sealed::AnyFormatItem, - ) -> Result<&'a [u8], error::ParseFromDescription> { - item.parse_item(self, input) - } - - /// Parse a sequence of [`BorrowedFormatItem`]s or [`OwnedFormatItem`]s, mutating the struct. - /// The remaining input is returned as the `Ok` value. - /// - /// This method will fail if any of the contained [`BorrowedFormatItem`]s or - /// [`OwnedFormatItem`]s fail to parse. `self` will not be mutated in this instance. - pub fn parse_items<'a>( - &mut self, - mut input: &'a [u8], - items: &[impl sealed::AnyFormatItem], - ) -> Result<&'a [u8], error::ParseFromDescription> { - // Make a copy that we can mutate. It will only be set to the user's copy if everything - // succeeds. - let mut this = *self; - for item in items { - input = this.parse_item(input, item)?; - } - *self = this; - Ok(input) - } - - /// Parse a literal byte sequence. The remaining input is returned as the `Ok` value. - pub fn parse_literal<'a>( - input: &'a [u8], - literal: &[u8], - ) -> Result<&'a [u8], error::ParseFromDescription> { - input - .strip_prefix(literal) - .ok_or(error::ParseFromDescription::InvalidLiteral) - } - - /// Parse a single component, mutating the struct. The remaining input is returned as the `Ok` - /// value. - pub fn parse_component<'a>( - &mut self, - input: &'a [u8], - component: Component, - ) -> Result<&'a [u8], error::ParseFromDescription> { - use error::ParseFromDescription::InvalidComponent; - - match component { - Component::Day(modifiers) => parse_day(input, modifiers) - .and_then(|parsed| parsed.consume_value(|value| self.set_day(value))) - .ok_or(InvalidComponent("day")), - Component::Month(modifiers) => parse_month(input, modifiers) - .and_then(|parsed| parsed.consume_value(|value| self.set_month(value))) - .ok_or(InvalidComponent("month")), - Component::Ordinal(modifiers) => parse_ordinal(input, modifiers) - .and_then(|parsed| parsed.consume_value(|value| self.set_ordinal(value))) - .ok_or(InvalidComponent("ordinal")), - Component::Weekday(modifiers) => parse_weekday(input, modifiers) - .and_then(|parsed| parsed.consume_value(|value| self.set_weekday(value))) - .ok_or(InvalidComponent("weekday")), - Component::WeekNumber(modifiers) => { - let ParsedItem(remaining, value) = - parse_week_number(input, modifiers).ok_or(InvalidComponent("week number"))?; - match modifiers.repr { - modifier::WeekNumberRepr::Iso => { - NonZeroU8::new(value).and_then(|value| self.set_iso_week_number(value)) - } - modifier::WeekNumberRepr::Sunday => self.set_sunday_week_number(value), - modifier::WeekNumberRepr::Monday => self.set_monday_week_number(value), - } - .ok_or(InvalidComponent("week number"))?; - Ok(remaining) - } - Component::Year(modifiers) => { - let ParsedItem(remaining, (value, is_negative)) = - parse_year(input, modifiers).ok_or(InvalidComponent("year"))?; - match (modifiers.iso_week_based, modifiers.repr) { - (false, modifier::YearRepr::Full) => self.set_year(value), - (false, modifier::YearRepr::Century) => { - self.set_year_century(value.truncate(), is_negative) - } - (false, modifier::YearRepr::LastTwo) => { - self.set_year_last_two(value.cast_unsigned().truncate()) - } - (true, modifier::YearRepr::Full) => self.set_iso_year(value), - (true, modifier::YearRepr::Century) => { - self.set_iso_year_century(value.truncate(), is_negative) - } - (true, modifier::YearRepr::LastTwo) => { - self.set_iso_year_last_two(value.cast_unsigned().truncate()) - } - } - .ok_or(InvalidComponent("year"))?; - Ok(remaining) - } - Component::Hour(modifiers) => { - let ParsedItem(remaining, value) = - parse_hour(input, modifiers).ok_or(InvalidComponent("hour"))?; - if modifiers.is_12_hour_clock { - NonZeroU8::new(value).and_then(|value| self.set_hour_12(value)) - } else { - self.set_hour_24(value) - } - .ok_or(InvalidComponent("hour"))?; - Ok(remaining) - } - Component::Minute(modifiers) => parse_minute(input, modifiers) - .and_then(|parsed| parsed.consume_value(|value| self.set_minute(value))) - .ok_or(InvalidComponent("minute")), - Component::Period(modifiers) => parse_period(input, modifiers) - .and_then(|parsed| { - parsed.consume_value(|value| self.set_hour_12_is_pm(value == Period::Pm)) - }) - .ok_or(InvalidComponent("period")), - Component::Second(modifiers) => parse_second(input, modifiers) - .and_then(|parsed| parsed.consume_value(|value| self.set_second(value))) - .ok_or(InvalidComponent("second")), - Component::Subsecond(modifiers) => parse_subsecond(input, modifiers) - .and_then(|parsed| parsed.consume_value(|value| self.set_subsecond(value))) - .ok_or(InvalidComponent("subsecond")), - Component::OffsetHour(modifiers) => parse_offset_hour(input, modifiers) - .and_then(|parsed| { - parsed.consume_value(|(value, is_negative)| { - self.set_offset_hour(value)?; - self.offset_is_negative = is_negative; - Some(()) - }) - }) - .ok_or(InvalidComponent("offset hour")), - Component::OffsetMinute(modifiers) => parse_offset_minute(input, modifiers) - .and_then(|parsed| { - parsed.consume_value(|value| self.set_offset_minute_signed(value)) - }) - .ok_or(InvalidComponent("offset minute")), - Component::OffsetSecond(modifiers) => parse_offset_second(input, modifiers) - .and_then(|parsed| { - parsed.consume_value(|value| self.set_offset_second_signed(value)) - }) - .ok_or(InvalidComponent("offset second")), - Component::Ignore(modifiers) => parse_ignore(input, modifiers) - .map(ParsedItem::<()>::into_inner) - .ok_or(InvalidComponent("ignore")), - Component::UnixTimestamp(modifiers) => parse_unix_timestamp(input, modifiers) - .and_then(|parsed| { - parsed.consume_value(|value| self.set_unix_timestamp_nanos(value)) - }) - .ok_or(InvalidComponent("unix_timestamp")), - Component::End(modifiers) => parse_end(input, modifiers) - .map(ParsedItem::<()>::into_inner) - .ok_or(error::ParseFromDescription::UnexpectedTrailingCharacters), - } - } -} - -/// Getter methods -impl Parsed { - /// Obtain the `year` component. - pub const fn year(&self) -> Option<i32> { - self.year.get_primitive() - } - - /// Obtain the `year_century` component. - /// - /// If the year is zero, the sign of the century is not stored. To differentiate between - /// positive and negative zero, use `year_century_is_negative`. - pub const fn year_century(&self) -> Option<i16> { - self.year_century.get_primitive() - } - - /// Obtain the `year_century_is_negative` component. - /// - /// This indicates whether the value returned from `year_century` is negative. If the year is - /// zero, it is necessary to call this method for disambiguation. - pub const fn year_century_is_negative(&self) -> Option<bool> { - match self.year_century() { - Some(_) => Some(self.year_century_is_negative), - None => None, - } - } - - /// Obtain the `year_last_two` component. - pub const fn year_last_two(&self) -> Option<u8> { - self.year_last_two.get_primitive() - } - - /// Obtain the `iso_year` component. - pub const fn iso_year(&self) -> Option<i32> { - self.iso_year.get_primitive() - } - - /// Obtain the `iso_year_century` component. - /// - /// If the year is zero, the sign of the century is not stored. To differentiate between - /// positive and negative zero, use `iso_year_century_is_negative`. - pub const fn iso_year_century(&self) -> Option<i16> { - self.iso_year_century.get_primitive() - } - - /// Obtain the `iso_year_century_is_negative` component. - /// - /// This indicates whether the value returned from `iso_year_century` is negative. If the year - /// is zero, it is necessary to call this method for disambiguation. - pub const fn iso_year_century_is_negative(&self) -> Option<bool> { - match self.iso_year_century() { - Some(_) => Some(self.iso_year_century_is_negative), - None => None, - } - } - - /// Obtain the `iso_year_last_two` component. - pub const fn iso_year_last_two(&self) -> Option<u8> { - self.iso_year_last_two.get_primitive() - } - - /// Obtain the `month` component. - pub const fn month(&self) -> Option<Month> { - self.month - } - - /// Obtain the `sunday_week_number` component. - pub const fn sunday_week_number(&self) -> Option<u8> { - self.sunday_week_number.get_primitive() - } - - /// Obtain the `monday_week_number` component. - pub const fn monday_week_number(&self) -> Option<u8> { - self.monday_week_number.get_primitive() - } - - /// Obtain the `iso_week_number` component. - pub const fn iso_week_number(&self) -> Option<NonZeroU8> { - NonZeroU8::new(const_try_opt!(self.iso_week_number.get_primitive())) - } - - /// Obtain the `weekday` component. - pub const fn weekday(&self) -> Option<Weekday> { - self.weekday - } - - /// Obtain the `ordinal` component. - pub const fn ordinal(&self) -> Option<NonZeroU16> { - NonZeroU16::new(const_try_opt!(self.ordinal.get_primitive())) - } - - /// Obtain the `day` component. - pub const fn day(&self) -> Option<NonZeroU8> { - NonZeroU8::new(const_try_opt!(self.day.get_primitive())) - } - - /// Obtain the `hour_24` component. - pub const fn hour_24(&self) -> Option<u8> { - self.hour_24.get_primitive() - } - - /// Obtain the `hour_12` component. - pub const fn hour_12(&self) -> Option<NonZeroU8> { - NonZeroU8::new(const_try_opt!(self.hour_12.get_primitive())) - } - - /// Obtain the `hour_12_is_pm` component. - pub const fn hour_12_is_pm(&self) -> Option<bool> { - self.hour_12_is_pm - } - - /// Obtain the `minute` component. - pub const fn minute(&self) -> Option<u8> { - self.minute.get_primitive() - } - - /// Obtain the `second` component. - pub const fn second(&self) -> Option<u8> { - self.second.get_primitive() - } - - /// Obtain the `subsecond` component. - pub const fn subsecond(&self) -> Option<u32> { - self.subsecond.get_primitive() - } - - /// Obtain the `offset_hour` component. - pub const fn offset_hour(&self) -> Option<i8> { - self.offset_hour.get_primitive() - } - - /// Obtain the absolute value of the `offset_minute` component. - #[doc(hidden)] - #[deprecated(since = "0.3.8", note = "use `parsed.offset_minute_signed()` instead")] - pub const fn offset_minute(&self) -> Option<u8> { - Some(const_try_opt!(self.offset_minute_signed()).unsigned_abs()) - } - - /// Obtain the `offset_minute` component. - pub const fn offset_minute_signed(&self) -> Option<i8> { - match (self.offset_minute.get_primitive(), self.offset_is_negative) { - (Some(offset_minute), true) => Some(-offset_minute), - (Some(offset_minute), _) => Some(offset_minute), - (None, _) => None, - } - } - - /// Obtain the absolute value of the `offset_second` component. - #[doc(hidden)] - #[deprecated(since = "0.3.8", note = "use `parsed.offset_second_signed()` instead")] - pub const fn offset_second(&self) -> Option<u8> { - Some(const_try_opt!(self.offset_second_signed()).unsigned_abs()) - } - - /// Obtain the `offset_second` component. - pub const fn offset_second_signed(&self) -> Option<i8> { - match (self.offset_second.get_primitive(), self.offset_is_negative) { - (Some(offset_second), true) => Some(-offset_second), - (Some(offset_second), _) => Some(offset_second), - (None, _) => None, - } - } - - /// Obtain the `unix_timestamp_nanos` component. - pub const fn unix_timestamp_nanos(&self) -> Option<i128> { - self.unix_timestamp_nanos.get_primitive() - } -} - -/// Generate setters based on the builders. -macro_rules! setters { - ($($name:ident $setter:ident $builder:ident $type:ty;)*) => {$( - #[doc = concat!("Set the `", stringify!($name), "` component.")] - pub fn $setter(&mut self, value: $type) -> Option<()> { - *self = self.$builder(value)?; - Some(()) - } - )*}; -} - -/// Setter methods -/// -/// All setters return `Option<()>`, which is `Some` if the value was set, and `None` if not. The -/// setters _may_ fail if the value is invalid, though behavior is not guaranteed. -impl Parsed { - setters! { - year set_year with_year i32; - } - - /// Set the `year_century` component. - /// - /// If the value is zero, the sign of the century is taken from the second parameter. Otherwise - /// the sign is inferred from the value. - pub fn set_year_century(&mut self, value: i16, is_negative: bool) -> Option<()> { - self.year_century = OptionRangedI16::Some(const_try_opt!(RangedI16::new(value))); - if value != 0 { - self.year_century_is_negative = value.is_negative(); - } else { - self.year_century_is_negative = is_negative; - } - Some(()) - } - - setters! { - year_last_two set_year_last_two with_year_last_two u8; - iso_year set_iso_year with_iso_year i32; - iso_year_last_two set_iso_year_last_two with_iso_year_last_two u8; - } - - /// Set the `iso_year_century` component. - /// - /// If the value is zero, the sign of the century is taken from the second parameter. Otherwise - /// the sign is inferred from the value. - pub fn set_iso_year_century(&mut self, value: i16, is_negative: bool) -> Option<()> { - self.iso_year_century = OptionRangedI16::Some(const_try_opt!(RangedI16::new(value))); - if value != 0 { - self.iso_year_century_is_negative = value.is_negative(); - } else { - self.iso_year_century_is_negative = is_negative; - } - Some(()) - } - - setters! { - month set_month with_month Month; - sunday_week_number set_sunday_week_number with_sunday_week_number u8; - monday_week_number set_monday_week_number with_monday_week_number u8; - iso_week_number set_iso_week_number with_iso_week_number NonZeroU8; - weekday set_weekday with_weekday Weekday; - ordinal set_ordinal with_ordinal NonZeroU16; - day set_day with_day NonZeroU8; - hour_24 set_hour_24 with_hour_24 u8; - hour_12 set_hour_12 with_hour_12 NonZeroU8; - hour_12_is_pm set_hour_12_is_pm with_hour_12_is_pm bool; - minute set_minute with_minute u8; - second set_second with_second u8; - subsecond set_subsecond with_subsecond u32; - offset_hour set_offset_hour with_offset_hour i8; - offset_minute set_offset_minute_signed with_offset_minute_signed i8; - offset_second set_offset_second_signed with_offset_second_signed i8; - unix_timestamp_nanos set_unix_timestamp_nanos with_unix_timestamp_nanos i128; - } - - /// Set the `offset_minute` component. - #[doc(hidden)] - #[deprecated( - since = "0.3.8", - note = "use `parsed.set_offset_minute_signed()` instead" - )] - pub fn set_offset_minute(&mut self, value: u8) -> Option<()> { - if value > i8::MAX.cast_unsigned() { - None - } else { - self.set_offset_minute_signed(value.cast_signed()) - } - } - - /// Set the `offset_minute` component. - #[doc(hidden)] - #[deprecated( - since = "0.3.8", - note = "use `parsed.set_offset_second_signed()` instead" - )] - pub fn set_offset_second(&mut self, value: u8) -> Option<()> { - if value > i8::MAX.cast_unsigned() { - None - } else { - self.set_offset_second_signed(value.cast_signed()) - } - } -} - -/// Builder methods -/// -/// All builder methods return `Option<Self>`, which is `Some` if the value was set, and `None` if -/// not. The builder methods _may_ fail if the value is invalid, though behavior is not guaranteed. -impl Parsed { - /// Set the `year` component and return `self`. - pub const fn with_year(mut self, value: i32) -> Option<Self> { - self.year = OptionRangedI32::Some(const_try_opt!(RangedI32::new(value))); - Some(self) - } - - /// Set the `year_century` component and return `self`. - /// - /// If the value is zero, the sign of the century is taken from the second parameter. Otherwise - /// the sign is inferred from the value. - pub const fn with_year_century(mut self, value: i16, is_negative: bool) -> Option<Self> { - self.year_century = OptionRangedI16::Some(const_try_opt!(RangedI16::new(value))); - if value != 0 { - self.year_century_is_negative = value.is_negative(); - } else { - self.year_century_is_negative = is_negative; - } - Some(self) - } - - /// Set the `year_last_two` component and return `self`. - pub const fn with_year_last_two(mut self, value: u8) -> Option<Self> { - self.year_last_two = OptionRangedU8::Some(const_try_opt!(RangedU8::new(value))); - Some(self) - } - - /// Set the `iso_year` component and return `self`. - pub const fn with_iso_year(mut self, value: i32) -> Option<Self> { - self.iso_year = OptionRangedI32::Some(const_try_opt!(RangedI32::new(value))); - Some(self) - } - - /// Set the `iso_year_century` component and return `self`. - /// - /// If the value is zero, the sign of the century is taken from the second parameter. Otherwise - /// the sign is inferred from the value. - pub const fn with_iso_year_century(mut self, value: i16, is_negative: bool) -> Option<Self> { - self.iso_year_century = OptionRangedI16::Some(const_try_opt!(RangedI16::new(value))); - if value != 0 { - self.iso_year_century_is_negative = value.is_negative(); - } else { - self.iso_year_century_is_negative = is_negative; - } - Some(self) - } - - /// Set the `iso_year_last_two` component and return `self`. - pub const fn with_iso_year_last_two(mut self, value: u8) -> Option<Self> { - self.iso_year_last_two = OptionRangedU8::Some(const_try_opt!(RangedU8::new(value))); - Some(self) - } - - /// Set the `month` component and return `self`. - pub const fn with_month(mut self, value: Month) -> Option<Self> { - self.month = Some(value); - Some(self) - } - - /// Set the `sunday_week_number` component and return `self`. - pub const fn with_sunday_week_number(mut self, value: u8) -> Option<Self> { - self.sunday_week_number = OptionRangedU8::Some(const_try_opt!(RangedU8::new(value))); - Some(self) - } - - /// Set the `monday_week_number` component and return `self`. - pub const fn with_monday_week_number(mut self, value: u8) -> Option<Self> { - self.monday_week_number = OptionRangedU8::Some(const_try_opt!(RangedU8::new(value))); - Some(self) - } - - /// Set the `iso_week_number` component and return `self`. - pub const fn with_iso_week_number(mut self, value: NonZeroU8) -> Option<Self> { - self.iso_week_number = OptionRangedU8::Some(const_try_opt!(RangedU8::new(value.get()))); - Some(self) - } - - /// Set the `weekday` component and return `self`. - pub const fn with_weekday(mut self, value: Weekday) -> Option<Self> { - self.weekday = Some(value); - Some(self) - } - - /// Set the `ordinal` component and return `self`. - pub const fn with_ordinal(mut self, value: NonZeroU16) -> Option<Self> { - self.ordinal = OptionRangedU16::Some(const_try_opt!(RangedU16::new(value.get()))); - Some(self) - } - - /// Set the `day` component and return `self`. - pub const fn with_day(mut self, value: NonZeroU8) -> Option<Self> { - self.day = OptionRangedU8::Some(const_try_opt!(RangedU8::new(value.get()))); - Some(self) - } - - /// Set the `hour_24` component and return `self`. - pub const fn with_hour_24(mut self, value: u8) -> Option<Self> { - self.hour_24 = OptionRangedU8::Some(const_try_opt!(RangedU8::new(value))); - Some(self) - } - - /// Set the `hour_12` component and return `self`. - pub const fn with_hour_12(mut self, value: NonZeroU8) -> Option<Self> { - self.hour_12 = OptionRangedU8::Some(const_try_opt!(RangedU8::new(value.get()))); - Some(self) - } - - /// Set the `hour_12_is_pm` component and return `self`. - pub const fn with_hour_12_is_pm(mut self, value: bool) -> Option<Self> { - self.hour_12_is_pm = Some(value); - Some(self) - } - - /// Set the `minute` component and return `self`. - pub const fn with_minute(mut self, value: u8) -> Option<Self> { - self.minute = OptionRangedU8::Some(const_try_opt!(RangedU8::new(value))); - Some(self) - } - - /// Set the `second` component and return `self`. - pub const fn with_second(mut self, value: u8) -> Option<Self> { - self.second = OptionRangedU8::Some(const_try_opt!(RangedU8::new(value))); - Some(self) - } - - /// Set the `subsecond` component and return `self`. - pub const fn with_subsecond(mut self, value: u32) -> Option<Self> { - self.subsecond = OptionRangedU32::Some(const_try_opt!(RangedU32::new(value))); - Some(self) - } - - /// Set the `offset_hour` component and return `self`. - pub const fn with_offset_hour(mut self, value: i8) -> Option<Self> { - self.offset_hour = OptionRangedI8::Some(const_try_opt!(RangedI8::new(value))); - Some(self) - } - - /// Set the `offset_minute` component and return `self`. - #[doc(hidden)] - #[deprecated( - since = "0.3.8", - note = "use `parsed.with_offset_minute_signed()` instead" - )] - pub const fn with_offset_minute(self, value: u8) -> Option<Self> { - if value > i8::MAX as u8 { - None - } else { - self.with_offset_minute_signed(value as i8) - } - } - - /// Set the `offset_minute` component and return `self`. - pub const fn with_offset_minute_signed(mut self, value: i8) -> Option<Self> { - self.offset_minute = OptionRangedI8::Some(const_try_opt!(RangedI8::new(value))); - Some(self) - } - - /// Set the `offset_minute` component and return `self`. - #[doc(hidden)] - #[deprecated( - since = "0.3.8", - note = "use `parsed.with_offset_second_signed()` instead" - )] - pub const fn with_offset_second(self, value: u8) -> Option<Self> { - if value > i8::MAX as u8 { - None - } else { - self.with_offset_second_signed(value as i8) - } - } - - /// Set the `offset_second` component and return `self`. - pub const fn with_offset_second_signed(mut self, value: i8) -> Option<Self> { - self.offset_second = OptionRangedI8::Some(const_try_opt!(RangedI8::new(value))); - Some(self) - } - - /// Set the `unix_timestamp_nanos` component and return `self`. - pub const fn with_unix_timestamp_nanos(mut self, value: i128) -> Option<Self> { - self.unix_timestamp_nanos = OptionRangedI128::Some(const_try_opt!(RangedI128::new(value))); - Some(self) - } -} - -impl TryFrom<Parsed> for Date { - type Error = error::TryFromParsed; - - fn try_from(mut parsed: Parsed) -> Result<Self, Self::Error> { - /// Match on the components that need to be present. - macro_rules! match_ { - (_ => $catch_all:expr $(,)?) => { - $catch_all - }; - (($($name:ident),* $(,)?) => $arm:expr, $($rest:tt)*) => { - if let ($(Some($name)),*) = ($(parsed.$name()),*) { - $arm - } else { - match_!($($rest)*) - } - }; - } - - /// Get the value needed to adjust the ordinal day for Sunday and Monday-based week - /// numbering. - const fn adjustment(year: i32) -> i16 { - // Safety: `ordinal` is not zero. - match unsafe { Date::__from_ordinal_date_unchecked(year, 1) }.weekday() { - Weekday::Monday => 7, - Weekday::Tuesday => 1, - Weekday::Wednesday => 2, - Weekday::Thursday => 3, - Weekday::Friday => 4, - Weekday::Saturday => 5, - Weekday::Sunday => 6, - } - } - - // If we do not have the year but we have *both* the century and the last two digits, we can - // construct the year. Likewise for the ISO year. - if let (None, Some(century), Some(is_negative), Some(last_two)) = ( - parsed.year(), - parsed.year_century(), - parsed.year_century_is_negative(), - parsed.year_last_two(), - ) { - let year = if is_negative { - 100 * century.extend::<i32>() - last_two.cast_signed().extend::<i32>() - } else { - 100 * century.extend::<i32>() + last_two.cast_signed().extend::<i32>() - }; - parsed.year = OptionRangedI32::from(RangedI32::new(year)); - } - if let (None, Some(century), Some(is_negative), Some(last_two)) = ( - parsed.iso_year(), - parsed.iso_year_century(), - parsed.iso_year_century_is_negative(), - parsed.iso_year_last_two(), - ) { - let iso_year = if is_negative { - 100 * century.extend::<i32>() - last_two.cast_signed().extend::<i32>() - } else { - 100 * century.extend::<i32>() + last_two.cast_signed().extend::<i32>() - }; - parsed.iso_year = OptionRangedI32::from(RangedI32::new(iso_year)); - } - - match_! { - (year, ordinal) => Ok(Self::from_ordinal_date(year, ordinal.get())?), - (year, month, day) => Ok(Self::from_calendar_date(year, month, day.get())?), - (iso_year, iso_week_number, weekday) => Ok(Self::from_iso_week_date( - iso_year, - iso_week_number.get(), - weekday, - )?), - (year, sunday_week_number, weekday) => Ok(Self::from_ordinal_date( - year, - (sunday_week_number.cast_signed().extend::<i16>() * 7 - + weekday.number_days_from_sunday().cast_signed().extend::<i16>() - - adjustment(year) - + 1).cast_unsigned(), - )?), - (year, monday_week_number, weekday) => Ok(Self::from_ordinal_date( - year, - (monday_week_number.cast_signed().extend::<i16>() * 7 - + weekday.number_days_from_monday().cast_signed().extend::<i16>() - - adjustment(year) - + 1).cast_unsigned(), - )?), - _ => Err(InsufficientInformation), - } - } -} - -impl TryFrom<Parsed> for Time { - type Error = error::TryFromParsed; - - fn try_from(parsed: Parsed) -> Result<Self, Self::Error> { - let hour = match (parsed.hour_24(), parsed.hour_12(), parsed.hour_12_is_pm()) { - (Some(hour), _, _) => hour, - (_, Some(hour), Some(false)) if hour.get() == 12 => 0, - (_, Some(hour), Some(true)) if hour.get() == 12 => 12, - (_, Some(hour), Some(false)) => hour.get(), - (_, Some(hour), Some(true)) => hour.get() + 12, - _ => return Err(InsufficientInformation), - }; - - if parsed.hour_24().is_none() - && parsed.hour_12().is_some() - && parsed.hour_12_is_pm().is_some() - && parsed.minute().is_none() - && parsed.second().is_none() - && parsed.subsecond().is_none() - { - return Ok(Self::from_hms_nano(hour, 0, 0, 0)?); - } - - // Reject combinations such as hour-second with minute omitted. - match (parsed.minute(), parsed.second(), parsed.subsecond()) { - (None, None, None) => Ok(Self::from_hms_nano(hour, 0, 0, 0)?), - (Some(minute), None, None) => Ok(Self::from_hms_nano(hour, minute, 0, 0)?), - (Some(minute), Some(second), None) => Ok(Self::from_hms_nano(hour, minute, second, 0)?), - (Some(minute), Some(second), Some(subsecond)) => { - Ok(Self::from_hms_nano(hour, minute, second, subsecond)?) - } - _ => Err(InsufficientInformation), - } - } -} - -fn utc_offset_try_from_parsed<const REQUIRED: bool>( - parsed: Parsed, -) -> Result<UtcOffset, error::TryFromParsed> { - let hour = match (REQUIRED, parsed.offset_hour()) { - // An offset is required, but the hour is missing. Return an error. - (true, None) => return Err(InsufficientInformation), - // An offset is not required (e.g. for `UtcDateTime`). As the hour is missing, minutes and - // seconds are not parsed. This is UTC. - (false, None) => return Ok(UtcOffset::UTC), - // Any other situation has an hour present. - (_, Some(hour)) => hour, - }; - let minute = parsed.offset_minute_signed(); - // Force `second` to be `None` if `minute` is `None`. - let second = minute.and_then(|_| parsed.offset_second_signed()); - - let minute = minute.unwrap_or(0); - let second = second.unwrap_or(0); - - UtcOffset::from_hms(hour, minute, second).map_err(|mut err| { - // Provide the user a more accurate error. - if err.name == "hours" { - err.name = "offset hour"; - } else if err.name == "minutes" { - err.name = "offset minute"; - } else if err.name == "seconds" { - err.name = "offset second"; - } - err.into() - }) -} - -impl TryFrom<Parsed> for UtcOffset { - type Error = error::TryFromParsed; - - fn try_from(parsed: Parsed) -> Result<Self, Self::Error> { - utc_offset_try_from_parsed::<true>(parsed) - } -} - -impl TryFrom<Parsed> for PrimitiveDateTime { - type Error = error::TryFromParsed; - - fn try_from(parsed: Parsed) -> Result<Self, Self::Error> { - Ok(Self::new(parsed.try_into()?, parsed.try_into()?)) - } -} - -impl TryFrom<Parsed> for UtcDateTime { - type Error = error::TryFromParsed; - - fn try_from(mut parsed: Parsed) -> Result<Self, Self::Error> { - if let Some(timestamp) = parsed.unix_timestamp_nanos() { - let mut value = Self::from_unix_timestamp_nanos(timestamp)?; - if let Some(subsecond) = parsed.subsecond() { - value = value.replace_nanosecond(subsecond)?; - } - return Ok(value); - } - - // Some well-known formats explicitly allow leap seconds. We don't currently support them, - // so treat it as the nearest preceding moment that can be represented. Because leap seconds - // always fall at the end of a month UTC, reject any that are at other times. - let leap_second_input = if parsed.leap_second_allowed && parsed.second() == Some(60) { - if parsed.set_second(59).is_none() { - bug!("59 is a valid second"); - } - if parsed.set_subsecond(999_999_999).is_none() { - bug!("999_999_999 is a valid subsecond"); - } - true - } else { - false - }; - - let dt = OffsetDateTime::new_in_offset( - Date::try_from(parsed)?, - Time::try_from(parsed)?, - utc_offset_try_from_parsed::<false>(parsed)?, - ) - .to_utc(); - - if leap_second_input && !dt.is_valid_leap_second_stand_in() { - return Err(error::TryFromParsed::ComponentRange( - error::ComponentRange { - name: "second", - minimum: 0, - maximum: 59, - value: 60, - conditional_message: Some("because leap seconds are not supported"), - }, - )); - } - Ok(dt) - } -} - -impl TryFrom<Parsed> for OffsetDateTime { - type Error = error::TryFromParsed; - - fn try_from(mut parsed: Parsed) -> Result<Self, Self::Error> { - if let Some(timestamp) = parsed.unix_timestamp_nanos() { - let mut value = Self::from_unix_timestamp_nanos(timestamp)?; - if let Some(subsecond) = parsed.subsecond() { - value = value.replace_nanosecond(subsecond)?; - } - return Ok(value); - } - - // Some well-known formats explicitly allow leap seconds. We don't currently support them, - // so treat it as the nearest preceding moment that can be represented. Because leap seconds - // always fall at the end of a month UTC, reject any that are at other times. - let leap_second_input = if parsed.leap_second_allowed && parsed.second() == Some(60) { - if parsed.set_second(59).is_none() { - bug!("59 is a valid second"); - } - if parsed.set_subsecond(999_999_999).is_none() { - bug!("999_999_999 is a valid subsecond"); - } - true - } else { - false - }; - - let dt = Self::new_in_offset( - Date::try_from(parsed)?, - Time::try_from(parsed)?, - UtcOffset::try_from(parsed)?, - ); - - if leap_second_input && !dt.is_valid_leap_second_stand_in() { - return Err(error::TryFromParsed::ComponentRange( - error::ComponentRange { - name: "second", - minimum: 0, - maximum: 59, - value: 60, - conditional_message: Some("because leap seconds are not supported"), - }, - )); - } - Ok(dt) - } -} diff --git a/vendor/time/src/parsing/shim.rs b/vendor/time/src/parsing/shim.rs deleted file mode 100644 index ced7feb0..00000000 --- a/vendor/time/src/parsing/shim.rs +++ /dev/null @@ -1,50 +0,0 @@ -//! Extension traits for things either not implemented or not yet stable in the MSRV. - -/// Equivalent of `foo.parse()` for slices. -pub(crate) trait IntegerParseBytes<T> { - #[allow(clippy::missing_docs_in_private_items)] - fn parse_bytes(&self) -> Option<T>; -} - -impl<T: Integer> IntegerParseBytes<T> for [u8] { - fn parse_bytes(&self) -> Option<T> { - T::parse_bytes(self) - } -} - -/// Marker trait for all integer types, including `NonZero*` -pub(crate) trait Integer: Sized { - #[allow(clippy::missing_docs_in_private_items)] - fn parse_bytes(src: &[u8]) -> Option<Self>; -} - -/// Parse the given types from bytes. -macro_rules! impl_parse_bytes { - ($($t:ty)*) => ($( - impl Integer for $t { - #[allow(trivial_numeric_casts)] - fn parse_bytes(src: &[u8]) -> Option<Self> { - src.iter().try_fold::<Self, _, _>(0, |result, c| { - result.checked_mul(10)?.checked_add((c - b'0') as Self) - }) - } - } - )*) -} -impl_parse_bytes! { u8 u16 u32 u128 } - -/// Parse the given types from bytes. -macro_rules! impl_parse_bytes_nonzero { - ($($t:ty)*) => {$( - impl Integer for $t { - fn parse_bytes(src: &[u8]) -> Option<Self> { - Self::new(src.parse_bytes()?) - } - } - )*} -} - -impl_parse_bytes_nonzero! { - core::num::NonZeroU8 - core::num::NonZeroU16 -} diff --git a/vendor/time/src/primitive_date_time.rs b/vendor/time/src/primitive_date_time.rs deleted file mode 100644 index 07c11cba..00000000 --- a/vendor/time/src/primitive_date_time.rs +++ /dev/null @@ -1,1050 +0,0 @@ -//! The [`PrimitiveDateTime`] struct and its associated `impl`s. - -#[cfg(feature = "formatting")] -use alloc::string::String; -use core::fmt; -use core::ops::{Add, AddAssign, Sub, SubAssign}; -use core::time::Duration as StdDuration; -#[cfg(feature = "formatting")] -use std::io; - -use powerfmt::ext::FormatterExt as _; -use powerfmt::smart_display::{self, FormatterOptions, Metadata, SmartDisplay}; - -#[cfg(feature = "formatting")] -use crate::formatting::Formattable; -use crate::internal_macros::{const_try, const_try_opt}; -#[cfg(feature = "parsing")] -use crate::parsing::Parsable; -use crate::{ - error, util, Date, Duration, Month, OffsetDateTime, Time, UtcDateTime, UtcOffset, Weekday, -}; - -/// Combined date and time. -#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] -pub struct PrimitiveDateTime { - date: Date, - time: Time, -} - -impl PrimitiveDateTime { - /// The smallest value that can be represented by `PrimitiveDateTime`. - /// - /// Depending on `large-dates` feature flag, value of this constant may vary. - /// - /// 1. With `large-dates` disabled it is equal to `-9999-01-01 00:00:00.0` - /// 2. With `large-dates` enabled it is equal to `-999999-01-01 00:00:00.0` - /// - /// ```rust - /// # use time::PrimitiveDateTime; - /// # use time_macros::datetime; - #[cfg_attr( - feature = "large-dates", - doc = "// Assuming `large-dates` feature is enabled." - )] - #[cfg_attr( - feature = "large-dates", - doc = "assert_eq!(PrimitiveDateTime::MIN, datetime!(-999999-01-01 0:00));" - )] - #[cfg_attr( - not(feature = "large-dates"), - doc = "// Assuming `large-dates` feature is disabled." - )] - #[cfg_attr( - not(feature = "large-dates"), - doc = "assert_eq!(PrimitiveDateTime::MIN, datetime!(-9999-01-01 0:00));" - )] - /// ``` - pub const MIN: Self = Self { - date: Date::MIN, - time: Time::MIDNIGHT, - }; - - /// The largest value that can be represented by `PrimitiveDateTime`. - /// - /// Depending on `large-dates` feature flag, value of this constant may vary. - /// - /// 1. With `large-dates` disabled it is equal to `9999-12-31 23:59:59.999_999_999` - /// 2. With `large-dates` enabled it is equal to `999999-12-31 23:59:59.999_999_999` - /// - /// ```rust - /// # use time::PrimitiveDateTime; - /// # use time_macros::datetime; - #[cfg_attr( - feature = "large-dates", - doc = "// Assuming `large-dates` feature is enabled." - )] - #[cfg_attr( - feature = "large-dates", - doc = "assert_eq!(PrimitiveDateTime::MAX, datetime!(+999999-12-31 23:59:59.999_999_999));" - )] - #[cfg_attr( - not(feature = "large-dates"), - doc = "// Assuming `large-dates` feature is disabled." - )] - #[cfg_attr( - not(feature = "large-dates"), - doc = "assert_eq!(PrimitiveDateTime::MAX, datetime!(+9999-12-31 23:59:59.999_999_999));" - )] - /// ``` - pub const MAX: Self = Self { - date: Date::MAX, - time: Time::MAX, - }; - - /// Create a new `PrimitiveDateTime` from the provided [`Date`] and [`Time`]. - /// - /// ```rust - /// # use time::PrimitiveDateTime; - /// # use time_macros::{date, datetime, time}; - /// assert_eq!( - /// PrimitiveDateTime::new(date!(2019-01-01), time!(0:00)), - /// datetime!(2019-01-01 0:00), - /// ); - /// ``` - pub const fn new(date: Date, time: Time) -> Self { - Self { date, time } - } - - /// Get the [`Date`] component of the `PrimitiveDateTime`. - /// - /// ```rust - /// # use time_macros::{date, datetime}; - /// assert_eq!(datetime!(2019-01-01 0:00).date(), date!(2019-01-01)); - /// ``` - pub const fn date(self) -> Date { - self.date - } - - /// Get the [`Time`] component of the `PrimitiveDateTime`. - /// - /// ```rust - /// # use time_macros::{datetime, time}; - /// assert_eq!(datetime!(2019-01-01 0:00).time(), time!(0:00)); - /// ``` - pub const fn time(self) -> Time { - self.time - } - - /// Get the year of the date. - /// - /// ```rust - /// # use time_macros::datetime; - /// assert_eq!(datetime!(2019-01-01 0:00).year(), 2019); - /// assert_eq!(datetime!(2019-12-31 0:00).year(), 2019); - /// assert_eq!(datetime!(2020-01-01 0:00).year(), 2020); - /// ``` - pub const fn year(self) -> i32 { - self.date().year() - } - - /// Get the month of the date. - /// - /// ```rust - /// # use time::Month; - /// # use time_macros::datetime; - /// assert_eq!(datetime!(2019-01-01 0:00).month(), Month::January); - /// assert_eq!(datetime!(2019-12-31 0:00).month(), Month::December); - /// ``` - pub const fn month(self) -> Month { - self.date().month() - } - - /// Get the day of the date. - /// - /// The returned value will always be in the range `1..=31`. - /// - /// ```rust - /// # use time_macros::datetime; - /// assert_eq!(datetime!(2019-01-01 0:00).day(), 1); - /// assert_eq!(datetime!(2019-12-31 0:00).day(), 31); - /// ``` - pub const fn day(self) -> u8 { - self.date().day() - } - - /// Get the day of the year. - /// - /// The returned value will always be in the range `1..=366` (`1..=365` for common years). - /// - /// ```rust - /// # use time_macros::datetime; - /// assert_eq!(datetime!(2019-01-01 0:00).ordinal(), 1); - /// assert_eq!(datetime!(2019-12-31 0:00).ordinal(), 365); - /// ``` - pub const fn ordinal(self) -> u16 { - self.date().ordinal() - } - - /// Get the ISO week number. - /// - /// The returned value will always be in the range `1..=53`. - /// - /// ```rust - /// # use time_macros::datetime; - /// assert_eq!(datetime!(2019-01-01 0:00).iso_week(), 1); - /// assert_eq!(datetime!(2019-10-04 0:00).iso_week(), 40); - /// assert_eq!(datetime!(2020-01-01 0:00).iso_week(), 1); - /// assert_eq!(datetime!(2020-12-31 0:00).iso_week(), 53); - /// assert_eq!(datetime!(2021-01-01 0:00).iso_week(), 53); - /// ``` - pub const fn iso_week(self) -> u8 { - self.date().iso_week() - } - - /// Get the week number where week 1 begins on the first Sunday. - /// - /// The returned value will always be in the range `0..=53`. - /// - /// ```rust - /// # use time_macros::datetime; - /// assert_eq!(datetime!(2019-01-01 0:00).sunday_based_week(), 0); - /// assert_eq!(datetime!(2020-01-01 0:00).sunday_based_week(), 0); - /// assert_eq!(datetime!(2020-12-31 0:00).sunday_based_week(), 52); - /// assert_eq!(datetime!(2021-01-01 0:00).sunday_based_week(), 0); - /// ``` - pub const fn sunday_based_week(self) -> u8 { - self.date().sunday_based_week() - } - - /// Get the week number where week 1 begins on the first Monday. - /// - /// The returned value will always be in the range `0..=53`. - /// - /// ```rust - /// # use time_macros::datetime; - /// assert_eq!(datetime!(2019-01-01 0:00).monday_based_week(), 0); - /// assert_eq!(datetime!(2020-01-01 0:00).monday_based_week(), 0); - /// assert_eq!(datetime!(2020-12-31 0:00).monday_based_week(), 52); - /// assert_eq!(datetime!(2021-01-01 0:00).monday_based_week(), 0); - /// ``` - pub const fn monday_based_week(self) -> u8 { - self.date().monday_based_week() - } - - /// Get the year, month, and day. - /// - /// ```rust - /// # use time::Month; - /// # use time_macros::datetime; - /// assert_eq!( - /// datetime!(2019-01-01 0:00).to_calendar_date(), - /// (2019, Month::January, 1) - /// ); - /// ``` - pub const fn to_calendar_date(self) -> (i32, Month, u8) { - self.date().to_calendar_date() - } - - /// Get the year and ordinal day number. - /// - /// ```rust - /// # use time_macros::datetime; - /// assert_eq!(datetime!(2019-01-01 0:00).to_ordinal_date(), (2019, 1)); - /// ``` - pub const fn to_ordinal_date(self) -> (i32, u16) { - self.date().to_ordinal_date() - } - - /// Get the ISO 8601 year, week number, and weekday. - /// - /// ```rust - /// # use time::Weekday::*; - /// # use time_macros::datetime; - /// assert_eq!( - /// datetime!(2019-01-01 0:00).to_iso_week_date(), - /// (2019, 1, Tuesday) - /// ); - /// assert_eq!( - /// datetime!(2019-10-04 0:00).to_iso_week_date(), - /// (2019, 40, Friday) - /// ); - /// assert_eq!( - /// datetime!(2020-01-01 0:00).to_iso_week_date(), - /// (2020, 1, Wednesday) - /// ); - /// assert_eq!( - /// datetime!(2020-12-31 0:00).to_iso_week_date(), - /// (2020, 53, Thursday) - /// ); - /// assert_eq!( - /// datetime!(2021-01-01 0:00).to_iso_week_date(), - /// (2020, 53, Friday) - /// ); - /// ``` - pub const fn to_iso_week_date(self) -> (i32, u8, Weekday) { - self.date().to_iso_week_date() - } - - /// Get the weekday. - /// - /// ```rust - /// # use time::Weekday::*; - /// # use time_macros::datetime; - /// assert_eq!(datetime!(2019-01-01 0:00).weekday(), Tuesday); - /// assert_eq!(datetime!(2019-02-01 0:00).weekday(), Friday); - /// assert_eq!(datetime!(2019-03-01 0:00).weekday(), Friday); - /// assert_eq!(datetime!(2019-04-01 0:00).weekday(), Monday); - /// assert_eq!(datetime!(2019-05-01 0:00).weekday(), Wednesday); - /// assert_eq!(datetime!(2019-06-01 0:00).weekday(), Saturday); - /// assert_eq!(datetime!(2019-07-01 0:00).weekday(), Monday); - /// assert_eq!(datetime!(2019-08-01 0:00).weekday(), Thursday); - /// assert_eq!(datetime!(2019-09-01 0:00).weekday(), Sunday); - /// assert_eq!(datetime!(2019-10-01 0:00).weekday(), Tuesday); - /// assert_eq!(datetime!(2019-11-01 0:00).weekday(), Friday); - /// assert_eq!(datetime!(2019-12-01 0:00).weekday(), Sunday); - /// ``` - pub const fn weekday(self) -> Weekday { - self.date().weekday() - } - - /// Get the Julian day for the date. The time is not taken into account for this calculation. - /// - /// The algorithm to perform this conversion is derived from one provided by Peter Baum; it is - /// freely available [here](https://www.researchgate.net/publication/316558298_Date_Algorithms). - /// - /// ```rust - /// # use time_macros::datetime; - /// assert_eq!(datetime!(-4713-11-24 0:00).to_julian_day(), 0); - /// assert_eq!(datetime!(2000-01-01 0:00).to_julian_day(), 2_451_545); - /// assert_eq!(datetime!(2019-01-01 0:00).to_julian_day(), 2_458_485); - /// assert_eq!(datetime!(2019-12-31 0:00).to_julian_day(), 2_458_849); - /// ``` - pub const fn to_julian_day(self) -> i32 { - self.date().to_julian_day() - } - - /// Get the clock hour, minute, and second. - /// - /// ```rust - /// # use time_macros::datetime; - /// assert_eq!(datetime!(2020-01-01 0:00:00).as_hms(), (0, 0, 0)); - /// assert_eq!(datetime!(2020-01-01 23:59:59).as_hms(), (23, 59, 59)); - /// ``` - pub const fn as_hms(self) -> (u8, u8, u8) { - self.time().as_hms() - } - - /// Get the clock hour, minute, second, and millisecond. - /// - /// ```rust - /// # use time_macros::datetime; - /// assert_eq!(datetime!(2020-01-01 0:00:00).as_hms_milli(), (0, 0, 0, 0)); - /// assert_eq!( - /// datetime!(2020-01-01 23:59:59.999).as_hms_milli(), - /// (23, 59, 59, 999) - /// ); - /// ``` - pub const fn as_hms_milli(self) -> (u8, u8, u8, u16) { - self.time().as_hms_milli() - } - - /// Get the clock hour, minute, second, and microsecond. - /// - /// ```rust - /// # use time_macros::datetime; - /// assert_eq!(datetime!(2020-01-01 0:00:00).as_hms_micro(), (0, 0, 0, 0)); - /// assert_eq!( - /// datetime!(2020-01-01 23:59:59.999_999).as_hms_micro(), - /// (23, 59, 59, 999_999) - /// ); - /// ``` - pub const fn as_hms_micro(self) -> (u8, u8, u8, u32) { - self.time().as_hms_micro() - } - - /// Get the clock hour, minute, second, and nanosecond. - /// - /// ```rust - /// # use time_macros::datetime; - /// assert_eq!(datetime!(2020-01-01 0:00:00).as_hms_nano(), (0, 0, 0, 0)); - /// assert_eq!( - /// datetime!(2020-01-01 23:59:59.999_999_999).as_hms_nano(), - /// (23, 59, 59, 999_999_999) - /// ); - /// ``` - pub const fn as_hms_nano(self) -> (u8, u8, u8, u32) { - self.time().as_hms_nano() - } - - /// Get the clock hour. - /// - /// The returned value will always be in the range `0..24`. - /// - /// ```rust - /// # use time_macros::datetime; - /// assert_eq!(datetime!(2019-01-01 0:00).hour(), 0); - /// assert_eq!(datetime!(2019-01-01 23:59:59).hour(), 23); - /// ``` - pub const fn hour(self) -> u8 { - self.time().hour() - } - - /// Get the minute within the hour. - /// - /// The returned value will always be in the range `0..60`. - /// - /// ```rust - /// # use time_macros::datetime; - /// assert_eq!(datetime!(2019-01-01 0:00).minute(), 0); - /// assert_eq!(datetime!(2019-01-01 23:59:59).minute(), 59); - /// ``` - pub const fn minute(self) -> u8 { - self.time().minute() - } - - /// Get the second within the minute. - /// - /// The returned value will always be in the range `0..60`. - /// - /// ```rust - /// # use time_macros::datetime; - /// assert_eq!(datetime!(2019-01-01 0:00).second(), 0); - /// assert_eq!(datetime!(2019-01-01 23:59:59).second(), 59); - /// ``` - pub const fn second(self) -> u8 { - self.time().second() - } - - /// Get the milliseconds within the second. - /// - /// The returned value will always be in the range `0..1_000`. - /// - /// ```rust - /// # use time_macros::datetime; - /// assert_eq!(datetime!(2019-01-01 0:00).millisecond(), 0); - /// assert_eq!(datetime!(2019-01-01 23:59:59.999).millisecond(), 999); - /// ``` - pub const fn millisecond(self) -> u16 { - self.time().millisecond() - } - - /// Get the microseconds within the second. - /// - /// The returned value will always be in the range `0..1_000_000`. - /// - /// ```rust - /// # use time_macros::datetime; - /// assert_eq!(datetime!(2019-01-01 0:00).microsecond(), 0); - /// assert_eq!( - /// datetime!(2019-01-01 23:59:59.999_999).microsecond(), - /// 999_999 - /// ); - /// ``` - pub const fn microsecond(self) -> u32 { - self.time().microsecond() - } - - /// Get the nanoseconds within the second. - /// - /// The returned value will always be in the range `0..1_000_000_000`. - /// - /// ```rust - /// # use time_macros::datetime; - /// assert_eq!(datetime!(2019-01-01 0:00).nanosecond(), 0); - /// assert_eq!( - /// datetime!(2019-01-01 23:59:59.999_999_999).nanosecond(), - /// 999_999_999, - /// ); - /// ``` - pub const fn nanosecond(self) -> u32 { - self.time().nanosecond() - } - - /// Assuming that the existing `PrimitiveDateTime` represents a moment in the provided - /// [`UtcOffset`], return an [`OffsetDateTime`]. - /// - /// ```rust - /// # use time_macros::{datetime, offset}; - /// assert_eq!( - /// datetime!(2019-01-01 0:00) - /// .assume_offset(offset!(UTC)) - /// .unix_timestamp(), - /// 1_546_300_800, - /// ); - /// assert_eq!( - /// datetime!(2019-01-01 0:00) - /// .assume_offset(offset!(-1)) - /// .unix_timestamp(), - /// 1_546_304_400, - /// ); - /// ``` - pub const fn assume_offset(self, offset: UtcOffset) -> OffsetDateTime { - OffsetDateTime::new_in_offset(self.date, self.time, offset) - } - - /// Assuming that the existing `PrimitiveDateTime` represents a moment in UTC, return an - /// [`OffsetDateTime`]. - /// - /// ```rust - /// # use time_macros::datetime; - /// assert_eq!( - /// datetime!(2019-01-01 0:00).assume_utc().unix_timestamp(), - /// 1_546_300_800, - /// ); - /// ``` - /// - /// **Note**: You may want a [`UtcDateTime`] instead, which can be obtained with the - /// [`PrimitiveDateTime::as_utc`] method. - pub const fn assume_utc(self) -> OffsetDateTime { - self.assume_offset(UtcOffset::UTC) - } - - /// Assuming that the existing `PrimitiveDateTime` represents a moment in UTC, return a - /// [`UtcDateTime`]. - /// - /// ```rust - /// # use time_macros::datetime; - /// assert_eq!( - /// datetime!(2019-01-01 0:00).as_utc().unix_timestamp(), - /// 1_546_300_800, - /// ); - /// ``` - pub const fn as_utc(self) -> UtcDateTime { - UtcDateTime::from_primitive(self) - } - - /// Computes `self + duration`, returning `None` if an overflow occurred. - /// - /// ``` - /// # use time::{Date, ext::NumericalDuration}; - /// # use time_macros::datetime; - /// let datetime = Date::MIN.midnight(); - /// assert_eq!(datetime.checked_add((-2).days()), None); - /// - /// let datetime = Date::MAX.midnight(); - /// assert_eq!(datetime.checked_add(1.days()), None); - /// - /// assert_eq!( - /// datetime!(2019-11-25 15:30).checked_add(27.hours()), - /// Some(datetime!(2019-11-26 18:30)) - /// ); - /// ``` - pub const fn checked_add(self, duration: Duration) -> Option<Self> { - let (date_adjustment, time) = self.time.adjusting_add(duration); - let date = const_try_opt!(self.date.checked_add(duration)); - - Some(Self { - date: match date_adjustment { - util::DateAdjustment::Previous => const_try_opt!(date.previous_day()), - util::DateAdjustment::Next => const_try_opt!(date.next_day()), - util::DateAdjustment::None => date, - }, - time, - }) - } - - /// Computes `self - duration`, returning `None` if an overflow occurred. - /// - /// ``` - /// # use time::{Date, ext::NumericalDuration}; - /// # use time_macros::datetime; - /// let datetime = Date::MIN.midnight(); - /// assert_eq!(datetime.checked_sub(2.days()), None); - /// - /// let datetime = Date::MAX.midnight(); - /// assert_eq!(datetime.checked_sub((-1).days()), None); - /// - /// assert_eq!( - /// datetime!(2019-11-25 15:30).checked_sub(27.hours()), - /// Some(datetime!(2019-11-24 12:30)) - /// ); - /// ``` - pub const fn checked_sub(self, duration: Duration) -> Option<Self> { - let (date_adjustment, time) = self.time.adjusting_sub(duration); - let date = const_try_opt!(self.date.checked_sub(duration)); - - Some(Self { - date: match date_adjustment { - util::DateAdjustment::Previous => const_try_opt!(date.previous_day()), - util::DateAdjustment::Next => const_try_opt!(date.next_day()), - util::DateAdjustment::None => date, - }, - time, - }) - } - - /// Computes `self + duration`, saturating value on overflow. - /// - /// ``` - /// # use time::{PrimitiveDateTime, ext::NumericalDuration}; - /// # use time_macros::datetime; - /// assert_eq!( - /// PrimitiveDateTime::MIN.saturating_add((-2).days()), - /// PrimitiveDateTime::MIN - /// ); - /// - /// assert_eq!( - /// PrimitiveDateTime::MAX.saturating_add(2.days()), - /// PrimitiveDateTime::MAX - /// ); - /// - /// assert_eq!( - /// datetime!(2019-11-25 15:30).saturating_add(27.hours()), - /// datetime!(2019-11-26 18:30) - /// ); - /// ``` - pub const fn saturating_add(self, duration: Duration) -> Self { - if let Some(datetime) = self.checked_add(duration) { - datetime - } else if duration.is_negative() { - Self::MIN - } else { - Self::MAX - } - } - - /// Computes `self - duration`, saturating value on overflow. - /// - /// ``` - /// # use time::{PrimitiveDateTime, ext::NumericalDuration}; - /// # use time_macros::datetime; - /// assert_eq!( - /// PrimitiveDateTime::MIN.saturating_sub(2.days()), - /// PrimitiveDateTime::MIN - /// ); - /// - /// assert_eq!( - /// PrimitiveDateTime::MAX.saturating_sub((-2).days()), - /// PrimitiveDateTime::MAX - /// ); - /// - /// assert_eq!( - /// datetime!(2019-11-25 15:30).saturating_sub(27.hours()), - /// datetime!(2019-11-24 12:30) - /// ); - /// ``` - pub const fn saturating_sub(self, duration: Duration) -> Self { - if let Some(datetime) = self.checked_sub(duration) { - datetime - } else if duration.is_negative() { - Self::MAX - } else { - Self::MIN - } - } -} - -/// Methods that replace part of the `PrimitiveDateTime`. -impl PrimitiveDateTime { - /// Replace the time, preserving the date. - /// - /// ```rust - /// # use time_macros::{datetime, time}; - /// assert_eq!( - /// datetime!(2020-01-01 17:00).replace_time(time!(5:00)), - /// datetime!(2020-01-01 5:00) - /// ); - /// ``` - #[must_use = "This method does not mutate the original `PrimitiveDateTime`."] - pub const fn replace_time(self, time: Time) -> Self { - Self { - date: self.date, - time, - } - } - - /// Replace the date, preserving the time. - /// - /// ```rust - /// # use time_macros::{datetime, date}; - /// assert_eq!( - /// datetime!(2020-01-01 12:00).replace_date(date!(2020-01-30)), - /// datetime!(2020-01-30 12:00) - /// ); - /// ``` - #[must_use = "This method does not mutate the original `PrimitiveDateTime`."] - pub const fn replace_date(self, date: Date) -> Self { - Self { - date, - time: self.time, - } - } - - /// Replace the year. The month and day will be unchanged. - /// - /// ```rust - /// # use time_macros::datetime; - /// assert_eq!( - /// datetime!(2022-02-18 12:00).replace_year(2019), - /// Ok(datetime!(2019-02-18 12:00)) - /// ); - /// assert!(datetime!(2022-02-18 12:00).replace_year(-1_000_000_000).is_err()); // -1_000_000_000 isn't a valid year - /// assert!(datetime!(2022-02-18 12:00).replace_year(1_000_000_000).is_err()); // 1_000_000_000 isn't a valid year - /// ``` - #[must_use = "This method does not mutate the original `PrimitiveDateTime`."] - pub const fn replace_year(self, year: i32) -> Result<Self, error::ComponentRange> { - Ok(Self { - date: const_try!(self.date.replace_year(year)), - time: self.time, - }) - } - - /// Replace the month of the year. - /// - /// ```rust - /// # use time_macros::datetime; - /// # use time::Month; - /// assert_eq!( - /// datetime!(2022-02-18 12:00).replace_month(Month::January), - /// Ok(datetime!(2022-01-18 12:00)) - /// ); - /// assert!(datetime!(2022-01-30 12:00).replace_month(Month::February).is_err()); // 30 isn't a valid day in February - /// ``` - #[must_use = "This method does not mutate the original `PrimitiveDateTime`."] - pub const fn replace_month(self, month: Month) -> Result<Self, error::ComponentRange> { - Ok(Self { - date: const_try!(self.date.replace_month(month)), - time: self.time, - }) - } - - /// Replace the day of the month. - /// - /// ```rust - /// # use time_macros::datetime; - /// assert_eq!( - /// datetime!(2022-02-18 12:00).replace_day(1), - /// Ok(datetime!(2022-02-01 12:00)) - /// ); - /// assert!(datetime!(2022-02-18 12:00).replace_day(0).is_err()); // 00 isn't a valid day - /// assert!(datetime!(2022-02-18 12:00).replace_day(30).is_err()); // 30 isn't a valid day in February - /// ``` - #[must_use = "This method does not mutate the original `PrimitiveDateTime`."] - pub const fn replace_day(self, day: u8) -> Result<Self, error::ComponentRange> { - Ok(Self { - date: const_try!(self.date.replace_day(day)), - time: self.time, - }) - } - - /// Replace the day of the year. - /// - /// ```rust - /// # use time_macros::datetime; - /// assert_eq!(datetime!(2022-049 12:00).replace_ordinal(1), Ok(datetime!(2022-001 12:00))); - /// assert!(datetime!(2022-049 12:00).replace_ordinal(0).is_err()); // 0 isn't a valid ordinal - /// assert!(datetime!(2022-049 12:00).replace_ordinal(366).is_err()); // 2022 isn't a leap year - /// ```` - #[must_use = "This method does not mutate the original `PrimitiveDateTime`."] - pub const fn replace_ordinal(self, ordinal: u16) -> Result<Self, error::ComponentRange> { - Ok(Self { - date: const_try!(self.date.replace_ordinal(ordinal)), - time: self.time, - }) - } - - /// Replace the clock hour. - /// - /// ```rust - /// # use time_macros::datetime; - /// assert_eq!( - /// datetime!(2022-02-18 01:02:03.004_005_006).replace_hour(7), - /// Ok(datetime!(2022-02-18 07:02:03.004_005_006)) - /// ); - /// assert!(datetime!(2022-02-18 01:02:03.004_005_006).replace_hour(24).is_err()); // 24 isn't a valid hour - /// ``` - #[must_use = "This method does not mutate the original `PrimitiveDateTime`."] - pub const fn replace_hour(self, hour: u8) -> Result<Self, error::ComponentRange> { - Ok(Self { - date: self.date, - time: const_try!(self.time.replace_hour(hour)), - }) - } - - /// Replace the minutes within the hour. - /// - /// ```rust - /// # use time_macros::datetime; - /// assert_eq!( - /// datetime!(2022-02-18 01:02:03.004_005_006).replace_minute(7), - /// Ok(datetime!(2022-02-18 01:07:03.004_005_006)) - /// ); - /// assert!(datetime!(2022-02-18 01:02:03.004_005_006).replace_minute(60).is_err()); // 60 isn't a valid minute - /// ``` - #[must_use = "This method does not mutate the original `PrimitiveDateTime`."] - pub const fn replace_minute(self, minute: u8) -> Result<Self, error::ComponentRange> { - Ok(Self { - date: self.date, - time: const_try!(self.time.replace_minute(minute)), - }) - } - - /// Replace the seconds within the minute. - /// - /// ```rust - /// # use time_macros::datetime; - /// assert_eq!( - /// datetime!(2022-02-18 01:02:03.004_005_006).replace_second(7), - /// Ok(datetime!(2022-02-18 01:02:07.004_005_006)) - /// ); - /// assert!(datetime!(2022-02-18 01:02:03.004_005_006).replace_second(60).is_err()); // 60 isn't a valid second - /// ``` - #[must_use = "This method does not mutate the original `PrimitiveDateTime`."] - pub const fn replace_second(self, second: u8) -> Result<Self, error::ComponentRange> { - Ok(Self { - date: self.date, - time: const_try!(self.time.replace_second(second)), - }) - } - - /// Replace the milliseconds within the second. - /// - /// ```rust - /// # use time_macros::datetime; - /// assert_eq!( - /// datetime!(2022-02-18 01:02:03.004_005_006).replace_millisecond(7), - /// Ok(datetime!(2022-02-18 01:02:03.007)) - /// ); - /// assert!(datetime!(2022-02-18 01:02:03.004_005_006).replace_millisecond(1_000).is_err()); // 1_000 isn't a valid millisecond - /// ``` - #[must_use = "This method does not mutate the original `PrimitiveDateTime`."] - pub const fn replace_millisecond( - self, - millisecond: u16, - ) -> Result<Self, error::ComponentRange> { - Ok(Self { - date: self.date, - time: const_try!(self.time.replace_millisecond(millisecond)), - }) - } - - /// Replace the microseconds within the second. - /// - /// ```rust - /// # use time_macros::datetime; - /// assert_eq!( - /// datetime!(2022-02-18 01:02:03.004_005_006).replace_microsecond(7_008), - /// Ok(datetime!(2022-02-18 01:02:03.007_008)) - /// ); - /// assert!(datetime!(2022-02-18 01:02:03.004_005_006).replace_microsecond(1_000_000).is_err()); // 1_000_000 isn't a valid microsecond - /// ``` - #[must_use = "This method does not mutate the original `PrimitiveDateTime`."] - pub const fn replace_microsecond( - self, - microsecond: u32, - ) -> Result<Self, error::ComponentRange> { - Ok(Self { - date: self.date, - time: const_try!(self.time.replace_microsecond(microsecond)), - }) - } - - /// Replace the nanoseconds within the second. - /// - /// ```rust - /// # use time_macros::datetime; - /// assert_eq!( - /// datetime!(2022-02-18 01:02:03.004_005_006).replace_nanosecond(7_008_009), - /// Ok(datetime!(2022-02-18 01:02:03.007_008_009)) - /// ); - /// assert!(datetime!(2022-02-18 01:02:03.004_005_006).replace_nanosecond(1_000_000_000).is_err()); // 1_000_000_000 isn't a valid nanosecond - /// ``` - #[must_use = "This method does not mutate the original `PrimitiveDateTime`."] - pub const fn replace_nanosecond(self, nanosecond: u32) -> Result<Self, error::ComponentRange> { - Ok(Self { - date: self.date, - time: const_try!(self.time.replace_nanosecond(nanosecond)), - }) - } -} - -#[cfg(feature = "formatting")] -impl PrimitiveDateTime { - /// Format the `PrimitiveDateTime` using the provided [format - /// description](crate::format_description). - pub fn format_into( - self, - output: &mut (impl io::Write + ?Sized), - format: &(impl Formattable + ?Sized), - ) -> Result<usize, error::Format> { - format.format_into(output, Some(self.date), Some(self.time), None) - } - - /// Format the `PrimitiveDateTime` using the provided [format - /// description](crate::format_description). - /// - /// ```rust - /// # use time::format_description; - /// # use time_macros::datetime; - /// let format = format_description::parse("[year]-[month]-[day] [hour]:[minute]:[second]")?; - /// assert_eq!( - /// datetime!(2020-01-02 03:04:05).format(&format)?, - /// "2020-01-02 03:04:05" - /// ); - /// # Ok::<_, time::Error>(()) - /// ``` - pub fn format(self, format: &(impl Formattable + ?Sized)) -> Result<String, error::Format> { - format.format(Some(self.date), Some(self.time), None) - } -} - -#[cfg(feature = "parsing")] -impl PrimitiveDateTime { - /// Parse a `PrimitiveDateTime` from the input using the provided [format - /// description](crate::format_description). - /// - /// ```rust - /// # use time::PrimitiveDateTime; - /// # use time_macros::{datetime, format_description}; - /// let format = format_description!("[year]-[month]-[day] [hour]:[minute]:[second]"); - /// assert_eq!( - /// PrimitiveDateTime::parse("2020-01-02 03:04:05", &format)?, - /// datetime!(2020-01-02 03:04:05) - /// ); - /// # Ok::<_, time::Error>(()) - /// ``` - pub fn parse( - input: &str, - description: &(impl Parsable + ?Sized), - ) -> Result<Self, error::Parse> { - description.parse_primitive_date_time(input.as_bytes()) - } -} - -impl SmartDisplay for PrimitiveDateTime { - type Metadata = (); - - fn metadata(&self, _: FormatterOptions) -> Metadata<Self> { - let width = smart_display::padded_width_of!(self.date, " ", self.time); - Metadata::new(width, self, ()) - } - - fn fmt_with_metadata( - &self, - f: &mut fmt::Formatter<'_>, - metadata: Metadata<Self>, - ) -> fmt::Result { - f.pad_with_width( - metadata.unpadded_width(), - format_args!("{} {}", self.date, self.time), - ) - } -} - -impl fmt::Display for PrimitiveDateTime { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - SmartDisplay::fmt(self, f) - } -} - -impl fmt::Debug for PrimitiveDateTime { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Display::fmt(self, f) - } -} - -impl Add<Duration> for PrimitiveDateTime { - type Output = Self; - - /// # Panics - /// - /// This may panic if an overflow occurs. - fn add(self, duration: Duration) -> Self::Output { - self.checked_add(duration) - .expect("resulting value is out of range") - } -} - -impl Add<StdDuration> for PrimitiveDateTime { - type Output = Self; - - /// # Panics - /// - /// This may panic if an overflow occurs. - fn add(self, duration: StdDuration) -> Self::Output { - let (is_next_day, time) = self.time.adjusting_add_std(duration); - - Self { - date: if is_next_day { - (self.date + duration) - .next_day() - .expect("resulting value is out of range") - } else { - self.date + duration - }, - time, - } - } -} - -impl AddAssign<Duration> for PrimitiveDateTime { - /// # Panics - /// - /// This may panic if an overflow occurs. - fn add_assign(&mut self, duration: Duration) { - *self = *self + duration; - } -} - -impl AddAssign<StdDuration> for PrimitiveDateTime { - /// # Panics - /// - /// This may panic if an overflow occurs. - fn add_assign(&mut self, duration: StdDuration) { - *self = *self + duration; - } -} - -impl Sub<Duration> for PrimitiveDateTime { - type Output = Self; - - /// # Panics - /// - /// This may panic if an overflow occurs. - fn sub(self, duration: Duration) -> Self::Output { - self.checked_sub(duration) - .expect("resulting value is out of range") - } -} - -impl Sub<StdDuration> for PrimitiveDateTime { - type Output = Self; - - /// # Panics - /// - /// This may panic if an overflow occurs. - fn sub(self, duration: StdDuration) -> Self::Output { - let (is_previous_day, time) = self.time.adjusting_sub_std(duration); - - Self { - date: if is_previous_day { - (self.date - duration) - .previous_day() - .expect("resulting value is out of range") - } else { - self.date - duration - }, - time, - } - } -} - -impl SubAssign<Duration> for PrimitiveDateTime { - /// # Panics - /// - /// This may panic if an overflow occurs. - fn sub_assign(&mut self, duration: Duration) { - *self = *self - duration; - } -} - -impl SubAssign<StdDuration> for PrimitiveDateTime { - /// # Panics - /// - /// This may panic if an overflow occurs. - fn sub_assign(&mut self, duration: StdDuration) { - *self = *self - duration; - } -} - -impl Sub for PrimitiveDateTime { - type Output = Duration; - - /// # Panics - /// - /// This may panic if an overflow occurs. - fn sub(self, rhs: Self) -> Self::Output { - (self.date - rhs.date) + (self.time - rhs.time) - } -} diff --git a/vendor/time/src/quickcheck.rs b/vendor/time/src/quickcheck.rs deleted file mode 100644 index 6336ec25..00000000 --- a/vendor/time/src/quickcheck.rs +++ /dev/null @@ -1,230 +0,0 @@ -//! Implementations of the [`quickcheck::Arbitrary`](quickcheck::Arbitrary) trait. -//! -//! This enables users to write tests such as this, and have test values provided automatically: -//! -//! ```ignore -//! # #![allow(dead_code)] -//! use quickcheck::quickcheck; -//! use time::Date; -//! -//! struct DateRange { -//! from: Date, -//! to: Date, -//! } -//! -//! impl DateRange { -//! fn new(from: Date, to: Date) -> Result<Self, ()> { -//! Ok(DateRange { from, to }) -//! } -//! } -//! -//! quickcheck! { -//! fn date_range_is_well_defined(from: Date, to: Date) -> bool { -//! let r = DateRange::new(from, to); -//! if from <= to { -//! r.is_ok() -//! } else { -//! r.is_err() -//! } -//! } -//! } -//! ``` -//! -//! An implementation for `Instant` is intentionally omitted since its values are only meaningful in -//! relation to a [`Duration`], and obtaining an `Instant` from a [`Duration`] is very simple -//! anyway. - -use alloc::boxed::Box; - -use quickcheck::{empty_shrinker, single_shrinker, Arbitrary, Gen}; - -use crate::{ - Date, Duration, Month, OffsetDateTime, PrimitiveDateTime, Time, UtcDateTime, UtcOffset, Weekday, -}; - -/// Obtain an arbitrary value between the minimum and maximum inclusive. -macro_rules! arbitrary_between { - ($type:ty; $gen:expr, $min:expr, $max:expr) => {{ - let min = $min; - let max = $max; - let range = max - min; - <$type>::arbitrary($gen).rem_euclid(range + 1) + min - }}; -} - -impl Arbitrary for Date { - fn arbitrary(g: &mut Gen) -> Self { - // Safety: The Julian day number is in range. - unsafe { - Self::from_julian_day_unchecked(arbitrary_between!( - i32; - g, - Self::MIN.to_julian_day(), - Self::MAX.to_julian_day() - )) - } - } - - fn shrink(&self) -> Box<dyn Iterator<Item = Self>> { - Box::new( - self.to_ordinal_date() - .shrink() - .flat_map(|(year, ordinal)| Self::from_ordinal_date(year, ordinal)), - ) - } -} - -impl Arbitrary for Duration { - fn arbitrary(g: &mut Gen) -> Self { - Self::new_ranged(<_>::arbitrary(g), <_>::arbitrary(g)) - } - - fn shrink(&self) -> Box<dyn Iterator<Item = Self>> { - Box::new( - (self.subsec_nanoseconds_ranged(), self.whole_seconds()) - .shrink() - .map(|(mut nanoseconds, seconds)| { - // Coerce the sign if necessary. - if (seconds > 0 && nanoseconds.get() < 0) - || (seconds < 0 && nanoseconds.get() > 0) - { - nanoseconds = nanoseconds.neg(); - } - - Self::new_ranged_unchecked(seconds, nanoseconds) - }), - ) - } -} - -impl Arbitrary for Time { - fn arbitrary(g: &mut Gen) -> Self { - Self::from_hms_nanos_ranged( - <_>::arbitrary(g), - <_>::arbitrary(g), - <_>::arbitrary(g), - <_>::arbitrary(g), - ) - } - - fn shrink(&self) -> Box<dyn Iterator<Item = Self>> { - Box::new( - self.as_hms_nano_ranged() - .shrink() - .map(|(hour, minute, second, nanosecond)| { - Self::from_hms_nanos_ranged(hour, minute, second, nanosecond) - }), - ) - } -} - -impl Arbitrary for PrimitiveDateTime { - fn arbitrary(g: &mut Gen) -> Self { - Self::new(<_>::arbitrary(g), <_>::arbitrary(g)) - } - - fn shrink(&self) -> Box<dyn Iterator<Item = Self>> { - Box::new( - (self.date(), self.time()) - .shrink() - .map(|(date, time)| Self::new(date, time)), - ) - } -} - -impl Arbitrary for UtcOffset { - fn arbitrary(g: &mut Gen) -> Self { - Self::from_hms_ranged(<_>::arbitrary(g), <_>::arbitrary(g), <_>::arbitrary(g)) - } - - fn shrink(&self) -> Box<dyn Iterator<Item = Self>> { - Box::new( - self.as_hms_ranged() - .shrink() - .map(|(hours, minutes, seconds)| Self::from_hms_ranged(hours, minutes, seconds)), - ) - } -} - -impl Arbitrary for OffsetDateTime { - fn arbitrary(g: &mut Gen) -> Self { - Self::new_in_offset(<_>::arbitrary(g), <_>::arbitrary(g), <_>::arbitrary(g)) - } - - fn shrink(&self) -> Box<dyn Iterator<Item = Self>> { - Box::new( - (self.date(), self.time(), self.offset()) - .shrink() - .map(|(date, time, offset)| Self::new_in_offset(date, time, offset)), - ) - } -} - -impl Arbitrary for UtcDateTime { - fn arbitrary(g: &mut Gen) -> Self { - Self::new(<_>::arbitrary(g), <_>::arbitrary(g)) - } - - fn shrink(&self) -> Box<dyn Iterator<Item = Self>> { - Box::new( - (self.date(), self.time()) - .shrink() - .map(|(date, time)| Self::new(date, time)), - ) - } -} - -impl Arbitrary for Weekday { - fn arbitrary(g: &mut Gen) -> Self { - use Weekday::*; - match arbitrary_between!(u8; g, 0, 6) { - 0 => Monday, - 1 => Tuesday, - 2 => Wednesday, - 3 => Thursday, - 4 => Friday, - 5 => Saturday, - val => { - debug_assert!(val == 6); - Sunday - } - } - } - - fn shrink(&self) -> Box<dyn Iterator<Item = Self>> { - match self { - Self::Monday => empty_shrinker(), - _ => single_shrinker(self.previous()), - } - } -} - -impl Arbitrary for Month { - fn arbitrary(g: &mut Gen) -> Self { - use Month::*; - match arbitrary_between!(u8; g, 1, 12) { - 1 => January, - 2 => February, - 3 => March, - 4 => April, - 5 => May, - 6 => June, - 7 => July, - 8 => August, - 9 => September, - 10 => October, - 11 => November, - val => { - debug_assert!(val == 12); - December - } - } - } - - fn shrink(&self) -> Box<dyn Iterator<Item = Self>> { - match self { - Self::January => empty_shrinker(), - _ => single_shrinker(self.previous()), - } - } -} diff --git a/vendor/time/src/rand.rs b/vendor/time/src/rand.rs deleted file mode 100644 index 8e4098cb..00000000 --- a/vendor/time/src/rand.rs +++ /dev/null @@ -1,90 +0,0 @@ -//! Implementation of [`Distribution`] for various structs. - -use rand::distributions::{Distribution, Standard}; -use rand::Rng; - -use crate::{Date, Duration, Month, OffsetDateTime, PrimitiveDateTime, Time, UtcOffset, Weekday}; - -impl Distribution<Time> for Standard { - fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Time { - Time::from_hms_nanos_ranged(rng.r#gen(), rng.r#gen(), rng.r#gen(), rng.r#gen()) - } -} - -impl Distribution<Date> for Standard { - fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Date { - // Safety: The Julian day number is in range. - unsafe { - Date::from_julian_day_unchecked( - rng.gen_range(Date::MIN.to_julian_day()..=Date::MAX.to_julian_day()), - ) - } - } -} - -impl Distribution<UtcOffset> for Standard { - fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> UtcOffset { - UtcOffset::from_hms_ranged(rng.r#gen(), rng.r#gen(), rng.r#gen()) - } -} - -impl Distribution<PrimitiveDateTime> for Standard { - fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> PrimitiveDateTime { - PrimitiveDateTime::new(Self.sample(rng), Self.sample(rng)) - } -} - -impl Distribution<OffsetDateTime> for Standard { - fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> OffsetDateTime { - let date_time: PrimitiveDateTime = Self.sample(rng); - date_time.assume_offset(Self.sample(rng)) - } -} - -impl Distribution<Duration> for Standard { - fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Duration { - Duration::new_ranged(rng.r#gen(), rng.r#gen()) - } -} - -impl Distribution<Weekday> for Standard { - fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Weekday { - use Weekday::*; - - match rng.gen_range(0u8..7) { - 0 => Monday, - 1 => Tuesday, - 2 => Wednesday, - 3 => Thursday, - 4 => Friday, - 5 => Saturday, - val => { - debug_assert!(val == 6); - Sunday - } - } - } -} - -impl Distribution<Month> for Standard { - fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Month { - use Month::*; - match rng.gen_range(1u8..=12) { - 1 => January, - 2 => February, - 3 => March, - 4 => April, - 5 => May, - 6 => June, - 7 => July, - 8 => August, - 9 => September, - 10 => October, - 11 => November, - val => { - debug_assert!(val == 12); - December - } - } - } -} diff --git a/vendor/time/src/serde/iso8601.rs b/vendor/time/src/serde/iso8601.rs deleted file mode 100644 index f08cf511..00000000 --- a/vendor/time/src/serde/iso8601.rs +++ /dev/null @@ -1,76 +0,0 @@ -//! Use the well-known [ISO 8601 format] when serializing and deserializing an [`OffsetDateTime`]. -//! -//! Use this module in combination with serde's [`#[with]`][with] attribute. -//! -//! [ISO 8601 format]: https://www.iso.org/iso-8601-date-and-time-format.html -//! [with]: https://serde.rs/field-attrs.html#with - -#[cfg(feature = "parsing")] -use core::marker::PhantomData; - -#[cfg(feature = "formatting")] -use serde::ser::Error as _; -#[cfg(feature = "parsing")] -use serde::Deserializer; -#[cfg(feature = "formatting")] -use serde::{Serialize, Serializer}; - -#[cfg(feature = "parsing")] -use super::Visitor; -use crate::format_description::well_known::iso8601::{Config, EncodedConfig}; -use crate::format_description::well_known::Iso8601; -use crate::OffsetDateTime; - -/// The configuration of ISO 8601 used for serde implementations. -pub(crate) const SERDE_CONFIG: EncodedConfig = - Config::DEFAULT.set_year_is_six_digits(true).encode(); - -/// Serialize an [`OffsetDateTime`] using the well-known ISO 8601 format. -#[cfg(feature = "formatting")] -pub fn serialize<S: Serializer>( - datetime: &OffsetDateTime, - serializer: S, -) -> Result<S::Ok, S::Error> { - datetime - .format(&Iso8601::<SERDE_CONFIG>) - .map_err(S::Error::custom)? - .serialize(serializer) -} - -/// Deserialize an [`OffsetDateTime`] from its ISO 8601 representation. -#[cfg(feature = "parsing")] -pub fn deserialize<'a, D: Deserializer<'a>>(deserializer: D) -> Result<OffsetDateTime, D::Error> { - deserializer.deserialize_str(Visitor::<Iso8601<SERDE_CONFIG>>(PhantomData)) -} - -/// Use the well-known ISO 8601 format when serializing and deserializing an -/// [`Option<OffsetDateTime>`]. -/// -/// Use this module in combination with serde's [`#[with]`][with] attribute. -/// -/// [ISO 8601 format]: https://www.iso.org/iso-8601-date-and-time-format.html -/// [with]: https://serde.rs/field-attrs.html#with -pub mod option { - use super::*; - - /// Serialize an [`Option<OffsetDateTime>`] using the well-known ISO 8601 format. - #[cfg(feature = "formatting")] - pub fn serialize<S: Serializer>( - option: &Option<OffsetDateTime>, - serializer: S, - ) -> Result<S::Ok, S::Error> { - option - .map(|odt| odt.format(&Iso8601::<SERDE_CONFIG>)) - .transpose() - .map_err(S::Error::custom)? - .serialize(serializer) - } - - /// Deserialize an [`Option<OffsetDateTime>`] from its ISO 8601 representation. - #[cfg(feature = "parsing")] - pub fn deserialize<'a, D: Deserializer<'a>>( - deserializer: D, - ) -> Result<Option<OffsetDateTime>, D::Error> { - deserializer.deserialize_option(Visitor::<Option<Iso8601<SERDE_CONFIG>>>(PhantomData)) - } -} diff --git a/vendor/time/src/serde/mod.rs b/vendor/time/src/serde/mod.rs deleted file mode 100644 index 72b43721..00000000 --- a/vendor/time/src/serde/mod.rs +++ /dev/null @@ -1,535 +0,0 @@ -//! Differential formats for serde. -// This also includes the serde implementations for all types. This doesn't need to be externally -// documented, though. - -// Types with guaranteed stable serde representations. Strings are avoided to allow for optimal -// representations in various binary forms. - -/// Consume the next item in a sequence. -macro_rules! item { - ($seq:expr, $name:literal) => { - $seq.next_element()? - .ok_or_else(|| <A::Error as serde::de::Error>::custom(concat!("expected ", $name))) - }; -} - -#[cfg(any(feature = "formatting", feature = "parsing"))] -pub mod iso8601; -#[cfg(any(feature = "formatting", feature = "parsing"))] -pub mod rfc2822; -#[cfg(any(feature = "formatting", feature = "parsing"))] -pub mod rfc3339; -pub mod timestamp; -mod visitor; - -#[cfg(feature = "serde-human-readable")] -use alloc::string::ToString; -use core::marker::PhantomData; - -#[cfg(feature = "serde-human-readable")] -use serde::ser::Error as _; -use serde::{Deserialize, Deserializer, Serialize, Serializer}; -/// Generate a custom serializer and deserializer from a format string or an existing format. -/// -/// The syntax accepted by this macro is the same as [`format_description::parse()`], which can -/// be found in [the book](https://time-rs.github.io/book/api/format-description.html). -/// -/// # Usage -/// -/// Invoked as `serde::format_description!(mod_name, Date, FORMAT)` where `FORMAT` is either a -/// `"<format string>"` or something that implements -#[cfg_attr( - all(feature = "formatting", feature = "parsing"), - doc = "[`Formattable`](crate::formatting::Formattable) and \ - [`Parsable`](crate::parsing::Parsable)." -)] -#[cfg_attr( - all(feature = "formatting", not(feature = "parsing")), - doc = "[`Formattable`](crate::formatting::Formattable)." -)] -#[cfg_attr( - all(not(feature = "formatting"), feature = "parsing"), - doc = "[`Parsable`](crate::parsing::Parsable)." -)] -/// This puts a module named `mod_name` in the current scope that can be used to format `Date` -/// structs. A submodule (`mod_name::option`) is also generated for `Option<Date>`. Both -/// modules are only visible in the current scope by default. To increase visibility, you can -/// specify `pub`, `pub(crate)`, or similar before the module name: -/// `serde::format_description!(pub mod_name, Date, FORMAT)`. -/// -/// The returned `Option` will contain a deserialized value if present and `None` if the field -/// is present but the value is `null` (or the equivalent in other formats). To return `None` -/// when the field is not present, you should use `#[serde(default)]` on the field. -/// -/// # Examples -/// -/// Using a format string: -/// -/// ```rust,no_run -/// # use time::OffsetDateTime; -#[cfg_attr( - all(feature = "formatting", feature = "parsing"), - doc = "use ::serde::{Serialize, Deserialize};" -)] -#[cfg_attr( - all(feature = "formatting", not(feature = "parsing")), - doc = "use ::serde::Serialize;" -)] -#[cfg_attr( - all(not(feature = "formatting"), feature = "parsing"), - doc = "use ::serde::Deserialize;" -)] -/// use time::serde; -/// -/// // Makes a module `mod my_format { ... }`. -/// serde::format_description!(my_format, OffsetDateTime, "hour=[hour], minute=[minute]"); -/// -/// # #[allow(dead_code)] -#[cfg_attr( - all(feature = "formatting", feature = "parsing"), - doc = "#[derive(Serialize, Deserialize)]" -)] -#[cfg_attr( - all(feature = "formatting", not(feature = "parsing")), - doc = "#[derive(Serialize)]" -)] -#[cfg_attr( - all(not(feature = "formatting"), feature = "parsing"), - doc = "#[derive(Deserialize)]" -)] -/// struct SerializesWithCustom { -/// #[serde(with = "my_format")] -/// dt: OffsetDateTime, -/// #[serde(with = "my_format::option")] -/// maybe_dt: Option<OffsetDateTime>, -/// } -/// ``` -/// -/// Define the format separately to be used in multiple places: -/// ```rust,no_run -/// # use time::OffsetDateTime; -#[cfg_attr( - all(feature = "formatting", feature = "parsing"), - doc = "use ::serde::{Serialize, Deserialize};" -)] -#[cfg_attr( - all(feature = "formatting", not(feature = "parsing")), - doc = "use ::serde::Serialize;" -)] -#[cfg_attr( - all(not(feature = "formatting"), feature = "parsing"), - doc = "use ::serde::Deserialize;" -)] -/// use time::serde; -/// use time::format_description::BorrowedFormatItem; -/// -/// const DATE_TIME_FORMAT: &[BorrowedFormatItem<'_>] = time::macros::format_description!( -/// "hour=[hour], minute=[minute]" -/// ); -/// -/// // Makes a module `mod my_format { ... }`. -/// serde::format_description!(my_format, OffsetDateTime, DATE_TIME_FORMAT); -/// -/// # #[allow(dead_code)] -#[cfg_attr( - all(feature = "formatting", feature = "parsing"), - doc = "#[derive(Serialize, Deserialize)]" -)] -#[cfg_attr( - all(feature = "formatting", not(feature = "parsing")), - doc = "#[derive(Serialize)]" -)] -#[cfg_attr( - all(not(feature = "formatting"), feature = "parsing"), - doc = "#[derive(Deserialize)]" -)] -/// struct SerializesWithCustom { -/// #[serde(with = "my_format")] -/// dt: OffsetDateTime, -/// #[serde(with = "my_format::option")] -/// maybe_dt: Option<OffsetDateTime>, -/// } -/// -/// fn main() { -/// # #[allow(unused_variables)] -/// let str_ts = OffsetDateTime::now_utc().format(DATE_TIME_FORMAT).unwrap(); -/// } -/// ``` -/// -/// Customize the configuration of ISO 8601 formatting/parsing: -/// ```rust,no_run -/// # use time::OffsetDateTime; -#[cfg_attr( - all(feature = "formatting", feature = "parsing"), - doc = "use ::serde::{Serialize, Deserialize};" -)] -#[cfg_attr( - all(feature = "formatting", not(feature = "parsing")), - doc = "use ::serde::Serialize;" -)] -#[cfg_attr( - all(not(feature = "formatting"), feature = "parsing"), - doc = "use ::serde::Deserialize;" -)] -/// use time::serde; -/// use time::format_description::well_known::{iso8601, Iso8601}; -/// -/// # #[allow(dead_code)] -/// const CONFIG: iso8601::EncodedConfig = iso8601::Config::DEFAULT -/// .set_year_is_six_digits(false) -/// .encode(); -/// # #[allow(dead_code)] -/// const FORMAT: Iso8601<CONFIG> = Iso8601::<CONFIG>; -/// -/// // Makes a module `mod my_format { ... }`. -/// serde::format_description!(my_format, OffsetDateTime, FORMAT); -/// -/// # #[allow(dead_code)] -#[cfg_attr( - all(feature = "formatting", feature = "parsing"), - doc = "#[derive(Serialize, Deserialize)]" -)] -#[cfg_attr( - all(feature = "formatting", not(feature = "parsing")), - doc = "#[derive(Serialize)]" -)] -#[cfg_attr( - all(not(feature = "formatting"), feature = "parsing"), - doc = "#[derive(Deserialize)]" -)] -/// struct SerializesWithCustom { -/// #[serde(with = "my_format")] -/// dt: OffsetDateTime, -/// #[serde(with = "my_format::option")] -/// maybe_dt: Option<OffsetDateTime>, -/// } -/// # fn main() {} -/// ``` -/// -/// [`format_description::parse()`]: crate::format_description::parse() -#[cfg(all(feature = "macros", any(feature = "formatting", feature = "parsing")))] -pub use time_macros::serde_format_description as format_description; - -use self::visitor::Visitor; -#[cfg(feature = "parsing")] -use crate::format_description::{modifier, BorrowedFormatItem, Component}; -use crate::{ - Date, Duration, Month, OffsetDateTime, PrimitiveDateTime, Time, UtcDateTime, UtcOffset, Weekday, -}; - -/// The format used when serializing and deserializing a human-readable `Date`. -#[cfg(feature = "parsing")] -const DATE_FORMAT: &[BorrowedFormatItem<'_>] = &[ - BorrowedFormatItem::Component(Component::Year(modifier::Year::default())), - BorrowedFormatItem::Literal(b"-"), - BorrowedFormatItem::Component(Component::Month(modifier::Month::default())), - BorrowedFormatItem::Literal(b"-"), - BorrowedFormatItem::Component(Component::Day(modifier::Day::default())), -]; - -impl Serialize for Date { - fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> { - #[cfg(feature = "serde-human-readable")] - if serializer.is_human_readable() { - let Ok(s) = self.format(&DATE_FORMAT) else { - return Err(S::Error::custom("failed formatting `Date`")); - }; - return serializer.serialize_str(&s); - } - - (self.year(), self.ordinal()).serialize(serializer) - } -} - -impl<'a> Deserialize<'a> for Date { - fn deserialize<D: Deserializer<'a>>(deserializer: D) -> Result<Self, D::Error> { - if cfg!(feature = "serde-human-readable") && deserializer.is_human_readable() { - deserializer.deserialize_any(Visitor::<Self>(PhantomData)) - } else { - deserializer.deserialize_tuple(2, Visitor::<Self>(PhantomData)) - } - } -} - -impl Serialize for Duration { - fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> { - #[cfg(feature = "serde-human-readable")] - if serializer.is_human_readable() { - return serializer.collect_str(&format_args!( - "{}{}.{:>09}", - if self.is_negative() { "-" } else { "" }, - self.whole_seconds().unsigned_abs(), - self.subsec_nanoseconds().abs(), - )); - } - - (self.whole_seconds(), self.subsec_nanoseconds()).serialize(serializer) - } -} - -impl<'a> Deserialize<'a> for Duration { - fn deserialize<D: Deserializer<'a>>(deserializer: D) -> Result<Self, D::Error> { - if cfg!(feature = "serde-human-readable") && deserializer.is_human_readable() { - deserializer.deserialize_any(Visitor::<Self>(PhantomData)) - } else { - deserializer.deserialize_tuple(2, Visitor::<Self>(PhantomData)) - } - } -} - -/// The format used when serializing and deserializing a human-readable `OffsetDateTime`. -#[cfg(feature = "parsing")] -const OFFSET_DATE_TIME_FORMAT: &[BorrowedFormatItem<'_>] = &[ - BorrowedFormatItem::Compound(DATE_FORMAT), - BorrowedFormatItem::Literal(b" "), - BorrowedFormatItem::Compound(TIME_FORMAT), - BorrowedFormatItem::Literal(b" "), - BorrowedFormatItem::Compound(UTC_OFFSET_FORMAT), -]; - -impl Serialize for OffsetDateTime { - fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> { - #[cfg(feature = "serde-human-readable")] - if serializer.is_human_readable() { - let Ok(s) = self.format(&OFFSET_DATE_TIME_FORMAT) else { - return Err(S::Error::custom("failed formatting `OffsetDateTime`")); - }; - return serializer.serialize_str(&s); - } - - ( - self.year(), - self.ordinal(), - self.hour(), - self.minute(), - self.second(), - self.nanosecond(), - self.offset().whole_hours(), - self.offset().minutes_past_hour(), - self.offset().seconds_past_minute(), - ) - .serialize(serializer) - } -} - -impl<'a> Deserialize<'a> for OffsetDateTime { - fn deserialize<D: Deserializer<'a>>(deserializer: D) -> Result<Self, D::Error> { - if cfg!(feature = "serde-human-readable") && deserializer.is_human_readable() { - deserializer.deserialize_any(Visitor::<Self>(PhantomData)) - } else { - deserializer.deserialize_tuple(9, Visitor::<Self>(PhantomData)) - } - } -} - -/// The format used when serializing and deserializing a human-readable `PrimitiveDateTime`. -#[cfg(feature = "parsing")] -const PRIMITIVE_DATE_TIME_FORMAT: &[BorrowedFormatItem<'_>] = &[ - BorrowedFormatItem::Compound(DATE_FORMAT), - BorrowedFormatItem::Literal(b" "), - BorrowedFormatItem::Compound(TIME_FORMAT), -]; - -impl Serialize for PrimitiveDateTime { - fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> { - #[cfg(feature = "serde-human-readable")] - if serializer.is_human_readable() { - let Ok(s) = self.format(&PRIMITIVE_DATE_TIME_FORMAT) else { - return Err(S::Error::custom("failed formatting `PrimitiveDateTime`")); - }; - return serializer.serialize_str(&s); - } - - ( - self.year(), - self.ordinal(), - self.hour(), - self.minute(), - self.second(), - self.nanosecond(), - ) - .serialize(serializer) - } -} - -impl<'a> Deserialize<'a> for PrimitiveDateTime { - fn deserialize<D: Deserializer<'a>>(deserializer: D) -> Result<Self, D::Error> { - if cfg!(feature = "serde-human-readable") && deserializer.is_human_readable() { - deserializer.deserialize_any(Visitor::<Self>(PhantomData)) - } else { - deserializer.deserialize_tuple(6, Visitor::<Self>(PhantomData)) - } - } -} - -/// The format used when serializing and deserializing a human-readable `UtcDateTime`. -#[cfg(feature = "parsing")] -const UTC_DATE_TIME_FORMAT: &[BorrowedFormatItem<'_>] = PRIMITIVE_DATE_TIME_FORMAT; - -impl Serialize for UtcDateTime { - fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> { - #[cfg(feature = "serde-human-readable")] - if serializer.is_human_readable() { - let Ok(s) = self.format(&PRIMITIVE_DATE_TIME_FORMAT) else { - return Err(S::Error::custom("failed formatting `UtcDateTime`")); - }; - return serializer.serialize_str(&s); - } - - ( - self.year(), - self.ordinal(), - self.hour(), - self.minute(), - self.second(), - self.nanosecond(), - ) - .serialize(serializer) - } -} - -impl<'a> Deserialize<'a> for UtcDateTime { - fn deserialize<D: Deserializer<'a>>(deserializer: D) -> Result<Self, D::Error> { - if cfg!(feature = "serde-human-readable") && deserializer.is_human_readable() { - deserializer.deserialize_any(Visitor::<Self>(PhantomData)) - } else { - deserializer.deserialize_tuple(6, Visitor::<Self>(PhantomData)) - } - } -} - -/// The format used when serializing and deserializing a human-readable `Time`. -#[cfg(feature = "parsing")] -const TIME_FORMAT: &[BorrowedFormatItem<'_>] = &[ - BorrowedFormatItem::Component(Component::Hour(modifier::Hour::default())), - BorrowedFormatItem::Literal(b":"), - BorrowedFormatItem::Component(Component::Minute(modifier::Minute::default())), - BorrowedFormatItem::Literal(b":"), - BorrowedFormatItem::Component(Component::Second(modifier::Second::default())), - BorrowedFormatItem::Literal(b"."), - BorrowedFormatItem::Component(Component::Subsecond(modifier::Subsecond::default())), -]; - -impl Serialize for Time { - fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> { - #[cfg(feature = "serde-human-readable")] - if serializer.is_human_readable() { - let Ok(s) = self.format(&TIME_FORMAT) else { - return Err(S::Error::custom("failed formatting `Time`")); - }; - return serializer.serialize_str(&s); - } - - (self.hour(), self.minute(), self.second(), self.nanosecond()).serialize(serializer) - } -} - -impl<'a> Deserialize<'a> for Time { - fn deserialize<D: Deserializer<'a>>(deserializer: D) -> Result<Self, D::Error> { - if cfg!(feature = "serde-human-readable") && deserializer.is_human_readable() { - deserializer.deserialize_any(Visitor::<Self>(PhantomData)) - } else { - deserializer.deserialize_tuple(4, Visitor::<Self>(PhantomData)) - } - } -} - -// FIXME: turn these constants into `const { ... }` blocks once we can depend on Rust 1.79. -#[cfg(feature = "parsing")] -const UTC_OFFSET_HOUR: modifier::OffsetHour = { - let mut m = modifier::OffsetHour::default(); - m.sign_is_mandatory = true; - m -}; -#[cfg(feature = "parsing")] -const UTC_OFFSET_MINUTE: modifier::OffsetMinute = modifier::OffsetMinute::default(); -#[cfg(feature = "parsing")] -const UTC_OFFSET_SECOND: modifier::OffsetSecond = modifier::OffsetSecond::default(); -/// The format used when serializing and deserializing a human-readable `UtcOffset`. -#[cfg(feature = "parsing")] -const UTC_OFFSET_FORMAT: &[BorrowedFormatItem<'_>] = &[ - BorrowedFormatItem::Component(Component::OffsetHour(UTC_OFFSET_HOUR)), - BorrowedFormatItem::Optional(&BorrowedFormatItem::Compound(&[ - BorrowedFormatItem::Literal(b":"), - BorrowedFormatItem::Component(Component::OffsetMinute(UTC_OFFSET_MINUTE)), - BorrowedFormatItem::Optional(&BorrowedFormatItem::Compound(&[ - BorrowedFormatItem::Literal(b":"), - BorrowedFormatItem::Component(Component::OffsetSecond(UTC_OFFSET_SECOND)), - ])), - ])), -]; - -impl Serialize for UtcOffset { - fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> { - #[cfg(feature = "serde-human-readable")] - if serializer.is_human_readable() { - let Ok(s) = self.format(&UTC_OFFSET_FORMAT) else { - return Err(S::Error::custom("failed formatting `UtcOffset`")); - }; - return serializer.serialize_str(&s); - } - - ( - self.whole_hours(), - self.minutes_past_hour(), - self.seconds_past_minute(), - ) - .serialize(serializer) - } -} - -impl<'a> Deserialize<'a> for UtcOffset { - fn deserialize<D: Deserializer<'a>>(deserializer: D) -> Result<Self, D::Error> { - if cfg!(feature = "serde-human-readable") && deserializer.is_human_readable() { - deserializer.deserialize_any(Visitor::<Self>(PhantomData)) - } else { - deserializer.deserialize_tuple(3, Visitor::<Self>(PhantomData)) - } - } -} - -impl Serialize for Weekday { - fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> { - #[cfg(feature = "serde-human-readable")] - if serializer.is_human_readable() { - #[cfg(not(feature = "std"))] - use alloc::string::ToString; - return self.to_string().serialize(serializer); - } - - self.number_from_monday().serialize(serializer) - } -} - -impl<'a> Deserialize<'a> for Weekday { - fn deserialize<D: Deserializer<'a>>(deserializer: D) -> Result<Self, D::Error> { - if cfg!(feature = "serde-human-readable") && deserializer.is_human_readable() { - deserializer.deserialize_any(Visitor::<Self>(PhantomData)) - } else { - deserializer.deserialize_u8(Visitor::<Self>(PhantomData)) - } - } -} - -impl Serialize for Month { - fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> { - #[cfg(feature = "serde-human-readable")] - if serializer.is_human_readable() { - #[cfg(not(feature = "std"))] - use alloc::string::String; - return self.to_string().serialize(serializer); - } - - u8::from(*self).serialize(serializer) - } -} - -impl<'a> Deserialize<'a> for Month { - fn deserialize<D: Deserializer<'a>>(deserializer: D) -> Result<Self, D::Error> { - if cfg!(feature = "serde-human-readable") && deserializer.is_human_readable() { - deserializer.deserialize_any(Visitor::<Self>(PhantomData)) - } else { - deserializer.deserialize_u8(Visitor::<Self>(PhantomData)) - } - } -} diff --git a/vendor/time/src/serde/rfc2822.rs b/vendor/time/src/serde/rfc2822.rs deleted file mode 100644 index c6716d58..00000000 --- a/vendor/time/src/serde/rfc2822.rs +++ /dev/null @@ -1,71 +0,0 @@ -//! Use the well-known [RFC2822 format] when serializing and deserializing an [`OffsetDateTime`]. -//! -//! Use this module in combination with serde's [`#[with]`][with] attribute. -//! -//! [RFC2822 format]: https://tools.ietf.org/html/rfc2822#section-3.3 -//! [with]: https://serde.rs/field-attrs.html#with - -#[cfg(feature = "parsing")] -use core::marker::PhantomData; - -#[cfg(feature = "formatting")] -use serde::ser::Error as _; -#[cfg(feature = "parsing")] -use serde::Deserializer; -#[cfg(feature = "formatting")] -use serde::{Serialize, Serializer}; - -#[cfg(feature = "parsing")] -use super::Visitor; -use crate::format_description::well_known::Rfc2822; -use crate::OffsetDateTime; - -/// Serialize an [`OffsetDateTime`] using the well-known RFC2822 format. -#[cfg(feature = "formatting")] -pub fn serialize<S: Serializer>( - datetime: &OffsetDateTime, - serializer: S, -) -> Result<S::Ok, S::Error> { - datetime - .format(&Rfc2822) - .map_err(S::Error::custom)? - .serialize(serializer) -} - -/// Deserialize an [`OffsetDateTime`] from its RFC2822 representation. -#[cfg(feature = "parsing")] -pub fn deserialize<'a, D: Deserializer<'a>>(deserializer: D) -> Result<OffsetDateTime, D::Error> { - deserializer.deserialize_str(Visitor::<Rfc2822>(PhantomData)) -} - -/// Use the well-known [RFC2822 format] when serializing and deserializing an -/// [`Option<OffsetDateTime>`]. -/// -/// Use this module in combination with serde's [`#[with]`][with] attribute. -/// -/// [RFC2822 format]: https://tools.ietf.org/html/rfc2822#section-3.3 -/// [with]: https://serde.rs/field-attrs.html#with -pub mod option { - use super::*; - - /// Serialize an [`Option<OffsetDateTime>`] using the well-known RFC2822 format. - #[cfg(feature = "formatting")] - pub fn serialize<S: Serializer>( - option: &Option<OffsetDateTime>, - serializer: S, - ) -> Result<S::Ok, S::Error> { - option - .map(|odt| odt.format(&Rfc2822)) - .transpose() - .map_err(S::Error::custom)? - .serialize(serializer) - } - - /// Deserialize an [`Option<OffsetDateTime>`] from its RFC2822 representation. - #[cfg(feature = "parsing")] - pub fn deserialize<'a, D: Deserializer<'a>>( - deserializer: D, - ) -> Result<Option<OffsetDateTime>, D::Error> { - deserializer.deserialize_option(Visitor::<Option<Rfc2822>>(PhantomData)) - } -} diff --git a/vendor/time/src/serde/rfc3339.rs b/vendor/time/src/serde/rfc3339.rs deleted file mode 100644 index 4cccd635..00000000 --- a/vendor/time/src/serde/rfc3339.rs +++ /dev/null @@ -1,71 +0,0 @@ -//! Use the well-known [RFC3339 format] when serializing and deserializing an [`OffsetDateTime`]. -//! -//! Use this module in combination with serde's [`#[with]`][with] attribute. -//! -//! [RFC3339 format]: https://tools.ietf.org/html/rfc3339#section-5.6 -//! [with]: https://serde.rs/field-attrs.html#with - -#[cfg(feature = "parsing")] -use core::marker::PhantomData; - -#[cfg(feature = "formatting")] -use serde::ser::Error as _; -#[cfg(feature = "parsing")] -use serde::Deserializer; -#[cfg(feature = "formatting")] -use serde::{Serialize, Serializer}; - -#[cfg(feature = "parsing")] -use super::Visitor; -use crate::format_description::well_known::Rfc3339; -use crate::OffsetDateTime; - -/// Serialize an [`OffsetDateTime`] using the well-known RFC3339 format. -#[cfg(feature = "formatting")] -pub fn serialize<S: Serializer>( - datetime: &OffsetDateTime, - serializer: S, -) -> Result<S::Ok, S::Error> { - datetime - .format(&Rfc3339) - .map_err(S::Error::custom)? - .serialize(serializer) -} - -/// Deserialize an [`OffsetDateTime`] from its RFC3339 representation. -#[cfg(feature = "parsing")] -pub fn deserialize<'a, D: Deserializer<'a>>(deserializer: D) -> Result<OffsetDateTime, D::Error> { - deserializer.deserialize_str(Visitor::<Rfc3339>(PhantomData)) -} - -/// Use the well-known [RFC3339 format] when serializing and deserializing an -/// [`Option<OffsetDateTime>`]. -/// -/// Use this module in combination with serde's [`#[with]`][with] attribute. -/// -/// [RFC3339 format]: https://tools.ietf.org/html/rfc3339#section-5.6 -/// [with]: https://serde.rs/field-attrs.html#with -pub mod option { - use super::*; - - /// Serialize an [`Option<OffsetDateTime>`] using the well-known RFC3339 format. - #[cfg(feature = "formatting")] - pub fn serialize<S: Serializer>( - option: &Option<OffsetDateTime>, - serializer: S, - ) -> Result<S::Ok, S::Error> { - option - .map(|odt| odt.format(&Rfc3339)) - .transpose() - .map_err(S::Error::custom)? - .serialize(serializer) - } - - /// Deserialize an [`Option<OffsetDateTime>`] from its RFC3339 representation. - #[cfg(feature = "parsing")] - pub fn deserialize<'a, D: Deserializer<'a>>( - deserializer: D, - ) -> Result<Option<OffsetDateTime>, D::Error> { - deserializer.deserialize_option(Visitor::<Option<Rfc3339>>(PhantomData)) - } -} diff --git a/vendor/time/src/serde/timestamp/microseconds.rs b/vendor/time/src/serde/timestamp/microseconds.rs deleted file mode 100644 index 65c603ec..00000000 --- a/vendor/time/src/serde/timestamp/microseconds.rs +++ /dev/null @@ -1,63 +0,0 @@ -//! Treat an [`OffsetDateTime`] as a [Unix timestamp] with microseconds for -//! the purposes of serde. -//! -//! Use this module in combination with serde's [`#[with]`][with] attribute. -//! -//! When deserializing, the offset is assumed to be UTC. -//! -//! [Unix timestamp]: https://en.wikipedia.org/wiki/Unix_time -//! [with]: https://serde.rs/field-attrs.html#with - -use serde::{de, Deserialize, Deserializer, Serialize, Serializer}; - -use crate::OffsetDateTime; - -/// Serialize an `OffsetDateTime` as its Unix timestamp with microseconds -pub fn serialize<S: Serializer>( - datetime: &OffsetDateTime, - serializer: S, -) -> Result<S::Ok, S::Error> { - let timestamp = datetime.unix_timestamp_nanos() / 1_000; - timestamp.serialize(serializer) -} - -/// Deserialize an `OffsetDateTime` from its Unix timestamp with microseconds -pub fn deserialize<'a, D: Deserializer<'a>>(deserializer: D) -> Result<OffsetDateTime, D::Error> { - let value: i128 = <_>::deserialize(deserializer)?; - OffsetDateTime::from_unix_timestamp_nanos(value * 1_000) - .map_err(|err| de::Error::invalid_value(de::Unexpected::Signed(err.value), &err)) -} - -/// Treat an `Option<OffsetDateTime>` as a [Unix timestamp] with microseconds -/// for the purposes of serde. -/// -/// Use this module in combination with serde's [`#[with]`][with] attribute. -/// -/// When deserializing, the offset is assumed to be UTC. -/// -/// [Unix timestamp]: https://en.wikipedia.org/wiki/Unix_time -/// [with]: https://serde.rs/field-attrs.html#with -pub mod option { - #[allow(clippy::wildcard_imports)] - use super::*; - - /// Serialize an `Option<OffsetDateTime>` as its Unix timestamp with microseconds - pub fn serialize<S: Serializer>( - option: &Option<OffsetDateTime>, - serializer: S, - ) -> Result<S::Ok, S::Error> { - option - .map(|timestamp| timestamp.unix_timestamp_nanos() / 1_000) - .serialize(serializer) - } - - /// Deserialize an `Option<OffsetDateTime>` from its Unix timestamp with microseconds - pub fn deserialize<'a, D: Deserializer<'a>>( - deserializer: D, - ) -> Result<Option<OffsetDateTime>, D::Error> { - Option::deserialize(deserializer)? - .map(|value: i128| OffsetDateTime::from_unix_timestamp_nanos(value * 1_000)) - .transpose() - .map_err(|err| de::Error::invalid_value(de::Unexpected::Signed(err.value), &err)) - } -} diff --git a/vendor/time/src/serde/timestamp/milliseconds.rs b/vendor/time/src/serde/timestamp/milliseconds.rs deleted file mode 100644 index e571b6c9..00000000 --- a/vendor/time/src/serde/timestamp/milliseconds.rs +++ /dev/null @@ -1,63 +0,0 @@ -//! Treat an [`OffsetDateTime`] as a [Unix timestamp] with milliseconds for -//! the purposes of serde. -//! -//! Use this module in combination with serde's [`#[with]`][with] attribute. -//! -//! When deserializing, the offset is assumed to be UTC. -//! -//! [Unix timestamp]: https://en.wikipedia.org/wiki/Unix_time -//! [with]: https://serde.rs/field-attrs.html#with - -use serde::{de, Deserialize, Deserializer, Serialize, Serializer}; - -use crate::OffsetDateTime; - -/// Serialize an `OffsetDateTime` as its Unix timestamp with milliseconds -pub fn serialize<S: Serializer>( - datetime: &OffsetDateTime, - serializer: S, -) -> Result<S::Ok, S::Error> { - let timestamp = datetime.unix_timestamp_nanos() / 1_000_000; - timestamp.serialize(serializer) -} - -/// Deserialize an `OffsetDateTime` from its Unix timestamp with milliseconds -pub fn deserialize<'a, D: Deserializer<'a>>(deserializer: D) -> Result<OffsetDateTime, D::Error> { - let value: i128 = <_>::deserialize(deserializer)?; - OffsetDateTime::from_unix_timestamp_nanos(value * 1_000_000) - .map_err(|err| de::Error::invalid_value(de::Unexpected::Signed(err.value), &err)) -} - -/// Treat an `Option<OffsetDateTime>` as a [Unix timestamp] with milliseconds -/// for the purposes of serde. -/// -/// Use this module in combination with serde's [`#[with]`][with] attribute. -/// -/// When deserializing, the offset is assumed to be UTC. -/// -/// [Unix timestamp]: https://en.wikipedia.org/wiki/Unix_time -/// [with]: https://serde.rs/field-attrs.html#with -pub mod option { - #[allow(clippy::wildcard_imports)] - use super::*; - - /// Serialize an `Option<OffsetDateTime>` as its Unix timestamp with milliseconds - pub fn serialize<S: Serializer>( - option: &Option<OffsetDateTime>, - serializer: S, - ) -> Result<S::Ok, S::Error> { - option - .map(|timestamp| timestamp.unix_timestamp_nanos() / 1_000_000) - .serialize(serializer) - } - - /// Deserialize an `Option<OffsetDateTime>` from its Unix timestamp with milliseconds - pub fn deserialize<'a, D: Deserializer<'a>>( - deserializer: D, - ) -> Result<Option<OffsetDateTime>, D::Error> { - Option::deserialize(deserializer)? - .map(|value: i128| OffsetDateTime::from_unix_timestamp_nanos(value * 1_000_000)) - .transpose() - .map_err(|err| de::Error::invalid_value(de::Unexpected::Signed(err.value), &err)) - } -} diff --git a/vendor/time/src/serde/timestamp/milliseconds_i64.rs b/vendor/time/src/serde/timestamp/milliseconds_i64.rs deleted file mode 100644 index 59f44644..00000000 --- a/vendor/time/src/serde/timestamp/milliseconds_i64.rs +++ /dev/null @@ -1,66 +0,0 @@ -//! Treat an [`OffsetDateTime`] as a [Unix timestamp] with milliseconds for -//! the purposes of serde. -//! -//! Use this module in combination with serde's [`#[with]`][with] attribute. -//! -//! When deserializing, the offset is assumed to be UTC. -//! -//! [Unix timestamp]: https://en.wikipedia.org/wiki/Unix_time -//! [with]: https://serde.rs/field-attrs.html#with - -use num_conv::prelude::*; -use serde::{de, Deserialize, Deserializer, Serialize, Serializer}; - -use crate::OffsetDateTime; - -/// Serialize an `OffsetDateTime` as its Unix timestamp with milliseconds -pub fn serialize<S: Serializer>( - datetime: &OffsetDateTime, - serializer: S, -) -> Result<S::Ok, S::Error> { - let timestamp = (datetime.unix_timestamp_nanos() / 1_000_000).truncate::<i64>(); - timestamp.serialize(serializer) -} - -/// Deserialize an `OffsetDateTime` from its Unix timestamp with milliseconds -pub fn deserialize<'a, D: Deserializer<'a>>(deserializer: D) -> Result<OffsetDateTime, D::Error> { - let value: i64 = <_>::deserialize(deserializer)?; - OffsetDateTime::from_unix_timestamp_nanos(value.extend::<i128>() * 1_000_000) - .map_err(|err| de::Error::invalid_value(de::Unexpected::Signed(err.value), &err)) -} - -/// Treat an `Option<OffsetDateTime>` as a [Unix timestamp] with milliseconds -/// for the purposes of serde. -/// -/// Use this module in combination with serde's [`#[with]`][with] attribute. -/// -/// When deserializing, the offset is assumed to be UTC. -/// -/// [Unix timestamp]: https://en.wikipedia.org/wiki/Unix_time -/// [with]: https://serde.rs/field-attrs.html#with -pub mod option { - #[allow(clippy::wildcard_imports)] - use super::*; - - /// Serialize an `Option<OffsetDateTime>` as its Unix timestamp with milliseconds - pub fn serialize<S: Serializer>( - option: &Option<OffsetDateTime>, - serializer: S, - ) -> Result<S::Ok, S::Error> { - option - .map(|timestamp| (timestamp.unix_timestamp_nanos() / 1_000_000).truncate::<i64>()) - .serialize(serializer) - } - - /// Deserialize an `Option<OffsetDateTime>` from its Unix timestamp with milliseconds - pub fn deserialize<'a, D: Deserializer<'a>>( - deserializer: D, - ) -> Result<Option<OffsetDateTime>, D::Error> { - Option::deserialize(deserializer)? - .map(|value: i64| { - OffsetDateTime::from_unix_timestamp_nanos(value.extend::<i128>() * 1_000_000) - }) - .transpose() - .map_err(|err| de::Error::invalid_value(de::Unexpected::Signed(err.value), &err)) - } -} diff --git a/vendor/time/src/serde/timestamp/mod.rs b/vendor/time/src/serde/timestamp/mod.rs deleted file mode 100644 index d27836b6..00000000 --- a/vendor/time/src/serde/timestamp/mod.rs +++ /dev/null @@ -1,65 +0,0 @@ -//! Treat an [`OffsetDateTime`] as a [Unix timestamp] for the purposes of serde. -//! -//! Use this module in combination with serde's [`#[with]`][with] attribute. -//! -//! When deserializing, the offset is assumed to be UTC. -//! -//! [Unix timestamp]: https://en.wikipedia.org/wiki/Unix_time -//! [with]: https://serde.rs/field-attrs.html#with - -pub mod microseconds; -pub mod milliseconds; -pub mod milliseconds_i64; -pub mod nanoseconds; - -use serde::{de, Deserialize, Deserializer, Serialize, Serializer}; - -use crate::OffsetDateTime; - -/// Serialize an `OffsetDateTime` as its Unix timestamp -pub fn serialize<S: Serializer>( - datetime: &OffsetDateTime, - serializer: S, -) -> Result<S::Ok, S::Error> { - datetime.unix_timestamp().serialize(serializer) -} - -/// Deserialize an `OffsetDateTime` from its Unix timestamp -pub fn deserialize<'a, D: Deserializer<'a>>(deserializer: D) -> Result<OffsetDateTime, D::Error> { - OffsetDateTime::from_unix_timestamp(<_>::deserialize(deserializer)?) - .map_err(|err| de::Error::invalid_value(de::Unexpected::Signed(err.value), &err)) -} - -/// Treat an `Option<OffsetDateTime>` as a [Unix timestamp] for the purposes of -/// serde. -/// -/// Use this module in combination with serde's [`#[with]`][with] attribute. -/// -/// When deserializing, the offset is assumed to be UTC. -/// -/// [Unix timestamp]: https://en.wikipedia.org/wiki/Unix_time -/// [with]: https://serde.rs/field-attrs.html#with -pub mod option { - #[allow(clippy::wildcard_imports)] - use super::*; - - /// Serialize an `Option<OffsetDateTime>` as its Unix timestamp - pub fn serialize<S: Serializer>( - option: &Option<OffsetDateTime>, - serializer: S, - ) -> Result<S::Ok, S::Error> { - option - .map(OffsetDateTime::unix_timestamp) - .serialize(serializer) - } - - /// Deserialize an `Option<OffsetDateTime>` from its Unix timestamp - pub fn deserialize<'a, D: Deserializer<'a>>( - deserializer: D, - ) -> Result<Option<OffsetDateTime>, D::Error> { - Option::deserialize(deserializer)? - .map(OffsetDateTime::from_unix_timestamp) - .transpose() - .map_err(|err| de::Error::invalid_value(de::Unexpected::Signed(err.value), &err)) - } -} diff --git a/vendor/time/src/serde/timestamp/nanoseconds.rs b/vendor/time/src/serde/timestamp/nanoseconds.rs deleted file mode 100644 index c71d1e7c..00000000 --- a/vendor/time/src/serde/timestamp/nanoseconds.rs +++ /dev/null @@ -1,61 +0,0 @@ -//! Treat an [`OffsetDateTime`] as a [Unix timestamp] with nanoseconds for -//! the purposes of serde. -//! -//! Use this module in combination with serde's [`#[with]`][with] attribute. -//! -//! When deserializing, the offset is assumed to be UTC. -//! -//! [Unix timestamp]: https://en.wikipedia.org/wiki/Unix_time -//! [with]: https://serde.rs/field-attrs.html#with - -use serde::{de, Deserialize, Deserializer, Serialize, Serializer}; - -use crate::OffsetDateTime; - -/// Serialize an `OffsetDateTime` as its Unix timestamp with nanoseconds -pub fn serialize<S: Serializer>( - datetime: &OffsetDateTime, - serializer: S, -) -> Result<S::Ok, S::Error> { - datetime.unix_timestamp_nanos().serialize(serializer) -} - -/// Deserialize an `OffsetDateTime` from its Unix timestamp with nanoseconds -pub fn deserialize<'a, D: Deserializer<'a>>(deserializer: D) -> Result<OffsetDateTime, D::Error> { - OffsetDateTime::from_unix_timestamp_nanos(<_>::deserialize(deserializer)?) - .map_err(|err| de::Error::invalid_value(de::Unexpected::Signed(err.value), &err)) -} - -/// Treat an `Option<OffsetDateTime>` as a [Unix timestamp] with nanoseconds -/// for the purposes of serde. -/// -/// Use this module in combination with serde's [`#[with]`][with] attribute. -/// -/// When deserializing, the offset is assumed to be UTC. -/// -/// [Unix timestamp]: https://en.wikipedia.org/wiki/Unix_time -/// [with]: https://serde.rs/field-attrs.html#with -pub mod option { - #[allow(clippy::wildcard_imports)] - use super::*; - - /// Serialize an `Option<OffsetDateTime>` as its Unix timestamp with nanoseconds - pub fn serialize<S: Serializer>( - option: &Option<OffsetDateTime>, - serializer: S, - ) -> Result<S::Ok, S::Error> { - option - .map(OffsetDateTime::unix_timestamp_nanos) - .serialize(serializer) - } - - /// Deserialize an `Option<OffsetDateTime>` from its Unix timestamp with nanoseconds - pub fn deserialize<'a, D: Deserializer<'a>>( - deserializer: D, - ) -> Result<Option<OffsetDateTime>, D::Error> { - Option::deserialize(deserializer)? - .map(OffsetDateTime::from_unix_timestamp_nanos) - .transpose() - .map_err(|err| de::Error::invalid_value(de::Unexpected::Signed(err.value), &err)) - } -} diff --git a/vendor/time/src/serde/visitor.rs b/vendor/time/src/serde/visitor.rs deleted file mode 100644 index b7034020..00000000 --- a/vendor/time/src/serde/visitor.rs +++ /dev/null @@ -1,355 +0,0 @@ -//! Serde visitor for various types. - -use core::fmt; -use core::marker::PhantomData; - -use serde::de; -#[cfg(feature = "parsing")] -use serde::Deserializer; - -#[cfg(feature = "parsing")] -use super::{ - DATE_FORMAT, OFFSET_DATE_TIME_FORMAT, PRIMITIVE_DATE_TIME_FORMAT, TIME_FORMAT, - UTC_DATE_TIME_FORMAT, UTC_OFFSET_FORMAT, -}; -use crate::error::ComponentRange; -#[cfg(feature = "parsing")] -use crate::format_description::well_known::*; -use crate::{ - Date, Duration, Month, OffsetDateTime, PrimitiveDateTime, Time, UtcDateTime, UtcOffset, Weekday, -}; - -/// A serde visitor for various types. -pub(super) struct Visitor<T: ?Sized>(pub(super) PhantomData<T>); - -impl<'a> de::Visitor<'a> for Visitor<Date> { - type Value = Date; - - fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { - formatter.write_str("a `Date`") - } - - #[cfg(feature = "parsing")] - fn visit_str<E: de::Error>(self, value: &str) -> Result<Date, E> { - Date::parse(value, &DATE_FORMAT).map_err(E::custom) - } - - fn visit_seq<A: de::SeqAccess<'a>>(self, mut seq: A) -> Result<Date, A::Error> { - let year = item!(seq, "year")?; - let ordinal = item!(seq, "day of year")?; - Date::from_ordinal_date(year, ordinal).map_err(ComponentRange::into_de_error) - } -} - -impl<'a> de::Visitor<'a> for Visitor<Duration> { - type Value = Duration; - - fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { - formatter.write_str("a `Duration`") - } - - fn visit_str<E: de::Error>(self, value: &str) -> Result<Duration, E> { - let (seconds, nanoseconds) = value.split_once('.').ok_or_else(|| { - de::Error::invalid_value(de::Unexpected::Str(value), &"a decimal point") - })?; - - let seconds = seconds - .parse() - .map_err(|_| de::Error::invalid_value(de::Unexpected::Str(seconds), &"seconds"))?; - let mut nanoseconds = nanoseconds.parse().map_err(|_| { - de::Error::invalid_value(de::Unexpected::Str(nanoseconds), &"nanoseconds") - })?; - - if seconds < 0 - // make sure sign does not disappear when seconds == 0 - || (seconds == 0 && value.starts_with("-")) - { - nanoseconds *= -1; - } - - Ok(Duration::new(seconds, nanoseconds)) - } - - fn visit_seq<A: de::SeqAccess<'a>>(self, mut seq: A) -> Result<Duration, A::Error> { - let seconds = item!(seq, "seconds")?; - let nanoseconds = item!(seq, "nanoseconds")?; - Ok(Duration::new(seconds, nanoseconds)) - } -} - -impl<'a> de::Visitor<'a> for Visitor<OffsetDateTime> { - type Value = OffsetDateTime; - - fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { - formatter.write_str("an `OffsetDateTime`") - } - - #[cfg(feature = "parsing")] - fn visit_str<E: de::Error>(self, value: &str) -> Result<OffsetDateTime, E> { - OffsetDateTime::parse(value, &OFFSET_DATE_TIME_FORMAT).map_err(E::custom) - } - - fn visit_seq<A: de::SeqAccess<'a>>(self, mut seq: A) -> Result<OffsetDateTime, A::Error> { - let year = item!(seq, "year")?; - let ordinal = item!(seq, "day of year")?; - let hour = item!(seq, "hour")?; - let minute = item!(seq, "minute")?; - let second = item!(seq, "second")?; - let nanosecond = item!(seq, "nanosecond")?; - let offset_hours = item!(seq, "offset hours")?; - let offset_minutes = item!(seq, "offset minutes")?; - let offset_seconds = item!(seq, "offset seconds")?; - - Date::from_ordinal_date(year, ordinal) - .and_then(|date| date.with_hms_nano(hour, minute, second, nanosecond)) - .and_then(|datetime| { - UtcOffset::from_hms(offset_hours, offset_minutes, offset_seconds) - .map(|offset| datetime.assume_offset(offset)) - }) - .map_err(ComponentRange::into_de_error) - } -} - -impl<'a> de::Visitor<'a> for Visitor<PrimitiveDateTime> { - type Value = PrimitiveDateTime; - - fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { - formatter.write_str("a `PrimitiveDateTime`") - } - - #[cfg(feature = "parsing")] - fn visit_str<E: de::Error>(self, value: &str) -> Result<PrimitiveDateTime, E> { - PrimitiveDateTime::parse(value, &PRIMITIVE_DATE_TIME_FORMAT).map_err(E::custom) - } - - fn visit_seq<A: de::SeqAccess<'a>>(self, mut seq: A) -> Result<PrimitiveDateTime, A::Error> { - let year = item!(seq, "year")?; - let ordinal = item!(seq, "day of year")?; - let hour = item!(seq, "hour")?; - let minute = item!(seq, "minute")?; - let second = item!(seq, "second")?; - let nanosecond = item!(seq, "nanosecond")?; - - Date::from_ordinal_date(year, ordinal) - .and_then(|date| date.with_hms_nano(hour, minute, second, nanosecond)) - .map_err(ComponentRange::into_de_error) - } -} - -impl<'a> de::Visitor<'a> for Visitor<UtcDateTime> { - type Value = UtcDateTime; - - fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { - formatter.write_str("a `PrimitiveDateTime`") - } - - #[cfg(feature = "parsing")] - fn visit_str<E: de::Error>(self, value: &str) -> Result<UtcDateTime, E> { - UtcDateTime::parse(value, &UTC_DATE_TIME_FORMAT).map_err(E::custom) - } - - fn visit_seq<A: de::SeqAccess<'a>>(self, mut seq: A) -> Result<UtcDateTime, A::Error> { - let year = item!(seq, "year")?; - let ordinal = item!(seq, "day of year")?; - let hour = item!(seq, "hour")?; - let minute = item!(seq, "minute")?; - let second = item!(seq, "second")?; - let nanosecond = item!(seq, "nanosecond")?; - - Date::from_ordinal_date(year, ordinal) - .and_then(|date| date.with_hms_nano(hour, minute, second, nanosecond)) - .map(UtcDateTime::from_primitive) - .map_err(ComponentRange::into_de_error) - } -} - -impl<'a> de::Visitor<'a> for Visitor<Time> { - type Value = Time; - - fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { - formatter.write_str("a `Time`") - } - - #[cfg(feature = "parsing")] - fn visit_str<E: de::Error>(self, value: &str) -> Result<Time, E> { - Time::parse(value, &TIME_FORMAT).map_err(E::custom) - } - - fn visit_seq<A: de::SeqAccess<'a>>(self, mut seq: A) -> Result<Time, A::Error> { - let hour = item!(seq, "hour")?; - let minute = item!(seq, "minute")?; - let second = item!(seq, "second")?; - let nanosecond = item!(seq, "nanosecond")?; - - Time::from_hms_nano(hour, minute, second, nanosecond).map_err(ComponentRange::into_de_error) - } -} - -impl<'a> de::Visitor<'a> for Visitor<UtcOffset> { - type Value = UtcOffset; - - fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { - formatter.write_str("a `UtcOffset`") - } - - #[cfg(feature = "parsing")] - fn visit_str<E: de::Error>(self, value: &str) -> Result<UtcOffset, E> { - UtcOffset::parse(value, &UTC_OFFSET_FORMAT).map_err(E::custom) - } - - fn visit_seq<A: de::SeqAccess<'a>>(self, mut seq: A) -> Result<UtcOffset, A::Error> { - let hours = item!(seq, "offset hours")?; - let mut minutes = 0; - let mut seconds = 0; - - if let Ok(Some(min)) = seq.next_element() { - minutes = min; - if let Ok(Some(sec)) = seq.next_element() { - seconds = sec; - } - }; - - UtcOffset::from_hms(hours, minutes, seconds).map_err(ComponentRange::into_de_error) - } -} - -impl de::Visitor<'_> for Visitor<Weekday> { - type Value = Weekday; - - fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { - formatter.write_str("a `Weekday`") - } - - fn visit_str<E: de::Error>(self, value: &str) -> Result<Weekday, E> { - match value { - "Monday" => Ok(Weekday::Monday), - "Tuesday" => Ok(Weekday::Tuesday), - "Wednesday" => Ok(Weekday::Wednesday), - "Thursday" => Ok(Weekday::Thursday), - "Friday" => Ok(Weekday::Friday), - "Saturday" => Ok(Weekday::Saturday), - "Sunday" => Ok(Weekday::Sunday), - _ => Err(E::invalid_value(de::Unexpected::Str(value), &"a `Weekday`")), - } - } - - fn visit_u64<E: de::Error>(self, value: u64) -> Result<Weekday, E> { - match value { - 1 => Ok(Weekday::Monday), - 2 => Ok(Weekday::Tuesday), - 3 => Ok(Weekday::Wednesday), - 4 => Ok(Weekday::Thursday), - 5 => Ok(Weekday::Friday), - 6 => Ok(Weekday::Saturday), - 7 => Ok(Weekday::Sunday), - _ => Err(E::invalid_value( - de::Unexpected::Unsigned(value), - &"a value in the range 1..=7", - )), - } - } -} - -impl de::Visitor<'_> for Visitor<Month> { - type Value = Month; - - fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { - formatter.write_str("a `Month`") - } - - fn visit_str<E: de::Error>(self, value: &str) -> Result<Month, E> { - match value { - "January" => Ok(Month::January), - "February" => Ok(Month::February), - "March" => Ok(Month::March), - "April" => Ok(Month::April), - "May" => Ok(Month::May), - "June" => Ok(Month::June), - "July" => Ok(Month::July), - "August" => Ok(Month::August), - "September" => Ok(Month::September), - "October" => Ok(Month::October), - "November" => Ok(Month::November), - "December" => Ok(Month::December), - _ => Err(E::invalid_value(de::Unexpected::Str(value), &"a `Month`")), - } - } - - fn visit_u64<E: de::Error>(self, value: u64) -> Result<Month, E> { - match value { - 1 => Ok(Month::January), - 2 => Ok(Month::February), - 3 => Ok(Month::March), - 4 => Ok(Month::April), - 5 => Ok(Month::May), - 6 => Ok(Month::June), - 7 => Ok(Month::July), - 8 => Ok(Month::August), - 9 => Ok(Month::September), - 10 => Ok(Month::October), - 11 => Ok(Month::November), - 12 => Ok(Month::December), - _ => Err(E::invalid_value( - de::Unexpected::Unsigned(value), - &"a value in the range 1..=12", - )), - } - } -} - -/// Implement a visitor for a well-known format. -macro_rules! well_known { - ($article:literal, $name:literal, $($ty:tt)+) => { - #[cfg(feature = "parsing")] - impl de::Visitor<'_> for Visitor<$($ty)+> { - type Value = OffsetDateTime; - - fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { - formatter.write_str(concat!($article, " ", $name, "-formatted `OffsetDateTime`")) - } - - fn visit_str<E: de::Error>(self, value: &str) -> Result<OffsetDateTime, E> { - OffsetDateTime::parse(value, &$($ty)+).map_err(E::custom) - } - } - - #[cfg(feature = "parsing")] - impl<'a> de::Visitor<'a> for Visitor<Option<$($ty)+>> { - type Value = Option<OffsetDateTime>; - - fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { - formatter.write_str(concat!( - $article, - " ", - $name, - "-formatted `Option<OffsetDateTime>`" - )) - } - - fn visit_some<D: Deserializer<'a>>( - self, - deserializer: D, - ) -> Result<Option<OffsetDateTime>, D::Error> { - deserializer - .deserialize_any(Visitor::<$($ty)+>(PhantomData)) - .map(Some) - } - - fn visit_none<E: de::Error>(self) -> Result<Option<OffsetDateTime>, E> { - Ok(None) - } - - fn visit_unit<E: de::Error>(self) -> Result<Self::Value, E> { - Ok(None) - } - } - }; -} - -well_known!("an", "RFC2822", Rfc2822); -well_known!("an", "RFC3339", Rfc3339); -well_known!( - "an", - "ISO 8601", - Iso8601::<{ super::iso8601::SERDE_CONFIG }> -); diff --git a/vendor/time/src/sys/local_offset_at/imp.rs b/vendor/time/src/sys/local_offset_at/imp.rs deleted file mode 100644 index 251fa667..00000000 --- a/vendor/time/src/sys/local_offset_at/imp.rs +++ /dev/null @@ -1,8 +0,0 @@ -//! A fallback for any OS not covered. - -use crate::{OffsetDateTime, UtcOffset}; - -#[allow(clippy::missing_docs_in_private_items)] -pub(super) fn local_offset_at(_datetime: OffsetDateTime) -> Option<UtcOffset> { - None -} diff --git a/vendor/time/src/sys/local_offset_at/mod.rs b/vendor/time/src/sys/local_offset_at/mod.rs deleted file mode 100644 index 04cfffd5..00000000 --- a/vendor/time/src/sys/local_offset_at/mod.rs +++ /dev/null @@ -1,23 +0,0 @@ -//! A method to obtain the local offset from UTC. - -#![allow(clippy::missing_const_for_fn)] - -#[cfg_attr(target_family = "windows", path = "windows.rs")] -#[cfg_attr(target_family = "unix", path = "unix.rs")] -#[cfg_attr( - all( - target_family = "wasm", - not(any(target_os = "emscripten", target_os = "wasi")), - feature = "wasm-bindgen" - ), - path = "wasm_js.rs" -)] -mod imp; - -use crate::{OffsetDateTime, UtcOffset}; - -/// Attempt to obtain the system's UTC offset. If the offset cannot be determined, `None` is -/// returned. -pub(crate) fn local_offset_at(datetime: OffsetDateTime) -> Option<UtcOffset> { - imp::local_offset_at(datetime) -} diff --git a/vendor/time/src/sys/local_offset_at/unix.rs b/vendor/time/src/sys/local_offset_at/unix.rs deleted file mode 100644 index d036a0e0..00000000 --- a/vendor/time/src/sys/local_offset_at/unix.rs +++ /dev/null @@ -1,101 +0,0 @@ -//! Get the system's UTC offset on Unix. - -use core::mem::MaybeUninit; - -use crate::{OffsetDateTime, UtcOffset}; - -/// Convert the given Unix timestamp to a `libc::tm`. Returns `None` on any error. -fn timestamp_to_tm(timestamp: i64) -> Option<libc::tm> { - // The exact type of `timestamp` beforehand can vary, so this conversion is necessary. - #[allow(clippy::useless_conversion)] - let timestamp = timestamp.try_into().ok()?; - - let mut tm = MaybeUninit::uninit(); - - // Safety: We are calling a system API, which mutates the `tm` variable. If a null - // pointer is returned, an error occurred. - let tm_ptr = unsafe { libc::localtime_r(×tamp, tm.as_mut_ptr()) }; - - if tm_ptr.is_null() { - None - } else { - // Safety: The value was initialized, as we no longer have a null pointer. - Some(unsafe { tm.assume_init() }) - } -} - -/// Convert a `libc::tm` to a `UtcOffset`. Returns `None` on any error. -// This is available to any target known to have the `tm_gmtoff` extension. -#[cfg(any( - target_os = "redox", - target_os = "linux", - target_os = "l4re", - target_os = "android", - target_os = "emscripten", - target_os = "macos", - target_os = "ios", - target_os = "watchos", - target_os = "freebsd", - target_os = "dragonfly", - target_os = "openbsd", - target_os = "netbsd", - target_os = "haiku", -))] -fn tm_to_offset(_unix_timestamp: i64, tm: libc::tm) -> Option<UtcOffset> { - let seconds = tm.tm_gmtoff.try_into().ok()?; - UtcOffset::from_whole_seconds(seconds).ok() -} - -/// Convert a `libc::tm` to a `UtcOffset`. Returns `None` on any error. -/// -/// This method can return an incorrect value, as it only approximates the `tm_gmtoff` field. The -/// reason for this is that daylight saving time does not start on the same date every year, nor are -/// the rules for daylight saving time the same for every year. This implementation assumes 1970 is -/// equivalent to every other year, which is not always the case. -#[cfg(not(any( - target_os = "redox", - target_os = "linux", - target_os = "l4re", - target_os = "android", - target_os = "emscripten", - target_os = "macos", - target_os = "ios", - target_os = "watchos", - target_os = "freebsd", - target_os = "dragonfly", - target_os = "openbsd", - target_os = "netbsd", - target_os = "haiku", -)))] -fn tm_to_offset(unix_timestamp: i64, tm: libc::tm) -> Option<UtcOffset> { - use crate::Date; - - let mut tm = tm; - if tm.tm_sec == 60 { - // Leap seconds are not currently supported. - tm.tm_sec = 59; - } - - let local_timestamp = - Date::from_ordinal_date(1900 + tm.tm_year, u16::try_from(tm.tm_yday).ok()? + 1) - .ok()? - .with_hms( - tm.tm_hour.try_into().ok()?, - tm.tm_min.try_into().ok()?, - tm.tm_sec.try_into().ok()?, - ) - .ok()? - .assume_utc() - .unix_timestamp(); - - let diff_secs = (local_timestamp - unix_timestamp).try_into().ok()?; - - UtcOffset::from_whole_seconds(diff_secs).ok() -} - -/// Obtain the system's UTC offset. -pub(super) fn local_offset_at(datetime: OffsetDateTime) -> Option<UtcOffset> { - let unix_timestamp = datetime.unix_timestamp(); - let tm = timestamp_to_tm(unix_timestamp)?; - tm_to_offset(unix_timestamp, tm) -} diff --git a/vendor/time/src/sys/local_offset_at/wasm_js.rs b/vendor/time/src/sys/local_offset_at/wasm_js.rs deleted file mode 100644 index a985e7c4..00000000 --- a/vendor/time/src/sys/local_offset_at/wasm_js.rs +++ /dev/null @@ -1,16 +0,0 @@ -use num_conv::prelude::*; - -use crate::convert::*; -use crate::{OffsetDateTime, UtcOffset}; - -/// Obtain the system's UTC offset. -pub(super) fn local_offset_at(datetime: OffsetDateTime) -> Option<UtcOffset> { - let js_date: js_sys::Date = datetime.into(); - // The number of minutes returned by getTimezoneOffset() is positive if the local time zone - // is behind UTC, and negative if the local time zone is ahead of UTC. For example, - // for UTC+10, -600 will be returned. - let timezone_offset = - (js_date.get_timezone_offset() as i32) * -Minute::per(Hour).cast_signed().extend::<i32>(); - - UtcOffset::from_whole_seconds(timezone_offset).ok() -} diff --git a/vendor/time/src/sys/local_offset_at/windows.rs b/vendor/time/src/sys/local_offset_at/windows.rs deleted file mode 100644 index d1442920..00000000 --- a/vendor/time/src/sys/local_offset_at/windows.rs +++ /dev/null @@ -1,113 +0,0 @@ -//! Get the system's UTC offset on Windows. - -use core::mem::MaybeUninit; - -use num_conv::prelude::*; - -use crate::convert::*; -use crate::{OffsetDateTime, UtcOffset}; - -// ffi: WINAPI FILETIME struct -#[repr(C)] -#[allow(non_snake_case, clippy::missing_docs_in_private_items)] -struct FileTime { - dwLowDateTime: u32, - dwHighDateTime: u32, -} - -// ffi: WINAPI SYSTEMTIME struct -#[repr(C)] -#[allow(non_snake_case, clippy::missing_docs_in_private_items)] -struct SystemTime { - wYear: u16, - wMonth: u16, - wDayOfWeek: u16, - wDay: u16, - wHour: u16, - wMinute: u16, - wSecond: u16, - wMilliseconds: u16, -} - -#[link(name = "kernel32")] -extern "system" { - // https://docs.microsoft.com/en-us/windows/win32/api/timezoneapi/nf-timezoneapi-systemtimetofiletime - fn SystemTimeToFileTime(lpSystemTime: *const SystemTime, lpFileTime: *mut FileTime) -> i32; - - // https://docs.microsoft.com/en-us/windows/win32/api/timezoneapi/nf-timezoneapi-systemtimetotzspecificlocaltime - fn SystemTimeToTzSpecificLocalTime( - lpTimeZoneInformation: *const core::ffi::c_void, // We only pass `nullptr` here - lpUniversalTime: *const SystemTime, - lpLocalTime: *mut SystemTime, - ) -> i32; -} - -/// Convert a `SYSTEMTIME` to a `FILETIME`. Returns `None` if any error occurred. -fn systemtime_to_filetime(systime: &SystemTime) -> Option<FileTime> { - let mut ft = MaybeUninit::uninit(); - - // Safety: `SystemTimeToFileTime` is thread-safe. - if 0 == unsafe { SystemTimeToFileTime(systime, ft.as_mut_ptr()) } { - // failed - None - } else { - // Safety: The call succeeded. - Some(unsafe { ft.assume_init() }) - } -} - -/// Convert a `FILETIME` to an `i64`, representing a number of seconds. -fn filetime_to_secs(filetime: &FileTime) -> i64 { - /// FILETIME represents 100-nanosecond intervals - const FT_TO_SECS: u64 = Nanosecond::per(Second) as u64 / 100; - ((filetime.dwHighDateTime.extend::<u64>() << 32 | filetime.dwLowDateTime.extend::<u64>()) - / FT_TO_SECS) as i64 -} - -/// Convert an [`OffsetDateTime`] to a `SYSTEMTIME`. -fn offset_to_systemtime(datetime: OffsetDateTime) -> SystemTime { - let (_, month, day_of_month) = datetime.to_offset(UtcOffset::UTC).date().to_calendar_date(); - SystemTime { - wYear: datetime.year().cast_unsigned().truncate(), - wMonth: u8::from(month).extend(), - wDay: day_of_month.extend(), - wDayOfWeek: 0, // ignored - wHour: datetime.hour().extend(), - wMinute: datetime.minute().extend(), - wSecond: datetime.second().extend(), - wMilliseconds: datetime.millisecond(), - } -} - -/// Obtain the system's UTC offset. -pub(super) fn local_offset_at(datetime: OffsetDateTime) -> Option<UtcOffset> { - // This function falls back to UTC if any system call fails. - let systime_utc = offset_to_systemtime(datetime.to_offset(UtcOffset::UTC)); - - // Safety: `local_time` is only read if it is properly initialized, and - // `SystemTimeToTzSpecificLocalTime` is thread-safe. - let systime_local = unsafe { - let mut local_time = MaybeUninit::uninit(); - - if 0 == SystemTimeToTzSpecificLocalTime( - core::ptr::null(), // use system's current timezone - &systime_utc, - local_time.as_mut_ptr(), - ) { - // call failed - return None; - } else { - local_time.assume_init() - } - }; - - // Convert SYSTEMTIMEs to FILETIMEs so we can perform arithmetic on them. - let ft_system = systemtime_to_filetime(&systime_utc)?; - let ft_local = systemtime_to_filetime(&systime_local)?; - - let diff_secs = (filetime_to_secs(&ft_local) - filetime_to_secs(&ft_system)) - .try_into() - .ok()?; - - UtcOffset::from_whole_seconds(diff_secs).ok() -} diff --git a/vendor/time/src/sys/mod.rs b/vendor/time/src/sys/mod.rs deleted file mode 100644 index 76ca93b5..00000000 --- a/vendor/time/src/sys/mod.rs +++ /dev/null @@ -1,11 +0,0 @@ -//! Functions with a common interface that rely on system calls. - -#[cfg(feature = "local-offset")] -mod local_offset_at; -#[cfg(feature = "local-offset")] -mod refresh_tz; - -#[cfg(feature = "local-offset")] -pub(crate) use self::local_offset_at::local_offset_at; -#[cfg(feature = "local-offset")] -pub(crate) use self::refresh_tz::{refresh_tz, refresh_tz_unchecked}; diff --git a/vendor/time/src/sys/refresh_tz/imp.rs b/vendor/time/src/sys/refresh_tz/imp.rs deleted file mode 100644 index 6f8b1328..00000000 --- a/vendor/time/src/sys/refresh_tz/imp.rs +++ /dev/null @@ -1,9 +0,0 @@ -//! A fallback for any OS not covered. - -#[allow(clippy::missing_docs_in_private_items)] -pub(super) unsafe fn refresh_tz_unchecked() {} - -#[allow(clippy::missing_docs_in_private_items)] -pub(super) fn refresh_tz() -> Option<()> { - Some(()) -} diff --git a/vendor/time/src/sys/refresh_tz/mod.rs b/vendor/time/src/sys/refresh_tz/mod.rs deleted file mode 100644 index 90ddaa99..00000000 --- a/vendor/time/src/sys/refresh_tz/mod.rs +++ /dev/null @@ -1,17 +0,0 @@ -#[cfg_attr(target_family = "unix", path = "unix.rs")] -mod imp; - -/// Update time zone information from the system. -/// -/// For safety documentation, see [`time::util::refresh_tz`]. -pub(crate) unsafe fn refresh_tz_unchecked() { - // Safety: The caller must uphold the safety requirements. - unsafe { imp::refresh_tz_unchecked() } -} - -/// Attempt to update time zone information from the system. -/// -/// Returns `None` if the call is not known to be sound. -pub(crate) fn refresh_tz() -> Option<()> { - imp::refresh_tz() -} diff --git a/vendor/time/src/sys/refresh_tz/unix.rs b/vendor/time/src/sys/refresh_tz/unix.rs deleted file mode 100644 index 6c9813e2..00000000 --- a/vendor/time/src/sys/refresh_tz/unix.rs +++ /dev/null @@ -1,48 +0,0 @@ -/// Whether the operating system has a thread-safe environment. This allows bypassing the check for -/// if the process is multi-threaded. -// This is the same value as `cfg!(target_os = "x")`. -// Use byte-strings to work around current limitations of const eval. -const OS_HAS_THREAD_SAFE_ENVIRONMENT: bool = match std::env::consts::OS.as_bytes() { - // https://github.com/illumos/illumos-gate/blob/0fb96ba1f1ce26ff8b286f8f928769a6afcb00a6/usr/src/lib/libc/port/gen/getenv.c - b"illumos" - // https://github.com/NetBSD/src/blob/f45028636a44111bc4af44d460924958a4460844/lib/libc/stdlib/getenv.c - // https://github.com/NetBSD/src/blob/f45028636a44111bc4af44d460924958a4460844/lib/libc/stdlib/setenv.c - | b"netbsd" - => true, - _ => false, -}; - -/// Update time zone information from the system. -/// -/// For safety documentation, see [`time::util::refresh_tz`]. -pub(super) unsafe fn refresh_tz_unchecked() { - extern "C" { - #[cfg_attr(target_os = "netbsd", link_name = "__tzset50")] - fn tzset(); - } - - // Safety: The caller must uphold the safety requirements. - unsafe { tzset() }; -} - -/// Attempt to update time zone information from the system. Returns `None` if the call is not known -/// to be sound. -pub(super) fn refresh_tz() -> Option<()> { - // Refresh $TZ if and only if the call is known to be sound. - // - // Soundness can be guaranteed either by knowledge of the operating system or knowledge that the - // process is single-threaded. If the process is single-threaded, then the environment cannot - // be mutated by a different thread in the process while execution of this function is taking - // place, which can cause a segmentation fault by dereferencing a dangling pointer. - // - // If the `num_threads` crate is incapable of determining the number of running threads, then - // we conservatively return `None` to avoid a soundness bug. - - if OS_HAS_THREAD_SAFE_ENVIRONMENT || num_threads::is_single_threaded() == Some(true) { - // Safety: The caller must uphold the safety requirements. - unsafe { refresh_tz_unchecked() }; - Some(()) - } else { - None - } -} diff --git a/vendor/time/src/tests.rs b/vendor/time/src/tests.rs deleted file mode 100644 index 1a404aa9..00000000 --- a/vendor/time/src/tests.rs +++ /dev/null @@ -1,104 +0,0 @@ -#![cfg(all( // require `--all-features` to be passed - feature = "default", - feature = "alloc", - feature = "formatting", - feature = "large-dates", - feature = "local-offset", - feature = "macros", - feature = "parsing", - feature = "quickcheck", - feature = "serde-human-readable", - feature = "serde-well-known", - feature = "std", - feature = "rand", - feature = "serde", -))] -#![allow( - let_underscore_drop, - clippy::clone_on_copy, - clippy::cognitive_complexity, - clippy::std_instead_of_core -)] - -//! Tests for internal details. -//! -//! This module should only be used when it is not possible to test the implementation in a -//! reasonable manner externally. - -use std::format; -use std::num::NonZeroU8; - -use crate::ext::DigitCount; -use crate::parsing::combinator::rfc::iso8601; -use crate::parsing::shim::Integer; -use crate::{duration, parsing}; - -#[test] -fn digit_count() { - assert_eq!(1_u8.num_digits(), 1); - assert_eq!(9_u8.num_digits(), 1); - assert_eq!(10_u8.num_digits(), 2); - assert_eq!(99_u8.num_digits(), 2); - assert_eq!(100_u8.num_digits(), 3); - - assert_eq!(1_u16.num_digits(), 1); - assert_eq!(9_u16.num_digits(), 1); - assert_eq!(10_u16.num_digits(), 2); - assert_eq!(99_u16.num_digits(), 2); - assert_eq!(100_u16.num_digits(), 3); - assert_eq!(999_u16.num_digits(), 3); - assert_eq!(1_000_u16.num_digits(), 4); - assert_eq!(9_999_u16.num_digits(), 4); - assert_eq!(10_000_u16.num_digits(), 5); - - assert_eq!(1_u32.num_digits(), 1); - assert_eq!(9_u32.num_digits(), 1); - assert_eq!(10_u32.num_digits(), 2); - assert_eq!(99_u32.num_digits(), 2); - assert_eq!(100_u32.num_digits(), 3); - assert_eq!(999_u32.num_digits(), 3); - assert_eq!(1_000_u32.num_digits(), 4); - assert_eq!(9_999_u32.num_digits(), 4); - assert_eq!(10_000_u32.num_digits(), 5); - assert_eq!(99_999_u32.num_digits(), 5); - assert_eq!(100_000_u32.num_digits(), 6); - assert_eq!(999_999_u32.num_digits(), 6); - assert_eq!(1_000_000_u32.num_digits(), 7); - assert_eq!(9_999_999_u32.num_digits(), 7); - assert_eq!(10_000_000_u32.num_digits(), 8); - assert_eq!(99_999_999_u32.num_digits(), 8); - assert_eq!(100_000_000_u32.num_digits(), 9); - assert_eq!(999_999_999_u32.num_digits(), 9); - assert_eq!(1_000_000_000_u32.num_digits(), 10); -} - -#[test] -fn debug() { - let _ = format!("{:?}", duration::Padding::Optimize); - let _ = format!("{:?}", parsing::ParsedItem(b"", 0)); - let _ = format!("{:?}", parsing::component::Period::Am); - let _ = format!("{:?}", iso8601::ExtendedKind::Basic); -} - -#[test] -fn clone() { - assert_eq!( - parsing::component::Period::Am.clone(), - parsing::component::Period::Am - ); - // does not impl Debug - assert!(crate::time::Padding::Optimize.clone() == crate::time::Padding::Optimize); - // does not impl PartialEq - assert!(matches!( - iso8601::ExtendedKind::Basic.clone(), - iso8601::ExtendedKind::Basic - )); -} - -#[test] -fn parsing_internals() { - assert!(parsing::ParsedItem(b"", ()) - .flat_map(|_| None::<()>) - .is_none()); - assert!(<NonZeroU8 as Integer>::parse_bytes(b"256").is_none()); -} diff --git a/vendor/time/src/time.rs b/vendor/time/src/time.rs deleted file mode 100644 index 627a2504..00000000 --- a/vendor/time/src/time.rs +++ /dev/null @@ -1,937 +0,0 @@ -//! The [`Time`] struct and its associated `impl`s. - -#[cfg(feature = "formatting")] -use alloc::string::String; -use core::fmt; -use core::ops::{Add, Sub}; -use core::time::Duration as StdDuration; -#[cfg(feature = "formatting")] -use std::io; - -use deranged::{RangedU32, RangedU8}; -use num_conv::prelude::*; -use powerfmt::ext::FormatterExt; -use powerfmt::smart_display::{self, FormatterOptions, Metadata, SmartDisplay}; - -use crate::convert::*; -#[cfg(feature = "formatting")] -use crate::formatting::Formattable; -use crate::internal_macros::{cascade, ensure_ranged, impl_add_assign, impl_sub_assign}; -#[cfg(feature = "parsing")] -use crate::parsing::Parsable; -use crate::util::DateAdjustment; -use crate::{error, Duration}; - -/// By explicitly inserting this enum where padding is expected, the compiler is able to better -/// perform niche value optimization. -#[repr(u8)] -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub(crate) enum Padding { - #[allow(clippy::missing_docs_in_private_items)] - Optimize, -} - -/// The type of the `hour` field of `Time`. -type Hours = RangedU8<0, { Hour::per(Day) - 1 }>; -/// The type of the `minute` field of `Time`. -type Minutes = RangedU8<0, { Minute::per(Hour) - 1 }>; -/// The type of the `second` field of `Time`. -type Seconds = RangedU8<0, { Second::per(Minute) - 1 }>; -/// The type of the `nanosecond` field of `Time`. -type Nanoseconds = RangedU32<0, { Nanosecond::per(Second) - 1 }>; - -/// The clock time within a given date. Nanosecond precision. -/// -/// All minutes are assumed to have exactly 60 seconds; no attempt is made to handle leap seconds -/// (either positive or negative). -/// -/// When comparing two `Time`s, they are assumed to be in the same calendar date. -#[derive(Clone, Copy, Eq)] -#[repr(C)] -pub struct Time { - // The order of this struct's fields matter! - // Do not change them. - - // Little endian version - #[cfg(target_endian = "little")] - nanosecond: Nanoseconds, - #[cfg(target_endian = "little")] - second: Seconds, - #[cfg(target_endian = "little")] - minute: Minutes, - #[cfg(target_endian = "little")] - hour: Hours, - #[cfg(target_endian = "little")] - padding: Padding, - - // Big endian version - #[cfg(target_endian = "big")] - padding: Padding, - #[cfg(target_endian = "big")] - hour: Hours, - #[cfg(target_endian = "big")] - minute: Minutes, - #[cfg(target_endian = "big")] - second: Seconds, - #[cfg(target_endian = "big")] - nanosecond: Nanoseconds, -} - -impl core::hash::Hash for Time { - fn hash<H: core::hash::Hasher>(&self, state: &mut H) { - self.as_u64().hash(state) - } -} - -impl PartialEq for Time { - fn eq(&self, other: &Self) -> bool { - self.as_u64().eq(&other.as_u64()) - } -} - -impl PartialOrd for Time { - fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> { - Some(self.cmp(other)) - } -} - -impl Ord for Time { - fn cmp(&self, other: &Self) -> core::cmp::Ordering { - self.as_u64().cmp(&other.as_u64()) - } -} - -impl Time { - /// Provides an u64 based representation **of the correct endianness** - /// - /// This representation can be used to do comparisons equality testing or hashing. - const fn as_u64(self) -> u64 { - let nano_bytes = self.nanosecond.get().to_ne_bytes(); - - #[cfg(target_endian = "big")] - return u64::from_be_bytes([ - self.padding as u8, - self.hour.get(), - self.minute.get(), - self.second.get(), - nano_bytes[0], - nano_bytes[1], - nano_bytes[2], - nano_bytes[3], - ]); - - #[cfg(target_endian = "little")] - return u64::from_le_bytes([ - nano_bytes[0], - nano_bytes[1], - nano_bytes[2], - nano_bytes[3], - self.second.get(), - self.minute.get(), - self.hour.get(), - self.padding as u8, - ]); - } - - /// A `Time` that is exactly midnight. This is the smallest possible value for a `Time`. - /// - /// ```rust - /// # use time::Time; - /// # use time_macros::time; - /// assert_eq!(Time::MIDNIGHT, time!(0:00)); - /// ``` - #[doc(alias = "MIN")] - pub const MIDNIGHT: Self = - Self::from_hms_nanos_ranged(Hours::MIN, Minutes::MIN, Seconds::MIN, Nanoseconds::MIN); - - /// A `Time` that is one nanosecond before midnight. This is the largest possible value for a - /// `Time`. - /// - /// ```rust - /// # use time::Time; - /// # use time_macros::time; - /// assert_eq!(Time::MAX, time!(23:59:59.999_999_999)); - /// ``` - pub const MAX: Self = - Self::from_hms_nanos_ranged(Hours::MAX, Minutes::MAX, Seconds::MAX, Nanoseconds::MAX); - - /// Create a `Time` from its components. - /// - /// # Safety - /// - /// - `hours` must be in the range `0..=23`. - /// - `minutes` must be in the range `0..=59`. - /// - `seconds` must be in the range `0..=59`. - /// - `nanoseconds` must be in the range `0..=999_999_999`. - #[doc(hidden)] - pub const unsafe fn __from_hms_nanos_unchecked( - hour: u8, - minute: u8, - second: u8, - nanosecond: u32, - ) -> Self { - // Safety: The caller must uphold the safety invariants. - unsafe { - Self::from_hms_nanos_ranged( - Hours::new_unchecked(hour), - Minutes::new_unchecked(minute), - Seconds::new_unchecked(second), - Nanoseconds::new_unchecked(nanosecond), - ) - } - } - - /// Attempt to create a `Time` from the hour, minute, and second. - /// - /// ```rust - /// # use time::Time; - /// assert!(Time::from_hms(1, 2, 3).is_ok()); - /// ``` - /// - /// ```rust - /// # use time::Time; - /// assert!(Time::from_hms(24, 0, 0).is_err()); // 24 isn't a valid hour. - /// assert!(Time::from_hms(0, 60, 0).is_err()); // 60 isn't a valid minute. - /// assert!(Time::from_hms(0, 0, 60).is_err()); // 60 isn't a valid second. - /// ``` - pub const fn from_hms(hour: u8, minute: u8, second: u8) -> Result<Self, error::ComponentRange> { - Ok(Self::from_hms_nanos_ranged( - ensure_ranged!(Hours: hour), - ensure_ranged!(Minutes: minute), - ensure_ranged!(Seconds: second), - Nanoseconds::MIN, - )) - } - - /// Create a `Time` from the hour, minute, second, and nanosecond. - pub(crate) const fn from_hms_nanos_ranged( - hour: Hours, - minute: Minutes, - second: Seconds, - nanosecond: Nanoseconds, - ) -> Self { - Self { - hour, - minute, - second, - nanosecond, - padding: Padding::Optimize, - } - } - - /// Attempt to create a `Time` from the hour, minute, second, and millisecond. - /// - /// ```rust - /// # use time::Time; - /// assert!(Time::from_hms_milli(1, 2, 3, 4).is_ok()); - /// ``` - /// - /// ```rust - /// # use time::Time; - /// assert!(Time::from_hms_milli(24, 0, 0, 0).is_err()); // 24 isn't a valid hour. - /// assert!(Time::from_hms_milli(0, 60, 0, 0).is_err()); // 60 isn't a valid minute. - /// assert!(Time::from_hms_milli(0, 0, 60, 0).is_err()); // 60 isn't a valid second. - /// assert!(Time::from_hms_milli(0, 0, 0, 1_000).is_err()); // 1_000 isn't a valid millisecond. - /// ``` - pub const fn from_hms_milli( - hour: u8, - minute: u8, - second: u8, - millisecond: u16, - ) -> Result<Self, error::ComponentRange> { - Ok(Self::from_hms_nanos_ranged( - ensure_ranged!(Hours: hour), - ensure_ranged!(Minutes: minute), - ensure_ranged!(Seconds: second), - ensure_ranged!(Nanoseconds: millisecond as u32 * Nanosecond::per(Millisecond)), - )) - } - - /// Attempt to create a `Time` from the hour, minute, second, and microsecond. - /// - /// ```rust - /// # use time::Time; - /// assert!(Time::from_hms_micro(1, 2, 3, 4).is_ok()); - /// ``` - /// - /// ```rust - /// # use time::Time; - /// assert!(Time::from_hms_micro(24, 0, 0, 0).is_err()); // 24 isn't a valid hour. - /// assert!(Time::from_hms_micro(0, 60, 0, 0).is_err()); // 60 isn't a valid minute. - /// assert!(Time::from_hms_micro(0, 0, 60, 0).is_err()); // 60 isn't a valid second. - /// assert!(Time::from_hms_micro(0, 0, 0, 1_000_000).is_err()); // 1_000_000 isn't a valid microsecond. - /// ``` - pub const fn from_hms_micro( - hour: u8, - minute: u8, - second: u8, - microsecond: u32, - ) -> Result<Self, error::ComponentRange> { - Ok(Self::from_hms_nanos_ranged( - ensure_ranged!(Hours: hour), - ensure_ranged!(Minutes: minute), - ensure_ranged!(Seconds: second), - ensure_ranged!(Nanoseconds: microsecond * Nanosecond::per(Microsecond) as u32), - )) - } - - /// Attempt to create a `Time` from the hour, minute, second, and nanosecond. - /// - /// ```rust - /// # use time::Time; - /// assert!(Time::from_hms_nano(1, 2, 3, 4).is_ok()); - /// ``` - /// - /// ```rust - /// # use time::Time; - /// assert!(Time::from_hms_nano(24, 0, 0, 0).is_err()); // 24 isn't a valid hour. - /// assert!(Time::from_hms_nano(0, 60, 0, 0).is_err()); // 60 isn't a valid minute. - /// assert!(Time::from_hms_nano(0, 0, 60, 0).is_err()); // 60 isn't a valid second. - /// assert!(Time::from_hms_nano(0, 0, 0, 1_000_000_000).is_err()); // 1_000_000_000 isn't a valid nanosecond. - /// ``` - pub const fn from_hms_nano( - hour: u8, - minute: u8, - second: u8, - nanosecond: u32, - ) -> Result<Self, error::ComponentRange> { - Ok(Self::from_hms_nanos_ranged( - ensure_ranged!(Hours: hour), - ensure_ranged!(Minutes: minute), - ensure_ranged!(Seconds: second), - ensure_ranged!(Nanoseconds: nanosecond), - )) - } - - /// Get the clock hour, minute, and second. - /// - /// ```rust - /// # use time_macros::time; - /// assert_eq!(time!(0:00:00).as_hms(), (0, 0, 0)); - /// assert_eq!(time!(23:59:59).as_hms(), (23, 59, 59)); - /// ``` - pub const fn as_hms(self) -> (u8, u8, u8) { - (self.hour.get(), self.minute.get(), self.second.get()) - } - - /// Get the clock hour, minute, second, and millisecond. - /// - /// ```rust - /// # use time_macros::time; - /// assert_eq!(time!(0:00:00).as_hms_milli(), (0, 0, 0, 0)); - /// assert_eq!(time!(23:59:59.999).as_hms_milli(), (23, 59, 59, 999)); - /// ``` - pub const fn as_hms_milli(self) -> (u8, u8, u8, u16) { - ( - self.hour.get(), - self.minute.get(), - self.second.get(), - (self.nanosecond.get() / Nanosecond::per(Millisecond)) as u16, - ) - } - - /// Get the clock hour, minute, second, and microsecond. - /// - /// ```rust - /// # use time_macros::time; - /// assert_eq!(time!(0:00:00).as_hms_micro(), (0, 0, 0, 0)); - /// assert_eq!( - /// time!(23:59:59.999_999).as_hms_micro(), - /// (23, 59, 59, 999_999) - /// ); - /// ``` - pub const fn as_hms_micro(self) -> (u8, u8, u8, u32) { - ( - self.hour.get(), - self.minute.get(), - self.second.get(), - self.nanosecond.get() / Nanosecond::per(Microsecond) as u32, - ) - } - - /// Get the clock hour, minute, second, and nanosecond. - /// - /// ```rust - /// # use time_macros::time; - /// assert_eq!(time!(0:00:00).as_hms_nano(), (0, 0, 0, 0)); - /// assert_eq!( - /// time!(23:59:59.999_999_999).as_hms_nano(), - /// (23, 59, 59, 999_999_999) - /// ); - /// ``` - pub const fn as_hms_nano(self) -> (u8, u8, u8, u32) { - ( - self.hour.get(), - self.minute.get(), - self.second.get(), - self.nanosecond.get(), - ) - } - - /// Get the clock hour, minute, second, and nanosecond. - #[cfg(feature = "quickcheck")] - pub(crate) const fn as_hms_nano_ranged(self) -> (Hours, Minutes, Seconds, Nanoseconds) { - (self.hour, self.minute, self.second, self.nanosecond) - } - - /// Get the clock hour. - /// - /// The returned value will always be in the range `0..24`. - /// - /// ```rust - /// # use time_macros::time; - /// assert_eq!(time!(0:00:00).hour(), 0); - /// assert_eq!(time!(23:59:59).hour(), 23); - /// ``` - pub const fn hour(self) -> u8 { - self.hour.get() - } - - /// Get the minute within the hour. - /// - /// The returned value will always be in the range `0..60`. - /// - /// ```rust - /// # use time_macros::time; - /// assert_eq!(time!(0:00:00).minute(), 0); - /// assert_eq!(time!(23:59:59).minute(), 59); - /// ``` - pub const fn minute(self) -> u8 { - self.minute.get() - } - - /// Get the second within the minute. - /// - /// The returned value will always be in the range `0..60`. - /// - /// ```rust - /// # use time_macros::time; - /// assert_eq!(time!(0:00:00).second(), 0); - /// assert_eq!(time!(23:59:59).second(), 59); - /// ``` - pub const fn second(self) -> u8 { - self.second.get() - } - - /// Get the milliseconds within the second. - /// - /// The returned value will always be in the range `0..1_000`. - /// - /// ```rust - /// # use time_macros::time; - /// assert_eq!(time!(0:00).millisecond(), 0); - /// assert_eq!(time!(23:59:59.999).millisecond(), 999); - /// ``` - pub const fn millisecond(self) -> u16 { - (self.nanosecond.get() / Nanosecond::per(Millisecond)) as u16 - } - - /// Get the microseconds within the second. - /// - /// The returned value will always be in the range `0..1_000_000`. - /// - /// ```rust - /// # use time_macros::time; - /// assert_eq!(time!(0:00).microsecond(), 0); - /// assert_eq!(time!(23:59:59.999_999).microsecond(), 999_999); - /// ``` - pub const fn microsecond(self) -> u32 { - self.nanosecond.get() / Nanosecond::per(Microsecond) as u32 - } - - /// Get the nanoseconds within the second. - /// - /// The returned value will always be in the range `0..1_000_000_000`. - /// - /// ```rust - /// # use time_macros::time; - /// assert_eq!(time!(0:00).nanosecond(), 0); - /// assert_eq!(time!(23:59:59.999_999_999).nanosecond(), 999_999_999); - /// ``` - pub const fn nanosecond(self) -> u32 { - self.nanosecond.get() - } - - /// Add the sub-day time of the [`Duration`] to the `Time`. Wraps on overflow, returning whether - /// the date is different. - pub(crate) const fn adjusting_add(self, duration: Duration) -> (DateAdjustment, Self) { - let mut nanoseconds = self.nanosecond.get() as i32 + duration.subsec_nanoseconds(); - let mut seconds = - self.second.get() as i8 + (duration.whole_seconds() % Second::per(Minute) as i64) as i8; - let mut minutes = - self.minute.get() as i8 + (duration.whole_minutes() % Minute::per(Hour) as i64) as i8; - let mut hours = - self.hour.get() as i8 + (duration.whole_hours() % Hour::per(Day) as i64) as i8; - let mut date_adjustment = DateAdjustment::None; - - cascade!(nanoseconds in 0..Nanosecond::per(Second) as i32 => seconds); - cascade!(seconds in 0..Second::per(Minute) as i8 => minutes); - cascade!(minutes in 0..Minute::per(Hour) as i8 => hours); - if hours >= Hour::per(Day) as i8 { - hours -= Hour::per(Day) as i8; - date_adjustment = DateAdjustment::Next; - } else if hours < 0 { - hours += Hour::per(Day) as i8; - date_adjustment = DateAdjustment::Previous; - } - - ( - date_adjustment, - // Safety: The cascades above ensure the values are in range. - unsafe { - Self::__from_hms_nanos_unchecked( - hours as u8, - minutes as u8, - seconds as u8, - nanoseconds as u32, - ) - }, - ) - } - - /// Subtract the sub-day time of the [`Duration`] to the `Time`. Wraps on overflow, returning - /// whether the date is different. - pub(crate) const fn adjusting_sub(self, duration: Duration) -> (DateAdjustment, Self) { - let mut nanoseconds = self.nanosecond.get() as i32 - duration.subsec_nanoseconds(); - let mut seconds = - self.second.get() as i8 - (duration.whole_seconds() % Second::per(Minute) as i64) as i8; - let mut minutes = - self.minute.get() as i8 - (duration.whole_minutes() % Minute::per(Hour) as i64) as i8; - let mut hours = - self.hour.get() as i8 - (duration.whole_hours() % Hour::per(Day) as i64) as i8; - let mut date_adjustment = DateAdjustment::None; - - cascade!(nanoseconds in 0..Nanosecond::per(Second) as i32 => seconds); - cascade!(seconds in 0..Second::per(Minute) as i8 => minutes); - cascade!(minutes in 0..Minute::per(Hour) as i8 => hours); - if hours >= Hour::per(Day) as i8 { - hours -= Hour::per(Day) as i8; - date_adjustment = DateAdjustment::Next; - } else if hours < 0 { - hours += Hour::per(Day) as i8; - date_adjustment = DateAdjustment::Previous; - } - - ( - date_adjustment, - // Safety: The cascades above ensure the values are in range. - unsafe { - Self::__from_hms_nanos_unchecked( - hours as u8, - minutes as u8, - seconds as u8, - nanoseconds as u32, - ) - }, - ) - } - - /// Add the sub-day time of the [`std::time::Duration`] to the `Time`. Wraps on overflow, - /// returning whether the date is the previous date as the first element of the tuple. - pub(crate) const fn adjusting_add_std(self, duration: StdDuration) -> (bool, Self) { - let mut nanosecond = self.nanosecond.get() + duration.subsec_nanos(); - let mut second = - self.second.get() + (duration.as_secs() % Second::per(Minute) as u64) as u8; - let mut minute = self.minute.get() - + ((duration.as_secs() / Second::per(Minute) as u64) % Minute::per(Hour) as u64) as u8; - let mut hour = self.hour.get() - + ((duration.as_secs() / Second::per(Hour) as u64) % Hour::per(Day) as u64) as u8; - let mut is_next_day = false; - - cascade!(nanosecond in 0..Nanosecond::per(Second) => second); - cascade!(second in 0..Second::per(Minute) => minute); - cascade!(minute in 0..Minute::per(Hour) => hour); - if hour >= Hour::per(Day) { - hour -= Hour::per(Day); - is_next_day = true; - } - - ( - is_next_day, - // Safety: The cascades above ensure the values are in range. - unsafe { Self::__from_hms_nanos_unchecked(hour, minute, second, nanosecond) }, - ) - } - - /// Subtract the sub-day time of the [`std::time::Duration`] to the `Time`. Wraps on overflow, - /// returning whether the date is the previous date as the first element of the tuple. - pub(crate) const fn adjusting_sub_std(self, duration: StdDuration) -> (bool, Self) { - let mut nanosecond = self.nanosecond.get() as i32 - duration.subsec_nanos() as i32; - let mut second = - self.second.get() as i8 - (duration.as_secs() % Second::per(Minute) as u64) as i8; - let mut minute = self.minute.get() as i8 - - ((duration.as_secs() / Second::per(Minute) as u64) % Minute::per(Hour) as u64) as i8; - let mut hour = self.hour.get() as i8 - - ((duration.as_secs() / Second::per(Hour) as u64) % Hour::per(Day) as u64) as i8; - let mut is_previous_day = false; - - cascade!(nanosecond in 0..Nanosecond::per(Second) as i32 => second); - cascade!(second in 0..Second::per(Minute) as i8 => minute); - cascade!(minute in 0..Minute::per(Hour) as i8 => hour); - if hour < 0 { - hour += Hour::per(Day) as i8; - is_previous_day = true; - } - - ( - is_previous_day, - // Safety: The cascades above ensure the values are in range. - unsafe { - Self::__from_hms_nanos_unchecked( - hour as u8, - minute as u8, - second as u8, - nanosecond as u32, - ) - }, - ) - } - - /// Replace the clock hour. - /// - /// ```rust - /// # use time_macros::time; - /// assert_eq!( - /// time!(01:02:03.004_005_006).replace_hour(7), - /// Ok(time!(07:02:03.004_005_006)) - /// ); - /// assert!(time!(01:02:03.004_005_006).replace_hour(24).is_err()); // 24 isn't a valid hour - /// ``` - #[must_use = "This method does not mutate the original `Time`."] - pub const fn replace_hour(mut self, hour: u8) -> Result<Self, error::ComponentRange> { - self.hour = ensure_ranged!(Hours: hour); - Ok(self) - } - - /// Replace the minutes within the hour. - /// - /// ```rust - /// # use time_macros::time; - /// assert_eq!( - /// time!(01:02:03.004_005_006).replace_minute(7), - /// Ok(time!(01:07:03.004_005_006)) - /// ); - /// assert!(time!(01:02:03.004_005_006).replace_minute(60).is_err()); // 60 isn't a valid minute - /// ``` - #[must_use = "This method does not mutate the original `Time`."] - pub const fn replace_minute(mut self, minute: u8) -> Result<Self, error::ComponentRange> { - self.minute = ensure_ranged!(Minutes: minute); - Ok(self) - } - - /// Replace the seconds within the minute. - /// - /// ```rust - /// # use time_macros::time; - /// assert_eq!( - /// time!(01:02:03.004_005_006).replace_second(7), - /// Ok(time!(01:02:07.004_005_006)) - /// ); - /// assert!(time!(01:02:03.004_005_006).replace_second(60).is_err()); // 60 isn't a valid second - /// ``` - #[must_use = "This method does not mutate the original `Time`."] - pub const fn replace_second(mut self, second: u8) -> Result<Self, error::ComponentRange> { - self.second = ensure_ranged!(Seconds: second); - Ok(self) - } - - /// Replace the milliseconds within the second. - /// - /// ```rust - /// # use time_macros::time; - /// assert_eq!( - /// time!(01:02:03.004_005_006).replace_millisecond(7), - /// Ok(time!(01:02:03.007)) - /// ); - /// assert!(time!(01:02:03.004_005_006) - /// .replace_millisecond(1_000) - /// .is_err()); // 1_000 isn't a valid millisecond - /// ``` - #[must_use = "This method does not mutate the original `Time`."] - pub const fn replace_millisecond( - mut self, - millisecond: u16, - ) -> Result<Self, error::ComponentRange> { - self.nanosecond = - ensure_ranged!(Nanoseconds: millisecond as u32 * Nanosecond::per(Millisecond)); - Ok(self) - } - - /// Replace the microseconds within the second. - /// - /// ```rust - /// # use time_macros::time; - /// assert_eq!( - /// time!(01:02:03.004_005_006).replace_microsecond(7_008), - /// Ok(time!(01:02:03.007_008)) - /// ); - /// assert!(time!(01:02:03.004_005_006) - /// .replace_microsecond(1_000_000) - /// .is_err()); // 1_000_000 isn't a valid microsecond - /// ``` - #[must_use = "This method does not mutate the original `Time`."] - pub const fn replace_microsecond( - mut self, - microsecond: u32, - ) -> Result<Self, error::ComponentRange> { - self.nanosecond = - ensure_ranged!(Nanoseconds: microsecond * Nanosecond::per(Microsecond) as u32); - Ok(self) - } - - /// Replace the nanoseconds within the second. - /// - /// ```rust - /// # use time_macros::time; - /// assert_eq!( - /// time!(01:02:03.004_005_006).replace_nanosecond(7_008_009), - /// Ok(time!(01:02:03.007_008_009)) - /// ); - /// assert!(time!(01:02:03.004_005_006) - /// .replace_nanosecond(1_000_000_000) - /// .is_err()); // 1_000_000_000 isn't a valid nanosecond - /// ``` - #[must_use = "This method does not mutate the original `Time`."] - pub const fn replace_nanosecond( - mut self, - nanosecond: u32, - ) -> Result<Self, error::ComponentRange> { - self.nanosecond = ensure_ranged!(Nanoseconds: nanosecond); - Ok(self) - } -} - -#[cfg(feature = "formatting")] -impl Time { - /// Format the `Time` using the provided [format description](crate::format_description). - pub fn format_into( - self, - output: &mut (impl io::Write + ?Sized), - format: &(impl Formattable + ?Sized), - ) -> Result<usize, error::Format> { - format.format_into(output, None, Some(self), None) - } - - /// Format the `Time` using the provided [format description](crate::format_description). - /// - /// ```rust - /// # use time::format_description; - /// # use time_macros::time; - /// let format = format_description::parse("[hour]:[minute]:[second]")?; - /// assert_eq!(time!(12:00).format(&format)?, "12:00:00"); - /// # Ok::<_, time::Error>(()) - /// ``` - pub fn format(self, format: &(impl Formattable + ?Sized)) -> Result<String, error::Format> { - format.format(None, Some(self), None) - } -} - -#[cfg(feature = "parsing")] -impl Time { - /// Parse a `Time` from the input using the provided [format - /// description](crate::format_description). - /// - /// ```rust - /// # use time::Time; - /// # use time_macros::{time, format_description}; - /// let format = format_description!("[hour]:[minute]:[second]"); - /// assert_eq!(Time::parse("12:00:00", &format)?, time!(12:00)); - /// # Ok::<_, time::Error>(()) - /// ``` - pub fn parse( - input: &str, - description: &(impl Parsable + ?Sized), - ) -> Result<Self, error::Parse> { - description.parse_time(input.as_bytes()) - } -} - -mod private { - #[non_exhaustive] - #[derive(Debug, Clone, Copy)] - pub struct TimeMetadata { - /// How many characters wide the formatted subsecond is. - pub(super) subsecond_width: u8, - /// The value to use when formatting the subsecond. Leading zeroes will be added as - /// necessary. - pub(super) subsecond_value: u32, - } -} -use private::TimeMetadata; - -impl SmartDisplay for Time { - type Metadata = TimeMetadata; - - fn metadata(&self, _: FormatterOptions) -> Metadata<Self> { - let (subsecond_value, subsecond_width) = match self.nanosecond() { - nanos if nanos % 10 != 0 => (nanos, 9), - nanos if (nanos / 10) % 10 != 0 => (nanos / 10, 8), - nanos if (nanos / 100) % 10 != 0 => (nanos / 100, 7), - nanos if (nanos / 1_000) % 10 != 0 => (nanos / 1_000, 6), - nanos if (nanos / 10_000) % 10 != 0 => (nanos / 10_000, 5), - nanos if (nanos / 100_000) % 10 != 0 => (nanos / 100_000, 4), - nanos if (nanos / 1_000_000) % 10 != 0 => (nanos / 1_000_000, 3), - nanos if (nanos / 10_000_000) % 10 != 0 => (nanos / 10_000_000, 2), - nanos => (nanos / 100_000_000, 1), - }; - - let formatted_width = smart_display::padded_width_of!( - self.hour.get(), - ":", - self.minute.get() => width(2) fill('0'), - ":", - self.second.get() => width(2) fill('0'), - ".", - ) + subsecond_width; - - Metadata::new( - formatted_width, - self, - TimeMetadata { - subsecond_width: subsecond_width.truncate(), - subsecond_value, - }, - ) - } - - fn fmt_with_metadata( - &self, - f: &mut fmt::Formatter<'_>, - metadata: Metadata<Self>, - ) -> fmt::Result { - let subsecond_width = metadata.subsecond_width.extend(); - let subsecond_value = metadata.subsecond_value; - - f.pad_with_width( - metadata.unpadded_width(), - format_args!( - "{}:{:02}:{:02}.{subsecond_value:0subsecond_width$}", - self.hour, self.minute, self.second - ), - ) - } -} - -impl fmt::Display for Time { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - SmartDisplay::fmt(self, f) - } -} - -impl fmt::Debug for Time { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Display::fmt(self, f) - } -} - -impl Add<Duration> for Time { - type Output = Self; - - /// Add the sub-day time of the [`Duration`] to the `Time`. Wraps on overflow. - /// - /// ```rust - /// # use time::ext::NumericalDuration; - /// # use time_macros::time; - /// assert_eq!(time!(12:00) + 2.hours(), time!(14:00)); - /// assert_eq!(time!(0:00:01) + (-2).seconds(), time!(23:59:59)); - /// ``` - fn add(self, duration: Duration) -> Self::Output { - self.adjusting_add(duration).1 - } -} - -impl Add<StdDuration> for Time { - type Output = Self; - - /// Add the sub-day time of the [`std::time::Duration`] to the `Time`. Wraps on overflow. - /// - /// ```rust - /// # use time::ext::NumericalStdDuration; - /// # use time_macros::time; - /// assert_eq!(time!(12:00) + 2.std_hours(), time!(14:00)); - /// assert_eq!(time!(23:59:59) + 2.std_seconds(), time!(0:00:01)); - /// ``` - fn add(self, duration: StdDuration) -> Self::Output { - self.adjusting_add_std(duration).1 - } -} - -impl_add_assign!(Time: Duration, StdDuration); - -impl Sub<Duration> for Time { - type Output = Self; - - /// Subtract the sub-day time of the [`Duration`] from the `Time`. Wraps on overflow. - /// - /// ```rust - /// # use time::ext::NumericalDuration; - /// # use time_macros::time; - /// assert_eq!(time!(14:00) - 2.hours(), time!(12:00)); - /// assert_eq!(time!(23:59:59) - (-2).seconds(), time!(0:00:01)); - /// ``` - fn sub(self, duration: Duration) -> Self::Output { - self.adjusting_sub(duration).1 - } -} - -impl Sub<StdDuration> for Time { - type Output = Self; - - /// Subtract the sub-day time of the [`std::time::Duration`] from the `Time`. Wraps on overflow. - /// - /// ```rust - /// # use time::ext::NumericalStdDuration; - /// # use time_macros::time; - /// assert_eq!(time!(14:00) - 2.std_hours(), time!(12:00)); - /// assert_eq!(time!(0:00:01) - 2.std_seconds(), time!(23:59:59)); - /// ``` - fn sub(self, duration: StdDuration) -> Self::Output { - self.adjusting_sub_std(duration).1 - } -} - -impl_sub_assign!(Time: Duration, StdDuration); - -impl Sub for Time { - type Output = Duration; - - /// Subtract two `Time`s, returning the [`Duration`] between. This assumes both `Time`s are in - /// the same calendar day. - /// - /// ```rust - /// # use time::ext::NumericalDuration; - /// # use time_macros::time; - /// assert_eq!(time!(0:00) - time!(0:00), 0.seconds()); - /// assert_eq!(time!(1:00) - time!(0:00), 1.hours()); - /// assert_eq!(time!(0:00) - time!(1:00), (-1).hours()); - /// assert_eq!(time!(0:00) - time!(23:00), (-23).hours()); - /// ``` - fn sub(self, rhs: Self) -> Self::Output { - let hour_diff = self.hour.get().cast_signed() - rhs.hour.get().cast_signed(); - let minute_diff = self.minute.get().cast_signed() - rhs.minute.get().cast_signed(); - let second_diff = self.second.get().cast_signed() - rhs.second.get().cast_signed(); - let nanosecond_diff = - self.nanosecond.get().cast_signed() - rhs.nanosecond.get().cast_signed(); - - let seconds = hour_diff.extend::<i64>() * Second::per(Hour).cast_signed().extend::<i64>() - + minute_diff.extend::<i64>() * Second::per(Minute).cast_signed().extend::<i64>() - + second_diff.extend::<i64>(); - - let (seconds, nanoseconds) = if seconds > 0 && nanosecond_diff < 0 { - ( - seconds - 1, - nanosecond_diff + Nanosecond::per(Second).cast_signed(), - ) - } else if seconds < 0 && nanosecond_diff > 0 { - ( - seconds + 1, - nanosecond_diff - Nanosecond::per(Second).cast_signed(), - ) - } else { - (seconds, nanosecond_diff) - }; - - // Safety: `nanoseconds` is in range due to the overflow handling. - unsafe { Duration::new_unchecked(seconds, nanoseconds) } - } -} diff --git a/vendor/time/src/utc_date_time.rs b/vendor/time/src/utc_date_time.rs deleted file mode 100644 index e7bb8026..00000000 --- a/vendor/time/src/utc_date_time.rs +++ /dev/null @@ -1,1223 +0,0 @@ -//! The [`UtcDateTime`] struct and associated `impl`s. - -#[cfg(feature = "formatting")] -use alloc::string::String; -use core::fmt; -use core::ops::{Add, AddAssign, Sub, SubAssign}; -use core::time::Duration as StdDuration; -#[cfg(feature = "formatting")] -use std::io; - -use deranged::RangedI64; -use powerfmt::ext::FormatterExt as _; -use powerfmt::smart_display::{self, FormatterOptions, Metadata, SmartDisplay}; - -use crate::convert::*; -use crate::date::{MAX_YEAR, MIN_YEAR}; -#[cfg(feature = "formatting")] -use crate::formatting::Formattable; -use crate::internal_macros::{ - cascade, const_try, const_try_opt, div_floor, ensure_ranged, expect_opt, -}; -#[cfg(feature = "parsing")] -use crate::parsing::Parsable; -use crate::{ - error, util, Date, Duration, Month, OffsetDateTime, PrimitiveDateTime, Time, UtcOffset, Weekday, -}; - -/// The Julian day of the Unix epoch. -const UNIX_EPOCH_JULIAN_DAY: i32 = UtcDateTime::UNIX_EPOCH.to_julian_day(); - -/// A [`PrimitiveDateTime`] that is known to be UTC. -/// -/// `UtcDateTime` is guaranteed to be ABI-compatible with [`PrimitiveDateTime`], meaning that -/// transmuting from one to the other will not result in undefined behavior. -#[repr(transparent)] -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub struct UtcDateTime { - inner: PrimitiveDateTime, -} - -impl UtcDateTime { - /// Midnight, 1 January, 1970. - /// - /// ```rust - /// # use time::UtcDateTime; - /// # use time_macros::utc_datetime; - /// assert_eq!(UtcDateTime::UNIX_EPOCH, utc_datetime!(1970-01-01 0:00)); - /// ``` - pub const UNIX_EPOCH: Self = Self::new( - // Safety: `ordinal` is not zero. - unsafe { Date::__from_ordinal_date_unchecked(1970, 1) }, - Time::MIDNIGHT, - ); - - /// The smallest value that can be represented by `UtcDateTime`. - /// - /// Depending on `large-dates` feature flag, value of this constant may vary. - /// - /// 1. With `large-dates` disabled it is equal to `-9999-01-01 00:00:00.0` - /// 2. With `large-dates` enabled it is equal to `-999999-01-01 00:00:00.0` - /// - /// ```rust - /// # use time::UtcDateTime; - /// # use time_macros::utc_datetime; - #[cfg_attr( - feature = "large-dates", - doc = "// Assuming `large-dates` feature is enabled." - )] - #[cfg_attr( - feature = "large-dates", - doc = "assert_eq!(UtcDateTime::MIN, utc_datetime!(-999999-01-01 0:00));" - )] - #[cfg_attr( - not(feature = "large-dates"), - doc = "// Assuming `large-dates` feature is disabled." - )] - #[cfg_attr( - not(feature = "large-dates"), - doc = "assert_eq!(UtcDateTime::MIN, utc_datetime!(-9999-01-01 0:00));" - )] - /// ``` - pub const MIN: Self = Self::new(Date::MIN, Time::MIDNIGHT); - - /// The largest value that can be represented by `UtcDateTime`. - /// - /// Depending on `large-dates` feature flag, value of this constant may vary. - /// - /// 1. With `large-dates` disabled it is equal to `9999-12-31 23:59:59.999_999_999` - /// 2. With `large-dates` enabled it is equal to `999999-12-31 23:59:59.999_999_999` - /// - /// ```rust - /// # use time::UtcDateTime; - /// # use time_macros::utc_datetime; - #[cfg_attr( - feature = "large-dates", - doc = "// Assuming `large-dates` feature is enabled." - )] - #[cfg_attr( - feature = "large-dates", - doc = "assert_eq!(UtcDateTime::MAX, utc_datetime!(+999999-12-31 23:59:59.999_999_999));" - )] - #[cfg_attr( - not(feature = "large-dates"), - doc = "// Assuming `large-dates` feature is disabled." - )] - #[cfg_attr( - not(feature = "large-dates"), - doc = "assert_eq!(UtcDateTime::MAX, utc_datetime!(+9999-12-31 23:59:59.999_999_999));" - )] - /// ``` - pub const MAX: Self = Self::new(Date::MAX, Time::MAX); - - /// Create a new `UtcDateTime` with the current date and time. - /// - /// ```rust - /// # use time::UtcDateTime; - /// assert!(UtcDateTime::now().year() >= 2019); - /// ``` - #[cfg(feature = "std")] - pub fn now() -> Self { - #[cfg(all( - target_family = "wasm", - not(any(target_os = "emscripten", target_os = "wasi")), - feature = "wasm-bindgen" - ))] - { - js_sys::Date::new_0().into() - } - - #[cfg(not(all( - target_family = "wasm", - not(any(target_os = "emscripten", target_os = "wasi")), - feature = "wasm-bindgen" - )))] - std::time::SystemTime::now().into() - } - - /// Create a new `UtcDateTime` from the provided [`Date`] and [`Time`]. - /// - /// ```rust - /// # use time::UtcDateTime; - /// # use time_macros::{date, utc_datetime, time}; - /// assert_eq!( - /// UtcDateTime::new(date!(2019-01-01), time!(0:00)), - /// utc_datetime!(2019-01-01 0:00), - /// ); - /// ``` - pub const fn new(date: Date, time: Time) -> Self { - Self { - inner: PrimitiveDateTime::new(date, time), - } - } - - /// Create a new `UtcDateTime` from the [`PrimitiveDateTime`], assuming that the latter is UTC. - pub(crate) const fn from_primitive(date_time: PrimitiveDateTime) -> Self { - Self { inner: date_time } - } - - /// Obtain the [`PrimitiveDateTime`] that this `UtcDateTime` represents. The no-longer-attached - /// [`UtcOffset`] is assumed to be UTC. - pub(crate) const fn as_primitive(self) -> PrimitiveDateTime { - self.inner - } - - /// Create a `UtcDateTime` from the provided Unix timestamp. - /// - /// ```rust - /// # use time::UtcDateTime; - /// # use time_macros::utc_datetime; - /// assert_eq!( - /// UtcDateTime::from_unix_timestamp(0), - /// Ok(UtcDateTime::UNIX_EPOCH), - /// ); - /// assert_eq!( - /// UtcDateTime::from_unix_timestamp(1_546_300_800), - /// Ok(utc_datetime!(2019-01-01 0:00)), - /// ); - /// ``` - /// - /// If you have a timestamp-nanosecond pair, you can use something along the lines of the - /// following: - /// - /// ```rust - /// # use time::{Duration, UtcDateTime, ext::NumericalDuration}; - /// let (timestamp, nanos) = (1, 500_000_000); - /// assert_eq!( - /// UtcDateTime::from_unix_timestamp(timestamp)? + Duration::nanoseconds(nanos), - /// UtcDateTime::UNIX_EPOCH + 1.5.seconds() - /// ); - /// # Ok::<_, time::Error>(()) - /// ``` - pub const fn from_unix_timestamp(timestamp: i64) -> Result<Self, error::ComponentRange> { - type Timestamp = - RangedI64<{ UtcDateTime::MIN.unix_timestamp() }, { UtcDateTime::MAX.unix_timestamp() }>; - ensure_ranged!(Timestamp: timestamp); - - // Use the unchecked method here, as the input validity has already been verified. - // Safety: The Julian day number is in range. - let date = unsafe { - Date::from_julian_day_unchecked( - UNIX_EPOCH_JULIAN_DAY + div_floor!(timestamp, Second::per(Day) as i64) as i32, - ) - }; - - let seconds_within_day = timestamp.rem_euclid(Second::per(Day) as i64); - // Safety: All values are in range. - let time = unsafe { - Time::__from_hms_nanos_unchecked( - (seconds_within_day / Second::per(Hour) as i64) as u8, - ((seconds_within_day % Second::per(Hour) as i64) / Minute::per(Hour) as i64) as u8, - (seconds_within_day % Second::per(Minute) as i64) as u8, - 0, - ) - }; - - Ok(Self::new(date, time)) - } - - /// Construct an `UtcDateTime` from the provided Unix timestamp (in nanoseconds). - /// - /// ```rust - /// # use time::UtcDateTime; - /// # use time_macros::utc_datetime; - /// assert_eq!( - /// UtcDateTime::from_unix_timestamp_nanos(0), - /// Ok(UtcDateTime::UNIX_EPOCH), - /// ); - /// assert_eq!( - /// UtcDateTime::from_unix_timestamp_nanos(1_546_300_800_000_000_000), - /// Ok(utc_datetime!(2019-01-01 0:00)), - /// ); - /// ``` - pub const fn from_unix_timestamp_nanos(timestamp: i128) -> Result<Self, error::ComponentRange> { - let datetime = const_try!(Self::from_unix_timestamp(div_floor!( - timestamp, - Nanosecond::per(Second) as i128 - ) as i64)); - - Ok(Self::new( - datetime.date(), - // Safety: `nanosecond` is in range due to `rem_euclid`. - unsafe { - Time::__from_hms_nanos_unchecked( - datetime.hour(), - datetime.minute(), - datetime.second(), - timestamp.rem_euclid(Nanosecond::per(Second) as i128) as u32, - ) - }, - )) - } - - /// Convert the `UtcDateTime` from UTC to the provided [`UtcOffset`], returning an - /// [`OffsetDateTime`]. - /// - /// ```rust - /// # use time_macros::{utc_datetime, offset}; - /// assert_eq!( - /// utc_datetime!(2000-01-01 0:00) - /// .to_offset(offset!(-1)) - /// .year(), - /// 1999, - /// ); - /// - /// // Construct midnight on new year's, UTC. - /// let utc = utc_datetime!(2000-01-01 0:00); - /// let new_york = utc.to_offset(offset!(-5)); - /// let los_angeles = utc.to_offset(offset!(-8)); - /// assert_eq!(utc.hour(), 0); - /// assert_eq!(new_york.hour(), 19); - /// assert_eq!(los_angeles.hour(), 16); - /// ``` - /// - /// # Panics - /// - /// This method panics if the local date-time in the new offset is outside the supported range. - pub const fn to_offset(self, offset: UtcOffset) -> OffsetDateTime { - expect_opt!( - self.checked_to_offset(offset), - "local datetime out of valid range" - ) - } - - /// Convert the `UtcDateTime` from UTC to the provided [`UtcOffset`], returning an - /// [`OffsetDateTime`]. `None` is returned if the date-time in the resulting offset is - /// invalid. - /// - /// ```rust - /// # use time::UtcDateTime; - /// # use time_macros::{utc_datetime, offset}; - /// assert_eq!( - /// utc_datetime!(2000-01-01 0:00) - /// .checked_to_offset(offset!(-1)) - /// .unwrap() - /// .year(), - /// 1999, - /// ); - /// assert_eq!( - /// UtcDateTime::MAX.checked_to_offset(offset!(+1)), - /// None, - /// ); - /// ``` - pub const fn checked_to_offset(self, offset: UtcOffset) -> Option<OffsetDateTime> { - // Fast path for when no conversion is necessary. - if offset.is_utc() { - return Some(self.inner.assume_utc()); - } - - let (year, ordinal, time) = self.to_offset_raw(offset); - - if year > MAX_YEAR || year < MIN_YEAR { - return None; - } - - Some(OffsetDateTime::new_in_offset( - // Safety: `ordinal` is not zero. - unsafe { Date::__from_ordinal_date_unchecked(year, ordinal) }, - time, - offset, - )) - } - - /// Equivalent to `.to_offset(UtcOffset::UTC)`, but returning the year, ordinal, and time. This - /// avoids constructing an invalid [`Date`] if the new value is out of range. - pub(crate) const fn to_offset_raw(self, offset: UtcOffset) -> (i32, u16, Time) { - let mut second = self.second() as i16 + offset.seconds_past_minute() as i16; - let mut minute = self.minute() as i16 + offset.minutes_past_hour() as i16; - let mut hour = self.hour() as i8 + offset.whole_hours(); - let (mut year, ordinal) = self.to_ordinal_date(); - let mut ordinal = ordinal as i16; - - cascade!(second in 0..Second::per(Minute) as i16 => minute); - cascade!(minute in 0..Minute::per(Hour) as i16 => hour); - cascade!(hour in 0..Hour::per(Day) as i8 => ordinal); - cascade!(ordinal => year); - - debug_assert!(ordinal > 0); - debug_assert!(ordinal <= util::days_in_year(year) as i16); - - ( - year, - ordinal as u16, - // Safety: The cascades above ensure the values are in range. - unsafe { - Time::__from_hms_nanos_unchecked( - hour as u8, - minute as u8, - second as u8, - self.nanosecond(), - ) - }, - ) - } - - /// Get the [Unix timestamp](https://en.wikipedia.org/wiki/Unix_time). - /// - /// ```rust - /// # use time_macros::utc_datetime; - /// assert_eq!(utc_datetime!(1970-01-01 0:00).unix_timestamp(), 0); - /// assert_eq!(utc_datetime!(1970-01-01 1:00).unix_timestamp(), 3_600); - /// ``` - pub const fn unix_timestamp(self) -> i64 { - let days = - (self.to_julian_day() as i64 - UNIX_EPOCH_JULIAN_DAY as i64) * Second::per(Day) as i64; - let hours = self.hour() as i64 * Second::per(Hour) as i64; - let minutes = self.minute() as i64 * Second::per(Minute) as i64; - let seconds = self.second() as i64; - days + hours + minutes + seconds - } - - /// Get the Unix timestamp in nanoseconds. - /// - /// ```rust - /// use time_macros::utc_datetime; - /// assert_eq!(utc_datetime!(1970-01-01 0:00).unix_timestamp_nanos(), 0); - /// assert_eq!( - /// utc_datetime!(1970-01-01 1:00).unix_timestamp_nanos(), - /// 3_600_000_000_000, - /// ); - /// ``` - pub const fn unix_timestamp_nanos(self) -> i128 { - self.unix_timestamp() as i128 * Nanosecond::per(Second) as i128 + self.nanosecond() as i128 - } - - /// Get the [`Date`] component of the `UtcDateTime`. - /// - /// ```rust - /// # use time_macros::{date, utc_datetime}; - /// assert_eq!(utc_datetime!(2019-01-01 0:00).date(), date!(2019-01-01)); - /// ``` - pub const fn date(self) -> Date { - self.inner.date() - } - - /// Get the [`Time`] component of the `UtcDateTime`. - /// - /// ```rust - /// # use time_macros::{utc_datetime, time}; - /// assert_eq!(utc_datetime!(2019-01-01 0:00).time(), time!(0:00)); - /// ``` - pub const fn time(self) -> Time { - self.inner.time() - } - - /// Get the year of the date. - /// - /// ```rust - /// # use time_macros::utc_datetime; - /// assert_eq!(utc_datetime!(2019-01-01 0:00).year(), 2019); - /// assert_eq!(utc_datetime!(2019-12-31 0:00).year(), 2019); - /// assert_eq!(utc_datetime!(2020-01-01 0:00).year(), 2020); - /// ``` - pub const fn year(self) -> i32 { - self.date().year() - } - - /// Get the month of the date. - /// - /// ```rust - /// # use time::Month; - /// # use time_macros::utc_datetime; - /// assert_eq!(utc_datetime!(2019-01-01 0:00).month(), Month::January); - /// assert_eq!(utc_datetime!(2019-12-31 0:00).month(), Month::December); - /// ``` - pub const fn month(self) -> Month { - self.date().month() - } - - /// Get the day of the date. - /// - /// The returned value will always be in the range `1..=31`. - /// - /// ```rust - /// # use time_macros::utc_datetime; - /// assert_eq!(utc_datetime!(2019-01-01 0:00).day(), 1); - /// assert_eq!(utc_datetime!(2019-12-31 0:00).day(), 31); - /// ``` - pub const fn day(self) -> u8 { - self.date().day() - } - - /// Get the day of the year. - /// - /// The returned value will always be in the range `1..=366` (`1..=365` for common years). - /// - /// ```rust - /// # use time_macros::utc_datetime; - /// assert_eq!(utc_datetime!(2019-01-01 0:00).ordinal(), 1); - /// assert_eq!(utc_datetime!(2019-12-31 0:00).ordinal(), 365); - /// ``` - pub const fn ordinal(self) -> u16 { - self.date().ordinal() - } - - /// Get the ISO week number. - /// - /// The returned value will always be in the range `1..=53`. - /// - /// ```rust - /// # use time_macros::utc_datetime; - /// assert_eq!(utc_datetime!(2019-01-01 0:00).iso_week(), 1); - /// assert_eq!(utc_datetime!(2019-10-04 0:00).iso_week(), 40); - /// assert_eq!(utc_datetime!(2020-01-01 0:00).iso_week(), 1); - /// assert_eq!(utc_datetime!(2020-12-31 0:00).iso_week(), 53); - /// assert_eq!(utc_datetime!(2021-01-01 0:00).iso_week(), 53); - /// ``` - pub const fn iso_week(self) -> u8 { - self.date().iso_week() - } - - /// Get the week number where week 1 begins on the first Sunday. - /// - /// The returned value will always be in the range `0..=53`. - /// - /// ```rust - /// # use time_macros::utc_datetime; - /// assert_eq!(utc_datetime!(2019-01-01 0:00).sunday_based_week(), 0); - /// assert_eq!(utc_datetime!(2020-01-01 0:00).sunday_based_week(), 0); - /// assert_eq!(utc_datetime!(2020-12-31 0:00).sunday_based_week(), 52); - /// assert_eq!(utc_datetime!(2021-01-01 0:00).sunday_based_week(), 0); - /// ``` - pub const fn sunday_based_week(self) -> u8 { - self.date().sunday_based_week() - } - - /// Get the week number where week 1 begins on the first Monday. - /// - /// The returned value will always be in the range `0..=53`. - /// - /// ```rust - /// # use time_macros::utc_datetime; - /// assert_eq!(utc_datetime!(2019-01-01 0:00).monday_based_week(), 0); - /// assert_eq!(utc_datetime!(2020-01-01 0:00).monday_based_week(), 0); - /// assert_eq!(utc_datetime!(2020-12-31 0:00).monday_based_week(), 52); - /// assert_eq!(utc_datetime!(2021-01-01 0:00).monday_based_week(), 0); - /// ``` - pub const fn monday_based_week(self) -> u8 { - self.date().monday_based_week() - } - - /// Get the year, month, and day. - /// - /// ```rust - /// # use time::Month; - /// # use time_macros::utc_datetime; - /// assert_eq!( - /// utc_datetime!(2019-01-01 0:00).to_calendar_date(), - /// (2019, Month::January, 1) - /// ); - /// ``` - pub const fn to_calendar_date(self) -> (i32, Month, u8) { - self.date().to_calendar_date() - } - - /// Get the year and ordinal day number. - /// - /// ```rust - /// # use time_macros::utc_datetime; - /// assert_eq!(utc_datetime!(2019-01-01 0:00).to_ordinal_date(), (2019, 1)); - /// ``` - pub const fn to_ordinal_date(self) -> (i32, u16) { - self.date().to_ordinal_date() - } - - /// Get the ISO 8601 year, week number, and weekday. - /// - /// ```rust - /// # use time::Weekday::*; - /// # use time_macros::utc_datetime; - /// assert_eq!( - /// utc_datetime!(2019-01-01 0:00).to_iso_week_date(), - /// (2019, 1, Tuesday) - /// ); - /// assert_eq!( - /// utc_datetime!(2019-10-04 0:00).to_iso_week_date(), - /// (2019, 40, Friday) - /// ); - /// assert_eq!( - /// utc_datetime!(2020-01-01 0:00).to_iso_week_date(), - /// (2020, 1, Wednesday) - /// ); - /// assert_eq!( - /// utc_datetime!(2020-12-31 0:00).to_iso_week_date(), - /// (2020, 53, Thursday) - /// ); - /// assert_eq!( - /// utc_datetime!(2021-01-01 0:00).to_iso_week_date(), - /// (2020, 53, Friday) - /// ); - /// ``` - pub const fn to_iso_week_date(self) -> (i32, u8, Weekday) { - self.date().to_iso_week_date() - } - - /// Get the weekday. - /// - /// ```rust - /// # use time::Weekday::*; - /// # use time_macros::utc_datetime; - /// assert_eq!(utc_datetime!(2019-01-01 0:00).weekday(), Tuesday); - /// assert_eq!(utc_datetime!(2019-02-01 0:00).weekday(), Friday); - /// assert_eq!(utc_datetime!(2019-03-01 0:00).weekday(), Friday); - /// assert_eq!(utc_datetime!(2019-04-01 0:00).weekday(), Monday); - /// assert_eq!(utc_datetime!(2019-05-01 0:00).weekday(), Wednesday); - /// assert_eq!(utc_datetime!(2019-06-01 0:00).weekday(), Saturday); - /// assert_eq!(utc_datetime!(2019-07-01 0:00).weekday(), Monday); - /// assert_eq!(utc_datetime!(2019-08-01 0:00).weekday(), Thursday); - /// assert_eq!(utc_datetime!(2019-09-01 0:00).weekday(), Sunday); - /// assert_eq!(utc_datetime!(2019-10-01 0:00).weekday(), Tuesday); - /// assert_eq!(utc_datetime!(2019-11-01 0:00).weekday(), Friday); - /// assert_eq!(utc_datetime!(2019-12-01 0:00).weekday(), Sunday); - /// ``` - pub const fn weekday(self) -> Weekday { - self.date().weekday() - } - - /// Get the Julian day for the date. The time is not taken into account for this calculation. - /// - /// The algorithm to perform this conversion is derived from one provided by Peter Baum; it is - /// freely available [here](https://www.researchgate.net/publication/316558298_Date_Algorithms). - /// - /// ```rust - /// # use time_macros::utc_datetime; - /// assert_eq!(utc_datetime!(-4713-11-24 0:00).to_julian_day(), 0); - /// assert_eq!(utc_datetime!(2000-01-01 0:00).to_julian_day(), 2_451_545); - /// assert_eq!(utc_datetime!(2019-01-01 0:00).to_julian_day(), 2_458_485); - /// assert_eq!(utc_datetime!(2019-12-31 0:00).to_julian_day(), 2_458_849); - /// ``` - pub const fn to_julian_day(self) -> i32 { - self.date().to_julian_day() - } - - /// Get the clock hour, minute, and second. - /// - /// ```rust - /// # use time_macros::utc_datetime; - /// assert_eq!(utc_datetime!(2020-01-01 0:00:00).as_hms(), (0, 0, 0)); - /// assert_eq!(utc_datetime!(2020-01-01 23:59:59).as_hms(), (23, 59, 59)); - /// ``` - pub const fn as_hms(self) -> (u8, u8, u8) { - self.time().as_hms() - } - - /// Get the clock hour, minute, second, and millisecond. - /// - /// ```rust - /// # use time_macros::utc_datetime; - /// assert_eq!(utc_datetime!(2020-01-01 0:00:00).as_hms_milli(), (0, 0, 0, 0)); - /// assert_eq!( - /// utc_datetime!(2020-01-01 23:59:59.999).as_hms_milli(), - /// (23, 59, 59, 999) - /// ); - /// ``` - pub const fn as_hms_milli(self) -> (u8, u8, u8, u16) { - self.time().as_hms_milli() - } - - /// Get the clock hour, minute, second, and microsecond. - /// - /// ```rust - /// # use time_macros::utc_datetime; - /// assert_eq!(utc_datetime!(2020-01-01 0:00:00).as_hms_micro(), (0, 0, 0, 0)); - /// assert_eq!( - /// utc_datetime!(2020-01-01 23:59:59.999_999).as_hms_micro(), - /// (23, 59, 59, 999_999) - /// ); - /// ``` - pub const fn as_hms_micro(self) -> (u8, u8, u8, u32) { - self.time().as_hms_micro() - } - - /// Get the clock hour, minute, second, and nanosecond. - /// - /// ```rust - /// # use time_macros::utc_datetime; - /// assert_eq!(utc_datetime!(2020-01-01 0:00:00).as_hms_nano(), (0, 0, 0, 0)); - /// assert_eq!( - /// utc_datetime!(2020-01-01 23:59:59.999_999_999).as_hms_nano(), - /// (23, 59, 59, 999_999_999) - /// ); - /// ``` - pub const fn as_hms_nano(self) -> (u8, u8, u8, u32) { - self.time().as_hms_nano() - } - - /// Get the clock hour. - /// - /// The returned value will always be in the range `0..24`. - /// - /// ```rust - /// # use time_macros::utc_datetime; - /// assert_eq!(utc_datetime!(2019-01-01 0:00).hour(), 0); - /// assert_eq!(utc_datetime!(2019-01-01 23:59:59).hour(), 23); - /// ``` - pub const fn hour(self) -> u8 { - self.time().hour() - } - - /// Get the minute within the hour. - /// - /// The returned value will always be in the range `0..60`. - /// - /// ```rust - /// # use time_macros::utc_datetime; - /// assert_eq!(utc_datetime!(2019-01-01 0:00).minute(), 0); - /// assert_eq!(utc_datetime!(2019-01-01 23:59:59).minute(), 59); - /// ``` - pub const fn minute(self) -> u8 { - self.time().minute() - } - - /// Get the second within the minute. - /// - /// The returned value will always be in the range `0..60`. - /// - /// ```rust - /// # use time_macros::utc_datetime; - /// assert_eq!(utc_datetime!(2019-01-01 0:00).second(), 0); - /// assert_eq!(utc_datetime!(2019-01-01 23:59:59).second(), 59); - /// ``` - pub const fn second(self) -> u8 { - self.time().second() - } - - /// Get the milliseconds within the second. - /// - /// The returned value will always be in the range `0..1_000`. - /// - /// ```rust - /// # use time_macros::utc_datetime; - /// assert_eq!(utc_datetime!(2019-01-01 0:00).millisecond(), 0); - /// assert_eq!(utc_datetime!(2019-01-01 23:59:59.999).millisecond(), 999); - /// ``` - pub const fn millisecond(self) -> u16 { - self.time().millisecond() - } - - /// Get the microseconds within the second. - /// - /// The returned value will always be in the range `0..1_000_000`. - /// - /// ```rust - /// # use time_macros::utc_datetime; - /// assert_eq!(utc_datetime!(2019-01-01 0:00).microsecond(), 0); - /// assert_eq!( - /// utc_datetime!(2019-01-01 23:59:59.999_999).microsecond(), - /// 999_999 - /// ); - /// ``` - pub const fn microsecond(self) -> u32 { - self.time().microsecond() - } - - /// Get the nanoseconds within the second. - /// - /// The returned value will always be in the range `0..1_000_000_000`. - /// - /// ```rust - /// # use time_macros::utc_datetime; - /// assert_eq!(utc_datetime!(2019-01-01 0:00).nanosecond(), 0); - /// assert_eq!( - /// utc_datetime!(2019-01-01 23:59:59.999_999_999).nanosecond(), - /// 999_999_999, - /// ); - /// ``` - pub const fn nanosecond(self) -> u32 { - self.time().nanosecond() - } - - /// Computes `self + duration`, returning `None` if an overflow occurred. - /// - /// ```rust - /// # use time::{UtcDateTime, ext::NumericalDuration}; - /// # use time_macros::utc_datetime; - /// assert_eq!(UtcDateTime::MIN.checked_add((-2).days()), None); - /// assert_eq!(UtcDateTime::MAX.checked_add(1.days()), None); - /// assert_eq!( - /// utc_datetime!(2019 - 11 - 25 15:30).checked_add(27.hours()), - /// Some(utc_datetime!(2019 - 11 - 26 18:30)) - /// ); - /// ``` - pub const fn checked_add(self, duration: Duration) -> Option<Self> { - Some(Self::from_primitive(const_try_opt!(self - .inner - .checked_add(duration)))) - } - - /// Computes `self - duration`, returning `None` if an overflow occurred. - /// - /// ```rust - /// # use time::{UtcDateTime, ext::NumericalDuration}; - /// # use time_macros::utc_datetime; - /// assert_eq!(UtcDateTime::MIN.checked_sub(2.days()), None); - /// assert_eq!(UtcDateTime::MAX.checked_sub((-1).days()), None); - /// assert_eq!( - /// utc_datetime!(2019 - 11 - 25 15:30).checked_sub(27.hours()), - /// Some(utc_datetime!(2019 - 11 - 24 12:30)) - /// ); - /// ``` - pub const fn checked_sub(self, duration: Duration) -> Option<Self> { - Some(Self::from_primitive(const_try_opt!(self - .inner - .checked_sub(duration)))) - } - - /// Computes `self + duration`, saturating value on overflow. - /// - /// ```rust - /// # use time::{UtcDateTime, ext::NumericalDuration}; - /// # use time_macros::utc_datetime; - /// assert_eq!( - /// UtcDateTime::MIN.saturating_add((-2).days()), - /// UtcDateTime::MIN - /// ); - /// assert_eq!( - /// UtcDateTime::MAX.saturating_add(2.days()), - /// UtcDateTime::MAX - /// ); - /// assert_eq!( - /// utc_datetime!(2019 - 11 - 25 15:30).saturating_add(27.hours()), - /// utc_datetime!(2019 - 11 - 26 18:30) - /// ); - /// ``` - pub const fn saturating_add(self, duration: Duration) -> Self { - Self::from_primitive(self.inner.saturating_add(duration)) - } - - /// Computes `self - duration`, saturating value on overflow. - /// - /// ```rust - /// # use time::{UtcDateTime, ext::NumericalDuration}; - /// # use time_macros::utc_datetime; - /// assert_eq!( - /// UtcDateTime::MIN.saturating_sub(2.days()), - /// UtcDateTime::MIN - /// ); - /// assert_eq!( - /// UtcDateTime::MAX.saturating_sub((-2).days()), - /// UtcDateTime::MAX - /// ); - /// assert_eq!( - /// utc_datetime!(2019 - 11 - 25 15:30).saturating_sub(27.hours()), - /// utc_datetime!(2019 - 11 - 24 12:30) - /// ); - /// ``` - pub const fn saturating_sub(self, duration: Duration) -> Self { - Self::from_primitive(self.inner.saturating_sub(duration)) - } -} - -/// Methods that replace part of the `UtcDateTime`. -impl UtcDateTime { - /// Replace the time, preserving the date. - /// - /// ```rust - /// # use time_macros::{utc_datetime, time}; - /// assert_eq!( - /// utc_datetime!(2020-01-01 17:00).replace_time(time!(5:00)), - /// utc_datetime!(2020-01-01 5:00) - /// ); - /// ``` - #[must_use = "This method does not mutate the original `UtcDateTime`."] - pub const fn replace_time(self, time: Time) -> Self { - Self::from_primitive(self.inner.replace_time(time)) - } - - /// Replace the date, preserving the time. - /// - /// ```rust - /// # use time_macros::{utc_datetime, date}; - /// assert_eq!( - /// utc_datetime!(2020-01-01 12:00).replace_date(date!(2020-01-30)), - /// utc_datetime!(2020-01-30 12:00) - /// ); - /// ``` - #[must_use = "This method does not mutate the original `UtcDateTime`."] - pub const fn replace_date(self, date: Date) -> Self { - Self::from_primitive(self.inner.replace_date(date)) - } - - /// Replace the year. The month and day will be unchanged. - /// - /// ```rust - /// # use time_macros::utc_datetime; - /// assert_eq!( - /// utc_datetime!(2022 - 02 - 18 12:00).replace_year(2019), - /// Ok(utc_datetime!(2019 - 02 - 18 12:00)) - /// ); - /// assert!(utc_datetime!(2022 - 02 - 18 12:00).replace_year(-1_000_000_000).is_err()); // -1_000_000_000 isn't a valid year - /// assert!(utc_datetime!(2022 - 02 - 18 12:00).replace_year(1_000_000_000).is_err()); // 1_000_000_000 isn't a valid year - /// ``` - #[must_use = "This method does not mutate the original `UtcDateTime`."] - pub const fn replace_year(self, year: i32) -> Result<Self, error::ComponentRange> { - Ok(Self::from_primitive(const_try!(self - .inner - .replace_year(year)))) - } - - /// Replace the month of the year. - /// - /// ```rust - /// # use time_macros::utc_datetime; - /// # use time::Month; - /// assert_eq!( - /// utc_datetime!(2022 - 02 - 18 12:00).replace_month(Month::January), - /// Ok(utc_datetime!(2022 - 01 - 18 12:00)) - /// ); - /// assert!(utc_datetime!(2022 - 01 - 30 12:00).replace_month(Month::February).is_err()); // 30 isn't a valid day in February - /// ``` - #[must_use = "This method does not mutate the original `UtcDateTime`."] - pub const fn replace_month(self, month: Month) -> Result<Self, error::ComponentRange> { - Ok(Self::from_primitive(const_try!(self - .inner - .replace_month(month)))) - } - - /// Replace the day of the month. - /// - /// ```rust - /// # use time_macros::utc_datetime; - /// assert_eq!( - /// utc_datetime!(2022 - 02 - 18 12:00).replace_day(1), - /// Ok(utc_datetime!(2022 - 02 - 01 12:00)) - /// ); - /// assert!(utc_datetime!(2022 - 02 - 18 12:00).replace_day(0).is_err()); // 00 isn't a valid day - /// assert!(utc_datetime!(2022 - 02 - 18 12:00).replace_day(30).is_err()); // 30 isn't a valid day in February - /// ``` - #[must_use = "This method does not mutate the original `UtcDateTime`."] - pub const fn replace_day(self, day: u8) -> Result<Self, error::ComponentRange> { - Ok(Self::from_primitive(const_try!(self - .inner - .replace_day(day)))) - } - - /// Replace the day of the year. - /// - /// ```rust - /// # use time_macros::utc_datetime; - /// assert_eq!(utc_datetime!(2022-049 12:00).replace_ordinal(1), Ok(utc_datetime!(2022-001 12:00))); - /// assert!(utc_datetime!(2022-049 12:00).replace_ordinal(0).is_err()); // 0 isn't a valid ordinal - /// assert!(utc_datetime!(2022-049 12:00).replace_ordinal(366).is_err()); // 2022 isn't a leap year - /// ``` - #[must_use = "This method does not mutate the original `UtcDateTime`."] - pub const fn replace_ordinal(self, ordinal: u16) -> Result<Self, error::ComponentRange> { - Ok(Self::from_primitive(const_try!(self - .inner - .replace_ordinal(ordinal)))) - } - - /// Replace the clock hour. - /// - /// ```rust - /// # use time_macros::utc_datetime; - /// assert_eq!( - /// utc_datetime!(2022 - 02 - 18 01:02:03.004_005_006).replace_hour(7), - /// Ok(utc_datetime!(2022 - 02 - 18 07:02:03.004_005_006)) - /// ); - /// assert!(utc_datetime!(2022 - 02 - 18 01:02:03.004_005_006).replace_hour(24).is_err()); // 24 isn't a valid hour - /// ``` - #[must_use = "This method does not mutate the original `UtcDateTime`."] - pub const fn replace_hour(self, hour: u8) -> Result<Self, error::ComponentRange> { - Ok(Self::from_primitive(const_try!(self - .inner - .replace_hour(hour)))) - } - - /// Replace the minutes within the hour. - /// - /// ```rust - /// # use time_macros::utc_datetime; - /// assert_eq!( - /// utc_datetime!(2022 - 02 - 18 01:02:03.004_005_006).replace_minute(7), - /// Ok(utc_datetime!(2022 - 02 - 18 01:07:03.004_005_006)) - /// ); - /// assert!(utc_datetime!(2022 - 02 - 18 01:02:03.004_005_006).replace_minute(60).is_err()); // 60 isn't a valid minute - /// ``` - #[must_use = "This method does not mutate the original `UtcDateTime`."] - pub const fn replace_minute( - self, - sunday_based_week: u8, - ) -> Result<Self, error::ComponentRange> { - Ok(Self::from_primitive(const_try!(self - .inner - .replace_minute(sunday_based_week)))) - } - - /// Replace the seconds within the minute. - /// - /// ```rust - /// # use time_macros::utc_datetime; - /// assert_eq!( - /// utc_datetime!(2022 - 02 - 18 01:02:03.004_005_006).replace_second(7), - /// Ok(utc_datetime!(2022 - 02 - 18 01:02:07.004_005_006)) - /// ); - /// assert!(utc_datetime!(2022 - 02 - 18 01:02:03.004_005_006).replace_second(60).is_err()); // 60 isn't a valid second - /// ``` - #[must_use = "This method does not mutate the original `UtcDateTime`."] - pub const fn replace_second( - self, - monday_based_week: u8, - ) -> Result<Self, error::ComponentRange> { - Ok(Self::from_primitive(const_try!(self - .inner - .replace_second(monday_based_week)))) - } - - /// Replace the milliseconds within the second. - /// - /// ```rust - /// # use time_macros::utc_datetime; - /// assert_eq!( - /// utc_datetime!(2022 - 02 - 18 01:02:03.004_005_006).replace_millisecond(7), - /// Ok(utc_datetime!(2022 - 02 - 18 01:02:03.007)) - /// ); - /// assert!(utc_datetime!(2022 - 02 - 18 01:02:03.004_005_006).replace_millisecond(1_000).is_err()); // 1_000 isn't a valid millisecond - /// ``` - #[must_use = "This method does not mutate the original `UtcDateTime`."] - pub const fn replace_millisecond( - self, - millisecond: u16, - ) -> Result<Self, error::ComponentRange> { - Ok(Self::from_primitive(const_try!(self - .inner - .replace_millisecond(millisecond)))) - } - - /// Replace the microseconds within the second. - /// - /// ```rust - /// # use time_macros::utc_datetime; - /// assert_eq!( - /// utc_datetime!(2022 - 02 - 18 01:02:03.004_005_006).replace_microsecond(7_008), - /// Ok(utc_datetime!(2022 - 02 - 18 01:02:03.007_008)) - /// ); - /// assert!(utc_datetime!(2022 - 02 - 18 01:02:03.004_005_006).replace_microsecond(1_000_000).is_err()); // 1_000_000 isn't a valid microsecond - /// ``` - #[must_use = "This method does not mutate the original `UtcDateTime`."] - pub const fn replace_microsecond( - self, - microsecond: u32, - ) -> Result<Self, error::ComponentRange> { - Ok(Self::from_primitive(const_try!(self - .inner - .replace_microsecond(microsecond)))) - } - - /// Replace the nanoseconds within the second. - /// - /// ```rust - /// # use time_macros::utc_datetime; - /// assert_eq!( - /// utc_datetime!(2022 - 02 - 18 01:02:03.004_005_006).replace_nanosecond(7_008_009), - /// Ok(utc_datetime!(2022 - 02 - 18 01:02:03.007_008_009)) - /// ); - /// assert!(utc_datetime!(2022 - 02 - 18 01:02:03.004_005_006).replace_nanosecond(1_000_000_000).is_err()); // 1_000_000_000 isn't a valid nanosecond - /// ``` - #[must_use = "This method does not mutate the original `UtcDateTime`."] - pub const fn replace_nanosecond(self, nanosecond: u32) -> Result<Self, error::ComponentRange> { - Ok(Self::from_primitive(const_try!(self - .inner - .replace_nanosecond(nanosecond)))) - } -} - -#[cfg(feature = "formatting")] -impl UtcDateTime { - /// Format the `UtcDateTime` using the provided [format - /// description](crate::format_description). - pub fn format_into( - self, - output: &mut (impl io::Write + ?Sized), - format: &(impl Formattable + ?Sized), - ) -> Result<usize, error::Format> { - format.format_into( - output, - Some(self.date()), - Some(self.time()), - Some(UtcOffset::UTC), - ) - } - - /// Format the `UtcDateTime` using the provided [format - /// description](crate::format_description). - /// - /// ```rust - /// # use time::format_description; - /// # use time_macros::utc_datetime; - /// let format = format_description::parse( - /// "[year]-[month]-[day] [hour]:[minute]:[second] [offset_hour \ - /// sign:mandatory]:[offset_minute]:[offset_second]", - /// )?; - /// assert_eq!( - /// utc_datetime!(2020-01-02 03:04:05).format(&format)?, - /// "2020-01-02 03:04:05 +00:00:00" - /// ); - /// # Ok::<_, time::Error>(()) - /// ``` - pub fn format(self, format: &(impl Formattable + ?Sized)) -> Result<String, error::Format> { - format.format(Some(self.date()), Some(self.time()), Some(UtcOffset::UTC)) - } -} - -#[cfg(feature = "parsing")] -impl UtcDateTime { - /// Parse an `UtcDateTime` from the input using the provided [format - /// description](crate::format_description). A [`UtcOffset`] is permitted, but not required to - /// be present. If present, the value will be converted to UTC. - /// - /// ```rust - /// # use time::UtcDateTime; - /// # use time_macros::{utc_datetime, format_description}; - /// let format = format_description!("[year]-[month]-[day] [hour]:[minute]:[second]"); - /// assert_eq!( - /// UtcDateTime::parse("2020-01-02 03:04:05", &format)?, - /// utc_datetime!(2020-01-02 03:04:05) - /// ); - /// # Ok::<_, time::Error>(()) - /// ``` - pub fn parse( - input: &str, - description: &(impl Parsable + ?Sized), - ) -> Result<Self, error::Parse> { - description.parse_utc_date_time(input.as_bytes()) - } - - /// A helper method to check if the `UtcDateTime` is a valid representation of a leap second. - /// Leap seconds, when parsed, are represented as the preceding nanosecond. However, leap - /// seconds can only occur as the last second of a month UTC. - #[cfg(feature = "parsing")] - pub(crate) const fn is_valid_leap_second_stand_in(self) -> bool { - let dt = self.inner; - - dt.hour() == 23 - && dt.minute() == 59 - && dt.second() == 59 - && dt.nanosecond() == 999_999_999 - && dt.day() == dt.month().length(dt.year()) - } -} - -impl SmartDisplay for UtcDateTime { - type Metadata = (); - - fn metadata(&self, _: FormatterOptions) -> Metadata<Self> { - let width = smart_display::padded_width_of!(self.date(), " ", self.time(), " +00"); - Metadata::new(width, self, ()) - } - - fn fmt_with_metadata( - &self, - f: &mut fmt::Formatter<'_>, - metadata: Metadata<Self>, - ) -> fmt::Result { - f.pad_with_width( - metadata.unpadded_width(), - format_args!("{} {} +00", self.date(), self.time()), - ) - } -} - -impl fmt::Display for UtcDateTime { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - SmartDisplay::fmt(self, f) - } -} - -impl fmt::Debug for UtcDateTime { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Display::fmt(self, f) - } -} - -impl Add<Duration> for UtcDateTime { - type Output = Self; - - /// # Panics - /// - /// This may panic if an overflow occurs. - fn add(self, duration: Duration) -> Self::Output { - self.inner.add(duration).as_utc() - } -} - -impl Add<StdDuration> for UtcDateTime { - type Output = Self; - - /// # Panics - /// - /// This may panic if an overflow occurs. - fn add(self, duration: StdDuration) -> Self::Output { - self.inner.add(duration).as_utc() - } -} - -impl AddAssign<Duration> for UtcDateTime { - /// # Panics - /// - /// This may panic if an overflow occurs. - fn add_assign(&mut self, rhs: Duration) { - self.inner.add_assign(rhs); - } -} - -impl AddAssign<StdDuration> for UtcDateTime { - /// # Panics - /// - /// This may panic if an overflow occurs. - fn add_assign(&mut self, rhs: StdDuration) { - self.inner.add_assign(rhs); - } -} - -impl Sub<Duration> for UtcDateTime { - type Output = Self; - - /// # Panics - /// - /// This may panic if an overflow occurs. - fn sub(self, rhs: Duration) -> Self::Output { - self.checked_sub(rhs) - .expect("resulting value is out of range") - } -} - -impl Sub<StdDuration> for UtcDateTime { - type Output = Self; - - /// # Panics - /// - /// This may panic if an overflow occurs. - fn sub(self, duration: StdDuration) -> Self::Output { - Self::from_primitive(self.inner.sub(duration)) - } -} - -impl SubAssign<Duration> for UtcDateTime { - /// # Panics - /// - /// This may panic if an overflow occurs. - fn sub_assign(&mut self, rhs: Duration) { - self.inner.sub_assign(rhs); - } -} - -impl SubAssign<StdDuration> for UtcDateTime { - /// # Panics - /// - /// This may panic if an overflow occurs. - fn sub_assign(&mut self, rhs: StdDuration) { - self.inner.sub_assign(rhs); - } -} - -impl Sub for UtcDateTime { - type Output = Duration; - - /// # Panics - /// - /// This may panic if an overflow occurs. - fn sub(self, rhs: Self) -> Self::Output { - self.inner.sub(rhs.inner) - } -} diff --git a/vendor/time/src/utc_offset.rs b/vendor/time/src/utc_offset.rs deleted file mode 100644 index 73bcf2d1..00000000 --- a/vendor/time/src/utc_offset.rs +++ /dev/null @@ -1,464 +0,0 @@ -//! The [`UtcOffset`] struct and its associated `impl`s. - -#[cfg(feature = "formatting")] -use alloc::string::String; -use core::fmt; -use core::ops::Neg; -#[cfg(feature = "formatting")] -use std::io; - -use deranged::{RangedI32, RangedI8}; -use powerfmt::ext::FormatterExt; -use powerfmt::smart_display::{self, FormatterOptions, Metadata, SmartDisplay}; - -use crate::convert::*; -use crate::error; -#[cfg(feature = "formatting")] -use crate::formatting::Formattable; -use crate::internal_macros::ensure_ranged; -#[cfg(feature = "parsing")] -use crate::parsing::Parsable; -#[cfg(feature = "local-offset")] -use crate::sys::local_offset_at; -#[cfg(feature = "local-offset")] -use crate::OffsetDateTime; - -/// The type of the `hours` field of `UtcOffset`. -type Hours = RangedI8<-25, 25>; -/// The type of the `minutes` field of `UtcOffset`. -type Minutes = RangedI8<{ -(Minute::per(Hour) as i8 - 1) }, { Minute::per(Hour) as i8 - 1 }>; -/// The type of the `seconds` field of `UtcOffset`. -type Seconds = RangedI8<{ -(Second::per(Minute) as i8 - 1) }, { Second::per(Minute) as i8 - 1 }>; -/// The type capable of storing the range of whole seconds that a `UtcOffset` can encompass. -type WholeSeconds = RangedI32< - { - Hours::MIN.get() as i32 * Second::per(Hour) as i32 - + Minutes::MIN.get() as i32 * Second::per(Minute) as i32 - + Seconds::MIN.get() as i32 - }, - { - Hours::MAX.get() as i32 * Second::per(Hour) as i32 - + Minutes::MAX.get() as i32 * Second::per(Minute) as i32 - + Seconds::MAX.get() as i32 - }, ->; - -/// An offset from UTC. -/// -/// This struct can store values up to ±25:59:59. If you need support outside this range, please -/// file an issue with your use case. -// All three components _must_ have the same sign. -#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] -pub struct UtcOffset { - hours: Hours, - minutes: Minutes, - seconds: Seconds, -} - -impl UtcOffset { - /// A `UtcOffset` that is UTC. - /// - /// ```rust - /// # use time::UtcOffset; - /// # use time_macros::offset; - /// assert_eq!(UtcOffset::UTC, offset!(UTC)); - /// ``` - pub const UTC: Self = Self::from_whole_seconds_ranged(WholeSeconds::new_static::<0>()); - - /// Create a `UtcOffset` representing an offset of the hours, minutes, and seconds provided, the - /// validity of which must be guaranteed by the caller. All three parameters must have the same - /// sign. - /// - /// # Safety - /// - /// - Hours must be in the range `-25..=25`. - /// - Minutes must be in the range `-59..=59`. - /// - Seconds must be in the range `-59..=59`. - /// - /// While the signs of the parameters are required to match to avoid bugs, this is not a safety - /// invariant. - #[doc(hidden)] - pub const unsafe fn __from_hms_unchecked(hours: i8, minutes: i8, seconds: i8) -> Self { - // Safety: The caller must uphold the safety invariants. - unsafe { - Self::from_hms_ranged_unchecked( - Hours::new_unchecked(hours), - Minutes::new_unchecked(minutes), - Seconds::new_unchecked(seconds), - ) - } - } - - /// Create a `UtcOffset` representing an offset by the number of hours, minutes, and seconds - /// provided. - /// - /// The sign of all three components should match. If they do not, all smaller components will - /// have their signs flipped. - /// - /// ```rust - /// # use time::UtcOffset; - /// assert_eq!(UtcOffset::from_hms(1, 2, 3)?.as_hms(), (1, 2, 3)); - /// assert_eq!(UtcOffset::from_hms(1, -2, -3)?.as_hms(), (1, 2, 3)); - /// # Ok::<_, time::Error>(()) - /// ``` - pub const fn from_hms( - hours: i8, - minutes: i8, - seconds: i8, - ) -> Result<Self, error::ComponentRange> { - Ok(Self::from_hms_ranged( - ensure_ranged!(Hours: hours), - ensure_ranged!(Minutes: minutes), - ensure_ranged!(Seconds: seconds), - )) - } - - /// Create a `UtcOffset` representing an offset of the hours, minutes, and seconds provided. All - /// three parameters must have the same sign. - /// - /// While the signs of the parameters are required to match, this is not a safety invariant. - pub(crate) const fn from_hms_ranged_unchecked( - hours: Hours, - minutes: Minutes, - seconds: Seconds, - ) -> Self { - if hours.get() < 0 { - debug_assert!(minutes.get() <= 0); - debug_assert!(seconds.get() <= 0); - } else if hours.get() > 0 { - debug_assert!(minutes.get() >= 0); - debug_assert!(seconds.get() >= 0); - } - if minutes.get() < 0 { - debug_assert!(seconds.get() <= 0); - } else if minutes.get() > 0 { - debug_assert!(seconds.get() >= 0); - } - - Self { - hours, - minutes, - seconds, - } - } - - /// Create a `UtcOffset` representing an offset by the number of hours, minutes, and seconds - /// provided. - /// - /// The sign of all three components should match. If they do not, all smaller components will - /// have their signs flipped. - pub(crate) const fn from_hms_ranged( - hours: Hours, - mut minutes: Minutes, - mut seconds: Seconds, - ) -> Self { - if (hours.get() > 0 && minutes.get() < 0) || (hours.get() < 0 && minutes.get() > 0) { - minutes = minutes.neg(); - } - if (hours.get() > 0 && seconds.get() < 0) - || (hours.get() < 0 && seconds.get() > 0) - || (minutes.get() > 0 && seconds.get() < 0) - || (minutes.get() < 0 && seconds.get() > 0) - { - seconds = seconds.neg(); - } - - Self { - hours, - minutes, - seconds, - } - } - - /// Create a `UtcOffset` representing an offset by the number of seconds provided. - /// - /// ```rust - /// # use time::UtcOffset; - /// assert_eq!(UtcOffset::from_whole_seconds(3_723)?.as_hms(), (1, 2, 3)); - /// # Ok::<_, time::Error>(()) - /// ``` - pub const fn from_whole_seconds(seconds: i32) -> Result<Self, error::ComponentRange> { - Ok(Self::from_whole_seconds_ranged( - ensure_ranged!(WholeSeconds: seconds), - )) - } - - /// Create a `UtcOffset` representing an offset by the number of seconds provided. - // ignore because the function is crate-private - /// ```rust,ignore - /// # use time::UtcOffset; - /// # use deranged::RangedI32; - /// assert_eq!( - /// UtcOffset::from_whole_seconds_ranged(RangedI32::new_static::<3_723>()).as_hms(), - /// (1, 2, 3) - /// ); - /// # Ok::<_, time::Error>(()) - /// ``` - pub(crate) const fn from_whole_seconds_ranged(seconds: WholeSeconds) -> Self { - // Safety: The type of `seconds` guarantees that all values are in range. - unsafe { - Self::__from_hms_unchecked( - (seconds.get() / Second::per(Hour) as i32) as i8, - ((seconds.get() % Second::per(Hour) as i32) / Minute::per(Hour) as i32) as i8, - (seconds.get() % Second::per(Minute) as i32) as i8, - ) - } - } - - /// Obtain the UTC offset as its hours, minutes, and seconds. The sign of all three components - /// will always match. A positive value indicates an offset to the east; a negative to the west. - /// - /// ```rust - /// # use time_macros::offset; - /// assert_eq!(offset!(+1:02:03).as_hms(), (1, 2, 3)); - /// assert_eq!(offset!(-1:02:03).as_hms(), (-1, -2, -3)); - /// ``` - pub const fn as_hms(self) -> (i8, i8, i8) { - (self.hours.get(), self.minutes.get(), self.seconds.get()) - } - - /// Obtain the UTC offset as its hours, minutes, and seconds. The sign of all three components - /// will always match. A positive value indicates an offset to the east; a negative to the west. - #[cfg(feature = "quickcheck")] - pub(crate) const fn as_hms_ranged(self) -> (Hours, Minutes, Seconds) { - (self.hours, self.minutes, self.seconds) - } - - /// Obtain the number of whole hours the offset is from UTC. A positive value indicates an - /// offset to the east; a negative to the west. - /// - /// ```rust - /// # use time_macros::offset; - /// assert_eq!(offset!(+1:02:03).whole_hours(), 1); - /// assert_eq!(offset!(-1:02:03).whole_hours(), -1); - /// ``` - pub const fn whole_hours(self) -> i8 { - self.hours.get() - } - - /// Obtain the number of whole minutes the offset is from UTC. A positive value indicates an - /// offset to the east; a negative to the west. - /// - /// ```rust - /// # use time_macros::offset; - /// assert_eq!(offset!(+1:02:03).whole_minutes(), 62); - /// assert_eq!(offset!(-1:02:03).whole_minutes(), -62); - /// ``` - pub const fn whole_minutes(self) -> i16 { - self.hours.get() as i16 * Minute::per(Hour) as i16 + self.minutes.get() as i16 - } - - /// Obtain the number of minutes past the hour the offset is from UTC. A positive value - /// indicates an offset to the east; a negative to the west. - /// - /// ```rust - /// # use time_macros::offset; - /// assert_eq!(offset!(+1:02:03).minutes_past_hour(), 2); - /// assert_eq!(offset!(-1:02:03).minutes_past_hour(), -2); - /// ``` - pub const fn minutes_past_hour(self) -> i8 { - self.minutes.get() - } - - /// Obtain the number of whole seconds the offset is from UTC. A positive value indicates an - /// offset to the east; a negative to the west. - /// - /// ```rust - /// # use time_macros::offset; - /// assert_eq!(offset!(+1:02:03).whole_seconds(), 3723); - /// assert_eq!(offset!(-1:02:03).whole_seconds(), -3723); - /// ``` - // This may be useful for anyone manually implementing arithmetic, as it - // would let them construct a `Duration` directly. - pub const fn whole_seconds(self) -> i32 { - self.hours.get() as i32 * Second::per(Hour) as i32 - + self.minutes.get() as i32 * Second::per(Minute) as i32 - + self.seconds.get() as i32 - } - - /// Obtain the number of seconds past the minute the offset is from UTC. A positive value - /// indicates an offset to the east; a negative to the west. - /// - /// ```rust - /// # use time_macros::offset; - /// assert_eq!(offset!(+1:02:03).seconds_past_minute(), 3); - /// assert_eq!(offset!(-1:02:03).seconds_past_minute(), -3); - /// ``` - pub const fn seconds_past_minute(self) -> i8 { - self.seconds.get() - } - - /// Check if the offset is exactly UTC. - /// - /// - /// ```rust - /// # use time_macros::offset; - /// assert!(!offset!(+1:02:03).is_utc()); - /// assert!(!offset!(-1:02:03).is_utc()); - /// assert!(offset!(UTC).is_utc()); - /// ``` - pub const fn is_utc(self) -> bool { - self.hours.get() == 0 && self.minutes.get() == 0 && self.seconds.get() == 0 - } - - /// Check if the offset is positive, or east of UTC. - /// - /// ```rust - /// # use time_macros::offset; - /// assert!(offset!(+1:02:03).is_positive()); - /// assert!(!offset!(-1:02:03).is_positive()); - /// assert!(!offset!(UTC).is_positive()); - /// ``` - pub const fn is_positive(self) -> bool { - self.hours.get() > 0 || self.minutes.get() > 0 || self.seconds.get() > 0 - } - - /// Check if the offset is negative, or west of UTC. - /// - /// ```rust - /// # use time_macros::offset; - /// assert!(!offset!(+1:02:03).is_negative()); - /// assert!(offset!(-1:02:03).is_negative()); - /// assert!(!offset!(UTC).is_negative()); - /// ``` - pub const fn is_negative(self) -> bool { - self.hours.get() < 0 || self.minutes.get() < 0 || self.seconds.get() < 0 - } - - /// Attempt to obtain the system's UTC offset at a known moment in time. If the offset cannot be - /// determined, an error is returned. - /// - /// ```rust - /// # use time::{UtcOffset, OffsetDateTime}; - /// let local_offset = UtcOffset::local_offset_at(OffsetDateTime::UNIX_EPOCH); - /// # if false { - /// assert!(local_offset.is_ok()); - /// # } - /// ``` - #[cfg(feature = "local-offset")] - pub fn local_offset_at(datetime: OffsetDateTime) -> Result<Self, error::IndeterminateOffset> { - local_offset_at(datetime).ok_or(error::IndeterminateOffset) - } - - /// Attempt to obtain the system's current UTC offset. If the offset cannot be determined, an - /// error is returned. - /// - /// ```rust - /// # use time::UtcOffset; - /// let local_offset = UtcOffset::current_local_offset(); - /// # if false { - /// assert!(local_offset.is_ok()); - /// # } - /// ``` - #[cfg(feature = "local-offset")] - pub fn current_local_offset() -> Result<Self, error::IndeterminateOffset> { - let now = OffsetDateTime::now_utc(); - local_offset_at(now).ok_or(error::IndeterminateOffset) - } -} - -#[cfg(feature = "formatting")] -impl UtcOffset { - /// Format the `UtcOffset` using the provided [format description](crate::format_description). - pub fn format_into( - self, - output: &mut (impl io::Write + ?Sized), - format: &(impl Formattable + ?Sized), - ) -> Result<usize, error::Format> { - format.format_into(output, None, None, Some(self)) - } - - /// Format the `UtcOffset` using the provided [format description](crate::format_description). - /// - /// ```rust - /// # use time::format_description; - /// # use time_macros::offset; - /// let format = format_description::parse("[offset_hour sign:mandatory]:[offset_minute]")?; - /// assert_eq!(offset!(+1).format(&format)?, "+01:00"); - /// # Ok::<_, time::Error>(()) - /// ``` - pub fn format(self, format: &(impl Formattable + ?Sized)) -> Result<String, error::Format> { - format.format(None, None, Some(self)) - } -} - -#[cfg(feature = "parsing")] -impl UtcOffset { - /// Parse a `UtcOffset` from the input using the provided [format - /// description](crate::format_description). - /// - /// ```rust - /// # use time::UtcOffset; - /// # use time_macros::{offset, format_description}; - /// let format = format_description!("[offset_hour]:[offset_minute]"); - /// assert_eq!(UtcOffset::parse("-03:42", &format)?, offset!(-3:42)); - /// # Ok::<_, time::Error>(()) - /// ``` - pub fn parse( - input: &str, - description: &(impl Parsable + ?Sized), - ) -> Result<Self, error::Parse> { - description.parse_offset(input.as_bytes()) - } -} - -mod private { - #[non_exhaustive] - #[derive(Debug, Clone, Copy)] - pub struct UtcOffsetMetadata; -} -use private::UtcOffsetMetadata; - -impl SmartDisplay for UtcOffset { - type Metadata = UtcOffsetMetadata; - - fn metadata(&self, _: FormatterOptions) -> Metadata<Self> { - let sign = if self.is_negative() { '-' } else { '+' }; - let width = smart_display::padded_width_of!( - sign, - self.hours.abs() => width(2), - ":", - self.minutes.abs() => width(2), - ":", - self.seconds.abs() => width(2), - ); - Metadata::new(width, self, UtcOffsetMetadata) - } - - fn fmt_with_metadata( - &self, - f: &mut fmt::Formatter<'_>, - metadata: Metadata<Self>, - ) -> fmt::Result { - f.pad_with_width( - metadata.unpadded_width(), - format_args!( - "{}{:02}:{:02}:{:02}", - if self.is_negative() { '-' } else { '+' }, - self.hours.abs(), - self.minutes.abs(), - self.seconds.abs(), - ), - ) - } -} - -impl fmt::Display for UtcOffset { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - SmartDisplay::fmt(self, f) - } -} - -impl fmt::Debug for UtcOffset { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Display::fmt(self, f) - } -} - -impl Neg for UtcOffset { - type Output = Self; - - fn neg(self) -> Self::Output { - Self::from_hms_ranged(self.hours.neg(), self.minutes.neg(), self.seconds.neg()) - } -} diff --git a/vendor/time/src/util.rs b/vendor/time/src/util.rs deleted file mode 100644 index c5166a70..00000000 --- a/vendor/time/src/util.rs +++ /dev/null @@ -1,105 +0,0 @@ -//! Utility functions, including updating time zone information. - -pub use time_core::util::{days_in_year, is_leap_year, weeks_in_year}; - -use crate::Month; - -/// Whether to adjust the date, and in which direction. Useful when implementing arithmetic. -pub(crate) enum DateAdjustment { - /// The previous day should be used. - Previous, - /// The next day should be used. - Next, - /// The date should be used as-is. - None, -} - -/// Get the number of days in the month of a given year. -/// -/// ```rust -/// # use time::{Month, util}; -/// assert_eq!(util::days_in_month(Month::February, 2020), 29); -/// ``` -pub const fn days_in_month(month: Month, year: i32) -> u8 { - time_core::util::days_in_month(month as u8, year) -} - -/// Get the number of days in the month of a given year. -/// -/// ```rust -/// # #![allow(deprecated)] -/// # use time::{Month, util}; -/// assert_eq!(util::days_in_year_month(2020, Month::February), 29); -/// ``` -#[deprecated( - since = "0.3.37", - note = "use `days_in_month` or `Month::length` instead" -)] -pub const fn days_in_year_month(year: i32, month: Month) -> u8 { - days_in_month(month, year) -} - -/// Update time zone information from the system. -/// -/// For a version of this function that is guaranteed to be sound, see [`refresh_tz`]. -/// -/// # Safety -/// -/// This is a system call with specific requirements. The following is from POSIX's description of -/// `tzset`: -/// -/// > If a thread accesses `tzname`, `daylight`, or `timezone` directly while another thread is in a -/// > call to `tzset()`, or to any function that is required or allowed to set timezone information -/// > as if by calling `tzset()`, the behavior is undefined. -/// -/// Effectively, this translates to the requirement that at least one of the following must be true: -/// -/// - The operating system provides a thread-safe environment. -/// - The process is single-threaded. -/// - The process is multi-threaded **and** no other thread is mutating the environment in any way -/// at the same time a call to a method that obtains the local UTC offset. This includes adding, -/// removing, or modifying an environment variable. -/// -/// ## Soundness is global -/// -/// You must not only verify this safety conditions for your code, but for **all** code that will be -/// included in the final binary. Notably, it applies to both direct and transitive dependencies and -/// to both Rust and non-Rust code. **For this reason it is not possible for a library to soundly -/// call this method.** -/// -/// ## Forward compatibility -/// -/// This currently only does anything on Unix-like systems. On other systems, it is a no-op. This -/// may change in the future if necessary, expanding the safety requirements. It is expected that, -/// at a minimum, calling this method when the process is single-threaded will remain sound. -#[cfg(feature = "local-offset")] -pub unsafe fn refresh_tz_unchecked() { - // Safety: The caller must uphold the safety requirements. - unsafe { crate::sys::refresh_tz_unchecked() }; -} - -/// Attempt to update time zone information from the system. -/// -/// Returns `None` if the call is not known to be sound. -#[cfg(feature = "local-offset")] -pub fn refresh_tz() -> Option<()> { - crate::sys::refresh_tz() -} - -#[doc(hidden)] -#[cfg(feature = "local-offset")] -#[allow(clippy::missing_const_for_fn)] -#[deprecated(since = "0.3.37", note = "no longer needed; TZ is refreshed manually")] -pub mod local_offset { - #[derive(Debug, Clone, Copy, PartialEq, Eq)] - pub enum Soundness { - Sound, - Unsound, - } - - pub unsafe fn set_soundness(_: Soundness) {} - - pub fn get_soundness() -> Soundness { - Soundness::Sound - } -} diff --git a/vendor/time/src/weekday.rs b/vendor/time/src/weekday.rs deleted file mode 100644 index 4331da83..00000000 --- a/vendor/time/src/weekday.rs +++ /dev/null @@ -1,220 +0,0 @@ -//! Days of the week. - -use core::fmt; -use core::str::FromStr; - -use powerfmt::smart_display::{FormatterOptions, Metadata, SmartDisplay}; - -use self::Weekday::*; -use crate::error; - -/// Days of the week. -/// -/// As order is dependent on context (Sunday could be either two days after or five days before -/// Friday), this type does not implement `PartialOrd` or `Ord`. -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub enum Weekday { - #[allow(missing_docs)] - Monday, - #[allow(missing_docs)] - Tuesday, - #[allow(missing_docs)] - Wednesday, - #[allow(missing_docs)] - Thursday, - #[allow(missing_docs)] - Friday, - #[allow(missing_docs)] - Saturday, - #[allow(missing_docs)] - Sunday, -} - -impl Weekday { - /// Get the previous weekday. - /// - /// ```rust - /// # use time::Weekday; - /// assert_eq!(Weekday::Tuesday.previous(), Weekday::Monday); - /// ``` - pub const fn previous(self) -> Self { - match self { - Monday => Sunday, - Tuesday => Monday, - Wednesday => Tuesday, - Thursday => Wednesday, - Friday => Thursday, - Saturday => Friday, - Sunday => Saturday, - } - } - - /// Get the next weekday. - /// - /// ```rust - /// # use time::Weekday; - /// assert_eq!(Weekday::Monday.next(), Weekday::Tuesday); - /// ``` - pub const fn next(self) -> Self { - match self { - Monday => Tuesday, - Tuesday => Wednesday, - Wednesday => Thursday, - Thursday => Friday, - Friday => Saturday, - Saturday => Sunday, - Sunday => Monday, - } - } - - /// Get n-th next day. - /// - /// ```rust - /// # use time::Weekday; - /// assert_eq!(Weekday::Monday.nth_next(1), Weekday::Tuesday); - /// assert_eq!(Weekday::Sunday.nth_next(10), Weekday::Wednesday); - /// ``` - pub const fn nth_next(self, n: u8) -> Self { - match (self.number_days_from_monday() + n % 7) % 7 { - 0 => Monday, - 1 => Tuesday, - 2 => Wednesday, - 3 => Thursday, - 4 => Friday, - 5 => Saturday, - val => { - debug_assert!(val == 6); - Sunday - } - } - } - - /// Get n-th previous day. - /// - /// ```rust - /// # use time::Weekday; - /// assert_eq!(Weekday::Monday.nth_prev(1), Weekday::Sunday); - /// assert_eq!(Weekday::Sunday.nth_prev(10), Weekday::Thursday); - /// ``` - pub const fn nth_prev(self, n: u8) -> Self { - match self.number_days_from_monday() as i8 - (n % 7) as i8 { - 1 | -6 => Tuesday, - 2 | -5 => Wednesday, - 3 | -4 => Thursday, - 4 | -3 => Friday, - 5 | -2 => Saturday, - 6 | -1 => Sunday, - val => { - debug_assert!(val == 0); - Monday - } - } - } - - /// Get the one-indexed number of days from Monday. - /// - /// ```rust - /// # use time::Weekday; - /// assert_eq!(Weekday::Monday.number_from_monday(), 1); - /// ``` - #[doc(alias = "iso_weekday_number")] - pub const fn number_from_monday(self) -> u8 { - self.number_days_from_monday() + 1 - } - - /// Get the one-indexed number of days from Sunday. - /// - /// ```rust - /// # use time::Weekday; - /// assert_eq!(Weekday::Monday.number_from_sunday(), 2); - /// ``` - pub const fn number_from_sunday(self) -> u8 { - self.number_days_from_sunday() + 1 - } - - /// Get the zero-indexed number of days from Monday. - /// - /// ```rust - /// # use time::Weekday; - /// assert_eq!(Weekday::Monday.number_days_from_monday(), 0); - /// ``` - pub const fn number_days_from_monday(self) -> u8 { - self as u8 - } - - /// Get the zero-indexed number of days from Sunday. - /// - /// ```rust - /// # use time::Weekday; - /// assert_eq!(Weekday::Monday.number_days_from_sunday(), 1); - /// ``` - pub const fn number_days_from_sunday(self) -> u8 { - match self { - Monday => 1, - Tuesday => 2, - Wednesday => 3, - Thursday => 4, - Friday => 5, - Saturday => 6, - Sunday => 0, - } - } -} - -mod private { - #[non_exhaustive] - #[derive(Debug, Clone, Copy)] - pub struct WeekdayMetadata; -} -use private::WeekdayMetadata; - -impl SmartDisplay for Weekday { - type Metadata = WeekdayMetadata; - - fn metadata(&self, _: FormatterOptions) -> Metadata<'_, Self> { - match self { - Monday => Metadata::new(6, self, WeekdayMetadata), - Tuesday => Metadata::new(7, self, WeekdayMetadata), - Wednesday => Metadata::new(9, self, WeekdayMetadata), - Thursday => Metadata::new(8, self, WeekdayMetadata), - Friday => Metadata::new(6, self, WeekdayMetadata), - Saturday => Metadata::new(8, self, WeekdayMetadata), - Sunday => Metadata::new(6, self, WeekdayMetadata), - } - } - - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.pad(match self { - Monday => "Monday", - Tuesday => "Tuesday", - Wednesday => "Wednesday", - Thursday => "Thursday", - Friday => "Friday", - Saturday => "Saturday", - Sunday => "Sunday", - }) - } -} - -impl fmt::Display for Weekday { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - SmartDisplay::fmt(self, f) - } -} - -impl FromStr for Weekday { - type Err = error::InvalidVariant; - - fn from_str(s: &str) -> Result<Self, Self::Err> { - match s { - "Monday" => Ok(Monday), - "Tuesday" => Ok(Tuesday), - "Wednesday" => Ok(Wednesday), - "Thursday" => Ok(Thursday), - "Friday" => Ok(Friday), - "Saturday" => Ok(Saturday), - "Sunday" => Ok(Sunday), - _ => Err(error::InvalidVariant), - } - } -} |
