summaryrefslogtreecommitdiffstats
path: root/vendor/tracing-tree
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
commit698f8c2f01ea549d77d7dc3338a12e04c11057b9 (patch)
tree173a775858bd501c378080a10dca74132f05bc50 /vendor/tracing-tree
parentInitial commit. (diff)
downloadrustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.tar.xz
rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.zip
Adding upstream version 1.64.0+dfsg1.upstream/1.64.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/tracing-tree')
-rw-r--r--vendor/tracing-tree/.cargo-checksum.json1
-rw-r--r--vendor/tracing-tree/Cargo.lock334
-rw-r--r--vendor/tracing-tree/Cargo.toml64
-rw-r--r--vendor/tracing-tree/LICENSE-APACHE201
-rw-r--r--vendor/tracing-tree/LICENSE-MIT21
-rw-r--r--vendor/tracing-tree/README.md38
-rw-r--r--vendor/tracing-tree/examples/basic.rs83
-rw-r--r--vendor/tracing-tree/examples/basic.stdout41
-rw-r--r--vendor/tracing-tree/examples/quiet.rs80
-rw-r--r--vendor/tracing-tree/examples/quiet.stdout28
-rw-r--r--vendor/tracing-tree/examples/stderr.rs40
-rw-r--r--vendor/tracing-tree/examples/stderr.stderr111
-rw-r--r--vendor/tracing-tree/examples/wraparound.rs31
-rw-r--r--vendor/tracing-tree/examples/wraparound.stdout96
-rw-r--r--vendor/tracing-tree/src/format.rs425
-rw-r--r--vendor/tracing-tree/src/lib.rs395
-rw-r--r--vendor/tracing-tree/tests/ui.rs79
17 files changed, 2068 insertions, 0 deletions
diff --git a/vendor/tracing-tree/.cargo-checksum.json b/vendor/tracing-tree/.cargo-checksum.json
new file mode 100644
index 000000000..c140e495f
--- /dev/null
+++ b/vendor/tracing-tree/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"Cargo.lock":"e54b0301e8816a5e2d82ba08646102d89ee556d5e9150c571123a34013e6a79a","Cargo.toml":"734e1e9cf702e362c0661b968e92fd4599b732208a65634dd516d085449d45b2","LICENSE-APACHE":"c9c77d27bd737506eee1be90c11885fad935695714eafacd6725f41fff9ec8da","LICENSE-MIT":"d31139de68f7e19f9b32cd7de53dbb125b3c68522bbbb1d0c186c33112d34466","README.md":"589c2534836513b4edfa2811269767a9ac3c48da909c8ab936db3e646410dcf7","examples/basic.rs":"b56dad20aa283aae17a9c1364cc0326714cdc89d6a02a6329034e476b3597fd7","examples/basic.stdout":"49767873eb520f3e457b48d930fa86583d9ca5ef5571d67582b08dcb788ff6f2","examples/quiet.rs":"65a4cbb650cea4939ed274c2fd4d50c953151716fa6564b23393e1df6fb7afd7","examples/quiet.stdout":"d58a3240258279821b5d08e0d39ea60dee2dbd6a955f8639daf0d149ad0616fa","examples/stderr.rs":"ce0896f50be810908fb7083661bf39da6c9733ddef9188d40499313a40fe2c7a","examples/stderr.stderr":"8a0f6553fee903f159c6ea528dda6c5b193064ef9b58c765d1f3f60ecba5ac1f","examples/wraparound.rs":"7998f2e7b9e1f0dfc4b0cf11b1cdcf0f44c85aeaabbea9749113584ac7a3879f","examples/wraparound.stdout":"1c042231b3f8b20a843c18af063e43a51fcc852597dd1713f5878d4a8128271c","src/format.rs":"a986c0a259aec3135bcfd4908f6a80173dea03b3f57efe1dfa7c9d79f2b55257","src/lib.rs":"0a62652d641131ff67c31103331b977ca42ed268a1703aa7365180c70465f536","tests/ui.rs":"32a02ef41ae5cbabe13164f8d665b287b0bb764b2dc5bcb80443cb551df5289a"},"package":"d07e90b329c621ade432823988574e820212648aa40e7a2497777d58de0fb453"} \ No newline at end of file
diff --git a/vendor/tracing-tree/Cargo.lock b/vendor/tracing-tree/Cargo.lock
new file mode 100644
index 000000000..82a94c9e0
--- /dev/null
+++ b/vendor/tracing-tree/Cargo.lock
@@ -0,0 +1,334 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "ansi_term"
+version = "0.12.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2"
+dependencies = [
+ "winapi",
+]
+
+[[package]]
+name = "assert_cmd"
+version = "1.0.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c98233c6673d8601ab23e77eb38f999c51100d46c5703b17288c57fddf3a1ffe"
+dependencies = [
+ "bstr",
+ "doc-comment",
+ "predicates",
+ "predicates-core",
+ "predicates-tree",
+ "wait-timeout",
+]
+
+[[package]]
+name = "atty"
+version = "0.2.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
+dependencies = [
+ "hermit-abi",
+ "libc",
+ "winapi",
+]
+
+[[package]]
+name = "bstr"
+version = "0.2.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223"
+dependencies = [
+ "lazy_static",
+ "memchr",
+ "regex-automata",
+]
+
+[[package]]
+name = "cfg-if"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+
+[[package]]
+name = "difflib"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6184e33543162437515c2e2b48714794e37845ec9851711914eec9d308f6ebe8"
+
+[[package]]
+name = "doc-comment"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10"
+
+[[package]]
+name = "either"
+version = "1.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
+
+[[package]]
+name = "glob"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
+
+[[package]]
+name = "hermit-abi"
+version = "0.1.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "itertools"
+version = "0.10.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3"
+dependencies = [
+ "either",
+]
+
+[[package]]
+name = "lazy_static"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
+
+[[package]]
+name = "libc"
+version = "0.2.126"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836"
+
+[[package]]
+name = "log"
+version = "0.4.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
+dependencies = [
+ "cfg-if",
+]
+
+[[package]]
+name = "memchr"
+version = "2.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
+
+[[package]]
+name = "once_cell"
+version = "1.12.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7709cef83f0c1f58f666e746a08b21e0085f7440fa6a29cc194d68aac97a4225"
+
+[[package]]
+name = "pin-project-lite"
+version = "0.2.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116"
+
+[[package]]
+name = "predicates"
+version = "2.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a5aab5be6e4732b473071984b3164dbbfb7a3674d30ea5ff44410b6bcd960c3c"
+dependencies = [
+ "difflib",
+ "itertools",
+ "predicates-core",
+]
+
+[[package]]
+name = "predicates-core"
+version = "1.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "da1c2388b1513e1b605fcec39a95e0a9e8ef088f71443ef37099fa9ae6673fcb"
+
+[[package]]
+name = "predicates-tree"
+version = "1.0.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4d86de6de25020a36c6d3643a86d9a6a9f552107c0559c60ea03551b5e16c032"
+dependencies = [
+ "predicates-core",
+ "termtree",
+]
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.39"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c54b25569025b7fc9651de43004ae593a75ad88543b17178aa5e1b9c4f15f56f"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "regex-automata"
+version = "0.1.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132"
+
+[[package]]
+name = "sharded-slab"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31"
+dependencies = [
+ "lazy_static",
+]
+
+[[package]]
+name = "syn"
+version = "1.0.95"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fbaf6116ab8924f39d52792136fb74fd60a80194cf1b1c6ffa6453eef1c3f942"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "termtree"
+version = "0.2.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "507e9898683b6c43a9aa55b64259b721b52ba226e0f3779137e50ad114a4c90b"
+
+[[package]]
+name = "thread_local"
+version = "1.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5516c27b78311c50bf42c071425c560ac799b11c30b31f87e3081965fe5e0180"
+dependencies = [
+ "once_cell",
+]
+
+[[package]]
+name = "tracing"
+version = "0.1.34"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5d0ecdcb44a79f0fe9844f0c4f33a342cbcbb5117de8001e6ba0dc2351327d09"
+dependencies = [
+ "cfg-if",
+ "pin-project-lite",
+ "tracing-attributes",
+ "tracing-core",
+]
+
+[[package]]
+name = "tracing-attributes"
+version = "0.1.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cc6b8ad3567499f98a1db7a752b07a7c8c7c7c34c332ec00effb2b0027974b7c"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "tracing-core"
+version = "0.1.26"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f54c8ca710e81886d498c2fd3331b56c93aa248d49de2222ad2742247c60072f"
+dependencies = [
+ "lazy_static",
+ "valuable",
+]
+
+[[package]]
+name = "tracing-log"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922"
+dependencies = [
+ "lazy_static",
+ "log",
+ "tracing-core",
+]
+
+[[package]]
+name = "tracing-subscriber"
+version = "0.3.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4bc28f93baff38037f64e6f43d34cfa1605f27a49c34e8a04c5e78b0babf2596"
+dependencies = [
+ "sharded-slab",
+ "thread_local",
+ "tracing-core",
+]
+
+[[package]]
+name = "tracing-tree"
+version = "0.2.1"
+dependencies = [
+ "ansi_term",
+ "assert_cmd",
+ "atty",
+ "glob",
+ "log",
+ "tracing",
+ "tracing-core",
+ "tracing-log",
+ "tracing-subscriber",
+]
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d22af068fba1eb5edcb4aea19d382b2a3deb4c8f9d475c589b6ada9e0fd493ee"
+
+[[package]]
+name = "valuable"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
+
+[[package]]
+name = "wait-timeout"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6"
+dependencies = [
+ "libc",
+]
+
+[[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-x86_64-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
diff --git a/vendor/tracing-tree/Cargo.toml b/vendor/tracing-tree/Cargo.toml
new file mode 100644
index 000000000..32c47092f
--- /dev/null
+++ b/vendor/tracing-tree/Cargo.toml
@@ -0,0 +1,64 @@
+# 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 = "2018"
+name = "tracing-tree"
+version = "0.2.1"
+authors = [
+ "David Barsky <me@davidbarsky.com>",
+ "Nathan Whitaker",
+]
+description = "A Tracing Layer which prints a tree of spans and events."
+readme = "README.md"
+license = "MIT OR Apache-2.0"
+repository = "https://github.com/davidbarsky/tracing-tree"
+
+[[test]]
+name = "ui"
+harness = false
+
+[dependencies.ansi_term]
+version = "0.12"
+
+[dependencies.atty]
+version = "0.2"
+
+[dependencies.tracing-core]
+version = "0.1"
+
+[dependencies.tracing-log]
+version = "0.1"
+optional = true
+
+[dependencies.tracing-subscriber]
+version = "0.3"
+features = [
+ "registry",
+ "fmt",
+ "std",
+]
+default-features = false
+
+[dev-dependencies.assert_cmd]
+version = "1"
+
+[dev-dependencies.glob]
+version = "0.3"
+
+[dev-dependencies.log]
+version = "0.4"
+
+[dev-dependencies.tracing]
+version = "0.1"
+
+[features]
+default = ["tracing-log"]
diff --git a/vendor/tracing-tree/LICENSE-APACHE b/vendor/tracing-tree/LICENSE-APACHE
new file mode 100644
index 000000000..cb38739ee
--- /dev/null
+++ b/vendor/tracing-tree/LICENSE-APACHE
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright 2021 tracing-tree contributors
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/vendor/tracing-tree/LICENSE-MIT b/vendor/tracing-tree/LICENSE-MIT
new file mode 100644
index 000000000..d0afab4a5
--- /dev/null
+++ b/vendor/tracing-tree/LICENSE-MIT
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2021 tracing-tree contributors
+
+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/tracing-tree/README.md b/vendor/tracing-tree/README.md
new file mode 100644
index 000000000..06751d4ec
--- /dev/null
+++ b/vendor/tracing-tree/README.md
@@ -0,0 +1,38 @@
+# tracing-tree
+
+Instrument your application with [tracing](https://github.com/tokio-rs/tracing)
+and get tree-structured summaries of your application activity with timing
+information on the console:
+
+<pre>
+ <b>server</b>{host=&quot;localhost&quot;, port=8080<b>}</b>
+ 0ms <b> INFO</b> starting
+ 300ms <b> INFO</b> listening
+ <b>conn</b>{peer_addr=&quot;82.9.9.9&quot;, port=42381<b>}</b>
+ 0ms <b>DEBUG</b> connected
+ 300ms <b>DEBUG</b> message received, length=2
+ <b>conn</b>{peer_addr=&quot;8.8.8.8&quot;, port=18230<b>}</b>
+ 300ms <b>DEBUG</b> connected
+ <b>conn</b>{peer_addr=&quot;82.9.9.9&quot;, port=42381<b>}</b>
+ 600ms <b> WARN</b> weak encryption requested, algo=&quot;xor&quot;
+ 901ms <b>DEBUG</b> response sent, length=8
+ 901ms <b>DEBUG</b> disconnected
+ <b>conn</b>{peer_addr=&quot;8.8.8.8&quot;, port=18230<b>}</b>
+ 600ms <b>DEBUG</b> message received, length=5
+ 901ms <b>DEBUG</b> response sent, length=8
+ 901ms <b>DEBUG</b> disconnected
+ 1502ms <b> WARN</b> internal error
+ 1502ms <b> INFO</b> exit
+</pre>
+
+(Format inspired by [slog-term](https://github.com/slog-rs/slog#terminal-output-example))
+
+## Setup
+
+After instrumenting your app with
+[tracing](https://github.com/tokio-rs/tracing), add this subscriber like this:
+
+```rust
+let subscriber = Registry::default().with(HierarchicalLayer::new(2));
+tracing::subscriber::set_global_default(subscriber).unwrap();
+``` \ No newline at end of file
diff --git a/vendor/tracing-tree/examples/basic.rs b/vendor/tracing-tree/examples/basic.rs
new file mode 100644
index 000000000..97f6263ff
--- /dev/null
+++ b/vendor/tracing-tree/examples/basic.rs
@@ -0,0 +1,83 @@
+use tracing::{debug, error, info, instrument, span, warn, Level};
+use tracing_subscriber::{layer::SubscriberExt, registry::Registry};
+use tracing_tree::HierarchicalLayer;
+
+fn main() {
+ let layer = HierarchicalLayer::default()
+ .with_writer(std::io::stdout)
+ .with_indent_lines(true)
+ .with_indent_amount(2)
+ .with_thread_names(true)
+ .with_thread_ids(true)
+ .with_verbose_exit(true)
+ .with_verbose_entry(true)
+ .with_targets(true);
+
+ let subscriber = Registry::default().with(layer);
+ tracing::subscriber::set_global_default(subscriber).unwrap();
+ #[cfg(feature = "tracing-log")]
+ tracing_log::LogTracer::init().unwrap();
+
+ let app_span = span!(Level::TRACE, "hierarchical-example", version = %0.1);
+ let _e = app_span.enter();
+
+ let server_span = span!(Level::TRACE, "server", host = "localhost", port = 8080);
+ let _e2 = server_span.enter();
+ info!("starting");
+ std::thread::sleep(std::time::Duration::from_millis(300));
+ info!("listening");
+ let peer1 = span!(Level::TRACE, "conn", peer_addr = "82.9.9.9", port = 42381);
+ peer1.in_scope(|| {
+ debug!("connected");
+ std::thread::sleep(std::time::Duration::from_millis(300));
+ debug!(length = 2, "message received");
+ });
+ drop(peer1);
+ let peer2 = span!(Level::TRACE, "conn", peer_addr = "8.8.8.8", port = 18230);
+ peer2.in_scope(|| {
+ std::thread::sleep(std::time::Duration::from_millis(300));
+ debug!("connected");
+ });
+ drop(peer2);
+ let peer3 = span!(
+ Level::TRACE,
+ "foomp",
+ normal_var = 43,
+ "{} <- format string",
+ 42
+ );
+ peer3.in_scope(|| {
+ error!("hello");
+ });
+ drop(peer3);
+ let peer1 = span!(Level::TRACE, "conn", peer_addr = "82.9.9.9", port = 42381);
+ peer1.in_scope(|| {
+ warn!(algo = "xor", "weak encryption requested");
+ std::thread::sleep(std::time::Duration::from_millis(300));
+ debug!(length = 8, "response sent");
+ debug!("disconnected");
+ });
+ drop(peer1);
+ let peer2 = span!(Level::TRACE, "conn", peer_addr = "8.8.8.8", port = 18230);
+ peer2.in_scope(|| {
+ debug!(length = 5, "message received");
+ std::thread::sleep(std::time::Duration::from_millis(300));
+ debug!(length = 8, "response sent");
+ debug!("disconnected");
+ });
+ drop(peer2);
+ warn!("internal error");
+ log::error!("this is a log message");
+ info!("exit");
+}
+
+#[instrument]
+fn call_a(name: &str) {
+ info!(name, "got a name");
+ call_b(name)
+}
+
+#[instrument]
+fn call_b(name: &str) {
+ info!(name, "got a name");
+}
diff --git a/vendor/tracing-tree/examples/basic.stdout b/vendor/tracing-tree/examples/basic.stdout
new file mode 100644
index 000000000..4a2d83f11
--- /dev/null
+++ b/vendor/tracing-tree/examples/basic.stdout
@@ -0,0 +1,41 @@
+1:main┐basic::hierarchical-example version=0.1
+1:main├┐basic::hierarchical-example version=0.1
+1:main│└┐basic::server host="localhost", port=8080
+1:main│ ├─ms INFO basic starting
+1:main│ ├─ms INFO basic listening
+1:main│ ├┐basic::server host="localhost", port=8080
+1:main│ │└┐basic::conn peer_addr="82.9.9.9", port=42381
+1:main│ │ ├─ms DEBUG basic connected
+1:main│ │ ├─ms DEBUG basic message received, length=2
+1:main│ │┌┘basic::conn peer_addr="82.9.9.9", port=42381
+1:main│ ├┘basic::server host="localhost", port=8080
+1:main│ ├┐basic::server host="localhost", port=8080
+1:main│ │└┐basic::conn peer_addr="8.8.8.8", port=18230
+1:main│ │ ├─ms DEBUG basic connected
+1:main│ │┌┘basic::conn peer_addr="8.8.8.8", port=18230
+1:main│ ├┘basic::server host="localhost", port=8080
+1:main│ ├┐basic::server host="localhost", port=8080
+1:main│ │└┐basic::foomp 42 <- format string, normal_var=43
+1:main│ │ ├─ms ERROR basic hello
+1:main│ │┌┘basic::foomp 42 <- format string, normal_var=43
+1:main│ ├┘basic::server host="localhost", port=8080
+1:main│ ├┐basic::server host="localhost", port=8080
+1:main│ │└┐basic::conn peer_addr="82.9.9.9", port=42381
+1:main│ │ ├─ms WARN basic weak encryption requested, algo="xor"
+1:main│ │ ├─ms DEBUG basic response sent, length=8
+1:main│ │ ├─ms DEBUG basic disconnected
+1:main│ │┌┘basic::conn peer_addr="82.9.9.9", port=42381
+1:main│ ├┘basic::server host="localhost", port=8080
+1:main│ ├┐basic::server host="localhost", port=8080
+1:main│ │└┐basic::conn peer_addr="8.8.8.8", port=18230
+1:main│ │ ├─ms DEBUG basic message received, length=5
+1:main│ │ ├─ms DEBUG basic response sent, length=8
+1:main│ │ ├─ms DEBUG basic disconnected
+1:main│ │┌┘basic::conn peer_addr="8.8.8.8", port=18230
+1:main│ ├┘basic::server host="localhost", port=8080
+1:main│ ├─ms WARN basic internal error
+1:main│ ├─ms ERROR basic this is a log message
+1:main│ ├─ms INFO basic exit
+1:main│┌┘basic::server host="localhost", port=8080
+1:main├┘basic::hierarchical-example version=0.1
+1:main┘basic::hierarchical-example version=0.1
diff --git a/vendor/tracing-tree/examples/quiet.rs b/vendor/tracing-tree/examples/quiet.rs
new file mode 100644
index 000000000..81b0c9c2f
--- /dev/null
+++ b/vendor/tracing-tree/examples/quiet.rs
@@ -0,0 +1,80 @@
+use tracing::{debug, error, info, instrument, span, warn, Level};
+use tracing_subscriber::{layer::SubscriberExt, registry::Registry};
+use tracing_tree::HierarchicalLayer;
+
+fn main() {
+ let layer = HierarchicalLayer::default()
+ .with_writer(std::io::stdout)
+ .with_indent_lines(true)
+ .with_indent_amount(2)
+ .with_thread_names(true)
+ .with_thread_ids(true)
+ .with_verbose_exit(false)
+ .with_verbose_entry(false)
+ .with_targets(true);
+
+ let subscriber = Registry::default().with(layer);
+ tracing::subscriber::set_global_default(subscriber).unwrap();
+
+ let app_span = span!(Level::TRACE, "hierarchical-example", version = %0.1);
+ let _e = app_span.enter();
+
+ let server_span = span!(Level::TRACE, "server", host = "localhost", port = 8080);
+ let _e2 = server_span.enter();
+ info!("starting");
+ std::thread::sleep(std::time::Duration::from_millis(300));
+ info!("listening");
+ let peer1 = span!(Level::TRACE, "conn", peer_addr = "82.9.9.9", port = 42381);
+ peer1.in_scope(|| {
+ debug!("connected");
+ std::thread::sleep(std::time::Duration::from_millis(300));
+ debug!(length = 2, "message received");
+ });
+ drop(peer1);
+ let peer2 = span!(Level::TRACE, "conn", peer_addr = "8.8.8.8", port = 18230);
+ peer2.in_scope(|| {
+ std::thread::sleep(std::time::Duration::from_millis(300));
+ debug!("connected");
+ });
+ drop(peer2);
+ let peer3 = span!(
+ Level::TRACE,
+ "foomp",
+ normal_var = 43,
+ "{} <- format string",
+ 42
+ );
+ peer3.in_scope(|| {
+ error!("hello");
+ });
+ drop(peer3);
+ let peer1 = span!(Level::TRACE, "conn", peer_addr = "82.9.9.9", port = 42381);
+ peer1.in_scope(|| {
+ warn!(algo = "xor", "weak encryption requested");
+ std::thread::sleep(std::time::Duration::from_millis(300));
+ debug!(length = 8, "response sent");
+ debug!("disconnected");
+ });
+ drop(peer1);
+ let peer2 = span!(Level::TRACE, "conn", peer_addr = "8.8.8.8", port = 18230);
+ peer2.in_scope(|| {
+ debug!(length = 5, "message received");
+ std::thread::sleep(std::time::Duration::from_millis(300));
+ debug!(length = 8, "response sent");
+ debug!("disconnected");
+ });
+ drop(peer2);
+ warn!("internal error");
+ info!("exit");
+}
+
+#[instrument]
+fn call_a(name: &str) {
+ info!(name, "got a name");
+ call_b(name)
+}
+
+#[instrument]
+fn call_b(name: &str) {
+ info!(name, "got a name");
+}
diff --git a/vendor/tracing-tree/examples/quiet.stdout b/vendor/tracing-tree/examples/quiet.stdout
new file mode 100644
index 000000000..96589655a
--- /dev/null
+++ b/vendor/tracing-tree/examples/quiet.stdout
@@ -0,0 +1,28 @@
+1:main┐quiet::hierarchical-example version=0.1
+1:main├─┐quiet::server host="localhost", port=8080
+1:main│ ├─ms INFO quiet starting
+1:main│ ├─ms INFO quiet listening
+1:main│ ├─┐quiet::conn peer_addr="82.9.9.9", port=42381
+1:main│ │ ├─ms DEBUG quiet connected
+1:main│ │ ├─ms DEBUG quiet message received, length=2
+1:main│ ├─┘
+1:main│ ├─┐quiet::conn peer_addr="8.8.8.8", port=18230
+1:main│ │ ├─ms DEBUG quiet connected
+1:main│ ├─┘
+1:main│ ├─┐quiet::foomp 42 <- format string, normal_var=43
+1:main│ │ ├─ms ERROR quiet hello
+1:main│ ├─┘
+1:main│ ├─┐quiet::conn peer_addr="82.9.9.9", port=42381
+1:main│ │ ├─ms WARN quiet weak encryption requested, algo="xor"
+1:main│ │ ├─ms DEBUG quiet response sent, length=8
+1:main│ │ ├─ms DEBUG quiet disconnected
+1:main│ ├─┘
+1:main│ ├─┐quiet::conn peer_addr="8.8.8.8", port=18230
+1:main│ │ ├─ms DEBUG quiet message received, length=5
+1:main│ │ ├─ms DEBUG quiet response sent, length=8
+1:main│ │ ├─ms DEBUG quiet disconnected
+1:main│ ├─┘
+1:main│ ├─ms WARN quiet internal error
+1:main│ ├─ms INFO quiet exit
+1:main├─┘
+1:main┘
diff --git a/vendor/tracing-tree/examples/stderr.rs b/vendor/tracing-tree/examples/stderr.rs
new file mode 100644
index 000000000..75880a376
--- /dev/null
+++ b/vendor/tracing-tree/examples/stderr.rs
@@ -0,0 +1,40 @@
+use tracing::{debug, info, instrument};
+use tracing_subscriber::{layer::SubscriberExt, registry::Registry};
+use tracing_tree::HierarchicalLayer;
+
+#[instrument]
+fn nth_fibonacci(n: u64) -> u64 {
+ if n == 0 || n == 1 {
+ debug!("Base case");
+ 1
+ } else {
+ debug!("Recursing");
+ nth_fibonacci(n - 1) + nth_fibonacci(n - 2)
+ }
+}
+
+#[instrument]
+fn fibonacci_seq(to: u64) -> Vec<u64> {
+ let mut sequence = vec![];
+
+ for n in 0..=to {
+ debug!("Pushing {n} fibonacci", n = n);
+ sequence.push(nth_fibonacci(n));
+ }
+
+ sequence
+}
+
+fn main() {
+ let layer = HierarchicalLayer::default()
+ .with_indent_lines(true)
+ .with_indent_amount(2)
+ .with_bracketed_fields(true);
+
+ let subscriber = Registry::default().with(layer);
+ tracing::subscriber::set_global_default(subscriber).unwrap();
+
+ let n = 5;
+ let sequence = fibonacci_seq(n);
+ info!("The first {} fibonacci numbers are {:?}", n, sequence);
+}
diff --git a/vendor/tracing-tree/examples/stderr.stderr b/vendor/tracing-tree/examples/stderr.stderr
new file mode 100644
index 000000000..0060f268f
--- /dev/null
+++ b/vendor/tracing-tree/examples/stderr.stderr
@@ -0,0 +1,111 @@
+┐fibonacci_seq{to=5}
+├─ms DEBUG Pushing 0 fibonacci
+├─┐nth_fibonacci{n=0}
+│ ├─ms DEBUG Base case
+├─┘
+├─ms DEBUG Pushing 1 fibonacci
+├─┐nth_fibonacci{n=1}
+│ ├─ms DEBUG Base case
+├─┘
+├─ms DEBUG Pushing 2 fibonacci
+├─┐nth_fibonacci{n=2}
+│ ├─ms DEBUG Recursing
+│ ├─┐nth_fibonacci{n=1}
+│ │ ├─ms DEBUG Base case
+│ ├─┘
+│ ├─┐nth_fibonacci{n=0}
+│ │ ├─ms DEBUG Base case
+│ ├─┘
+├─┘
+├─ms DEBUG Pushing 3 fibonacci
+├─┐nth_fibonacci{n=3}
+│ ├─ms DEBUG Recursing
+│ ├─┐nth_fibonacci{n=2}
+│ │ ├─ms DEBUG Recursing
+│ │ ├─┐nth_fibonacci{n=1}
+│ │ │ ├─ms DEBUG Base case
+│ │ ├─┘
+│ │ ├─┐nth_fibonacci{n=0}
+│ │ │ ├─ms DEBUG Base case
+│ │ ├─┘
+│ ├─┘
+│ ├─┐nth_fibonacci{n=1}
+│ │ ├─ms DEBUG Base case
+│ ├─┘
+├─┘
+├─ms DEBUG Pushing 4 fibonacci
+├─┐nth_fibonacci{n=4}
+│ ├─ms DEBUG Recursing
+│ ├─┐nth_fibonacci{n=3}
+│ │ ├─ms DEBUG Recursing
+│ │ ├─┐nth_fibonacci{n=2}
+│ │ │ ├─ms DEBUG Recursing
+│ │ │ ├─┐nth_fibonacci{n=1}
+│ │ │ │ ├─ms DEBUG Base case
+│ │ │ ├─┘
+│ │ │ ├─┐nth_fibonacci{n=0}
+│ │ │ │ ├─ms DEBUG Base case
+│ │ │ ├─┘
+│ │ ├─┘
+│ │ ├─┐nth_fibonacci{n=1}
+│ │ │ ├─ms DEBUG Base case
+│ │ ├─┘
+│ ├─┘
+│ ├─┐nth_fibonacci{n=2}
+│ │ ├─ms DEBUG Recursing
+│ │ ├─┐nth_fibonacci{n=1}
+│ │ │ ├─ms DEBUG Base case
+│ │ ├─┘
+│ │ ├─┐nth_fibonacci{n=0}
+│ │ │ ├─ms DEBUG Base case
+│ │ ├─┘
+│ ├─┘
+├─┘
+├─ms DEBUG Pushing 5 fibonacci
+├─┐nth_fibonacci{n=5}
+│ ├─ms DEBUG Recursing
+│ ├─┐nth_fibonacci{n=4}
+│ │ ├─ms DEBUG Recursing
+│ │ ├─┐nth_fibonacci{n=3}
+│ │ │ ├─ms DEBUG Recursing
+│ │ │ ├─┐nth_fibonacci{n=2}
+│ │ │ │ ├─ms DEBUG Recursing
+│ │ │ │ ├─┐nth_fibonacci{n=1}
+│ │ │ │ │ ├─ms DEBUG Base case
+│ │ │ │ ├─┘
+│ │ │ │ ├─┐nth_fibonacci{n=0}
+│ │ │ │ │ ├─ms DEBUG Base case
+│ │ │ │ ├─┘
+│ │ │ ├─┘
+│ │ │ ├─┐nth_fibonacci{n=1}
+│ │ │ │ ├─ms DEBUG Base case
+│ │ │ ├─┘
+│ │ ├─┘
+│ │ ├─┐nth_fibonacci{n=2}
+│ │ │ ├─ms DEBUG Recursing
+│ │ │ ├─┐nth_fibonacci{n=1}
+│ │ │ │ ├─ms DEBUG Base case
+│ │ │ ├─┘
+│ │ │ ├─┐nth_fibonacci{n=0}
+│ │ │ │ ├─ms DEBUG Base case
+│ │ │ ├─┘
+│ │ ├─┘
+│ ├─┘
+│ ├─┐nth_fibonacci{n=3}
+│ │ ├─ms DEBUG Recursing
+│ │ ├─┐nth_fibonacci{n=2}
+│ │ │ ├─ms DEBUG Recursing
+│ │ │ ├─┐nth_fibonacci{n=1}
+│ │ │ │ ├─ms DEBUG Base case
+│ │ │ ├─┘
+│ │ │ ├─┐nth_fibonacci{n=0}
+│ │ │ │ ├─ms DEBUG Base case
+│ │ │ ├─┘
+│ │ ├─┘
+│ │ ├─┐nth_fibonacci{n=1}
+│ │ │ ├─ms DEBUG Base case
+│ │ ├─┘
+│ ├─┘
+├─┘
+┘
+INFO The first 5 fibonacci numbers are [1, 1, 2, 3, 5, 8]
diff --git a/vendor/tracing-tree/examples/wraparound.rs b/vendor/tracing-tree/examples/wraparound.rs
new file mode 100644
index 000000000..e045eb9f2
--- /dev/null
+++ b/vendor/tracing-tree/examples/wraparound.rs
@@ -0,0 +1,31 @@
+use tracing::{instrument, warn};
+use tracing_subscriber::{layer::SubscriberExt, registry::Registry};
+use tracing_tree::HierarchicalLayer;
+
+fn main() {
+ let layer = HierarchicalLayer::default()
+ .with_writer(std::io::stdout)
+ .with_indent_lines(true)
+ .with_indent_amount(2)
+ .with_thread_names(true)
+ .with_thread_ids(true)
+ .with_targets(true)
+ .with_wraparound(5);
+
+ let subscriber = Registry::default().with(layer);
+ tracing::subscriber::set_global_default(subscriber).unwrap();
+
+ recurse(0);
+}
+
+#[instrument]
+fn recurse(i: usize) {
+ warn!("boop");
+ if i > 20 {
+ warn!("bop");
+ return;
+ } else {
+ recurse(i + 1);
+ }
+ warn!("bop");
+}
diff --git a/vendor/tracing-tree/examples/wraparound.stdout b/vendor/tracing-tree/examples/wraparound.stdout
new file mode 100644
index 000000000..bbf422545
--- /dev/null
+++ b/vendor/tracing-tree/examples/wraparound.stdout
@@ -0,0 +1,96 @@
+1:main┐wraparound::recurse i=0
+1:main├─ms WARN wraparound boop
+1:main├─┐wraparound::recurse i=1
+1:main│ ├─ms WARN wraparound boop
+1:main│ ├─┐wraparound::recurse i=2
+1:main│ │ ├─ms WARN wraparound boop
+1:main│ │ ├─┐wraparound::recurse i=3
+1:main│ │ │ ├─ms WARN wraparound boop
+1:main│ │ │ ├─┐wraparound::recurse i=4
+1:main────────┘
+1:mainms WARN wraparound boop
+1:main┐wraparound::recurse i=5
+1:main├─ms WARN wraparound boop
+1:main├─┐wraparound::recurse i=6
+1:main│ ├─ms WARN wraparound boop
+1:main│ ├─┐wraparound::recurse i=7
+1:main│ │ ├─ms WARN wraparound boop
+1:main│ │ ├─┐wraparound::recurse i=8
+1:main│ │ │ ├─ms WARN wraparound boop
+1:main│ │ │ ├─┐wraparound::recurse i=9
+1:main────────┘
+1:mainms WARN wraparound boop
+1:main┐wraparound::recurse i=10
+1:main├─ms WARN wraparound boop
+1:main├─┐wraparound::recurse i=11
+1:main│ ├─ms WARN wraparound boop
+1:main│ ├─┐wraparound::recurse i=12
+1:main│ │ ├─ms WARN wraparound boop
+1:main│ │ ├─┐wraparound::recurse i=13
+1:main│ │ │ ├─ms WARN wraparound boop
+1:main│ │ │ ├─┐wraparound::recurse i=14
+1:main────────┘
+1:mainms WARN wraparound boop
+1:main┐wraparound::recurse i=15
+1:main├─ms WARN wraparound boop
+1:main├─┐wraparound::recurse i=16
+1:main│ ├─ms WARN wraparound boop
+1:main│ ├─┐wraparound::recurse i=17
+1:main│ │ ├─ms WARN wraparound boop
+1:main│ │ ├─┐wraparound::recurse i=18
+1:main│ │ │ ├─ms WARN wraparound boop
+1:main│ │ │ ├─┐wraparound::recurse i=19
+1:main────────┘
+1:mainms WARN wraparound boop
+1:main┐wraparound::recurse i=20
+1:main├─ms WARN wraparound boop
+1:main├─┐wraparound::recurse i=21
+1:main│ ├─ms WARN wraparound boop
+1:main│ ├─ms WARN wraparound bop
+1:main├─┘
+1:main├─ms WARN wraparound bop
+1:main┘
+1:mainms WARN wraparound bop
+1:main────────┐
+1:main│ │ │ ├─┘
+1:main│ │ │ ├─ms WARN wraparound bop
+1:main│ │ ├─┘
+1:main│ │ ├─ms WARN wraparound bop
+1:main│ ├─┘
+1:main│ ├─ms WARN wraparound bop
+1:main├─┘
+1:main├─ms WARN wraparound bop
+1:main┘
+1:mainms WARN wraparound bop
+1:main────────┐
+1:main│ │ │ ├─┘
+1:main│ │ │ ├─ms WARN wraparound bop
+1:main│ │ ├─┘
+1:main│ │ ├─ms WARN wraparound bop
+1:main│ ├─┘
+1:main│ ├─ms WARN wraparound bop
+1:main├─┘
+1:main├─ms WARN wraparound bop
+1:main┘
+1:mainms WARN wraparound bop
+1:main────────┐
+1:main│ │ │ ├─┘
+1:main│ │ │ ├─ms WARN wraparound bop
+1:main│ │ ├─┘
+1:main│ │ ├─ms WARN wraparound bop
+1:main│ ├─┘
+1:main│ ├─ms WARN wraparound bop
+1:main├─┘
+1:main├─ms WARN wraparound bop
+1:main┘
+1:mainms WARN wraparound bop
+1:main────────┐
+1:main│ │ │ ├─┘
+1:main│ │ │ ├─ms WARN wraparound bop
+1:main│ │ ├─┘
+1:main│ │ ├─ms WARN wraparound bop
+1:main│ ├─┘
+1:main│ ├─ms WARN wraparound bop
+1:main├─┘
+1:main├─ms WARN wraparound bop
+1:main┘
diff --git a/vendor/tracing-tree/src/format.rs b/vendor/tracing-tree/src/format.rs
new file mode 100644
index 000000000..067ea9771
--- /dev/null
+++ b/vendor/tracing-tree/src/format.rs
@@ -0,0 +1,425 @@
+use ansi_term::Color;
+use std::{
+ fmt::{self, Write as _},
+ io,
+};
+use tracing_core::{
+ field::{Field, Visit},
+ Level,
+};
+
+pub(crate) const LINE_VERT: &str = "│";
+const LINE_HORIZ: &str = "─";
+pub(crate) const LINE_BRANCH: &str = "├";
+pub(crate) const LINE_CLOSE: &str = "┘";
+pub(crate) const LINE_OPEN: &str = "┐";
+
+#[derive(Copy, Clone)]
+pub(crate) enum SpanMode {
+ PreOpen,
+ Open { verbose: bool },
+ Close { verbose: bool },
+ PostClose,
+ Event,
+}
+
+#[derive(Debug)]
+pub struct Config {
+ /// Whether to use colors.
+ pub ansi: bool,
+ /// Whether an ascii art tree is used or (if false) whether to just use whitespace indent
+ pub indent_lines: bool,
+ /// The amount of chars to indent.
+ pub indent_amount: usize,
+ /// Whether to show the module paths.
+ pub targets: bool,
+ /// Whether to show thread ids.
+ pub render_thread_ids: bool,
+ /// Whether to show thread names.
+ pub render_thread_names: bool,
+ /// Specifies after how many indentation levels we will wrap back around to zero
+ pub wraparound: usize,
+ /// Whether to print the current span before activating a new one
+ pub verbose_entry: bool,
+ /// Whether to print the current span before exiting it.
+ pub verbose_exit: bool,
+ /// Whether to print squiggly brackets (`{}`) around the list of fields in a span.
+ pub bracketed_fields: bool,
+}
+
+impl Config {
+ pub fn with_ansi(self, ansi: bool) -> Self {
+ Self { ansi, ..self }
+ }
+
+ pub fn with_indent_lines(self, indent_lines: bool) -> Self {
+ Self {
+ indent_lines,
+ ..self
+ }
+ }
+
+ pub fn with_targets(self, targets: bool) -> Self {
+ Self { targets, ..self }
+ }
+
+ pub fn with_thread_ids(self, render_thread_ids: bool) -> Self {
+ Self {
+ render_thread_ids,
+ ..self
+ }
+ }
+
+ pub fn with_thread_names(self, render_thread_names: bool) -> Self {
+ Self {
+ render_thread_names,
+ ..self
+ }
+ }
+
+ pub fn with_wraparound(self, wraparound: usize) -> Self {
+ Self { wraparound, ..self }
+ }
+
+ pub fn with_verbose_entry(self, verbose_entry: bool) -> Self {
+ Self {
+ verbose_entry,
+ ..self
+ }
+ }
+
+ pub fn with_verbose_exit(self, verbose_exit: bool) -> Self {
+ Self {
+ verbose_exit,
+ ..self
+ }
+ }
+
+ pub fn with_bracketed_fields(self, bracketed_fields: bool) -> Self {
+ Self {
+ bracketed_fields,
+ ..self
+ }
+ }
+
+ pub(crate) fn prefix(&self) -> String {
+ let mut buf = String::new();
+ if self.render_thread_ids {
+ write!(buf, "{:?}", std::thread::current().id()).unwrap();
+ if buf.ends_with(')') {
+ buf.truncate(buf.len() - 1);
+ }
+ if buf.starts_with("ThreadId(") {
+ buf.drain(0.."ThreadId(".len());
+ }
+ }
+ if self.render_thread_names {
+ if let Some(name) = std::thread::current().name() {
+ if self.render_thread_ids {
+ buf.push(':');
+ }
+ buf.push_str(name);
+ }
+ }
+ buf
+ }
+}
+
+impl Default for Config {
+ fn default() -> Self {
+ Self {
+ ansi: true,
+ indent_lines: false,
+ indent_amount: 2,
+ targets: false,
+ render_thread_ids: false,
+ render_thread_names: false,
+ wraparound: usize::max_value(),
+ verbose_entry: false,
+ verbose_exit: false,
+ bracketed_fields: false,
+ }
+ }
+}
+
+#[derive(Debug)]
+pub struct Buffers {
+ pub current_buf: String,
+ pub indent_buf: String,
+}
+
+impl Buffers {
+ pub fn new() -> Self {
+ Self {
+ current_buf: String::new(),
+ indent_buf: String::new(),
+ }
+ }
+
+ pub fn flush_current_buf(&mut self, mut writer: impl io::Write) {
+ write!(writer, "{}", &self.current_buf).unwrap();
+ self.current_buf.clear();
+ }
+
+ pub fn flush_indent_buf(&mut self) {
+ self.current_buf.push_str(&self.indent_buf);
+ self.indent_buf.clear();
+ }
+
+ pub(crate) fn indent_current(&mut self, indent: usize, config: &Config, style: SpanMode) {
+ self.current_buf.push('\n');
+ let prefix = config.prefix();
+
+ // Render something when wraparound occurs so the user is aware of it
+ if config.indent_lines {
+ match style {
+ SpanMode::Close { .. } | SpanMode::PostClose => {
+ if indent > 0 && (indent + 1) % config.wraparound == 0 {
+ self.indent_buf.push_str(&prefix);
+ for _ in 0..(indent % config.wraparound * config.indent_amount) {
+ self.indent_buf.push_str(LINE_HORIZ);
+ }
+ self.indent_buf.push_str(LINE_OPEN);
+ self.indent_buf.push('\n');
+ }
+ }
+ _ => {}
+ }
+ }
+
+ indent_block(
+ &mut self.current_buf,
+ &mut self.indent_buf,
+ indent % config.wraparound,
+ config.indent_amount,
+ config.indent_lines,
+ &prefix,
+ style,
+ );
+ self.current_buf.clear();
+ self.flush_indent_buf();
+
+ // Render something when wraparound occurs so the user is aware of it
+ if config.indent_lines {
+ match style {
+ SpanMode::PreOpen | SpanMode::Open { .. } => {
+ if indent > 0 && (indent + 1) % config.wraparound == 0 {
+ self.current_buf.push_str(&prefix);
+ for _ in 0..(indent % config.wraparound * config.indent_amount) {
+ self.current_buf.push_str(LINE_HORIZ);
+ }
+ self.current_buf.push_str(LINE_CLOSE);
+ self.current_buf.push('\n');
+ }
+ }
+ _ => {}
+ }
+ }
+ }
+}
+
+pub struct FmtEvent<'a> {
+ pub bufs: &'a mut Buffers,
+ pub comma: bool,
+}
+
+impl<'a> Visit for FmtEvent<'a> {
+ fn record_debug(&mut self, field: &Field, value: &dyn fmt::Debug) {
+ let buf = &mut self.bufs.current_buf;
+ let comma = if self.comma { "," } else { "" };
+ match field.name() {
+ "message" => {
+ write!(buf, "{} {:?}", comma, value).unwrap();
+ self.comma = true;
+ }
+ // Skip fields that are actually log metadata that have already been handled
+ #[cfg(feature = "tracing-log")]
+ name if name.starts_with("log.") => {}
+ name => {
+ write!(buf, "{} {}={:?}", comma, name, value).unwrap();
+ self.comma = true;
+ }
+ }
+ }
+}
+
+pub struct ColorLevel<'a>(pub &'a Level);
+
+impl<'a> fmt::Display for ColorLevel<'a> {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ match *self.0 {
+ Level::TRACE => Color::Purple.bold().paint("TRACE"),
+ Level::DEBUG => Color::Blue.bold().paint("DEBUG"),
+ Level::INFO => Color::Green.bold().paint(" INFO"),
+ Level::WARN => Color::RGB(252, 234, 160).bold().paint(" WARN"), // orange
+ Level::ERROR => Color::Red.bold().paint("ERROR"),
+ }
+ .fmt(f)
+ }
+}
+
+fn indent_block_with_lines(
+ lines: &[&str],
+ buf: &mut String,
+ indent: usize,
+ indent_amount: usize,
+ prefix: &str,
+ style: SpanMode,
+) {
+ let indent_spaces = indent * indent_amount;
+ if lines.is_empty() {
+ return;
+ } else if indent_spaces == 0 {
+ for line in lines {
+ buf.push_str(prefix);
+ // The first indent is special, we only need to print open/close and nothing else
+ if indent == 0 {
+ match style {
+ SpanMode::Open { .. } => buf.push_str(LINE_OPEN),
+ SpanMode::Close { .. } => buf.push_str(LINE_CLOSE),
+ SpanMode::PreOpen | SpanMode::PostClose => {}
+ SpanMode::Event => {}
+ }
+ }
+ buf.push_str(line);
+ buf.push('\n');
+ }
+ return;
+ }
+ let mut s = String::with_capacity(indent_spaces + prefix.len());
+ s.push_str(prefix);
+
+ // instead of using all spaces to indent, draw a vertical line at every indent level
+ // up until the last indent
+ for i in 0..(indent_spaces - indent_amount) {
+ if i % indent_amount == 0 {
+ s.push_str(LINE_VERT);
+ } else {
+ s.push(' ');
+ }
+ }
+
+ // draw branch
+ buf.push_str(&s);
+
+ match style {
+ SpanMode::PreOpen => {
+ buf.push_str(LINE_BRANCH);
+ for _ in 1..(indent_amount / 2) {
+ buf.push_str(LINE_HORIZ);
+ }
+ buf.push_str(LINE_OPEN);
+ }
+ SpanMode::Open { verbose: false } => {
+ buf.push_str(LINE_BRANCH);
+ for _ in 1..indent_amount {
+ buf.push_str(LINE_HORIZ);
+ }
+ buf.push_str(LINE_OPEN);
+ }
+ SpanMode::Open { verbose: true } => {
+ buf.push_str(LINE_VERT);
+ for _ in 1..(indent_amount / 2) {
+ buf.push(' ');
+ }
+ // We don't have the space for fancy rendering at single space indent.
+ if indent_amount > 1 {
+ buf.push('└');
+ }
+ for _ in (indent_amount / 2)..(indent_amount - 1) {
+ buf.push_str(LINE_HORIZ);
+ }
+ // We don't have the space for fancy rendering at single space indent.
+ if indent_amount > 1 {
+ buf.push_str(LINE_OPEN);
+ } else {
+ buf.push_str(LINE_VERT);
+ }
+ }
+ SpanMode::Close { verbose: false } => {
+ buf.push_str(LINE_BRANCH);
+ for _ in 1..indent_amount {
+ buf.push_str(LINE_HORIZ);
+ }
+ buf.push_str(LINE_CLOSE);
+ }
+ SpanMode::Close { verbose: true } => {
+ buf.push_str(LINE_VERT);
+ for _ in 1..(indent_amount / 2) {
+ buf.push(' ');
+ }
+ // We don't have the space for fancy rendering at single space indent.
+ if indent_amount > 1 {
+ buf.push('┌');
+ }
+ for _ in (indent_amount / 2)..(indent_amount - 1) {
+ buf.push_str(LINE_HORIZ);
+ }
+ // We don't have the space for fancy rendering at single space indent.
+ if indent_amount > 1 {
+ buf.push_str(LINE_CLOSE);
+ } else {
+ buf.push_str(LINE_VERT);
+ }
+ }
+ SpanMode::PostClose => {
+ buf.push_str(LINE_BRANCH);
+ for _ in 1..(indent_amount / 2) {
+ buf.push_str(LINE_HORIZ);
+ }
+ buf.push_str(LINE_CLOSE);
+ }
+ SpanMode::Event => {
+ buf.push_str(LINE_BRANCH);
+
+ // add `indent_amount - 1` horizontal lines before the span/event
+ for _ in 0..(indent_amount - 1) {
+ buf.push_str(LINE_HORIZ);
+ }
+ }
+ }
+ buf.push_str(lines[0]);
+ buf.push('\n');
+
+ // add the rest of the indentation, since we don't want to draw horizontal lines
+ // for subsequent lines
+ for i in 0..indent_amount {
+ if i % indent_amount == 0 {
+ s.push_str(LINE_VERT);
+ } else {
+ s.push(' ');
+ }
+ }
+
+ // add all of the actual content, with each line preceded by the indent string
+ for line in &lines[1..] {
+ buf.push_str(&s);
+ buf.push_str(line);
+ buf.push('\n');
+ }
+}
+
+fn indent_block(
+ block: &mut String,
+ buf: &mut String,
+ indent: usize,
+ indent_amount: usize,
+ indent_lines: bool,
+ prefix: &str,
+ style: SpanMode,
+) {
+ let lines: Vec<&str> = block.lines().collect();
+ let indent_spaces = indent * indent_amount;
+ buf.reserve(block.len() + (lines.len() * indent_spaces));
+ if indent_lines {
+ indent_block_with_lines(&lines, buf, indent, indent_amount, prefix, style);
+ } else {
+ let indent_str = String::from(" ").repeat(indent_spaces);
+ for line in lines {
+ buf.push_str(prefix);
+ buf.push_str(&indent_str);
+ buf.push_str(line);
+ buf.push('\n');
+ }
+ }
+}
diff --git a/vendor/tracing-tree/src/lib.rs b/vendor/tracing-tree/src/lib.rs
new file mode 100644
index 000000000..dbacaa57e
--- /dev/null
+++ b/vendor/tracing-tree/src/lib.rs
@@ -0,0 +1,395 @@
+pub(crate) mod format;
+
+use ansi_term::{Color, Style};
+use format::{Buffers, ColorLevel, Config, FmtEvent, SpanMode};
+use std::{
+ fmt::{self, Write as _},
+ io,
+ sync::Mutex,
+ time::Instant,
+};
+use tracing_core::{
+ field::{Field, Visit},
+ span::{Attributes, Id},
+ Event, Subscriber,
+};
+#[cfg(feature = "tracing-log")]
+use tracing_log::NormalizeEvent;
+use tracing_subscriber::{
+ fmt::MakeWriter,
+ layer::{Context, Layer},
+ registry::{self, LookupSpan},
+};
+
+pub(crate) struct Data {
+ start: Instant,
+ kvs: Vec<(&'static str, String)>,
+}
+
+impl Data {
+ pub fn new(attrs: &Attributes<'_>) -> Self {
+ let mut span = Self {
+ start: Instant::now(),
+ kvs: Vec::new(),
+ };
+ attrs.record(&mut span);
+ span
+ }
+}
+
+impl Visit for Data {
+ fn record_debug(&mut self, field: &Field, value: &dyn fmt::Debug) {
+ self.kvs.push((field.name(), format!("{:?}", value)))
+ }
+}
+#[derive(Debug)]
+pub struct HierarchicalLayer<W = fn() -> io::Stderr>
+where
+ W: for<'writer> MakeWriter<'writer> + 'static,
+{
+ make_writer: W,
+ bufs: Mutex<Buffers>,
+ config: Config,
+}
+
+impl Default for HierarchicalLayer {
+ fn default() -> Self {
+ Self::new(2)
+ }
+}
+
+impl HierarchicalLayer<fn() -> io::Stderr> {
+ pub fn new(indent_amount: usize) -> Self {
+ let ansi = atty::is(atty::Stream::Stderr);
+ let config = Config {
+ ansi,
+ indent_amount,
+ ..Default::default()
+ };
+ Self {
+ make_writer: io::stderr,
+ bufs: Mutex::new(Buffers::new()),
+ config,
+ }
+ }
+}
+
+impl<W> HierarchicalLayer<W>
+where
+ W: for<'writer> MakeWriter<'writer> + 'static,
+{
+ /// Enables terminal colors, boldness and italics.
+ pub fn with_ansi(self, ansi: bool) -> Self {
+ Self {
+ config: self.config.with_ansi(ansi),
+ ..self
+ }
+ }
+
+ pub fn with_writer<W2>(self, make_writer: W2) -> HierarchicalLayer<W2>
+ where
+ W2: for<'writer> MakeWriter<'writer>,
+ {
+ HierarchicalLayer {
+ make_writer,
+ config: self.config,
+ bufs: self.bufs,
+ }
+ }
+
+ pub fn with_indent_amount(self, indent_amount: usize) -> Self {
+ let config = Config {
+ indent_amount,
+ ..self.config
+ };
+ Self { config, ..self }
+ }
+
+ /// Renders an ascii art tree instead of just using whitespace indentation.
+ pub fn with_indent_lines(self, indent_lines: bool) -> Self {
+ Self {
+ config: self.config.with_indent_lines(indent_lines),
+ ..self
+ }
+ }
+
+ /// Whether to render the event and span targets. Usually targets are the module path to the
+ /// event/span macro invocation.
+ pub fn with_targets(self, targets: bool) -> Self {
+ Self {
+ config: self.config.with_targets(targets),
+ ..self
+ }
+ }
+
+ /// Whether to render the thread id in the beginning of every line. This is helpful to
+ /// untangle the tracing statements emitted by each thread.
+ pub fn with_thread_ids(self, thread_ids: bool) -> Self {
+ Self {
+ config: self.config.with_thread_ids(thread_ids),
+ ..self
+ }
+ }
+
+ /// Whether to render the thread name in the beginning of every line. Not all threads have
+ /// names, but if they do, this may be more helpful than the generic thread ids.
+ pub fn with_thread_names(self, thread_names: bool) -> Self {
+ Self {
+ config: self.config.with_thread_names(thread_names),
+ ..self
+ }
+ }
+
+ /// Resets the indentation to zero after `wraparound` indentation levels.
+ /// This is helpful if you expect very deeply nested spans as otherwise the indentation
+ /// just runs out of your screen.
+ pub fn with_wraparound(self, wraparound: usize) -> Self {
+ Self {
+ config: self.config.with_wraparound(wraparound),
+ ..self
+ }
+ }
+
+ /// Whether to print the currently active span's message again before entering a new span.
+ /// This helps if the entry to the current span was quite a while back (and with scrolling
+ /// upwards in logs).
+ pub fn with_verbose_entry(self, verbose_entry: bool) -> Self {
+ Self {
+ config: self.config.with_verbose_entry(verbose_entry),
+ ..self
+ }
+ }
+
+ /// Whether to print the currently active span's message again before dropping it.
+ /// This helps if the entry to the current span was quite a while back (and with scrolling
+ /// upwards in logs).
+ pub fn with_verbose_exit(self, verbose_exit: bool) -> Self {
+ Self {
+ config: self.config.with_verbose_exit(verbose_exit),
+ ..self
+ }
+ }
+
+ /// Whether to print `{}` around the fields when printing a span.
+ /// This can help visually distinguish fields from the rest of the message.
+ pub fn with_bracketed_fields(self, bracketed_fields: bool) -> Self {
+ Self {
+ config: self.config.with_bracketed_fields(bracketed_fields),
+ ..self
+ }
+ }
+
+ fn styled(&self, style: Style, text: impl AsRef<str>) -> String {
+ if self.config.ansi {
+ style.paint(text.as_ref()).to_string()
+ } else {
+ text.as_ref().to_string()
+ }
+ }
+
+ fn print_kvs<'a, I, V>(&self, buf: &mut impl fmt::Write, kvs: I) -> fmt::Result
+ where
+ I: IntoIterator<Item = (&'a str, V)>,
+ V: fmt::Display + 'a,
+ {
+ let mut kvs = kvs.into_iter();
+ if let Some((k, v)) = kvs.next() {
+ if k == "message" {
+ write!(buf, "{}", v)?;
+ } else {
+ write!(buf, "{}={}", k, v)?;
+ }
+ }
+ for (k, v) in kvs {
+ write!(buf, ", {}={}", k, v)?;
+ }
+ Ok(())
+ }
+
+ fn write_span_info<S>(&self, id: &Id, ctx: &Context<S>, style: SpanMode)
+ where
+ S: Subscriber + for<'span> LookupSpan<'span>,
+ {
+ let span = ctx
+ .span(id)
+ .expect("in on_enter/on_exit but span does not exist");
+ let ext = span.extensions();
+ let data = ext.get::<Data>().expect("span does not have data");
+
+ let mut guard = self.bufs.lock().unwrap();
+ let bufs = &mut *guard;
+ let mut current_buf = &mut bufs.current_buf;
+
+ let indent = ctx
+ .lookup_current()
+ .as_ref()
+ .map(registry::SpanRef::scope)
+ .map(registry::Scope::from_root)
+ .into_iter()
+ .flatten()
+ .count();
+
+ if self.config.verbose_entry || matches!(style, SpanMode::Open { .. } | SpanMode::Event) {
+ if self.config.targets {
+ let target = span.metadata().target();
+ write!(
+ &mut current_buf,
+ "{}::",
+ self.styled(Style::new().dimmed(), target,),
+ )
+ .expect("Unable to write to buffer");
+ }
+
+ write!(
+ current_buf,
+ "{name}",
+ name = self.styled(Style::new().fg(Color::Green).bold(), span.metadata().name())
+ )
+ .unwrap();
+ if self.config.bracketed_fields {
+ write!(
+ current_buf,
+ "{}",
+ self.styled(Style::new().fg(Color::Green).bold(), "{") // Style::new().fg(Color::Green).dimmed().paint("{")
+ )
+ .unwrap();
+ } else {
+ write!(current_buf, " ").unwrap();
+ }
+ self.print_kvs(&mut current_buf, data.kvs.iter().map(|(k, v)| (*k, v)))
+ .unwrap();
+ if self.config.bracketed_fields {
+ write!(
+ current_buf,
+ "{}",
+ self.styled(Style::new().fg(Color::Green).bold(), "}") // Style::new().dimmed().paint("}")
+ )
+ .unwrap();
+ }
+ }
+
+ bufs.indent_current(indent, &self.config, style);
+ let writer = self.make_writer.make_writer();
+ bufs.flush_current_buf(writer)
+ }
+}
+
+impl<S, W> Layer<S> for HierarchicalLayer<W>
+where
+ S: Subscriber + for<'span> LookupSpan<'span>,
+ W: for<'writer> MakeWriter<'writer> + 'static,
+{
+ fn on_new_span(&self, attrs: &Attributes, id: &Id, ctx: Context<S>) {
+ let span = ctx.span(id).expect("in new_span but span does not exist");
+ if span.extensions().get::<Data>().is_none() {
+ let data = Data::new(attrs);
+ span.extensions_mut().insert(data);
+ }
+
+ if self.config.verbose_exit {
+ if let Some(span) = span.parent() {
+ self.write_span_info(&span.id(), &ctx, SpanMode::PreOpen);
+ }
+ }
+
+ self.write_span_info(
+ id,
+ &ctx,
+ SpanMode::Open {
+ verbose: self.config.verbose_entry,
+ },
+ );
+ }
+
+ fn on_event(&self, event: &Event<'_>, ctx: Context<S>) {
+ let mut guard = self.bufs.lock().unwrap();
+ let bufs = &mut *guard;
+ let mut event_buf = &mut bufs.current_buf;
+
+ // printing the indentation
+ let indent = if ctx.current_span().id().is_some() {
+ // size hint isn't implemented on Scope.
+ ctx.event_scope(event)
+ .expect("Unable to get span scope; this is a bug")
+ .count()
+ } else {
+ 0
+ };
+
+ // check if this event occurred in the context of a span.
+ // if it has, get the start time of this span.
+ let start = match ctx.current_span().id() {
+ Some(id) => match ctx.span(id) {
+ // if the event is in a span, get the span's starting point.
+ Some(ctx) => {
+ let ext = ctx.extensions();
+ let data = ext
+ .get::<Data>()
+ .expect("Data cannot be found in extensions");
+ Some(data.start)
+ }
+ None => None,
+ },
+ None => None,
+ };
+ if let Some(start) = start {
+ let elapsed = start.elapsed();
+ write!(
+ &mut event_buf,
+ "{timestamp}{unit} ",
+ timestamp = self.styled(Style::new().dimmed(), elapsed.as_millis().to_string()),
+ unit = self.styled(Style::new().dimmed(), "ms"),
+ )
+ .expect("Unable to write to buffer");
+ }
+
+ #[cfg(feature = "tracing-log")]
+ let normalized_meta = event.normalized_metadata();
+ #[cfg(feature = "tracing-log")]
+ let metadata = normalized_meta.as_ref().unwrap_or_else(|| event.metadata());
+ #[cfg(not(feature = "tracing-log"))]
+ let metadata = event.metadata();
+
+ let level = metadata.level();
+ let level = if self.config.ansi {
+ ColorLevel(level).to_string()
+ } else {
+ level.to_string()
+ };
+ write!(&mut event_buf, "{level}", level = level).expect("Unable to write to buffer");
+
+ if self.config.targets {
+ let target = metadata.target();
+ write!(
+ &mut event_buf,
+ " {}",
+ self.styled(Style::new().dimmed(), target,),
+ )
+ .expect("Unable to write to buffer");
+ }
+
+ let mut visitor = FmtEvent { comma: false, bufs };
+ event.record(&mut visitor);
+ visitor
+ .bufs
+ .indent_current(indent, &self.config, SpanMode::Event);
+ let writer = self.make_writer.make_writer();
+ bufs.flush_current_buf(writer)
+ }
+
+ fn on_close(&self, id: Id, ctx: Context<S>) {
+ self.write_span_info(
+ &id,
+ &ctx,
+ SpanMode::Close {
+ verbose: self.config.verbose_exit,
+ },
+ );
+
+ if self.config.verbose_exit {
+ if let Some(span) = ctx.span(&id).and_then(|span| span.parent()) {
+ self.write_span_info(&span.id(), &ctx, SpanMode::PostClose);
+ }
+ }
+ }
+}
diff --git a/vendor/tracing-tree/tests/ui.rs b/vendor/tracing-tree/tests/ui.rs
new file mode 100644
index 000000000..68c54e66e
--- /dev/null
+++ b/vendor/tracing-tree/tests/ui.rs
@@ -0,0 +1,79 @@
+use assert_cmd::prelude::*;
+
+use std::process::Command;
+
+// Timings are flaky, so tests would spuriously fail.
+// Thus we replace all `/([0-9]+)ms/` with underscores
+fn replace_ms(data: &[u8]) -> Vec<u8> {
+ let mut skip = false;
+ let mut seen_s = false;
+ let mut v: Vec<u8> = data
+ .iter()
+ .rev()
+ .filter_map(|&b| match (b, skip, seen_s) {
+ (b'0'..=b'9', true, _) => None,
+ (_, true, _) => {
+ skip = false;
+ Some(b)
+ }
+ (b's', _, _) => {
+ seen_s = true;
+ Some(b)
+ }
+ (b'm', _, true) => {
+ seen_s = false;
+ skip = true;
+ Some(b)
+ }
+ _ => Some(b),
+ })
+ .collect();
+ v.reverse();
+ v
+}
+
+fn main() {
+ for entry in glob::glob("examples/*.rs").expect("Failed to read glob pattern") {
+ let entry = entry.unwrap();
+ let mut cmd = Command::cargo_bin(entry.with_extension("").to_str().unwrap()).unwrap();
+ let output = cmd.unwrap();
+ let stderr = entry.with_extension("stderr");
+ let stdout = entry.with_extension("stdout");
+
+ if std::env::args().any(|arg| arg == "--bless") {
+ if output.stderr.is_empty() {
+ let _ = std::fs::remove_file(stderr);
+ } else {
+ std::fs::write(stderr, replace_ms(&output.stderr)).unwrap();
+ }
+ if output.stdout.is_empty() {
+ let _ = std::fs::remove_file(stdout);
+ } else {
+ std::fs::write(stdout, replace_ms(&output.stdout)).unwrap();
+ }
+ } else {
+ if output.stderr.is_empty() {
+ assert!(
+ !stderr.exists(),
+ "{} exists but there was no stderr output",
+ stderr.display()
+ );
+ } else {
+ assert!(
+ std::fs::read(&stderr).unwrap() == replace_ms(&output.stderr),
+ "{} is not the expected output, rerun the test with `cargo test -- -- --bless`",
+ stderr.display()
+ );
+ }
+ if output.stdout.is_empty() {
+ assert!(!stdout.exists());
+ } else {
+ assert!(
+ std::fs::read(&stdout).unwrap() == replace_ms(&output.stdout),
+ "{} is not the expected output, rerun the test with `cargo test -- -- --bless`",
+ stdout.display()
+ );
+ }
+ }
+ }
+}