Deleted vendor folder
This commit is contained in:
		@@ -1,5 +0,0 @@
 | 
				
			|||||||
[source.crates-io]
 | 
					 | 
				
			||||||
replace-with = "vendored-sources"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[source.vendored-sources]
 | 
					 | 
				
			||||||
directory = "vendor"
 | 
					 | 
				
			||||||
							
								
								
									
										1
									
								
								vendor/addr2line/.cargo-checksum.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								vendor/addr2line/.cargo-checksum.json
									
									
									
									
										vendored
									
									
								
							@@ -1 +0,0 @@
 | 
				
			|||||||
{"files":{"CHANGELOG.md":"ef9fa958318e442f1da7d204494cefec75c144aa6d5d5c93b0a5d6fcdf4ef6c6","Cargo.lock":"20b23c454fc3127f08a1bcd2864bbf029793759e6411fba24d44d8f4b7831ad0","Cargo.toml":"d0f15fde73d42bdf00e93f960dff908447225bede9364cb1659e44740a536c04","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"e99d88d232bf57d70f0fb87f6b496d44b6653f99f8a63d250a54c61ea4bcde40","README.md":"76d28502bd2e83f6a9e3576bd45e9a7fe5308448c4b5384b0d249515b5f67a5c","bench.plot.r":"6a5d7a4d36ed6b3d9919be703a479bef47698bf947818b483ff03951df2d4e01","benchmark.sh":"b35f89b1ca2c1dc0476cdd07f0284b72d41920d1c7b6054072f50ffba296d78d","coverage.sh":"4677e81922d08a82e83068a911717a247c66af12e559f37b78b6be3337ac9f07","examples/addr2line.rs":"3c5eb5a6726634df6cf53e4d67ee9f90c9ac09838303947f45c3bea1e84548b5","rustfmt.toml":"01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b","src/builtin_split_dwarf_loader.rs":"dc6979de81b35f82e97275e6be27ec61f3c4225ea10574a9e031813e00185174","src/function.rs":"68f047e0c78afe18ad165db255c8254ee74c35cd6df0cc07e400252981f661ed","src/lazy.rs":"0bf23f7098f1902f181e43c2ffa82a3f86df2c0dbcb9bc0ebce6a0168dd8b060","src/lib.rs":"9d6531f71fd138d31cc7596db9ab234198d0895a21ea9cb116434c19ec78b660","tests/correctness.rs":"4081f8019535305e3aa254c6a4e1436272dd873f9717c687ca0e66ea8d5871ed","tests/output_equivalence.rs":"b2cd7c59fa55808a2e66e9fe7f160d846867e3ecefe22c22a818f822c3c41f23","tests/parse.rs":"c2f7362e4679c1b4803b12ec6e8dca6da96aed7273fd210a857524a4182c30e7"},"package":"8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb"}
 | 
					 | 
				
			||||||
							
								
								
									
										336
									
								
								vendor/addr2line/CHANGELOG.md
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										336
									
								
								vendor/addr2line/CHANGELOG.md
									
									
									
									
										vendored
									
									
								
							@@ -1,336 +0,0 @@
 | 
				
			|||||||
# `addr2line` Change Log
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
--------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## 0.21.0 (2023/08/12)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### Breaking changes
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
* Updated `gimli`, `object`, and `fallible-iterator` dependencies.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### Changed
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
* The minimum supported rust version is 1.65.0.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
* Store boxed slices instead of `Vec` objects in `Context`.
 | 
					 | 
				
			||||||
  [#278](https://github.com/gimli-rs/addr2line/pull/278)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
--------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## 0.20.0 (2023/04/15)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### Breaking changes
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
* The minimum supported rust version is 1.58.0.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
* Changed `Context::find_frames` to return `LookupResult`.
 | 
					 | 
				
			||||||
  Use `LookupResult::skip_all_loads` to obtain the result without loading split DWARF.
 | 
					 | 
				
			||||||
  [#260](https://github.com/gimli-rs/addr2line/pull/260)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
* Replaced `Context::find_dwarf_unit` with `Context::find_dwarf_and_unit`.
 | 
					 | 
				
			||||||
  [#260](https://github.com/gimli-rs/addr2line/pull/260)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
* Updated `object` dependency.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### Changed
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
* Fix handling of file index 0 for DWARF 5.
 | 
					 | 
				
			||||||
  [#264](https://github.com/gimli-rs/addr2line/pull/264)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### Added
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
* Added types and methods to support loading split DWARF:
 | 
					 | 
				
			||||||
  `LookupResult`, `SplitDwarfLoad`, `SplitDwarfLoader`, `Context::preload_units`.
 | 
					 | 
				
			||||||
  [#260](https://github.com/gimli-rs/addr2line/pull/260)
 | 
					 | 
				
			||||||
  [#262](https://github.com/gimli-rs/addr2line/pull/262)
 | 
					 | 
				
			||||||
  [#263](https://github.com/gimli-rs/addr2line/pull/263)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
--------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## 0.19.0 (2022/11/24)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### Breaking changes
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
* Updated `gimli` and `object` dependencies.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
--------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## 0.18.0 (2022/07/16)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### Breaking changes
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
* Updated `object` dependency.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### Changed
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
* Fixed handling of relative path for `DW_AT_comp_dir`.
 | 
					 | 
				
			||||||
  [#239](https://github.com/gimli-rs/addr2line/pull/239)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
* Fixed handling of `DW_FORM_addrx` for DWARF 5 support.
 | 
					 | 
				
			||||||
  [#243](https://github.com/gimli-rs/addr2line/pull/243)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
* Fixed handling of units that are missing range information.
 | 
					 | 
				
			||||||
  [#249](https://github.com/gimli-rs/addr2line/pull/249)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
--------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## 0.17.0 (2021/10/24)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### Breaking changes
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
* Updated `gimli` and `object` dependencies.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### Changed
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
* Use `skip_attributes` to improve performance.
 | 
					 | 
				
			||||||
  [#236](https://github.com/gimli-rs/addr2line/pull/236)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
--------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## 0.16.0 (2021/07/26)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### Breaking changes
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
* Updated `gimli` and `object` dependencies.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
--------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## 0.15.2 (2021/06/04)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### Fixed
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
* Allow `Context` to be `Send`.
 | 
					 | 
				
			||||||
  [#219](https://github.com/gimli-rs/addr2line/pull/219)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
--------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## 0.15.1 (2021/05/02)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### Fixed
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
* Don't ignore aranges with address 0.
 | 
					 | 
				
			||||||
  [#217](https://github.com/gimli-rs/addr2line/pull/217)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
--------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## 0.15.0 (2021/05/02)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### Breaking changes
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
* Updated `gimli` and `object` dependencies.
 | 
					 | 
				
			||||||
  [#215](https://github.com/gimli-rs/addr2line/pull/215)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
* Added `debug_aranges` parameter to `Context::from_sections`.
 | 
					 | 
				
			||||||
  [#200](https://github.com/gimli-rs/addr2line/pull/200)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### Added
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
* Added `.debug_aranges` support.
 | 
					 | 
				
			||||||
  [#200](https://github.com/gimli-rs/addr2line/pull/200)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
* Added supplementary object file support.
 | 
					 | 
				
			||||||
  [#208](https://github.com/gimli-rs/addr2line/pull/208)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### Fixed
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
* Fixed handling of Windows paths in locations.
 | 
					 | 
				
			||||||
  [#209](https://github.com/gimli-rs/addr2line/pull/209)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
* examples/addr2line: Flush stdout after each response.
 | 
					 | 
				
			||||||
  [#210](https://github.com/gimli-rs/addr2line/pull/210)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
* examples/addr2line: Avoid copying every section.
 | 
					 | 
				
			||||||
  [#213](https://github.com/gimli-rs/addr2line/pull/213)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
--------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## 0.14.1 (2020/12/31)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### Fixed
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
* Fix location lookup for skeleton units.
 | 
					 | 
				
			||||||
  [#201](https://github.com/gimli-rs/addr2line/pull/201)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### Added
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
* Added `Context::find_location_range`.
 | 
					 | 
				
			||||||
  [#196](https://github.com/gimli-rs/addr2line/pull/196)
 | 
					 | 
				
			||||||
  [#199](https://github.com/gimli-rs/addr2line/pull/199)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
--------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## 0.14.0 (2020/10/27)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### Breaking changes
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
* Updated `gimli` and `object` dependencies.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### Fixed
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
* Handle units that only have line information.
 | 
					 | 
				
			||||||
  [#188](https://github.com/gimli-rs/addr2line/pull/188)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
* Handle DWARF units with version <= 4 and no `DW_AT_name`.
 | 
					 | 
				
			||||||
  [#191](https://github.com/gimli-rs/addr2line/pull/191)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
* Fix handling of `DW_FORM_ref_addr`.
 | 
					 | 
				
			||||||
  [#193](https://github.com/gimli-rs/addr2line/pull/193)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
--------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## 0.13.0 (2020/07/07)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### Breaking changes
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
* Updated `gimli` and `object` dependencies.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
* Added `rustc-dep-of-std` feature.
 | 
					 | 
				
			||||||
  [#166](https://github.com/gimli-rs/addr2line/pull/166)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### Changed
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
* Improve performance by parsing function contents lazily.
 | 
					 | 
				
			||||||
  [#178](https://github.com/gimli-rs/addr2line/pull/178)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
* Don't skip `.debug_info` and `.debug_line` entries with a zero address.
 | 
					 | 
				
			||||||
  [#182](https://github.com/gimli-rs/addr2line/pull/182)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
--------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## 0.12.2 (2020/06/21)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### Fixed
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
* Avoid linear search for `DW_FORM_ref_addr`.
 | 
					 | 
				
			||||||
  [#175](https://github.com/gimli-rs/addr2line/pull/175)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
--------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## 0.12.1 (2020/05/19)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### Fixed
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
* Handle units with overlapping address ranges.
 | 
					 | 
				
			||||||
  [#163](https://github.com/gimli-rs/addr2line/pull/163)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
* Don't assert for functions with overlapping address ranges.
 | 
					 | 
				
			||||||
  [#168](https://github.com/gimli-rs/addr2line/pull/168)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
--------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## 0.12.0 (2020/05/12)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### Breaking changes
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
* Updated `gimli` and `object` dependencies.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
* Added more optional features: `smallvec` and `fallible-iterator`.
 | 
					 | 
				
			||||||
  [#160](https://github.com/gimli-rs/addr2line/pull/160)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### Added
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
*  Added `Context::dwarf` and `Context::find_dwarf_unit`.
 | 
					 | 
				
			||||||
  [#159](https://github.com/gimli-rs/addr2line/pull/159)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### Changed
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
* Removed `lazycell` dependency.
 | 
					 | 
				
			||||||
  [#160](https://github.com/gimli-rs/addr2line/pull/160)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
--------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## 0.11.0 (2020/01/11)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### Breaking changes
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
* Updated `gimli` and `object` dependencies.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
* [#130](https://github.com/gimli-rs/addr2line/pull/130)
 | 
					 | 
				
			||||||
  Changed `Location::file` from `Option<String>` to `Option<&str>`.
 | 
					 | 
				
			||||||
  This required adding lifetime parameters to `Location` and other structs that
 | 
					 | 
				
			||||||
  contain it.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
* [#152](https://github.com/gimli-rs/addr2line/pull/152)
 | 
					 | 
				
			||||||
  Changed `Location::line` and `Location::column` from `Option<u64>`to `Option<u32>`.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
* [#156](https://github.com/gimli-rs/addr2line/pull/156)
 | 
					 | 
				
			||||||
  Deleted `alloc` feature, and fixed `no-std` builds with stable rust.
 | 
					 | 
				
			||||||
  Removed default `Reader` parameter for `Context`, and added `ObjectContext` instead.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### Added
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
* [#134](https://github.com/gimli-rs/addr2line/pull/134)
 | 
					 | 
				
			||||||
  Added `Context::from_dwarf`.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### Changed
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
* [#133](https://github.com/gimli-rs/addr2line/pull/133)
 | 
					 | 
				
			||||||
  Fixed handling of units that can't be parsed.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
* [#155](https://github.com/gimli-rs/addr2line/pull/155)
 | 
					 | 
				
			||||||
  Fixed `addr2line` output to match binutils.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
* [#130](https://github.com/gimli-rs/addr2line/pull/130)
 | 
					 | 
				
			||||||
  Improved `.debug_line` parsing performance.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
* [#148](https://github.com/gimli-rs/addr2line/pull/148)
 | 
					 | 
				
			||||||
  [#150](https://github.com/gimli-rs/addr2line/pull/150)
 | 
					 | 
				
			||||||
  [#151](https://github.com/gimli-rs/addr2line/pull/151)
 | 
					 | 
				
			||||||
  [#152](https://github.com/gimli-rs/addr2line/pull/152)
 | 
					 | 
				
			||||||
  Improved `.debug_info` parsing performance.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
* [#137](https://github.com/gimli-rs/addr2line/pull/137)
 | 
					 | 
				
			||||||
  [#138](https://github.com/gimli-rs/addr2line/pull/138)
 | 
					 | 
				
			||||||
  [#139](https://github.com/gimli-rs/addr2line/pull/139)
 | 
					 | 
				
			||||||
  [#140](https://github.com/gimli-rs/addr2line/pull/140)
 | 
					 | 
				
			||||||
  [#146](https://github.com/gimli-rs/addr2line/pull/146)
 | 
					 | 
				
			||||||
  Improved benchmarks.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
--------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## 0.10.0 (2019/07/07)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### Breaking changes
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
* [#127](https://github.com/gimli-rs/addr2line/pull/127)
 | 
					 | 
				
			||||||
  Update `gimli`.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
--------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## 0.9.0 (2019/05/02)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### Breaking changes
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
* [#121](https://github.com/gimli-rs/addr2line/pull/121)
 | 
					 | 
				
			||||||
  Update `gimli`, `object`, and `fallible-iterator` dependencies.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### Added
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
* [#121](https://github.com/gimli-rs/addr2line/pull/121)
 | 
					 | 
				
			||||||
  Reexport `gimli`, `object`, and `fallible-iterator`.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
--------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## 0.8.0 (2019/02/06)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### Breaking changes
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
* [#107](https://github.com/gimli-rs/addr2line/pull/107)
 | 
					 | 
				
			||||||
  Update `object` dependency to 0.11. This is part of the public API.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### Added
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
* [#101](https://github.com/gimli-rs/addr2line/pull/101)
 | 
					 | 
				
			||||||
  Add `object` feature (enabled by default). Disable this feature to remove
 | 
					 | 
				
			||||||
  the `object` dependency and `Context::new` API.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
* [#102](https://github.com/gimli-rs/addr2line/pull/102)
 | 
					 | 
				
			||||||
  Add `std` (enabled by default) and `alloc` features.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### Changed
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
* [#108](https://github.com/gimli-rs/addr2line/issues/108)
 | 
					 | 
				
			||||||
  `demangle` no longer outputs the hash for rust symbols.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
* [#109](https://github.com/gimli-rs/addr2line/issues/109)
 | 
					 | 
				
			||||||
  Set default `R` for `Context<R>`.
 | 
					 | 
				
			||||||
							
								
								
									
										704
									
								
								vendor/addr2line/Cargo.lock
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										704
									
								
								vendor/addr2line/Cargo.lock
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,704 +0,0 @@
 | 
				
			|||||||
# This file is automatically @generated by Cargo.
 | 
					 | 
				
			||||||
# It is not intended for manual editing.
 | 
					 | 
				
			||||||
version = 3
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "addr2line"
 | 
					 | 
				
			||||||
version = "0.19.0"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "a76fd60b23679b7d19bd066031410fb7e458ccc5e958eb5c325888ce4baedc97"
 | 
					 | 
				
			||||||
dependencies = [
 | 
					 | 
				
			||||||
 "gimli 0.27.2",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "addr2line"
 | 
					 | 
				
			||||||
version = "0.21.0"
 | 
					 | 
				
			||||||
dependencies = [
 | 
					 | 
				
			||||||
 "backtrace",
 | 
					 | 
				
			||||||
 "clap",
 | 
					 | 
				
			||||||
 "compiler_builtins",
 | 
					 | 
				
			||||||
 "cpp_demangle",
 | 
					 | 
				
			||||||
 "fallible-iterator",
 | 
					 | 
				
			||||||
 "findshlibs",
 | 
					 | 
				
			||||||
 "gimli 0.28.0",
 | 
					 | 
				
			||||||
 "libtest-mimic",
 | 
					 | 
				
			||||||
 "memmap2",
 | 
					 | 
				
			||||||
 "object 0.32.0",
 | 
					 | 
				
			||||||
 "rustc-demangle",
 | 
					 | 
				
			||||||
 "rustc-std-workspace-alloc",
 | 
					 | 
				
			||||||
 "rustc-std-workspace-core",
 | 
					 | 
				
			||||||
 "smallvec",
 | 
					 | 
				
			||||||
 "typed-arena",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "adler"
 | 
					 | 
				
			||||||
version = "1.0.2"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "anstream"
 | 
					 | 
				
			||||||
version = "0.3.2"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "0ca84f3628370c59db74ee214b3263d58f9aadd9b4fe7e711fd87dc452b7f163"
 | 
					 | 
				
			||||||
dependencies = [
 | 
					 | 
				
			||||||
 "anstyle",
 | 
					 | 
				
			||||||
 "anstyle-parse",
 | 
					 | 
				
			||||||
 "anstyle-query",
 | 
					 | 
				
			||||||
 "anstyle-wincon",
 | 
					 | 
				
			||||||
 "colorchoice",
 | 
					 | 
				
			||||||
 "is-terminal",
 | 
					 | 
				
			||||||
 "utf8parse",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "anstyle"
 | 
					 | 
				
			||||||
version = "1.0.1"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "3a30da5c5f2d5e72842e00bcb57657162cdabef0931f40e2deb9b4140440cecd"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "anstyle-parse"
 | 
					 | 
				
			||||||
version = "0.2.1"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "938874ff5980b03a87c5524b3ae5b59cf99b1d6bc836848df7bc5ada9643c333"
 | 
					 | 
				
			||||||
dependencies = [
 | 
					 | 
				
			||||||
 "utf8parse",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "anstyle-query"
 | 
					 | 
				
			||||||
version = "1.0.0"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b"
 | 
					 | 
				
			||||||
dependencies = [
 | 
					 | 
				
			||||||
 "windows-sys",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "anstyle-wincon"
 | 
					 | 
				
			||||||
version = "1.0.2"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "c677ab05e09154296dd37acecd46420c17b9713e8366facafa8fc0885167cf4c"
 | 
					 | 
				
			||||||
dependencies = [
 | 
					 | 
				
			||||||
 "anstyle",
 | 
					 | 
				
			||||||
 "windows-sys",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "backtrace"
 | 
					 | 
				
			||||||
version = "0.3.67"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "233d376d6d185f2a3093e58f283f60f880315b6c60075b01f36b3b85154564ca"
 | 
					 | 
				
			||||||
dependencies = [
 | 
					 | 
				
			||||||
 "addr2line 0.19.0",
 | 
					 | 
				
			||||||
 "cc",
 | 
					 | 
				
			||||||
 "cfg-if",
 | 
					 | 
				
			||||||
 "libc",
 | 
					 | 
				
			||||||
 "miniz_oxide",
 | 
					 | 
				
			||||||
 "object 0.30.3",
 | 
					 | 
				
			||||||
 "rustc-demangle",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "bitflags"
 | 
					 | 
				
			||||||
version = "1.3.2"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "bitflags"
 | 
					 | 
				
			||||||
version = "2.4.0"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "byteorder"
 | 
					 | 
				
			||||||
version = "1.4.3"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "cc"
 | 
					 | 
				
			||||||
version = "1.0.79"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "cfg-if"
 | 
					 | 
				
			||||||
version = "1.0.0"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "clap"
 | 
					 | 
				
			||||||
version = "4.3.21"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "c27cdf28c0f604ba3f512b0c9a409f8de8513e4816705deb0498b627e7c3a3fd"
 | 
					 | 
				
			||||||
dependencies = [
 | 
					 | 
				
			||||||
 "clap_builder",
 | 
					 | 
				
			||||||
 "clap_derive",
 | 
					 | 
				
			||||||
 "once_cell",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "clap_builder"
 | 
					 | 
				
			||||||
version = "4.3.21"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "08a9f1ab5e9f01a9b81f202e8562eb9a10de70abf9eaeac1be465c28b75aa4aa"
 | 
					 | 
				
			||||||
dependencies = [
 | 
					 | 
				
			||||||
 "anstream",
 | 
					 | 
				
			||||||
 "anstyle",
 | 
					 | 
				
			||||||
 "clap_lex",
 | 
					 | 
				
			||||||
 "strsim",
 | 
					 | 
				
			||||||
 "terminal_size",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "clap_derive"
 | 
					 | 
				
			||||||
version = "4.3.12"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "54a9bb5758fc5dfe728d1019941681eccaf0cf8a4189b692a0ee2f2ecf90a050"
 | 
					 | 
				
			||||||
dependencies = [
 | 
					 | 
				
			||||||
 "heck",
 | 
					 | 
				
			||||||
 "proc-macro2",
 | 
					 | 
				
			||||||
 "quote",
 | 
					 | 
				
			||||||
 "syn 2.0.15",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "clap_lex"
 | 
					 | 
				
			||||||
version = "0.5.0"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "2da6da31387c7e4ef160ffab6d5e7f00c42626fe39aea70a7b0f1773f7dd6c1b"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "colorchoice"
 | 
					 | 
				
			||||||
version = "1.0.0"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "compiler_builtins"
 | 
					 | 
				
			||||||
version = "0.1.91"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "571298a3cce7e2afbd3d61abb91a18667d5ab25993ec577a88ee8ac45f00cc3a"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "cpp_demangle"
 | 
					 | 
				
			||||||
version = "0.4.1"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "2c76f98bdfc7f66172e6c7065f981ebb576ffc903fe4c0561d9f0c2509226dc6"
 | 
					 | 
				
			||||||
dependencies = [
 | 
					 | 
				
			||||||
 "cfg-if",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "crc32fast"
 | 
					 | 
				
			||||||
version = "1.3.2"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d"
 | 
					 | 
				
			||||||
dependencies = [
 | 
					 | 
				
			||||||
 "cfg-if",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "errno"
 | 
					 | 
				
			||||||
version = "0.3.2"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "6b30f669a7961ef1631673d2766cc92f52d64f7ef354d4fe0ddfd30ed52f0f4f"
 | 
					 | 
				
			||||||
dependencies = [
 | 
					 | 
				
			||||||
 "errno-dragonfly",
 | 
					 | 
				
			||||||
 "libc",
 | 
					 | 
				
			||||||
 "windows-sys",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "errno-dragonfly"
 | 
					 | 
				
			||||||
version = "0.1.2"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf"
 | 
					 | 
				
			||||||
dependencies = [
 | 
					 | 
				
			||||||
 "cc",
 | 
					 | 
				
			||||||
 "libc",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "fallible-iterator"
 | 
					 | 
				
			||||||
version = "0.3.0"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "findshlibs"
 | 
					 | 
				
			||||||
version = "0.10.2"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "40b9e59cd0f7e0806cca4be089683ecb6434e602038df21fe6bf6711b2f07f64"
 | 
					 | 
				
			||||||
dependencies = [
 | 
					 | 
				
			||||||
 "cc",
 | 
					 | 
				
			||||||
 "lazy_static",
 | 
					 | 
				
			||||||
 "libc",
 | 
					 | 
				
			||||||
 "winapi",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "flate2"
 | 
					 | 
				
			||||||
version = "1.0.25"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "a8a2db397cb1c8772f31494cb8917e48cd1e64f0fa7efac59fbd741a0a8ce841"
 | 
					 | 
				
			||||||
dependencies = [
 | 
					 | 
				
			||||||
 "crc32fast",
 | 
					 | 
				
			||||||
 "miniz_oxide",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "gimli"
 | 
					 | 
				
			||||||
version = "0.27.2"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "ad0a93d233ebf96623465aad4046a8d3aa4da22d4f4beba5388838c8a434bbb4"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "gimli"
 | 
					 | 
				
			||||||
version = "0.28.0"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0"
 | 
					 | 
				
			||||||
dependencies = [
 | 
					 | 
				
			||||||
 "compiler_builtins",
 | 
					 | 
				
			||||||
 "fallible-iterator",
 | 
					 | 
				
			||||||
 "rustc-std-workspace-alloc",
 | 
					 | 
				
			||||||
 "rustc-std-workspace-core",
 | 
					 | 
				
			||||||
 "stable_deref_trait",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "heck"
 | 
					 | 
				
			||||||
version = "0.4.1"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "hermit-abi"
 | 
					 | 
				
			||||||
version = "0.2.6"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7"
 | 
					 | 
				
			||||||
dependencies = [
 | 
					 | 
				
			||||||
 "libc",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "hermit-abi"
 | 
					 | 
				
			||||||
version = "0.3.2"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "io-lifetimes"
 | 
					 | 
				
			||||||
version = "1.0.11"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2"
 | 
					 | 
				
			||||||
dependencies = [
 | 
					 | 
				
			||||||
 "hermit-abi 0.3.2",
 | 
					 | 
				
			||||||
 "libc",
 | 
					 | 
				
			||||||
 "windows-sys",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "is-terminal"
 | 
					 | 
				
			||||||
version = "0.4.9"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b"
 | 
					 | 
				
			||||||
dependencies = [
 | 
					 | 
				
			||||||
 "hermit-abi 0.3.2",
 | 
					 | 
				
			||||||
 "rustix 0.38.8",
 | 
					 | 
				
			||||||
 "windows-sys",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[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.147"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "libtest-mimic"
 | 
					 | 
				
			||||||
version = "0.6.1"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "6d8de370f98a6cb8a4606618e53e802f93b094ddec0f96988eaec2c27e6e9ce7"
 | 
					 | 
				
			||||||
dependencies = [
 | 
					 | 
				
			||||||
 "clap",
 | 
					 | 
				
			||||||
 "termcolor",
 | 
					 | 
				
			||||||
 "threadpool",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "linux-raw-sys"
 | 
					 | 
				
			||||||
version = "0.3.8"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "linux-raw-sys"
 | 
					 | 
				
			||||||
version = "0.4.5"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "57bcfdad1b858c2db7c38303a6d2ad4dfaf5eb53dfeb0910128b2c26d6158503"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "memchr"
 | 
					 | 
				
			||||||
version = "2.5.0"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "memmap2"
 | 
					 | 
				
			||||||
version = "0.5.10"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "83faa42c0a078c393f6b29d5db232d8be22776a891f8f56e5284faee4a20b327"
 | 
					 | 
				
			||||||
dependencies = [
 | 
					 | 
				
			||||||
 "libc",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "miniz_oxide"
 | 
					 | 
				
			||||||
version = "0.6.2"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa"
 | 
					 | 
				
			||||||
dependencies = [
 | 
					 | 
				
			||||||
 "adler",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "num_cpus"
 | 
					 | 
				
			||||||
version = "1.15.0"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b"
 | 
					 | 
				
			||||||
dependencies = [
 | 
					 | 
				
			||||||
 "hermit-abi 0.2.6",
 | 
					 | 
				
			||||||
 "libc",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "object"
 | 
					 | 
				
			||||||
version = "0.30.3"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "ea86265d3d3dcb6a27fc51bd29a4bf387fae9d2986b823079d4986af253eb439"
 | 
					 | 
				
			||||||
dependencies = [
 | 
					 | 
				
			||||||
 "memchr",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "object"
 | 
					 | 
				
			||||||
version = "0.32.0"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "77ac5bbd07aea88c60a577a1ce218075ffd59208b2d7ca97adf9bfc5aeb21ebe"
 | 
					 | 
				
			||||||
dependencies = [
 | 
					 | 
				
			||||||
 "flate2",
 | 
					 | 
				
			||||||
 "memchr",
 | 
					 | 
				
			||||||
 "ruzstd",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "once_cell"
 | 
					 | 
				
			||||||
version = "1.17.1"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "proc-macro2"
 | 
					 | 
				
			||||||
version = "1.0.56"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435"
 | 
					 | 
				
			||||||
dependencies = [
 | 
					 | 
				
			||||||
 "unicode-ident",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "quote"
 | 
					 | 
				
			||||||
version = "1.0.26"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc"
 | 
					 | 
				
			||||||
dependencies = [
 | 
					 | 
				
			||||||
 "proc-macro2",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "rustc-demangle"
 | 
					 | 
				
			||||||
version = "0.1.22"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "d4a36c42d1873f9a77c53bde094f9664d9891bc604a45b4798fd2c389ed12e5b"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "rustc-std-workspace-alloc"
 | 
					 | 
				
			||||||
version = "1.0.0"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "ff66d57013a5686e1917ed6a025d54dd591fcda71a41fe07edf4d16726aefa86"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "rustc-std-workspace-core"
 | 
					 | 
				
			||||||
version = "1.0.0"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "1956f5517128a2b6f23ab2dadf1a976f4f5b27962e7724c2bf3d45e539ec098c"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "rustix"
 | 
					 | 
				
			||||||
version = "0.37.23"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "4d69718bf81c6127a49dc64e44a742e8bb9213c0ff8869a22c308f84c1d4ab06"
 | 
					 | 
				
			||||||
dependencies = [
 | 
					 | 
				
			||||||
 "bitflags 1.3.2",
 | 
					 | 
				
			||||||
 "errno",
 | 
					 | 
				
			||||||
 "io-lifetimes",
 | 
					 | 
				
			||||||
 "libc",
 | 
					 | 
				
			||||||
 "linux-raw-sys 0.3.8",
 | 
					 | 
				
			||||||
 "windows-sys",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "rustix"
 | 
					 | 
				
			||||||
version = "0.38.8"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "19ed4fa021d81c8392ce04db050a3da9a60299050b7ae1cf482d862b54a7218f"
 | 
					 | 
				
			||||||
dependencies = [
 | 
					 | 
				
			||||||
 "bitflags 2.4.0",
 | 
					 | 
				
			||||||
 "errno",
 | 
					 | 
				
			||||||
 "libc",
 | 
					 | 
				
			||||||
 "linux-raw-sys 0.4.5",
 | 
					 | 
				
			||||||
 "windows-sys",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "ruzstd"
 | 
					 | 
				
			||||||
version = "0.4.0"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "ac3ffab8f9715a0d455df4bbb9d21e91135aab3cd3ca187af0cd0c3c3f868fdc"
 | 
					 | 
				
			||||||
dependencies = [
 | 
					 | 
				
			||||||
 "byteorder",
 | 
					 | 
				
			||||||
 "thiserror-core",
 | 
					 | 
				
			||||||
 "twox-hash",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "smallvec"
 | 
					 | 
				
			||||||
version = "1.10.0"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "stable_deref_trait"
 | 
					 | 
				
			||||||
version = "1.2.0"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "static_assertions"
 | 
					 | 
				
			||||||
version = "1.1.0"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "strsim"
 | 
					 | 
				
			||||||
version = "0.10.0"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[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.15"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "a34fcf3e8b60f57e6a14301a2e916d323af98b0ea63c599441eec8558660c822"
 | 
					 | 
				
			||||||
dependencies = [
 | 
					 | 
				
			||||||
 "proc-macro2",
 | 
					 | 
				
			||||||
 "quote",
 | 
					 | 
				
			||||||
 "unicode-ident",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "termcolor"
 | 
					 | 
				
			||||||
version = "1.2.0"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6"
 | 
					 | 
				
			||||||
dependencies = [
 | 
					 | 
				
			||||||
 "winapi-util",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "terminal_size"
 | 
					 | 
				
			||||||
version = "0.2.6"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "8e6bf6f19e9f8ed8d4048dc22981458ebcf406d67e94cd422e5ecd73d63b3237"
 | 
					 | 
				
			||||||
dependencies = [
 | 
					 | 
				
			||||||
 "rustix 0.37.23",
 | 
					 | 
				
			||||||
 "windows-sys",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "thiserror-core"
 | 
					 | 
				
			||||||
version = "1.0.38"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "0d97345f6437bb2004cd58819d8a9ef8e36cdd7661c2abc4bbde0a7c40d9f497"
 | 
					 | 
				
			||||||
dependencies = [
 | 
					 | 
				
			||||||
 "thiserror-core-impl",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "thiserror-core-impl"
 | 
					 | 
				
			||||||
version = "1.0.38"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "10ac1c5050e43014d16b2f94d0d2ce79e65ffdd8b38d8048f9c8f6a8a6da62ac"
 | 
					 | 
				
			||||||
dependencies = [
 | 
					 | 
				
			||||||
 "proc-macro2",
 | 
					 | 
				
			||||||
 "quote",
 | 
					 | 
				
			||||||
 "syn 1.0.109",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "threadpool"
 | 
					 | 
				
			||||||
version = "1.8.1"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa"
 | 
					 | 
				
			||||||
dependencies = [
 | 
					 | 
				
			||||||
 "num_cpus",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "twox-hash"
 | 
					 | 
				
			||||||
version = "1.6.3"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675"
 | 
					 | 
				
			||||||
dependencies = [
 | 
					 | 
				
			||||||
 "cfg-if",
 | 
					 | 
				
			||||||
 "static_assertions",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "typed-arena"
 | 
					 | 
				
			||||||
version = "2.0.2"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "6af6ae20167a9ece4bcb41af5b80f8a1f1df981f6391189ce00fd257af04126a"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "unicode-ident"
 | 
					 | 
				
			||||||
version = "1.0.8"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "utf8parse"
 | 
					 | 
				
			||||||
version = "0.2.1"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[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.5"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
 | 
					 | 
				
			||||||
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.48.0"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
 | 
					 | 
				
			||||||
dependencies = [
 | 
					 | 
				
			||||||
 "windows-targets",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "windows-targets"
 | 
					 | 
				
			||||||
version = "0.48.1"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f"
 | 
					 | 
				
			||||||
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.48.0"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "windows_aarch64_msvc"
 | 
					 | 
				
			||||||
version = "0.48.0"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "windows_i686_gnu"
 | 
					 | 
				
			||||||
version = "0.48.0"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "windows_i686_msvc"
 | 
					 | 
				
			||||||
version = "0.48.0"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "windows_x86_64_gnu"
 | 
					 | 
				
			||||||
version = "0.48.0"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "windows_x86_64_gnullvm"
 | 
					 | 
				
			||||||
version = "0.48.0"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "windows_x86_64_msvc"
 | 
					 | 
				
			||||||
version = "0.48.0"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a"
 | 
					 | 
				
			||||||
							
								
								
									
										147
									
								
								vendor/addr2line/Cargo.toml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										147
									
								
								vendor/addr2line/Cargo.toml
									
									
									
									
										vendored
									
									
								
							@@ -1,147 +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 = "2018"
 | 
					 | 
				
			||||||
rust-version = "1.65"
 | 
					 | 
				
			||||||
name = "addr2line"
 | 
					 | 
				
			||||||
version = "0.21.0"
 | 
					 | 
				
			||||||
exclude = [
 | 
					 | 
				
			||||||
    "/benches/*",
 | 
					 | 
				
			||||||
    "/fixtures/*",
 | 
					 | 
				
			||||||
    ".github",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
description = "A cross-platform symbolication library written in Rust, using `gimli`"
 | 
					 | 
				
			||||||
documentation = "https://docs.rs/addr2line"
 | 
					 | 
				
			||||||
readme = "./README.md"
 | 
					 | 
				
			||||||
keywords = [
 | 
					 | 
				
			||||||
    "DWARF",
 | 
					 | 
				
			||||||
    "debug",
 | 
					 | 
				
			||||||
    "elf",
 | 
					 | 
				
			||||||
    "symbolicate",
 | 
					 | 
				
			||||||
    "atos",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
categories = ["development-tools::debugging"]
 | 
					 | 
				
			||||||
license = "Apache-2.0 OR MIT"
 | 
					 | 
				
			||||||
repository = "https://github.com/gimli-rs/addr2line"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[profile.bench]
 | 
					 | 
				
			||||||
codegen-units = 1
 | 
					 | 
				
			||||||
debug = true
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[profile.release]
 | 
					 | 
				
			||||||
debug = true
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[example]]
 | 
					 | 
				
			||||||
name = "addr2line"
 | 
					 | 
				
			||||||
required-features = ["default"]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[test]]
 | 
					 | 
				
			||||||
name = "output_equivalence"
 | 
					 | 
				
			||||||
harness = false
 | 
					 | 
				
			||||||
required-features = ["default"]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[test]]
 | 
					 | 
				
			||||||
name = "correctness"
 | 
					 | 
				
			||||||
required-features = ["default"]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[test]]
 | 
					 | 
				
			||||||
name = "parse"
 | 
					 | 
				
			||||||
required-features = ["std-object"]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[dependencies.alloc]
 | 
					 | 
				
			||||||
version = "1.0.0"
 | 
					 | 
				
			||||||
optional = true
 | 
					 | 
				
			||||||
package = "rustc-std-workspace-alloc"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[dependencies.compiler_builtins]
 | 
					 | 
				
			||||||
version = "0.1.2"
 | 
					 | 
				
			||||||
optional = true
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[dependencies.core]
 | 
					 | 
				
			||||||
version = "1.0.0"
 | 
					 | 
				
			||||||
optional = true
 | 
					 | 
				
			||||||
package = "rustc-std-workspace-core"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[dependencies.cpp_demangle]
 | 
					 | 
				
			||||||
version = "0.4"
 | 
					 | 
				
			||||||
features = ["alloc"]
 | 
					 | 
				
			||||||
optional = true
 | 
					 | 
				
			||||||
default-features = false
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[dependencies.fallible-iterator]
 | 
					 | 
				
			||||||
version = "0.3.0"
 | 
					 | 
				
			||||||
optional = true
 | 
					 | 
				
			||||||
default-features = false
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[dependencies.gimli]
 | 
					 | 
				
			||||||
version = "0.28.0"
 | 
					 | 
				
			||||||
features = ["read"]
 | 
					 | 
				
			||||||
default-features = false
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[dependencies.memmap2]
 | 
					 | 
				
			||||||
version = "0.5.5"
 | 
					 | 
				
			||||||
optional = true
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[dependencies.object]
 | 
					 | 
				
			||||||
version = "0.32.0"
 | 
					 | 
				
			||||||
features = ["read"]
 | 
					 | 
				
			||||||
optional = true
 | 
					 | 
				
			||||||
default-features = false
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[dependencies.rustc-demangle]
 | 
					 | 
				
			||||||
version = "0.1"
 | 
					 | 
				
			||||||
optional = true
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[dependencies.smallvec]
 | 
					 | 
				
			||||||
version = "1"
 | 
					 | 
				
			||||||
optional = true
 | 
					 | 
				
			||||||
default-features = false
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[dev-dependencies.backtrace]
 | 
					 | 
				
			||||||
version = "0.3.13"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[dev-dependencies.clap]
 | 
					 | 
				
			||||||
version = "4.3.21"
 | 
					 | 
				
			||||||
features = ["wrap_help"]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[dev-dependencies.findshlibs]
 | 
					 | 
				
			||||||
version = "0.10"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[dev-dependencies.libtest-mimic]
 | 
					 | 
				
			||||||
version = "0.6.1"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[dev-dependencies.typed-arena]
 | 
					 | 
				
			||||||
version = "2"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[features]
 | 
					 | 
				
			||||||
default = [
 | 
					 | 
				
			||||||
    "rustc-demangle",
 | 
					 | 
				
			||||||
    "cpp_demangle",
 | 
					 | 
				
			||||||
    "std-object",
 | 
					 | 
				
			||||||
    "fallible-iterator",
 | 
					 | 
				
			||||||
    "smallvec",
 | 
					 | 
				
			||||||
    "memmap2",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
rustc-dep-of-std = [
 | 
					 | 
				
			||||||
    "core",
 | 
					 | 
				
			||||||
    "alloc",
 | 
					 | 
				
			||||||
    "compiler_builtins",
 | 
					 | 
				
			||||||
    "gimli/rustc-dep-of-std",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
std = ["gimli/std"]
 | 
					 | 
				
			||||||
std-object = [
 | 
					 | 
				
			||||||
    "std",
 | 
					 | 
				
			||||||
    "object",
 | 
					 | 
				
			||||||
    "object/std",
 | 
					 | 
				
			||||||
    "object/compression",
 | 
					 | 
				
			||||||
    "gimli/endian-reader",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
							
								
								
									
										201
									
								
								vendor/addr2line/LICENSE-APACHE
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										201
									
								
								vendor/addr2line/LICENSE-APACHE
									
									
									
									
										vendored
									
									
								
							@@ -1,201 +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
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
APPENDIX: How to apply the Apache License to your work.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   To apply the Apache License to your work, attach the following
 | 
					 | 
				
			||||||
   boilerplate notice, with the fields enclosed by brackets "[]"
 | 
					 | 
				
			||||||
   replaced with your own identifying information. (Don't include
 | 
					 | 
				
			||||||
   the brackets!)  The text should be enclosed in the appropriate
 | 
					 | 
				
			||||||
   comment syntax for the file format. We also recommend that a
 | 
					 | 
				
			||||||
   file or class name and description of purpose be included on the
 | 
					 | 
				
			||||||
   same "printed page" as the copyright notice for easier
 | 
					 | 
				
			||||||
   identification within third-party archives.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Copyright [yyyy] [name of copyright owner]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Licensed under the Apache License, Version 2.0 (the "License");
 | 
					 | 
				
			||||||
you may not use this file except in compliance with the License.
 | 
					 | 
				
			||||||
You may obtain a copy of the License at
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	http://www.apache.org/licenses/LICENSE-2.0
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Unless required by applicable law or agreed to in writing, software
 | 
					 | 
				
			||||||
distributed under the License is distributed on an "AS IS" BASIS,
 | 
					 | 
				
			||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
					 | 
				
			||||||
See the License for the specific language governing permissions and
 | 
					 | 
				
			||||||
limitations under the License.
 | 
					 | 
				
			||||||
							
								
								
									
										25
									
								
								vendor/addr2line/LICENSE-MIT
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										25
									
								
								vendor/addr2line/LICENSE-MIT
									
									
									
									
										vendored
									
									
								
							@@ -1,25 +0,0 @@
 | 
				
			|||||||
Copyright (c) 2016-2018 The gimli Developers
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
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.
 | 
					 | 
				
			||||||
							
								
								
									
										48
									
								
								vendor/addr2line/README.md
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										48
									
								
								vendor/addr2line/README.md
									
									
									
									
										vendored
									
									
								
							@@ -1,48 +0,0 @@
 | 
				
			|||||||
# addr2line
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[](https://crates.io/crates/addr2line)
 | 
					 | 
				
			||||||
[](https://docs.rs/addr2line)
 | 
					 | 
				
			||||||
[](https://coveralls.io/github/gimli-rs/addr2line?branch=master)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
A cross-platform library for retrieving per-address debug information
 | 
					 | 
				
			||||||
from files with DWARF debug information.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
`addr2line` uses [`gimli`](https://github.com/gimli-rs/gimli) to parse
 | 
					 | 
				
			||||||
the debug information, and exposes an interface for finding
 | 
					 | 
				
			||||||
the source file, line number, and wrapping function for instruction
 | 
					 | 
				
			||||||
addresses within the target program. These lookups can either be
 | 
					 | 
				
			||||||
performed programmatically through `Context::find_location` and
 | 
					 | 
				
			||||||
`Context::find_frames`, or via the included example binary,
 | 
					 | 
				
			||||||
`addr2line` (named and modelled after the equivalent utility from
 | 
					 | 
				
			||||||
[GNU binutils](https://sourceware.org/binutils/docs/binutils/addr2line.html)).
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Quickstart
 | 
					 | 
				
			||||||
 - Add the [`addr2line` crate](https://crates.io/crates/addr2line) to your `Cargo.toml`
 | 
					 | 
				
			||||||
 - Load the file and parse it with [`addr2line::object::read::File::parse`](https://docs.rs/object/*/object/read/struct.File.html#method.parse)
 | 
					 | 
				
			||||||
 - Pass the parsed file to [`addr2line::Context::new` ](https://docs.rs/addr2line/*/addr2line/struct.Context.html#method.new)
 | 
					 | 
				
			||||||
 - Use [`addr2line::Context::find_location`](https://docs.rs/addr2line/*/addr2line/struct.Context.html#method.find_location)
 | 
					 | 
				
			||||||
   or [`addr2line::Context::find_frames`](https://docs.rs/addr2line/*/addr2line/struct.Context.html#method.find_frames)
 | 
					 | 
				
			||||||
   to look up debug information for an address
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Performance
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
`addr2line` optimizes for speed over memory by caching parsed information.
 | 
					 | 
				
			||||||
The DWARF information is parsed lazily where possible.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
The library aims to perform similarly to equivalent existing tools such
 | 
					 | 
				
			||||||
as `addr2line` from binutils, `eu-addr2line` from elfutils, and
 | 
					 | 
				
			||||||
`llvm-symbolize` from the llvm project, and in the past some benchmarking
 | 
					 | 
				
			||||||
was done that indicates a comparable performance.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## License
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Licensed under either of
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  * Apache License, Version 2.0 ([`LICENSE-APACHE`](./LICENSE-APACHE) or https://www.apache.org/licenses/LICENSE-2.0)
 | 
					 | 
				
			||||||
  * MIT license ([`LICENSE-MIT`](./LICENSE-MIT) or https://opensource.org/licenses/MIT)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
at your option.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Unless you explicitly state otherwise, any contribution intentionally submitted
 | 
					 | 
				
			||||||
for inclusion in the work by you, as defined in the Apache-2.0 license, shall be
 | 
					 | 
				
			||||||
dual licensed as above, without any additional terms or conditions.
 | 
					 | 
				
			||||||
							
								
								
									
										23
									
								
								vendor/addr2line/bench.plot.r
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										23
									
								
								vendor/addr2line/bench.plot.r
									
									
									
									
										vendored
									
									
								
							@@ -1,23 +0,0 @@
 | 
				
			|||||||
v <- read.table(file("stdin"))
 | 
					 | 
				
			||||||
t <- data.frame(prog=v[,1], funcs=(v[,2]=="func"), time=v[,3], mem=v[,4], stringsAsFactors=FALSE)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
t$prog <- as.character(t$prog)
 | 
					 | 
				
			||||||
t$prog[t$prog == "master"] <- "gimli-rs/addr2line"
 | 
					 | 
				
			||||||
t$funcs[t$funcs == TRUE] <- "With functions"
 | 
					 | 
				
			||||||
t$funcs[t$funcs == FALSE] <- "File/line only"
 | 
					 | 
				
			||||||
t$mem = t$mem / 1024.0
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
library(ggplot2)
 | 
					 | 
				
			||||||
p <- ggplot(data=t, aes(x=prog, y=time, fill=prog))
 | 
					 | 
				
			||||||
p <- p + geom_bar(stat = "identity")
 | 
					 | 
				
			||||||
p <- p + facet_wrap(~ funcs)
 | 
					 | 
				
			||||||
p <- p + theme(axis.title.x=element_blank(), axis.text.x=element_blank(), axis.ticks.x=element_blank())
 | 
					 | 
				
			||||||
p <- p + ylab("time (s)") + ggtitle("addr2line runtime")
 | 
					 | 
				
			||||||
ggsave('time.png',plot=p,width=10,height=6)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
p <- ggplot(data=t, aes(x=prog, y=mem, fill=prog))
 | 
					 | 
				
			||||||
p <- p + geom_bar(stat = "identity")
 | 
					 | 
				
			||||||
p <- p + facet_wrap(~ funcs)
 | 
					 | 
				
			||||||
p <- p + theme(axis.title.x=element_blank(), axis.text.x=element_blank(), axis.ticks.x=element_blank())
 | 
					 | 
				
			||||||
p <- p + ylab("memory (kB)") + ggtitle("addr2line memory usage")
 | 
					 | 
				
			||||||
ggsave('memory.png',plot=p,width=10,height=6)
 | 
					 | 
				
			||||||
							
								
								
									
										112
									
								
								vendor/addr2line/benchmark.sh
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										112
									
								
								vendor/addr2line/benchmark.sh
									
									
									
									
										vendored
									
									
								
							@@ -1,112 +0,0 @@
 | 
				
			|||||||
#!/bin/bash
 | 
					 | 
				
			||||||
if [[ $# -le 1 ]]; then
 | 
					 | 
				
			||||||
	echo "Usage: $0 <executable> [<addresses>] REFS..."
 | 
					 | 
				
			||||||
	exit 1
 | 
					 | 
				
			||||||
fi
 | 
					 | 
				
			||||||
target="$1"
 | 
					 | 
				
			||||||
shift
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
addresses=""
 | 
					 | 
				
			||||||
if [[ -e "$1" ]]; then
 | 
					 | 
				
			||||||
	addresses="$1"
 | 
					 | 
				
			||||||
	shift
 | 
					 | 
				
			||||||
fi
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# path to "us"
 | 
					 | 
				
			||||||
# readlink -f, but more portable:
 | 
					 | 
				
			||||||
dirname=$(perl -e 'use Cwd "abs_path";print abs_path(shift)' "$(dirname "$0")")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# https://stackoverflow.com/a/2358432/472927
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	# compile all refs
 | 
					 | 
				
			||||||
	pushd "$dirname" > /dev/null
 | 
					 | 
				
			||||||
	# if the user has some local changes, preserve them
 | 
					 | 
				
			||||||
	nstashed=$(git stash list | wc -l)
 | 
					 | 
				
			||||||
	echo "==> Stashing any local modifications"
 | 
					 | 
				
			||||||
	git stash --keep-index > /dev/null
 | 
					 | 
				
			||||||
	popstash() {
 | 
					 | 
				
			||||||
		# https://stackoverflow.com/q/24520791/472927
 | 
					 | 
				
			||||||
		if [[ "$(git stash list | wc -l)" -ne "$nstashed" ]]; then
 | 
					 | 
				
			||||||
			echo "==> Restoring stashed state"
 | 
					 | 
				
			||||||
			git stash pop > /dev/null
 | 
					 | 
				
			||||||
		fi
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	# if the user has added stuff to the index, abort
 | 
					 | 
				
			||||||
	if ! git diff-index --quiet HEAD --; then
 | 
					 | 
				
			||||||
		echo "Refusing to overwrite outstanding git changes"
 | 
					 | 
				
			||||||
		popstash
 | 
					 | 
				
			||||||
		exit 2
 | 
					 | 
				
			||||||
	fi
 | 
					 | 
				
			||||||
	current=$(git symbolic-ref --short HEAD)
 | 
					 | 
				
			||||||
	for ref in "$@"; do
 | 
					 | 
				
			||||||
		echo "==> Compiling $ref"
 | 
					 | 
				
			||||||
		git checkout -q "$ref"
 | 
					 | 
				
			||||||
		commit=$(git rev-parse HEAD)
 | 
					 | 
				
			||||||
		fn="target/release/addr2line-$commit"
 | 
					 | 
				
			||||||
		if [[ ! -e "$fn" ]]; then
 | 
					 | 
				
			||||||
			cargo build --release --example addr2line
 | 
					 | 
				
			||||||
			cp target/release/examples/addr2line "$fn"
 | 
					 | 
				
			||||||
		fi
 | 
					 | 
				
			||||||
		if [[ "$ref" != "$commit" ]]; then
 | 
					 | 
				
			||||||
			ln -sfn "addr2line-$commit" target/release/addr2line-"$ref"
 | 
					 | 
				
			||||||
		fi
 | 
					 | 
				
			||||||
	done
 | 
					 | 
				
			||||||
	git checkout -q "$current"
 | 
					 | 
				
			||||||
	popstash
 | 
					 | 
				
			||||||
	popd > /dev/null
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	# get us some addresses to look up
 | 
					 | 
				
			||||||
	if [[ -z "$addresses" ]]; then
 | 
					 | 
				
			||||||
		echo "==> Looking for benchmarking addresses (this may take a while)"
 | 
					 | 
				
			||||||
		addresses=$(mktemp tmp.XXXXXXXXXX)
 | 
					 | 
				
			||||||
		objdump -C -x --disassemble -l "$target" \
 | 
					 | 
				
			||||||
			| grep -P '0[048]:' \
 | 
					 | 
				
			||||||
			| awk '{print $1}' \
 | 
					 | 
				
			||||||
			| sed 's/:$//' \
 | 
					 | 
				
			||||||
			> "$addresses"
 | 
					 | 
				
			||||||
		echo "  -> Addresses stored in $addresses; you should re-use it next time"
 | 
					 | 
				
			||||||
	fi
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	run() {
 | 
					 | 
				
			||||||
		func="$1"
 | 
					 | 
				
			||||||
		name="$2"
 | 
					 | 
				
			||||||
		cmd="$3"
 | 
					 | 
				
			||||||
		args="$4"
 | 
					 | 
				
			||||||
		printf "%s\t%s\t" "$name" "$func"
 | 
					 | 
				
			||||||
		if [[ "$cmd" =~ llvm-symbolizer ]]; then
 | 
					 | 
				
			||||||
			/usr/bin/time -f '%e\t%M' "$cmd" $args -obj="$target" < "$addresses" 2>&1 >/dev/null
 | 
					 | 
				
			||||||
		else
 | 
					 | 
				
			||||||
			/usr/bin/time -f '%e\t%M' "$cmd" $args -e "$target" < "$addresses" 2>&1 >/dev/null
 | 
					 | 
				
			||||||
		fi
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	# run without functions
 | 
					 | 
				
			||||||
	log1=$(mktemp tmp.XXXXXXXXXX)
 | 
					 | 
				
			||||||
	echo "==> Benchmarking"
 | 
					 | 
				
			||||||
	run nofunc binutils addr2line >> "$log1"
 | 
					 | 
				
			||||||
	#run nofunc elfutils eu-addr2line >> "$log1"
 | 
					 | 
				
			||||||
	run nofunc llvm-sym llvm-symbolizer -functions=none >> "$log1"
 | 
					 | 
				
			||||||
	for ref in "$@"; do
 | 
					 | 
				
			||||||
		run nofunc "$ref" "$dirname/target/release/addr2line-$ref" >> "$log1"
 | 
					 | 
				
			||||||
	done
 | 
					 | 
				
			||||||
	cat "$log1" | column -t
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	# run with functions
 | 
					 | 
				
			||||||
	log2=$(mktemp tmp.XXXXXXXXXX)
 | 
					 | 
				
			||||||
	echo "==> Benchmarking with -f"
 | 
					 | 
				
			||||||
	run func binutils addr2line "-f -i" >> "$log2"
 | 
					 | 
				
			||||||
	#run func elfutils eu-addr2line "-f -i"  >> "$log2"
 | 
					 | 
				
			||||||
	run func llvm-sym llvm-symbolizer "-functions=linkage -demangle=0" >> "$log2"
 | 
					 | 
				
			||||||
	for ref in "$@"; do
 | 
					 | 
				
			||||||
		run func "$ref" "$dirname/target/release/addr2line-$ref" "-f -i" >> "$log2"
 | 
					 | 
				
			||||||
	done
 | 
					 | 
				
			||||||
	cat "$log2" | column -t
 | 
					 | 
				
			||||||
	cat "$log2" >> "$log1"; rm "$log2"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	echo "==> Plotting"
 | 
					 | 
				
			||||||
	Rscript --no-readline --no-restore --no-save "$dirname/bench.plot.r" < "$log1"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	echo "==> Cleaning up"
 | 
					 | 
				
			||||||
	rm "$log1"
 | 
					 | 
				
			||||||
	exit 0
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										5
									
								
								vendor/addr2line/coverage.sh
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								vendor/addr2line/coverage.sh
									
									
									
									
										vendored
									
									
								
							@@ -1,5 +0,0 @@
 | 
				
			|||||||
#!/bin/sh
 | 
					 | 
				
			||||||
# Run tarpaulin and pycobertura to generate coverage.html.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
cargo tarpaulin --skip-clean --out Xml
 | 
					 | 
				
			||||||
pycobertura show --format html --output coverage.html cobertura.xml
 | 
					 | 
				
			||||||
							
								
								
									
										317
									
								
								vendor/addr2line/examples/addr2line.rs
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										317
									
								
								vendor/addr2line/examples/addr2line.rs
									
									
									
									
										vendored
									
									
								
							@@ -1,317 +0,0 @@
 | 
				
			|||||||
use std::borrow::Cow;
 | 
					 | 
				
			||||||
use std::fs::File;
 | 
					 | 
				
			||||||
use std::io::{BufRead, Lines, StdinLock, Write};
 | 
					 | 
				
			||||||
use std::path::{Path, PathBuf};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use clap::{Arg, ArgAction, Command};
 | 
					 | 
				
			||||||
use fallible_iterator::FallibleIterator;
 | 
					 | 
				
			||||||
use object::{Object, ObjectSection, SymbolMap, SymbolMapName};
 | 
					 | 
				
			||||||
use typed_arena::Arena;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use addr2line::{Context, Location};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
fn parse_uint_from_hex_string(string: &str) -> Option<u64> {
 | 
					 | 
				
			||||||
    if string.len() > 2 && string.starts_with("0x") {
 | 
					 | 
				
			||||||
        u64::from_str_radix(&string[2..], 16).ok()
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
        u64::from_str_radix(string, 16).ok()
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum Addrs<'a> {
 | 
					 | 
				
			||||||
    Args(clap::parser::ValuesRef<'a, String>),
 | 
					 | 
				
			||||||
    Stdin(Lines<StdinLock<'a>>),
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl<'a> Iterator for Addrs<'a> {
 | 
					 | 
				
			||||||
    type Item = Option<u64>;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    fn next(&mut self) -> Option<Option<u64>> {
 | 
					 | 
				
			||||||
        let text = match *self {
 | 
					 | 
				
			||||||
            Addrs::Args(ref mut vals) => vals.next().map(Cow::from),
 | 
					 | 
				
			||||||
            Addrs::Stdin(ref mut lines) => lines.next().map(Result::unwrap).map(Cow::from),
 | 
					 | 
				
			||||||
        };
 | 
					 | 
				
			||||||
        text.as_ref()
 | 
					 | 
				
			||||||
            .map(Cow::as_ref)
 | 
					 | 
				
			||||||
            .map(parse_uint_from_hex_string)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
fn print_loc(loc: Option<&Location<'_>>, basenames: bool, llvm: bool) {
 | 
					 | 
				
			||||||
    if let Some(loc) = loc {
 | 
					 | 
				
			||||||
        if let Some(ref file) = loc.file.as_ref() {
 | 
					 | 
				
			||||||
            let path = if basenames {
 | 
					 | 
				
			||||||
                Path::new(Path::new(file).file_name().unwrap())
 | 
					 | 
				
			||||||
            } else {
 | 
					 | 
				
			||||||
                Path::new(file)
 | 
					 | 
				
			||||||
            };
 | 
					 | 
				
			||||||
            print!("{}:", path.display());
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            print!("??:");
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        if llvm {
 | 
					 | 
				
			||||||
            print!("{}:{}", loc.line.unwrap_or(0), loc.column.unwrap_or(0));
 | 
					 | 
				
			||||||
        } else if let Some(line) = loc.line {
 | 
					 | 
				
			||||||
            print!("{}", line);
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            print!("?");
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        println!();
 | 
					 | 
				
			||||||
    } else if llvm {
 | 
					 | 
				
			||||||
        println!("??:0:0");
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
        println!("??:0");
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
fn print_function(name: Option<&str>, language: Option<gimli::DwLang>, demangle: bool) {
 | 
					 | 
				
			||||||
    if let Some(name) = name {
 | 
					 | 
				
			||||||
        if demangle {
 | 
					 | 
				
			||||||
            print!("{}", addr2line::demangle_auto(Cow::from(name), language));
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            print!("{}", name);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
        print!("??");
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
fn load_file_section<'input, 'arena, Endian: gimli::Endianity>(
 | 
					 | 
				
			||||||
    id: gimli::SectionId,
 | 
					 | 
				
			||||||
    file: &object::File<'input>,
 | 
					 | 
				
			||||||
    endian: Endian,
 | 
					 | 
				
			||||||
    arena_data: &'arena Arena<Cow<'input, [u8]>>,
 | 
					 | 
				
			||||||
) -> Result<gimli::EndianSlice<'arena, Endian>, ()> {
 | 
					 | 
				
			||||||
    // TODO: Unify with dwarfdump.rs in gimli.
 | 
					 | 
				
			||||||
    let name = id.name();
 | 
					 | 
				
			||||||
    match file.section_by_name(name) {
 | 
					 | 
				
			||||||
        Some(section) => match section.uncompressed_data().unwrap() {
 | 
					 | 
				
			||||||
            Cow::Borrowed(b) => Ok(gimli::EndianSlice::new(b, endian)),
 | 
					 | 
				
			||||||
            Cow::Owned(b) => Ok(gimli::EndianSlice::new(arena_data.alloc(b.into()), endian)),
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        None => Ok(gimli::EndianSlice::new(&[][..], endian)),
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
fn find_name_from_symbols<'a>(
 | 
					 | 
				
			||||||
    symbols: &'a SymbolMap<SymbolMapName<'_>>,
 | 
					 | 
				
			||||||
    probe: u64,
 | 
					 | 
				
			||||||
) -> Option<&'a str> {
 | 
					 | 
				
			||||||
    symbols.get(probe).map(|x| x.name())
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct Options<'a> {
 | 
					 | 
				
			||||||
    do_functions: bool,
 | 
					 | 
				
			||||||
    do_inlines: bool,
 | 
					 | 
				
			||||||
    pretty: bool,
 | 
					 | 
				
			||||||
    print_addrs: bool,
 | 
					 | 
				
			||||||
    basenames: bool,
 | 
					 | 
				
			||||||
    demangle: bool,
 | 
					 | 
				
			||||||
    llvm: bool,
 | 
					 | 
				
			||||||
    exe: &'a PathBuf,
 | 
					 | 
				
			||||||
    sup: Option<&'a PathBuf>,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
fn main() {
 | 
					 | 
				
			||||||
    let matches = Command::new("addr2line")
 | 
					 | 
				
			||||||
        .version(env!("CARGO_PKG_VERSION"))
 | 
					 | 
				
			||||||
        .about("A fast addr2line Rust port")
 | 
					 | 
				
			||||||
        .max_term_width(100)
 | 
					 | 
				
			||||||
        .args(&[
 | 
					 | 
				
			||||||
            Arg::new("exe")
 | 
					 | 
				
			||||||
                .short('e')
 | 
					 | 
				
			||||||
                .long("exe")
 | 
					 | 
				
			||||||
                .value_name("filename")
 | 
					 | 
				
			||||||
                .value_parser(clap::value_parser!(PathBuf))
 | 
					 | 
				
			||||||
                .help(
 | 
					 | 
				
			||||||
                    "Specify the name of the executable for which addresses should be translated.",
 | 
					 | 
				
			||||||
                )
 | 
					 | 
				
			||||||
                .required(true),
 | 
					 | 
				
			||||||
            Arg::new("sup")
 | 
					 | 
				
			||||||
                .long("sup")
 | 
					 | 
				
			||||||
                .value_name("filename")
 | 
					 | 
				
			||||||
                .value_parser(clap::value_parser!(PathBuf))
 | 
					 | 
				
			||||||
                .help("Path to supplementary object file."),
 | 
					 | 
				
			||||||
            Arg::new("functions")
 | 
					 | 
				
			||||||
                .short('f')
 | 
					 | 
				
			||||||
                .long("functions")
 | 
					 | 
				
			||||||
                .action(ArgAction::SetTrue)
 | 
					 | 
				
			||||||
                .help("Display function names as well as file and line number information."),
 | 
					 | 
				
			||||||
            Arg::new("pretty").short('p').long("pretty-print")
 | 
					 | 
				
			||||||
                .action(ArgAction::SetTrue)
 | 
					 | 
				
			||||||
                .help(
 | 
					 | 
				
			||||||
                "Make the output more human friendly: each location are printed on one line.",
 | 
					 | 
				
			||||||
            ),
 | 
					 | 
				
			||||||
            Arg::new("inlines").short('i').long("inlines")
 | 
					 | 
				
			||||||
                .action(ArgAction::SetTrue)
 | 
					 | 
				
			||||||
                .help(
 | 
					 | 
				
			||||||
                "If the address belongs to a function that was inlined, the source information for \
 | 
					 | 
				
			||||||
                all enclosing scopes back to the first non-inlined function will also be printed.",
 | 
					 | 
				
			||||||
            ),
 | 
					 | 
				
			||||||
            Arg::new("addresses").short('a').long("addresses")
 | 
					 | 
				
			||||||
                .action(ArgAction::SetTrue)
 | 
					 | 
				
			||||||
                .help(
 | 
					 | 
				
			||||||
                "Display the address before the function name, file and line number information.",
 | 
					 | 
				
			||||||
            ),
 | 
					 | 
				
			||||||
            Arg::new("basenames")
 | 
					 | 
				
			||||||
                .short('s')
 | 
					 | 
				
			||||||
                .long("basenames")
 | 
					 | 
				
			||||||
                .action(ArgAction::SetTrue)
 | 
					 | 
				
			||||||
                .help("Display only the base of each file name."),
 | 
					 | 
				
			||||||
            Arg::new("demangle").short('C').long("demangle")
 | 
					 | 
				
			||||||
                .action(ArgAction::SetTrue)
 | 
					 | 
				
			||||||
                .help(
 | 
					 | 
				
			||||||
                "Demangle function names. \
 | 
					 | 
				
			||||||
                Specifying a specific demangling style (like GNU addr2line) is not supported. \
 | 
					 | 
				
			||||||
                (TODO)"
 | 
					 | 
				
			||||||
            ),
 | 
					 | 
				
			||||||
            Arg::new("llvm")
 | 
					 | 
				
			||||||
                .long("llvm")
 | 
					 | 
				
			||||||
                .action(ArgAction::SetTrue)
 | 
					 | 
				
			||||||
                .help("Display output in the same format as llvm-symbolizer."),
 | 
					 | 
				
			||||||
            Arg::new("addrs")
 | 
					 | 
				
			||||||
                .action(ArgAction::Append)
 | 
					 | 
				
			||||||
                .help("Addresses to use instead of reading from stdin."),
 | 
					 | 
				
			||||||
        ])
 | 
					 | 
				
			||||||
        .get_matches();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let arena_data = Arena::new();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let opts = Options {
 | 
					 | 
				
			||||||
        do_functions: matches.get_flag("functions"),
 | 
					 | 
				
			||||||
        do_inlines: matches.get_flag("inlines"),
 | 
					 | 
				
			||||||
        pretty: matches.get_flag("pretty"),
 | 
					 | 
				
			||||||
        print_addrs: matches.get_flag("addresses"),
 | 
					 | 
				
			||||||
        basenames: matches.get_flag("basenames"),
 | 
					 | 
				
			||||||
        demangle: matches.get_flag("demangle"),
 | 
					 | 
				
			||||||
        llvm: matches.get_flag("llvm"),
 | 
					 | 
				
			||||||
        exe: matches.get_one::<PathBuf>("exe").unwrap(),
 | 
					 | 
				
			||||||
        sup: matches.get_one::<PathBuf>("sup"),
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let file = File::open(opts.exe).unwrap();
 | 
					 | 
				
			||||||
    let map = unsafe { memmap2::Mmap::map(&file).unwrap() };
 | 
					 | 
				
			||||||
    let object = &object::File::parse(&*map).unwrap();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let endian = if object.is_little_endian() {
 | 
					 | 
				
			||||||
        gimli::RunTimeEndian::Little
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
        gimli::RunTimeEndian::Big
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let mut load_section = |id: gimli::SectionId| -> Result<_, _> {
 | 
					 | 
				
			||||||
        load_file_section(id, object, endian, &arena_data)
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let sup_map;
 | 
					 | 
				
			||||||
    let sup_object = if let Some(sup_path) = opts.sup {
 | 
					 | 
				
			||||||
        let sup_file = File::open(sup_path).unwrap();
 | 
					 | 
				
			||||||
        sup_map = unsafe { memmap2::Mmap::map(&sup_file).unwrap() };
 | 
					 | 
				
			||||||
        Some(object::File::parse(&*sup_map).unwrap())
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
        None
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let symbols = object.symbol_map();
 | 
					 | 
				
			||||||
    let mut dwarf = gimli::Dwarf::load(&mut load_section).unwrap();
 | 
					 | 
				
			||||||
    if let Some(ref sup_object) = sup_object {
 | 
					 | 
				
			||||||
        let mut load_sup_section = |id: gimli::SectionId| -> Result<_, _> {
 | 
					 | 
				
			||||||
            load_file_section(id, sup_object, endian, &arena_data)
 | 
					 | 
				
			||||||
        };
 | 
					 | 
				
			||||||
        dwarf.load_sup(&mut load_sup_section).unwrap();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let mut split_dwarf_loader = addr2line::builtin_split_dwarf_loader::SplitDwarfLoader::new(
 | 
					 | 
				
			||||||
        |data, endian| {
 | 
					 | 
				
			||||||
            gimli::EndianSlice::new(arena_data.alloc(Cow::Owned(data.into_owned())), endian)
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        Some(opts.exe.clone()),
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
    let ctx = Context::from_dwarf(dwarf).unwrap();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let stdin = std::io::stdin();
 | 
					 | 
				
			||||||
    let addrs = matches
 | 
					 | 
				
			||||||
        .get_many::<String>("addrs")
 | 
					 | 
				
			||||||
        .map(Addrs::Args)
 | 
					 | 
				
			||||||
        .unwrap_or_else(|| Addrs::Stdin(stdin.lock().lines()));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    for probe in addrs {
 | 
					 | 
				
			||||||
        if opts.print_addrs {
 | 
					 | 
				
			||||||
            let addr = probe.unwrap_or(0);
 | 
					 | 
				
			||||||
            if opts.llvm {
 | 
					 | 
				
			||||||
                print!("0x{:x}", addr);
 | 
					 | 
				
			||||||
            } else {
 | 
					 | 
				
			||||||
                print!("0x{:016x}", addr);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            if opts.pretty {
 | 
					 | 
				
			||||||
                print!(": ");
 | 
					 | 
				
			||||||
            } else {
 | 
					 | 
				
			||||||
                println!();
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if opts.do_functions || opts.do_inlines {
 | 
					 | 
				
			||||||
            let mut printed_anything = false;
 | 
					 | 
				
			||||||
            if let Some(probe) = probe {
 | 
					 | 
				
			||||||
                let frames = ctx.find_frames(probe);
 | 
					 | 
				
			||||||
                let frames = split_dwarf_loader.run(frames).unwrap();
 | 
					 | 
				
			||||||
                let mut frames = frames.enumerate();
 | 
					 | 
				
			||||||
                while let Some((i, frame)) = frames.next().unwrap() {
 | 
					 | 
				
			||||||
                    if opts.pretty && i != 0 {
 | 
					 | 
				
			||||||
                        print!(" (inlined by) ");
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    if opts.do_functions {
 | 
					 | 
				
			||||||
                        if let Some(func) = frame.function {
 | 
					 | 
				
			||||||
                            print_function(
 | 
					 | 
				
			||||||
                                func.raw_name().ok().as_ref().map(AsRef::as_ref),
 | 
					 | 
				
			||||||
                                func.language,
 | 
					 | 
				
			||||||
                                opts.demangle,
 | 
					 | 
				
			||||||
                            );
 | 
					 | 
				
			||||||
                        } else {
 | 
					 | 
				
			||||||
                            let name = find_name_from_symbols(&symbols, probe);
 | 
					 | 
				
			||||||
                            print_function(name, None, opts.demangle);
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                        if opts.pretty {
 | 
					 | 
				
			||||||
                            print!(" at ");
 | 
					 | 
				
			||||||
                        } else {
 | 
					 | 
				
			||||||
                            println!();
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    print_loc(frame.location.as_ref(), opts.basenames, opts.llvm);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    printed_anything = true;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    if !opts.do_inlines {
 | 
					 | 
				
			||||||
                        break;
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if !printed_anything {
 | 
					 | 
				
			||||||
                if opts.do_functions {
 | 
					 | 
				
			||||||
                    let name = probe.and_then(|probe| find_name_from_symbols(&symbols, probe));
 | 
					 | 
				
			||||||
                    print_function(name, None, opts.demangle);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    if opts.pretty {
 | 
					 | 
				
			||||||
                        print!(" at ");
 | 
					 | 
				
			||||||
                    } else {
 | 
					 | 
				
			||||||
                        println!();
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                print_loc(None, opts.basenames, opts.llvm);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            let loc = probe.and_then(|probe| ctx.find_location(probe).unwrap());
 | 
					 | 
				
			||||||
            print_loc(loc.as_ref(), opts.basenames, opts.llvm);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if opts.llvm {
 | 
					 | 
				
			||||||
            println!();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        std::io::stdout().flush().unwrap();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										1
									
								
								vendor/addr2line/rustfmt.toml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								vendor/addr2line/rustfmt.toml
									
									
									
									
										vendored
									
									
								
							@@ -1 +0,0 @@
 | 
				
			|||||||
 | 
					 | 
				
			||||||
							
								
								
									
										164
									
								
								vendor/addr2line/src/builtin_split_dwarf_loader.rs
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										164
									
								
								vendor/addr2line/src/builtin_split_dwarf_loader.rs
									
									
									
									
										vendored
									
									
								
							@@ -1,164 +0,0 @@
 | 
				
			|||||||
use alloc::borrow::Cow;
 | 
					 | 
				
			||||||
use alloc::sync::Arc;
 | 
					 | 
				
			||||||
use std::fs::File;
 | 
					 | 
				
			||||||
use std::path::PathBuf;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use object::Object;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use crate::{LookupContinuation, LookupResult};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[cfg(unix)]
 | 
					 | 
				
			||||||
fn convert_path<R: gimli::Reader<Endian = gimli::RunTimeEndian>>(
 | 
					 | 
				
			||||||
    r: &R,
 | 
					 | 
				
			||||||
) -> Result<PathBuf, gimli::Error> {
 | 
					 | 
				
			||||||
    use std::ffi::OsStr;
 | 
					 | 
				
			||||||
    use std::os::unix::ffi::OsStrExt;
 | 
					 | 
				
			||||||
    let bytes = r.to_slice()?;
 | 
					 | 
				
			||||||
    let s = OsStr::from_bytes(&bytes);
 | 
					 | 
				
			||||||
    Ok(PathBuf::from(s))
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[cfg(not(unix))]
 | 
					 | 
				
			||||||
fn convert_path<R: gimli::Reader<Endian = gimli::RunTimeEndian>>(
 | 
					 | 
				
			||||||
    r: &R,
 | 
					 | 
				
			||||||
) -> Result<PathBuf, gimli::Error> {
 | 
					 | 
				
			||||||
    let bytes = r.to_slice()?;
 | 
					 | 
				
			||||||
    let s = std::str::from_utf8(&bytes).map_err(|_| gimli::Error::BadUtf8)?;
 | 
					 | 
				
			||||||
    Ok(PathBuf::from(s))
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
fn load_section<'data: 'file, 'file, O, R, F>(
 | 
					 | 
				
			||||||
    id: gimli::SectionId,
 | 
					 | 
				
			||||||
    file: &'file O,
 | 
					 | 
				
			||||||
    endian: R::Endian,
 | 
					 | 
				
			||||||
    loader: &mut F,
 | 
					 | 
				
			||||||
) -> Result<R, gimli::Error>
 | 
					 | 
				
			||||||
where
 | 
					 | 
				
			||||||
    O: object::Object<'data, 'file>,
 | 
					 | 
				
			||||||
    R: gimli::Reader<Endian = gimli::RunTimeEndian>,
 | 
					 | 
				
			||||||
    F: FnMut(Cow<'data, [u8]>, R::Endian) -> R,
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    use object::ObjectSection;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let data = id
 | 
					 | 
				
			||||||
        .dwo_name()
 | 
					 | 
				
			||||||
        .and_then(|dwo_name| {
 | 
					 | 
				
			||||||
            file.section_by_name(dwo_name)
 | 
					 | 
				
			||||||
                .and_then(|section| section.uncompressed_data().ok())
 | 
					 | 
				
			||||||
        })
 | 
					 | 
				
			||||||
        .unwrap_or(Cow::Borrowed(&[]));
 | 
					 | 
				
			||||||
    Ok(loader(data, endian))
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// A simple builtin split DWARF loader.
 | 
					 | 
				
			||||||
pub struct SplitDwarfLoader<R, F>
 | 
					 | 
				
			||||||
where
 | 
					 | 
				
			||||||
    R: gimli::Reader<Endian = gimli::RunTimeEndian>,
 | 
					 | 
				
			||||||
    F: FnMut(Cow<'_, [u8]>, R::Endian) -> R,
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    loader: F,
 | 
					 | 
				
			||||||
    dwarf_package: Option<gimli::DwarfPackage<R>>,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl<R, F> SplitDwarfLoader<R, F>
 | 
					 | 
				
			||||||
where
 | 
					 | 
				
			||||||
    R: gimli::Reader<Endian = gimli::RunTimeEndian>,
 | 
					 | 
				
			||||||
    F: FnMut(Cow<'_, [u8]>, R::Endian) -> R,
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    fn load_dwarf_package(loader: &mut F, path: Option<PathBuf>) -> Option<gimli::DwarfPackage<R>> {
 | 
					 | 
				
			||||||
        let mut path = path.map(Ok).unwrap_or_else(std::env::current_exe).ok()?;
 | 
					 | 
				
			||||||
        let dwp_extension = path
 | 
					 | 
				
			||||||
            .extension()
 | 
					 | 
				
			||||||
            .map(|previous_extension| {
 | 
					 | 
				
			||||||
                let mut previous_extension = previous_extension.to_os_string();
 | 
					 | 
				
			||||||
                previous_extension.push(".dwp");
 | 
					 | 
				
			||||||
                previous_extension
 | 
					 | 
				
			||||||
            })
 | 
					 | 
				
			||||||
            .unwrap_or_else(|| "dwp".into());
 | 
					 | 
				
			||||||
        path.set_extension(dwp_extension);
 | 
					 | 
				
			||||||
        let file = File::open(&path).ok()?;
 | 
					 | 
				
			||||||
        let map = unsafe { memmap2::Mmap::map(&file).ok()? };
 | 
					 | 
				
			||||||
        let dwp = object::File::parse(&*map).ok()?;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        let endian = if dwp.is_little_endian() {
 | 
					 | 
				
			||||||
            gimli::RunTimeEndian::Little
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            gimli::RunTimeEndian::Big
 | 
					 | 
				
			||||||
        };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        let empty = loader(Cow::Borrowed(&[]), endian);
 | 
					 | 
				
			||||||
        gimli::DwarfPackage::load(
 | 
					 | 
				
			||||||
            |section_id| load_section(section_id, &dwp, endian, loader),
 | 
					 | 
				
			||||||
            empty,
 | 
					 | 
				
			||||||
        )
 | 
					 | 
				
			||||||
        .ok()
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Create a new split DWARF loader.
 | 
					 | 
				
			||||||
    pub fn new(mut loader: F, path: Option<PathBuf>) -> SplitDwarfLoader<R, F> {
 | 
					 | 
				
			||||||
        let dwarf_package = SplitDwarfLoader::load_dwarf_package(&mut loader, path);
 | 
					 | 
				
			||||||
        SplitDwarfLoader {
 | 
					 | 
				
			||||||
            loader,
 | 
					 | 
				
			||||||
            dwarf_package,
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Run the provided `LookupResult` to completion, loading any necessary
 | 
					 | 
				
			||||||
    /// split DWARF along the way.
 | 
					 | 
				
			||||||
    pub fn run<L>(&mut self, mut l: LookupResult<L>) -> L::Output
 | 
					 | 
				
			||||||
    where
 | 
					 | 
				
			||||||
        L: LookupContinuation<Buf = R>,
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        loop {
 | 
					 | 
				
			||||||
            let (load, continuation) = match l {
 | 
					 | 
				
			||||||
                LookupResult::Output(output) => break output,
 | 
					 | 
				
			||||||
                LookupResult::Load { load, continuation } => (load, continuation),
 | 
					 | 
				
			||||||
            };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            let mut r: Option<Arc<gimli::Dwarf<_>>> = None;
 | 
					 | 
				
			||||||
            if let Some(dwp) = self.dwarf_package.as_ref() {
 | 
					 | 
				
			||||||
                if let Ok(Some(cu)) = dwp.find_cu(load.dwo_id, &load.parent) {
 | 
					 | 
				
			||||||
                    r = Some(Arc::new(cu));
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if r.is_none() {
 | 
					 | 
				
			||||||
                let mut path = PathBuf::new();
 | 
					 | 
				
			||||||
                if let Some(p) = load.comp_dir.as_ref() {
 | 
					 | 
				
			||||||
                    if let Ok(p) = convert_path(p) {
 | 
					 | 
				
			||||||
                        path.push(p);
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                if let Some(p) = load.path.as_ref() {
 | 
					 | 
				
			||||||
                    if let Ok(p) = convert_path(p) {
 | 
					 | 
				
			||||||
                        path.push(p);
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                if let Ok(file) = File::open(&path) {
 | 
					 | 
				
			||||||
                    if let Ok(map) = unsafe { memmap2::Mmap::map(&file) } {
 | 
					 | 
				
			||||||
                        if let Ok(file) = object::File::parse(&*map) {
 | 
					 | 
				
			||||||
                            let endian = if file.is_little_endian() {
 | 
					 | 
				
			||||||
                                gimli::RunTimeEndian::Little
 | 
					 | 
				
			||||||
                            } else {
 | 
					 | 
				
			||||||
                                gimli::RunTimeEndian::Big
 | 
					 | 
				
			||||||
                            };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                            r = gimli::Dwarf::load(|id| {
 | 
					 | 
				
			||||||
                                load_section(id, &file, endian, &mut self.loader)
 | 
					 | 
				
			||||||
                            })
 | 
					 | 
				
			||||||
                            .ok()
 | 
					 | 
				
			||||||
                            .map(|mut dwo_dwarf| {
 | 
					 | 
				
			||||||
                                dwo_dwarf.make_dwo(&load.parent);
 | 
					 | 
				
			||||||
                                Arc::new(dwo_dwarf)
 | 
					 | 
				
			||||||
                            });
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            l = continuation.resume(r);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										555
									
								
								vendor/addr2line/src/function.rs
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										555
									
								
								vendor/addr2line/src/function.rs
									
									
									
									
										vendored
									
									
								
							@@ -1,555 +0,0 @@
 | 
				
			|||||||
use alloc::boxed::Box;
 | 
					 | 
				
			||||||
use alloc::vec::Vec;
 | 
					 | 
				
			||||||
use core::cmp::Ordering;
 | 
					 | 
				
			||||||
use core::iter;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use crate::lazy::LazyCell;
 | 
					 | 
				
			||||||
use crate::maybe_small;
 | 
					 | 
				
			||||||
use crate::{Context, DebugFile, Error, RangeAttributes};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pub(crate) struct Functions<R: gimli::Reader> {
 | 
					 | 
				
			||||||
    /// List of all `DW_TAG_subprogram` details in the unit.
 | 
					 | 
				
			||||||
    pub(crate) functions: Box<
 | 
					 | 
				
			||||||
        [(
 | 
					 | 
				
			||||||
            gimli::UnitOffset<R::Offset>,
 | 
					 | 
				
			||||||
            LazyCell<Result<Function<R>, Error>>,
 | 
					 | 
				
			||||||
        )],
 | 
					 | 
				
			||||||
    >,
 | 
					 | 
				
			||||||
    /// List of `DW_TAG_subprogram` address ranges in the unit.
 | 
					 | 
				
			||||||
    pub(crate) addresses: Box<[FunctionAddress]>,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// A single address range for a function.
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// It is possible for a function to have multiple address ranges; this
 | 
					 | 
				
			||||||
/// is handled by having multiple `FunctionAddress` entries with the same
 | 
					 | 
				
			||||||
/// `function` field.
 | 
					 | 
				
			||||||
pub(crate) struct FunctionAddress {
 | 
					 | 
				
			||||||
    range: gimli::Range,
 | 
					 | 
				
			||||||
    /// An index into `Functions::functions`.
 | 
					 | 
				
			||||||
    pub(crate) function: usize,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pub(crate) struct Function<R: gimli::Reader> {
 | 
					 | 
				
			||||||
    pub(crate) dw_die_offset: gimli::UnitOffset<R::Offset>,
 | 
					 | 
				
			||||||
    pub(crate) name: Option<R>,
 | 
					 | 
				
			||||||
    /// List of all `DW_TAG_inlined_subroutine` details in this function.
 | 
					 | 
				
			||||||
    inlined_functions: Box<[InlinedFunction<R>]>,
 | 
					 | 
				
			||||||
    /// List of `DW_TAG_inlined_subroutine` address ranges in this function.
 | 
					 | 
				
			||||||
    inlined_addresses: Box<[InlinedFunctionAddress]>,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pub(crate) struct InlinedFunctionAddress {
 | 
					 | 
				
			||||||
    range: gimli::Range,
 | 
					 | 
				
			||||||
    call_depth: usize,
 | 
					 | 
				
			||||||
    /// An index into `Function::inlined_functions`.
 | 
					 | 
				
			||||||
    function: usize,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pub(crate) struct InlinedFunction<R: gimli::Reader> {
 | 
					 | 
				
			||||||
    pub(crate) dw_die_offset: gimli::UnitOffset<R::Offset>,
 | 
					 | 
				
			||||||
    pub(crate) name: Option<R>,
 | 
					 | 
				
			||||||
    pub(crate) call_file: Option<u64>,
 | 
					 | 
				
			||||||
    pub(crate) call_line: u32,
 | 
					 | 
				
			||||||
    pub(crate) call_column: u32,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl<R: gimli::Reader> Functions<R> {
 | 
					 | 
				
			||||||
    pub(crate) fn parse(
 | 
					 | 
				
			||||||
        unit: &gimli::Unit<R>,
 | 
					 | 
				
			||||||
        sections: &gimli::Dwarf<R>,
 | 
					 | 
				
			||||||
    ) -> Result<Functions<R>, Error> {
 | 
					 | 
				
			||||||
        let mut functions = Vec::new();
 | 
					 | 
				
			||||||
        let mut addresses = Vec::new();
 | 
					 | 
				
			||||||
        let mut entries = unit.entries_raw(None)?;
 | 
					 | 
				
			||||||
        while !entries.is_empty() {
 | 
					 | 
				
			||||||
            let dw_die_offset = entries.next_offset();
 | 
					 | 
				
			||||||
            if let Some(abbrev) = entries.read_abbreviation()? {
 | 
					 | 
				
			||||||
                if abbrev.tag() == gimli::DW_TAG_subprogram {
 | 
					 | 
				
			||||||
                    let mut ranges = RangeAttributes::default();
 | 
					 | 
				
			||||||
                    for spec in abbrev.attributes() {
 | 
					 | 
				
			||||||
                        match entries.read_attribute(*spec) {
 | 
					 | 
				
			||||||
                            Ok(ref attr) => {
 | 
					 | 
				
			||||||
                                match attr.name() {
 | 
					 | 
				
			||||||
                                    gimli::DW_AT_low_pc => match attr.value() {
 | 
					 | 
				
			||||||
                                        gimli::AttributeValue::Addr(val) => {
 | 
					 | 
				
			||||||
                                            ranges.low_pc = Some(val)
 | 
					 | 
				
			||||||
                                        }
 | 
					 | 
				
			||||||
                                        gimli::AttributeValue::DebugAddrIndex(index) => {
 | 
					 | 
				
			||||||
                                            ranges.low_pc = Some(sections.address(unit, index)?);
 | 
					 | 
				
			||||||
                                        }
 | 
					 | 
				
			||||||
                                        _ => {}
 | 
					 | 
				
			||||||
                                    },
 | 
					 | 
				
			||||||
                                    gimli::DW_AT_high_pc => match attr.value() {
 | 
					 | 
				
			||||||
                                        gimli::AttributeValue::Addr(val) => {
 | 
					 | 
				
			||||||
                                            ranges.high_pc = Some(val)
 | 
					 | 
				
			||||||
                                        }
 | 
					 | 
				
			||||||
                                        gimli::AttributeValue::DebugAddrIndex(index) => {
 | 
					 | 
				
			||||||
                                            ranges.high_pc = Some(sections.address(unit, index)?);
 | 
					 | 
				
			||||||
                                        }
 | 
					 | 
				
			||||||
                                        gimli::AttributeValue::Udata(val) => {
 | 
					 | 
				
			||||||
                                            ranges.size = Some(val)
 | 
					 | 
				
			||||||
                                        }
 | 
					 | 
				
			||||||
                                        _ => {}
 | 
					 | 
				
			||||||
                                    },
 | 
					 | 
				
			||||||
                                    gimli::DW_AT_ranges => {
 | 
					 | 
				
			||||||
                                        ranges.ranges_offset =
 | 
					 | 
				
			||||||
                                            sections.attr_ranges_offset(unit, attr.value())?;
 | 
					 | 
				
			||||||
                                    }
 | 
					 | 
				
			||||||
                                    _ => {}
 | 
					 | 
				
			||||||
                                };
 | 
					 | 
				
			||||||
                            }
 | 
					 | 
				
			||||||
                            Err(e) => return Err(e),
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    let function_index = functions.len();
 | 
					 | 
				
			||||||
                    if ranges.for_each_range(sections, unit, |range| {
 | 
					 | 
				
			||||||
                        addresses.push(FunctionAddress {
 | 
					 | 
				
			||||||
                            range,
 | 
					 | 
				
			||||||
                            function: function_index,
 | 
					 | 
				
			||||||
                        });
 | 
					 | 
				
			||||||
                    })? {
 | 
					 | 
				
			||||||
                        functions.push((dw_die_offset, LazyCell::new()));
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                } else {
 | 
					 | 
				
			||||||
                    entries.skip_attributes(abbrev.attributes())?;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // The binary search requires the addresses to be sorted.
 | 
					 | 
				
			||||||
        //
 | 
					 | 
				
			||||||
        // It also requires them to be non-overlapping.  In practice, overlapping
 | 
					 | 
				
			||||||
        // function ranges are unlikely, so we don't try to handle that yet.
 | 
					 | 
				
			||||||
        //
 | 
					 | 
				
			||||||
        // It's possible for multiple functions to have the same address range if the
 | 
					 | 
				
			||||||
        // compiler can detect and remove functions with identical code.  In that case
 | 
					 | 
				
			||||||
        // we'll nondeterministically return one of them.
 | 
					 | 
				
			||||||
        addresses.sort_by_key(|x| x.range.begin);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Ok(Functions {
 | 
					 | 
				
			||||||
            functions: functions.into_boxed_slice(),
 | 
					 | 
				
			||||||
            addresses: addresses.into_boxed_slice(),
 | 
					 | 
				
			||||||
        })
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    pub(crate) fn find_address(&self, probe: u64) -> Option<usize> {
 | 
					 | 
				
			||||||
        self.addresses
 | 
					 | 
				
			||||||
            .binary_search_by(|address| {
 | 
					 | 
				
			||||||
                if probe < address.range.begin {
 | 
					 | 
				
			||||||
                    Ordering::Greater
 | 
					 | 
				
			||||||
                } else if probe >= address.range.end {
 | 
					 | 
				
			||||||
                    Ordering::Less
 | 
					 | 
				
			||||||
                } else {
 | 
					 | 
				
			||||||
                    Ordering::Equal
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            })
 | 
					 | 
				
			||||||
            .ok()
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    pub(crate) fn parse_inlined_functions(
 | 
					 | 
				
			||||||
        &self,
 | 
					 | 
				
			||||||
        file: DebugFile,
 | 
					 | 
				
			||||||
        unit: &gimli::Unit<R>,
 | 
					 | 
				
			||||||
        ctx: &Context<R>,
 | 
					 | 
				
			||||||
        sections: &gimli::Dwarf<R>,
 | 
					 | 
				
			||||||
    ) -> Result<(), Error> {
 | 
					 | 
				
			||||||
        for function in &*self.functions {
 | 
					 | 
				
			||||||
            function
 | 
					 | 
				
			||||||
                .1
 | 
					 | 
				
			||||||
                .borrow_with(|| Function::parse(function.0, file, unit, ctx, sections))
 | 
					 | 
				
			||||||
                .as_ref()
 | 
					 | 
				
			||||||
                .map_err(Error::clone)?;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        Ok(())
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl<R: gimli::Reader> Function<R> {
 | 
					 | 
				
			||||||
    pub(crate) fn parse(
 | 
					 | 
				
			||||||
        dw_die_offset: gimli::UnitOffset<R::Offset>,
 | 
					 | 
				
			||||||
        file: DebugFile,
 | 
					 | 
				
			||||||
        unit: &gimli::Unit<R>,
 | 
					 | 
				
			||||||
        ctx: &Context<R>,
 | 
					 | 
				
			||||||
        sections: &gimli::Dwarf<R>,
 | 
					 | 
				
			||||||
    ) -> Result<Self, Error> {
 | 
					 | 
				
			||||||
        let mut entries = unit.entries_raw(Some(dw_die_offset))?;
 | 
					 | 
				
			||||||
        let depth = entries.next_depth();
 | 
					 | 
				
			||||||
        let abbrev = entries.read_abbreviation()?.unwrap();
 | 
					 | 
				
			||||||
        debug_assert_eq!(abbrev.tag(), gimli::DW_TAG_subprogram);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        let mut name = None;
 | 
					 | 
				
			||||||
        for spec in abbrev.attributes() {
 | 
					 | 
				
			||||||
            match entries.read_attribute(*spec) {
 | 
					 | 
				
			||||||
                Ok(ref attr) => {
 | 
					 | 
				
			||||||
                    match attr.name() {
 | 
					 | 
				
			||||||
                        gimli::DW_AT_linkage_name | gimli::DW_AT_MIPS_linkage_name => {
 | 
					 | 
				
			||||||
                            if let Ok(val) = sections.attr_string(unit, attr.value()) {
 | 
					 | 
				
			||||||
                                name = Some(val);
 | 
					 | 
				
			||||||
                            }
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                        gimli::DW_AT_name => {
 | 
					 | 
				
			||||||
                            if name.is_none() {
 | 
					 | 
				
			||||||
                                name = sections.attr_string(unit, attr.value()).ok();
 | 
					 | 
				
			||||||
                            }
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                        gimli::DW_AT_abstract_origin | gimli::DW_AT_specification => {
 | 
					 | 
				
			||||||
                            if name.is_none() {
 | 
					 | 
				
			||||||
                                name = name_attr(attr.value(), file, unit, ctx, sections, 16)?;
 | 
					 | 
				
			||||||
                            }
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                        _ => {}
 | 
					 | 
				
			||||||
                    };
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                Err(e) => return Err(e),
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        let mut inlined_functions = Vec::new();
 | 
					 | 
				
			||||||
        let mut inlined_addresses = Vec::new();
 | 
					 | 
				
			||||||
        Function::parse_children(
 | 
					 | 
				
			||||||
            &mut entries,
 | 
					 | 
				
			||||||
            depth,
 | 
					 | 
				
			||||||
            file,
 | 
					 | 
				
			||||||
            unit,
 | 
					 | 
				
			||||||
            ctx,
 | 
					 | 
				
			||||||
            sections,
 | 
					 | 
				
			||||||
            &mut inlined_functions,
 | 
					 | 
				
			||||||
            &mut inlined_addresses,
 | 
					 | 
				
			||||||
            0,
 | 
					 | 
				
			||||||
        )?;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Sort ranges in "breadth-first traversal order", i.e. first by call_depth
 | 
					 | 
				
			||||||
        // and then by range.begin. This allows finding the range containing an
 | 
					 | 
				
			||||||
        // address at a certain depth using binary search.
 | 
					 | 
				
			||||||
        // Note: Using DFS order, i.e. ordering by range.begin first and then by
 | 
					 | 
				
			||||||
        // call_depth, would not work! Consider the two examples
 | 
					 | 
				
			||||||
        // "[0..10 at depth 0], [0..2 at depth 1], [6..8 at depth 1]"  and
 | 
					 | 
				
			||||||
        // "[0..5 at depth 0], [0..2 at depth 1], [5..10 at depth 0], [6..8 at depth 1]".
 | 
					 | 
				
			||||||
        // In this example, if you want to look up address 7 at depth 0, and you
 | 
					 | 
				
			||||||
        // encounter [0..2 at depth 1], are you before or after the target range?
 | 
					 | 
				
			||||||
        // You don't know.
 | 
					 | 
				
			||||||
        inlined_addresses.sort_by(|r1, r2| {
 | 
					 | 
				
			||||||
            if r1.call_depth < r2.call_depth {
 | 
					 | 
				
			||||||
                Ordering::Less
 | 
					 | 
				
			||||||
            } else if r1.call_depth > r2.call_depth {
 | 
					 | 
				
			||||||
                Ordering::Greater
 | 
					 | 
				
			||||||
            } else if r1.range.begin < r2.range.begin {
 | 
					 | 
				
			||||||
                Ordering::Less
 | 
					 | 
				
			||||||
            } else if r1.range.begin > r2.range.begin {
 | 
					 | 
				
			||||||
                Ordering::Greater
 | 
					 | 
				
			||||||
            } else {
 | 
					 | 
				
			||||||
                Ordering::Equal
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Ok(Function {
 | 
					 | 
				
			||||||
            dw_die_offset,
 | 
					 | 
				
			||||||
            name,
 | 
					 | 
				
			||||||
            inlined_functions: inlined_functions.into_boxed_slice(),
 | 
					 | 
				
			||||||
            inlined_addresses: inlined_addresses.into_boxed_slice(),
 | 
					 | 
				
			||||||
        })
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    fn parse_children(
 | 
					 | 
				
			||||||
        entries: &mut gimli::EntriesRaw<'_, '_, R>,
 | 
					 | 
				
			||||||
        depth: isize,
 | 
					 | 
				
			||||||
        file: DebugFile,
 | 
					 | 
				
			||||||
        unit: &gimli::Unit<R>,
 | 
					 | 
				
			||||||
        ctx: &Context<R>,
 | 
					 | 
				
			||||||
        sections: &gimli::Dwarf<R>,
 | 
					 | 
				
			||||||
        inlined_functions: &mut Vec<InlinedFunction<R>>,
 | 
					 | 
				
			||||||
        inlined_addresses: &mut Vec<InlinedFunctionAddress>,
 | 
					 | 
				
			||||||
        inlined_depth: usize,
 | 
					 | 
				
			||||||
    ) -> Result<(), Error> {
 | 
					 | 
				
			||||||
        loop {
 | 
					 | 
				
			||||||
            let dw_die_offset = entries.next_offset();
 | 
					 | 
				
			||||||
            let next_depth = entries.next_depth();
 | 
					 | 
				
			||||||
            if next_depth <= depth {
 | 
					 | 
				
			||||||
                return Ok(());
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            if let Some(abbrev) = entries.read_abbreviation()? {
 | 
					 | 
				
			||||||
                match abbrev.tag() {
 | 
					 | 
				
			||||||
                    gimli::DW_TAG_subprogram => {
 | 
					 | 
				
			||||||
                        Function::skip(entries, abbrev, next_depth)?;
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    gimli::DW_TAG_inlined_subroutine => {
 | 
					 | 
				
			||||||
                        InlinedFunction::parse(
 | 
					 | 
				
			||||||
                            dw_die_offset,
 | 
					 | 
				
			||||||
                            entries,
 | 
					 | 
				
			||||||
                            abbrev,
 | 
					 | 
				
			||||||
                            next_depth,
 | 
					 | 
				
			||||||
                            file,
 | 
					 | 
				
			||||||
                            unit,
 | 
					 | 
				
			||||||
                            ctx,
 | 
					 | 
				
			||||||
                            sections,
 | 
					 | 
				
			||||||
                            inlined_functions,
 | 
					 | 
				
			||||||
                            inlined_addresses,
 | 
					 | 
				
			||||||
                            inlined_depth,
 | 
					 | 
				
			||||||
                        )?;
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    _ => {
 | 
					 | 
				
			||||||
                        entries.skip_attributes(abbrev.attributes())?;
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    fn skip(
 | 
					 | 
				
			||||||
        entries: &mut gimli::EntriesRaw<'_, '_, R>,
 | 
					 | 
				
			||||||
        abbrev: &gimli::Abbreviation,
 | 
					 | 
				
			||||||
        depth: isize,
 | 
					 | 
				
			||||||
    ) -> Result<(), Error> {
 | 
					 | 
				
			||||||
        // TODO: use DW_AT_sibling
 | 
					 | 
				
			||||||
        entries.skip_attributes(abbrev.attributes())?;
 | 
					 | 
				
			||||||
        while entries.next_depth() > depth {
 | 
					 | 
				
			||||||
            if let Some(abbrev) = entries.read_abbreviation()? {
 | 
					 | 
				
			||||||
                entries.skip_attributes(abbrev.attributes())?;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        Ok(())
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Build the list of inlined functions that contain `probe`.
 | 
					 | 
				
			||||||
    pub(crate) fn find_inlined_functions(
 | 
					 | 
				
			||||||
        &self,
 | 
					 | 
				
			||||||
        probe: u64,
 | 
					 | 
				
			||||||
    ) -> iter::Rev<maybe_small::IntoIter<&InlinedFunction<R>>> {
 | 
					 | 
				
			||||||
        // `inlined_functions` is ordered from outside to inside.
 | 
					 | 
				
			||||||
        let mut inlined_functions = maybe_small::Vec::new();
 | 
					 | 
				
			||||||
        let mut inlined_addresses = &self.inlined_addresses[..];
 | 
					 | 
				
			||||||
        loop {
 | 
					 | 
				
			||||||
            let current_depth = inlined_functions.len();
 | 
					 | 
				
			||||||
            // Look up (probe, current_depth) in inline_ranges.
 | 
					 | 
				
			||||||
            // `inlined_addresses` is sorted in "breadth-first traversal order", i.e.
 | 
					 | 
				
			||||||
            // by `call_depth` first, and then by `range.begin`. See the comment at
 | 
					 | 
				
			||||||
            // the sort call for more information about why.
 | 
					 | 
				
			||||||
            let search = inlined_addresses.binary_search_by(|range| {
 | 
					 | 
				
			||||||
                if range.call_depth > current_depth {
 | 
					 | 
				
			||||||
                    Ordering::Greater
 | 
					 | 
				
			||||||
                } else if range.call_depth < current_depth {
 | 
					 | 
				
			||||||
                    Ordering::Less
 | 
					 | 
				
			||||||
                } else if range.range.begin > probe {
 | 
					 | 
				
			||||||
                    Ordering::Greater
 | 
					 | 
				
			||||||
                } else if range.range.end <= probe {
 | 
					 | 
				
			||||||
                    Ordering::Less
 | 
					 | 
				
			||||||
                } else {
 | 
					 | 
				
			||||||
                    Ordering::Equal
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
            if let Ok(index) = search {
 | 
					 | 
				
			||||||
                let function_index = inlined_addresses[index].function;
 | 
					 | 
				
			||||||
                inlined_functions.push(&self.inlined_functions[function_index]);
 | 
					 | 
				
			||||||
                inlined_addresses = &inlined_addresses[index + 1..];
 | 
					 | 
				
			||||||
            } else {
 | 
					 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        inlined_functions.into_iter().rev()
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl<R: gimli::Reader> InlinedFunction<R> {
 | 
					 | 
				
			||||||
    fn parse(
 | 
					 | 
				
			||||||
        dw_die_offset: gimli::UnitOffset<R::Offset>,
 | 
					 | 
				
			||||||
        entries: &mut gimli::EntriesRaw<'_, '_, R>,
 | 
					 | 
				
			||||||
        abbrev: &gimli::Abbreviation,
 | 
					 | 
				
			||||||
        depth: isize,
 | 
					 | 
				
			||||||
        file: DebugFile,
 | 
					 | 
				
			||||||
        unit: &gimli::Unit<R>,
 | 
					 | 
				
			||||||
        ctx: &Context<R>,
 | 
					 | 
				
			||||||
        sections: &gimli::Dwarf<R>,
 | 
					 | 
				
			||||||
        inlined_functions: &mut Vec<InlinedFunction<R>>,
 | 
					 | 
				
			||||||
        inlined_addresses: &mut Vec<InlinedFunctionAddress>,
 | 
					 | 
				
			||||||
        inlined_depth: usize,
 | 
					 | 
				
			||||||
    ) -> Result<(), Error> {
 | 
					 | 
				
			||||||
        let mut ranges = RangeAttributes::default();
 | 
					 | 
				
			||||||
        let mut name = None;
 | 
					 | 
				
			||||||
        let mut call_file = None;
 | 
					 | 
				
			||||||
        let mut call_line = 0;
 | 
					 | 
				
			||||||
        let mut call_column = 0;
 | 
					 | 
				
			||||||
        for spec in abbrev.attributes() {
 | 
					 | 
				
			||||||
            match entries.read_attribute(*spec) {
 | 
					 | 
				
			||||||
                Ok(ref attr) => match attr.name() {
 | 
					 | 
				
			||||||
                    gimli::DW_AT_low_pc => match attr.value() {
 | 
					 | 
				
			||||||
                        gimli::AttributeValue::Addr(val) => ranges.low_pc = Some(val),
 | 
					 | 
				
			||||||
                        gimli::AttributeValue::DebugAddrIndex(index) => {
 | 
					 | 
				
			||||||
                            ranges.low_pc = Some(sections.address(unit, index)?);
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                        _ => {}
 | 
					 | 
				
			||||||
                    },
 | 
					 | 
				
			||||||
                    gimli::DW_AT_high_pc => match attr.value() {
 | 
					 | 
				
			||||||
                        gimli::AttributeValue::Addr(val) => ranges.high_pc = Some(val),
 | 
					 | 
				
			||||||
                        gimli::AttributeValue::DebugAddrIndex(index) => {
 | 
					 | 
				
			||||||
                            ranges.high_pc = Some(sections.address(unit, index)?);
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                        gimli::AttributeValue::Udata(val) => ranges.size = Some(val),
 | 
					 | 
				
			||||||
                        _ => {}
 | 
					 | 
				
			||||||
                    },
 | 
					 | 
				
			||||||
                    gimli::DW_AT_ranges => {
 | 
					 | 
				
			||||||
                        ranges.ranges_offset = sections.attr_ranges_offset(unit, attr.value())?;
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    gimli::DW_AT_linkage_name | gimli::DW_AT_MIPS_linkage_name => {
 | 
					 | 
				
			||||||
                        if let Ok(val) = sections.attr_string(unit, attr.value()) {
 | 
					 | 
				
			||||||
                            name = Some(val);
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    gimli::DW_AT_name => {
 | 
					 | 
				
			||||||
                        if name.is_none() {
 | 
					 | 
				
			||||||
                            name = sections.attr_string(unit, attr.value()).ok();
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    gimli::DW_AT_abstract_origin | gimli::DW_AT_specification => {
 | 
					 | 
				
			||||||
                        if name.is_none() {
 | 
					 | 
				
			||||||
                            name = name_attr(attr.value(), file, unit, ctx, sections, 16)?;
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    gimli::DW_AT_call_file => {
 | 
					 | 
				
			||||||
                        // There is a spec issue [1] with how DW_AT_call_file is specified in DWARF 5.
 | 
					 | 
				
			||||||
                        // Before, a file index of 0 would indicate no source file, however in
 | 
					 | 
				
			||||||
                        // DWARF 5 this could be a valid index into the file table.
 | 
					 | 
				
			||||||
                        //
 | 
					 | 
				
			||||||
                        // Implementations such as LLVM generates a file index of 0 when DWARF 5 is
 | 
					 | 
				
			||||||
                        // used.
 | 
					 | 
				
			||||||
                        //
 | 
					 | 
				
			||||||
                        // Thus, if we see a version of 5 or later, treat a file index of 0 as such.
 | 
					 | 
				
			||||||
                        // [1]: http://wiki.dwarfstd.org/index.php?title=DWARF5_Line_Table_File_Numbers
 | 
					 | 
				
			||||||
                        if let gimli::AttributeValue::FileIndex(fi) = attr.value() {
 | 
					 | 
				
			||||||
                            if fi > 0 || unit.header.version() >= 5 {
 | 
					 | 
				
			||||||
                                call_file = Some(fi);
 | 
					 | 
				
			||||||
                            }
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    gimli::DW_AT_call_line => {
 | 
					 | 
				
			||||||
                        call_line = attr.udata_value().unwrap_or(0) as u32;
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    gimli::DW_AT_call_column => {
 | 
					 | 
				
			||||||
                        call_column = attr.udata_value().unwrap_or(0) as u32;
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    _ => {}
 | 
					 | 
				
			||||||
                },
 | 
					 | 
				
			||||||
                Err(e) => return Err(e),
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        let function_index = inlined_functions.len();
 | 
					 | 
				
			||||||
        inlined_functions.push(InlinedFunction {
 | 
					 | 
				
			||||||
            dw_die_offset,
 | 
					 | 
				
			||||||
            name,
 | 
					 | 
				
			||||||
            call_file,
 | 
					 | 
				
			||||||
            call_line,
 | 
					 | 
				
			||||||
            call_column,
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        ranges.for_each_range(sections, unit, |range| {
 | 
					 | 
				
			||||||
            inlined_addresses.push(InlinedFunctionAddress {
 | 
					 | 
				
			||||||
                range,
 | 
					 | 
				
			||||||
                call_depth: inlined_depth,
 | 
					 | 
				
			||||||
                function: function_index,
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
        })?;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Function::parse_children(
 | 
					 | 
				
			||||||
            entries,
 | 
					 | 
				
			||||||
            depth,
 | 
					 | 
				
			||||||
            file,
 | 
					 | 
				
			||||||
            unit,
 | 
					 | 
				
			||||||
            ctx,
 | 
					 | 
				
			||||||
            sections,
 | 
					 | 
				
			||||||
            inlined_functions,
 | 
					 | 
				
			||||||
            inlined_addresses,
 | 
					 | 
				
			||||||
            inlined_depth + 1,
 | 
					 | 
				
			||||||
        )
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
fn name_attr<R>(
 | 
					 | 
				
			||||||
    attr: gimli::AttributeValue<R>,
 | 
					 | 
				
			||||||
    mut file: DebugFile,
 | 
					 | 
				
			||||||
    unit: &gimli::Unit<R>,
 | 
					 | 
				
			||||||
    ctx: &Context<R>,
 | 
					 | 
				
			||||||
    sections: &gimli::Dwarf<R>,
 | 
					 | 
				
			||||||
    recursion_limit: usize,
 | 
					 | 
				
			||||||
) -> Result<Option<R>, Error>
 | 
					 | 
				
			||||||
where
 | 
					 | 
				
			||||||
    R: gimli::Reader,
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    if recursion_limit == 0 {
 | 
					 | 
				
			||||||
        return Ok(None);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    match attr {
 | 
					 | 
				
			||||||
        gimli::AttributeValue::UnitRef(offset) => {
 | 
					 | 
				
			||||||
            name_entry(file, unit, offset, ctx, sections, recursion_limit)
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        gimli::AttributeValue::DebugInfoRef(dr) => {
 | 
					 | 
				
			||||||
            let (unit, offset) = ctx.find_unit(dr, file)?;
 | 
					 | 
				
			||||||
            name_entry(file, unit, offset, ctx, sections, recursion_limit)
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        gimli::AttributeValue::DebugInfoRefSup(dr) => {
 | 
					 | 
				
			||||||
            if let Some(sup_sections) = sections.sup.as_ref() {
 | 
					 | 
				
			||||||
                file = DebugFile::Supplementary;
 | 
					 | 
				
			||||||
                let (unit, offset) = ctx.find_unit(dr, file)?;
 | 
					 | 
				
			||||||
                name_entry(file, unit, offset, ctx, sup_sections, recursion_limit)
 | 
					 | 
				
			||||||
            } else {
 | 
					 | 
				
			||||||
                Ok(None)
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        _ => Ok(None),
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
fn name_entry<R>(
 | 
					 | 
				
			||||||
    file: DebugFile,
 | 
					 | 
				
			||||||
    unit: &gimli::Unit<R>,
 | 
					 | 
				
			||||||
    offset: gimli::UnitOffset<R::Offset>,
 | 
					 | 
				
			||||||
    ctx: &Context<R>,
 | 
					 | 
				
			||||||
    sections: &gimli::Dwarf<R>,
 | 
					 | 
				
			||||||
    recursion_limit: usize,
 | 
					 | 
				
			||||||
) -> Result<Option<R>, Error>
 | 
					 | 
				
			||||||
where
 | 
					 | 
				
			||||||
    R: gimli::Reader,
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    let mut entries = unit.entries_raw(Some(offset))?;
 | 
					 | 
				
			||||||
    let abbrev = if let Some(abbrev) = entries.read_abbreviation()? {
 | 
					 | 
				
			||||||
        abbrev
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
        return Err(gimli::Error::NoEntryAtGivenOffset);
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let mut name = None;
 | 
					 | 
				
			||||||
    let mut next = None;
 | 
					 | 
				
			||||||
    for spec in abbrev.attributes() {
 | 
					 | 
				
			||||||
        match entries.read_attribute(*spec) {
 | 
					 | 
				
			||||||
            Ok(ref attr) => match attr.name() {
 | 
					 | 
				
			||||||
                gimli::DW_AT_linkage_name | gimli::DW_AT_MIPS_linkage_name => {
 | 
					 | 
				
			||||||
                    if let Ok(val) = sections.attr_string(unit, attr.value()) {
 | 
					 | 
				
			||||||
                        return Ok(Some(val));
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                gimli::DW_AT_name => {
 | 
					 | 
				
			||||||
                    if let Ok(val) = sections.attr_string(unit, attr.value()) {
 | 
					 | 
				
			||||||
                        name = Some(val);
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                gimli::DW_AT_abstract_origin | gimli::DW_AT_specification => {
 | 
					 | 
				
			||||||
                    next = Some(attr.value());
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                _ => {}
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
            Err(e) => return Err(e),
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if name.is_some() {
 | 
					 | 
				
			||||||
        return Ok(name);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if let Some(next) = next {
 | 
					 | 
				
			||||||
        return name_attr(next, file, unit, ctx, sections, recursion_limit - 1);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Ok(None)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										31
									
								
								vendor/addr2line/src/lazy.rs
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										31
									
								
								vendor/addr2line/src/lazy.rs
									
									
									
									
										vendored
									
									
								
							@@ -1,31 +0,0 @@
 | 
				
			|||||||
use core::cell::UnsafeCell;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pub struct LazyCell<T> {
 | 
					 | 
				
			||||||
    contents: UnsafeCell<Option<T>>,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
impl<T> LazyCell<T> {
 | 
					 | 
				
			||||||
    pub fn new() -> LazyCell<T> {
 | 
					 | 
				
			||||||
        LazyCell {
 | 
					 | 
				
			||||||
            contents: UnsafeCell::new(None),
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    pub fn borrow(&self) -> Option<&T> {
 | 
					 | 
				
			||||||
        unsafe { &*self.contents.get() }.as_ref()
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    pub fn borrow_with(&self, closure: impl FnOnce() -> T) -> &T {
 | 
					 | 
				
			||||||
        // First check if we're already initialized...
 | 
					 | 
				
			||||||
        let ptr = self.contents.get();
 | 
					 | 
				
			||||||
        if let Some(val) = unsafe { &*ptr } {
 | 
					 | 
				
			||||||
            return val;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        // Note that while we're executing `closure` our `borrow_with` may
 | 
					 | 
				
			||||||
        // be called recursively. This means we need to check again after
 | 
					 | 
				
			||||||
        // the closure has executed. For that we use the `get_or_insert`
 | 
					 | 
				
			||||||
        // method which will only perform mutation if we aren't already
 | 
					 | 
				
			||||||
        // `Some`.
 | 
					 | 
				
			||||||
        let val = closure();
 | 
					 | 
				
			||||||
        unsafe { (*ptr).get_or_insert(val) }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										1729
									
								
								vendor/addr2line/src/lib.rs
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1729
									
								
								vendor/addr2line/src/lib.rs
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										126
									
								
								vendor/addr2line/tests/correctness.rs
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										126
									
								
								vendor/addr2line/tests/correctness.rs
									
									
									
									
										vendored
									
									
								
							@@ -1,126 +0,0 @@
 | 
				
			|||||||
use addr2line::Context;
 | 
					 | 
				
			||||||
use fallible_iterator::FallibleIterator;
 | 
					 | 
				
			||||||
use findshlibs::{IterationControl, SharedLibrary, TargetSharedLibrary};
 | 
					 | 
				
			||||||
use object::Object;
 | 
					 | 
				
			||||||
use std::borrow::Cow;
 | 
					 | 
				
			||||||
use std::fs::File;
 | 
					 | 
				
			||||||
use std::sync::Arc;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
fn find_debuginfo() -> memmap2::Mmap {
 | 
					 | 
				
			||||||
    let path = std::env::current_exe().unwrap();
 | 
					 | 
				
			||||||
    let file = File::open(&path).unwrap();
 | 
					 | 
				
			||||||
    let map = unsafe { memmap2::Mmap::map(&file).unwrap() };
 | 
					 | 
				
			||||||
    let file = &object::File::parse(&*map).unwrap();
 | 
					 | 
				
			||||||
    if let Ok(uuid) = file.mach_uuid() {
 | 
					 | 
				
			||||||
        for candidate in path.parent().unwrap().read_dir().unwrap() {
 | 
					 | 
				
			||||||
            let path = candidate.unwrap().path();
 | 
					 | 
				
			||||||
            if !path.to_str().unwrap().ends_with(".dSYM") {
 | 
					 | 
				
			||||||
                continue;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            for candidate in path.join("Contents/Resources/DWARF").read_dir().unwrap() {
 | 
					 | 
				
			||||||
                let path = candidate.unwrap().path();
 | 
					 | 
				
			||||||
                let file = File::open(&path).unwrap();
 | 
					 | 
				
			||||||
                let map = unsafe { memmap2::Mmap::map(&file).unwrap() };
 | 
					 | 
				
			||||||
                let file = &object::File::parse(&*map).unwrap();
 | 
					 | 
				
			||||||
                if file.mach_uuid().unwrap() == uuid {
 | 
					 | 
				
			||||||
                    return map;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return map;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[test]
 | 
					 | 
				
			||||||
fn correctness() {
 | 
					 | 
				
			||||||
    let map = find_debuginfo();
 | 
					 | 
				
			||||||
    let file = &object::File::parse(&*map).unwrap();
 | 
					 | 
				
			||||||
    let module_base = file.relative_address_base();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let endian = if file.is_little_endian() {
 | 
					 | 
				
			||||||
        gimli::RunTimeEndian::Little
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
        gimli::RunTimeEndian::Big
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    fn load_section<'data: 'file, 'file, O, Endian>(
 | 
					 | 
				
			||||||
        id: gimli::SectionId,
 | 
					 | 
				
			||||||
        file: &'file O,
 | 
					 | 
				
			||||||
        endian: Endian,
 | 
					 | 
				
			||||||
    ) -> Result<gimli::EndianArcSlice<Endian>, gimli::Error>
 | 
					 | 
				
			||||||
    where
 | 
					 | 
				
			||||||
        O: object::Object<'data, 'file>,
 | 
					 | 
				
			||||||
        Endian: gimli::Endianity,
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        use object::ObjectSection;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        let data = file
 | 
					 | 
				
			||||||
            .section_by_name(id.name())
 | 
					 | 
				
			||||||
            .and_then(|section| section.uncompressed_data().ok())
 | 
					 | 
				
			||||||
            .unwrap_or(Cow::Borrowed(&[]));
 | 
					 | 
				
			||||||
        Ok(gimli::EndianArcSlice::new(Arc::from(&*data), endian))
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let dwarf = gimli::Dwarf::load(|id| load_section(id, file, endian)).unwrap();
 | 
					 | 
				
			||||||
    let ctx = Context::from_dwarf(dwarf).unwrap();
 | 
					 | 
				
			||||||
    let mut split_dwarf_loader = addr2line::builtin_split_dwarf_loader::SplitDwarfLoader::new(
 | 
					 | 
				
			||||||
        |data, endian| gimli::EndianArcSlice::new(Arc::from(&*data), endian),
 | 
					 | 
				
			||||||
        None,
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let mut bias = None;
 | 
					 | 
				
			||||||
    TargetSharedLibrary::each(|lib| {
 | 
					 | 
				
			||||||
        bias = Some((lib.virtual_memory_bias().0 as u64).wrapping_sub(module_base));
 | 
					 | 
				
			||||||
        IterationControl::Break
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[allow(unused_mut)]
 | 
					 | 
				
			||||||
    let mut test = |sym: u64, expected_prefix: &str| {
 | 
					 | 
				
			||||||
        let ip = sym.wrapping_sub(bias.unwrap());
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        let frames = ctx.find_frames(ip);
 | 
					 | 
				
			||||||
        let frames = split_dwarf_loader.run(frames).unwrap();
 | 
					 | 
				
			||||||
        let frame = frames.last().unwrap().unwrap();
 | 
					 | 
				
			||||||
        let name = frame.function.as_ref().unwrap().demangle().unwrap();
 | 
					 | 
				
			||||||
        // Old rust versions generate DWARF with wrong linkage name,
 | 
					 | 
				
			||||||
        // so only check the start.
 | 
					 | 
				
			||||||
        if !name.starts_with(expected_prefix) {
 | 
					 | 
				
			||||||
            panic!("incorrect name '{}', expected {:?}", name, expected_prefix);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    test(test_function as u64, "correctness::test_function");
 | 
					 | 
				
			||||||
    test(
 | 
					 | 
				
			||||||
        small::test_function as u64,
 | 
					 | 
				
			||||||
        "correctness::small::test_function",
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
    test(auxiliary::foo as u64, "auxiliary::foo");
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
mod small {
 | 
					 | 
				
			||||||
    pub fn test_function() {
 | 
					 | 
				
			||||||
        println!("y");
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
fn test_function() {
 | 
					 | 
				
			||||||
    println!("x");
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[test]
 | 
					 | 
				
			||||||
fn zero_function() {
 | 
					 | 
				
			||||||
    let map = find_debuginfo();
 | 
					 | 
				
			||||||
    let file = &object::File::parse(&*map).unwrap();
 | 
					 | 
				
			||||||
    let ctx = Context::new(file).unwrap();
 | 
					 | 
				
			||||||
    for probe in 0..10 {
 | 
					 | 
				
			||||||
        assert!(
 | 
					 | 
				
			||||||
            ctx.find_frames(probe)
 | 
					 | 
				
			||||||
                .skip_all_loads()
 | 
					 | 
				
			||||||
                .unwrap()
 | 
					 | 
				
			||||||
                .count()
 | 
					 | 
				
			||||||
                .unwrap()
 | 
					 | 
				
			||||||
                < 10
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										135
									
								
								vendor/addr2line/tests/output_equivalence.rs
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										135
									
								
								vendor/addr2line/tests/output_equivalence.rs
									
									
									
									
										vendored
									
									
								
							@@ -1,135 +0,0 @@
 | 
				
			|||||||
use std::env;
 | 
					 | 
				
			||||||
use std::ffi::OsStr;
 | 
					 | 
				
			||||||
use std::path::Path;
 | 
					 | 
				
			||||||
use std::process::Command;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use backtrace::Backtrace;
 | 
					 | 
				
			||||||
use findshlibs::{IterationControl, SharedLibrary, TargetSharedLibrary};
 | 
					 | 
				
			||||||
use libtest_mimic::{Arguments, Failed, Trial};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[inline(never)]
 | 
					 | 
				
			||||||
fn make_trace() -> Vec<String> {
 | 
					 | 
				
			||||||
    fn foo() -> Backtrace {
 | 
					 | 
				
			||||||
        bar()
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    #[inline(never)]
 | 
					 | 
				
			||||||
    fn bar() -> Backtrace {
 | 
					 | 
				
			||||||
        baz()
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    #[inline(always)]
 | 
					 | 
				
			||||||
    fn baz() -> Backtrace {
 | 
					 | 
				
			||||||
        Backtrace::new_unresolved()
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let mut base_addr = None;
 | 
					 | 
				
			||||||
    TargetSharedLibrary::each(|lib| {
 | 
					 | 
				
			||||||
        base_addr = Some(lib.virtual_memory_bias().0 as isize);
 | 
					 | 
				
			||||||
        IterationControl::Break
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
    let addrfix = -base_addr.unwrap();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let trace = foo();
 | 
					 | 
				
			||||||
    trace
 | 
					 | 
				
			||||||
        .frames()
 | 
					 | 
				
			||||||
        .iter()
 | 
					 | 
				
			||||||
        .take(5)
 | 
					 | 
				
			||||||
        .map(|x| format!("{:p}", (x.ip() as *const u8).wrapping_offset(addrfix)))
 | 
					 | 
				
			||||||
        .collect()
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
fn run_cmd<P: AsRef<OsStr>>(exe: P, me: &Path, flags: Option<&str>, trace: &str) -> String {
 | 
					 | 
				
			||||||
    let mut cmd = Command::new(exe);
 | 
					 | 
				
			||||||
    cmd.env("LC_ALL", "C"); // GNU addr2line is localized, we aren't
 | 
					 | 
				
			||||||
    cmd.env("RUST_BACKTRACE", "1"); // if a child crashes, we want to know why
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if let Some(flags) = flags {
 | 
					 | 
				
			||||||
        cmd.arg(flags);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    cmd.arg("--exe").arg(me).arg(trace);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let output = cmd.output().unwrap();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert!(output.status.success());
 | 
					 | 
				
			||||||
    String::from_utf8(output.stdout).unwrap()
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
fn run_test(flags: Option<&str>) -> Result<(), Failed> {
 | 
					 | 
				
			||||||
    let me = env::current_exe().unwrap();
 | 
					 | 
				
			||||||
    let mut exe = me.clone();
 | 
					 | 
				
			||||||
    assert!(exe.pop());
 | 
					 | 
				
			||||||
    if exe.file_name().unwrap().to_str().unwrap() == "deps" {
 | 
					 | 
				
			||||||
        assert!(exe.pop());
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    exe.push("examples");
 | 
					 | 
				
			||||||
    exe.push("addr2line");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert!(exe.is_file());
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let trace = make_trace();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // HACK: GNU addr2line has a bug where looking up multiple addresses can cause the second
 | 
					 | 
				
			||||||
    // lookup to fail. Workaround by doing one address at a time.
 | 
					 | 
				
			||||||
    for addr in &trace {
 | 
					 | 
				
			||||||
        let theirs = run_cmd("addr2line", &me, flags, addr);
 | 
					 | 
				
			||||||
        let ours = run_cmd(&exe, &me, flags, addr);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // HACK: GNU addr2line does not tidy up paths properly, causing double slashes to be printed.
 | 
					 | 
				
			||||||
        // We consider our behavior to be correct, so we fix their output to match ours.
 | 
					 | 
				
			||||||
        let theirs = theirs.replace("//", "/");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        assert!(
 | 
					 | 
				
			||||||
            theirs == ours,
 | 
					 | 
				
			||||||
            "Output not equivalent:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
$ addr2line {0} --exe {1} {2}
 | 
					 | 
				
			||||||
{4}
 | 
					 | 
				
			||||||
$ {3} {0} --exe {1} {2}
 | 
					 | 
				
			||||||
{5}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
",
 | 
					 | 
				
			||||||
            flags.unwrap_or(""),
 | 
					 | 
				
			||||||
            me.display(),
 | 
					 | 
				
			||||||
            trace.join(" "),
 | 
					 | 
				
			||||||
            exe.display(),
 | 
					 | 
				
			||||||
            theirs,
 | 
					 | 
				
			||||||
            ours
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    Ok(())
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static FLAGS: &str = "aipsf";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
fn make_tests() -> Vec<Trial> {
 | 
					 | 
				
			||||||
    (0..(1 << FLAGS.len()))
 | 
					 | 
				
			||||||
        .map(|bits| {
 | 
					 | 
				
			||||||
            if bits == 0 {
 | 
					 | 
				
			||||||
                None
 | 
					 | 
				
			||||||
            } else {
 | 
					 | 
				
			||||||
                let mut param = String::new();
 | 
					 | 
				
			||||||
                param.push('-');
 | 
					 | 
				
			||||||
                for (i, flag) in FLAGS.chars().enumerate() {
 | 
					 | 
				
			||||||
                    if (bits & (1 << i)) != 0 {
 | 
					 | 
				
			||||||
                        param.push(flag);
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                Some(param)
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        })
 | 
					 | 
				
			||||||
        .map(|param| {
 | 
					 | 
				
			||||||
            Trial::test(
 | 
					 | 
				
			||||||
                format!("addr2line {}", param.as_ref().map_or("", String::as_str)),
 | 
					 | 
				
			||||||
                move || run_test(param.as_ref().map(String::as_str)),
 | 
					 | 
				
			||||||
            )
 | 
					 | 
				
			||||||
        })
 | 
					 | 
				
			||||||
        .collect()
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
fn main() {
 | 
					 | 
				
			||||||
    if !cfg!(target_os = "linux") {
 | 
					 | 
				
			||||||
        return;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    let args = Arguments::from_args();
 | 
					 | 
				
			||||||
    libtest_mimic::run(&args, make_tests()).exit();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										114
									
								
								vendor/addr2line/tests/parse.rs
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										114
									
								
								vendor/addr2line/tests/parse.rs
									
									
									
									
										vendored
									
									
								
							@@ -1,114 +0,0 @@
 | 
				
			|||||||
use std::borrow::Cow;
 | 
					 | 
				
			||||||
use std::env;
 | 
					 | 
				
			||||||
use std::fs::File;
 | 
					 | 
				
			||||||
use std::path::{self, PathBuf};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use object::Object;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
fn release_fixture_path() -> PathBuf {
 | 
					 | 
				
			||||||
    if let Ok(p) = env::var("ADDR2LINE_FIXTURE_PATH") {
 | 
					 | 
				
			||||||
        return p.into();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let mut path = PathBuf::new();
 | 
					 | 
				
			||||||
    if let Ok(dir) = env::var("CARGO_MANIFEST_DIR") {
 | 
					 | 
				
			||||||
        path.push(dir);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    path.push("fixtures");
 | 
					 | 
				
			||||||
    path.push("addr2line-release");
 | 
					 | 
				
			||||||
    path
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
fn with_file<F: FnOnce(&object::File<'_>)>(target: &path::Path, f: F) {
 | 
					 | 
				
			||||||
    let file = File::open(target).unwrap();
 | 
					 | 
				
			||||||
    let map = unsafe { memmap2::Mmap::map(&file).unwrap() };
 | 
					 | 
				
			||||||
    let file = object::File::parse(&*map).unwrap();
 | 
					 | 
				
			||||||
    f(&file)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
fn dwarf_load<'a>(object: &object::File<'a>) -> gimli::Dwarf<Cow<'a, [u8]>> {
 | 
					 | 
				
			||||||
    let load_section = |id: gimli::SectionId| -> Result<Cow<'a, [u8]>, gimli::Error> {
 | 
					 | 
				
			||||||
        use object::ObjectSection;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        let data = object
 | 
					 | 
				
			||||||
            .section_by_name(id.name())
 | 
					 | 
				
			||||||
            .and_then(|section| section.data().ok())
 | 
					 | 
				
			||||||
            .unwrap_or(&[][..]);
 | 
					 | 
				
			||||||
        Ok(Cow::Borrowed(data))
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
    gimli::Dwarf::load(&load_section).unwrap()
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
fn dwarf_borrow<'a>(
 | 
					 | 
				
			||||||
    dwarf: &'a gimli::Dwarf<Cow<'_, [u8]>>,
 | 
					 | 
				
			||||||
) -> gimli::Dwarf<gimli::EndianSlice<'a, gimli::LittleEndian>> {
 | 
					 | 
				
			||||||
    let borrow_section: &dyn for<'b> Fn(
 | 
					 | 
				
			||||||
        &'b Cow<'_, [u8]>,
 | 
					 | 
				
			||||||
    ) -> gimli::EndianSlice<'b, gimli::LittleEndian> =
 | 
					 | 
				
			||||||
        &|section| gimli::EndianSlice::new(section, gimli::LittleEndian);
 | 
					 | 
				
			||||||
    dwarf.borrow(&borrow_section)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[test]
 | 
					 | 
				
			||||||
fn parse_base_rc() {
 | 
					 | 
				
			||||||
    let target = release_fixture_path();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    with_file(&target, |file| {
 | 
					 | 
				
			||||||
        addr2line::ObjectContext::new(file).unwrap();
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[test]
 | 
					 | 
				
			||||||
fn parse_base_slice() {
 | 
					 | 
				
			||||||
    let target = release_fixture_path();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    with_file(&target, |file| {
 | 
					 | 
				
			||||||
        let dwarf = dwarf_load(file);
 | 
					 | 
				
			||||||
        let dwarf = dwarf_borrow(&dwarf);
 | 
					 | 
				
			||||||
        addr2line::Context::from_dwarf(dwarf).unwrap();
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[test]
 | 
					 | 
				
			||||||
fn parse_lines_rc() {
 | 
					 | 
				
			||||||
    let target = release_fixture_path();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    with_file(&target, |file| {
 | 
					 | 
				
			||||||
        let context = addr2line::ObjectContext::new(file).unwrap();
 | 
					 | 
				
			||||||
        context.parse_lines().unwrap();
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[test]
 | 
					 | 
				
			||||||
fn parse_lines_slice() {
 | 
					 | 
				
			||||||
    let target = release_fixture_path();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    with_file(&target, |file| {
 | 
					 | 
				
			||||||
        let dwarf = dwarf_load(file);
 | 
					 | 
				
			||||||
        let dwarf = dwarf_borrow(&dwarf);
 | 
					 | 
				
			||||||
        let context = addr2line::Context::from_dwarf(dwarf).unwrap();
 | 
					 | 
				
			||||||
        context.parse_lines().unwrap();
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[test]
 | 
					 | 
				
			||||||
fn parse_functions_rc() {
 | 
					 | 
				
			||||||
    let target = release_fixture_path();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    with_file(&target, |file| {
 | 
					 | 
				
			||||||
        let context = addr2line::ObjectContext::new(file).unwrap();
 | 
					 | 
				
			||||||
        context.parse_functions().unwrap();
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[test]
 | 
					 | 
				
			||||||
fn parse_functions_slice() {
 | 
					 | 
				
			||||||
    let target = release_fixture_path();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    with_file(&target, |file| {
 | 
					 | 
				
			||||||
        let dwarf = dwarf_load(file);
 | 
					 | 
				
			||||||
        let dwarf = dwarf_borrow(&dwarf);
 | 
					 | 
				
			||||||
        let context = addr2line::Context::from_dwarf(dwarf).unwrap();
 | 
					 | 
				
			||||||
        context.parse_functions().unwrap();
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										1
									
								
								vendor/adler/.cargo-checksum.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								vendor/adler/.cargo-checksum.json
									
									
									
									
										vendored
									
									
								
							@@ -1 +0,0 @@
 | 
				
			|||||||
{"files":{"CHANGELOG.md":"737088e45fdf27fe2cfedce163332d8ce08c58fd86ca287de2de34c0fbaf63e7","Cargo.toml":"f410869f0f1a5697f65a8a77be03da7aeecc0be26e7cf3a1feb1acaa4f518770","LICENSE-0BSD":"861399f8c21c042b110517e76dc6b63a2b334276c8cf17412fc3c8908ca8dc17","LICENSE-APACHE":"8ada45cd9f843acf64e4722ae262c622a2b3b3007c7310ef36ac1061a30f6adb","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"308c50cdb42b9573743068158339570b45ca3f895015ca3b87ba983edb0a21e6","RELEASE_PROCESS.md":"a86cd10fc70f167f8d00e9e4ce0c6b4ebdfa1865058390dffd1e0ad4d3e68d9d","benches/bench.rs":"c07ce370e3680c602e415f8d1ec4e543ea2163ab22a09b6b82d93e8a30adca82","src/algo.rs":"b664b131f724a809591394a10b9023f40ab5963e32a83fa3163c2668e59c8b66","src/lib.rs":"b55ba9c629b30360d08168b2ca0c96275432856a539737a105a6d6ae6bf7e88f"},"package":"f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"}
 | 
					 | 
				
			||||||
							
								
								
									
										63
									
								
								vendor/adler/CHANGELOG.md
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										63
									
								
								vendor/adler/CHANGELOG.md
									
									
									
									
										vendored
									
									
								
							@@ -1,63 +0,0 @@
 | 
				
			|||||||
# Changelog
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## Unreleased
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
No changes.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## [1.0.2 - 2021-02-26](https://github.com/jonas-schievink/adler/releases/tag/v1.0.2)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- Fix doctest on big-endian systems ([#9]).
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[#9]: https://github.com/jonas-schievink/adler/pull/9
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## [1.0.1 - 2020-11-08](https://github.com/jonas-schievink/adler/releases/tag/v1.0.1)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### Fixes
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- Fix documentation on docs.rs.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## [1.0.0 - 2020-11-08](https://github.com/jonas-schievink/adler/releases/tag/v1.0.0)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### Fixes
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- Fix `cargo test --no-default-features` ([#5]).
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### Improvements
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- Extended and clarified documentation.
 | 
					 | 
				
			||||||
- Added more rustdoc examples.
 | 
					 | 
				
			||||||
- Extended CI to test the crate with `--no-default-features`.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### Breaking Changes
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- `adler32_reader` now takes its generic argument by value instead of as a `&mut`.
 | 
					 | 
				
			||||||
- Renamed `adler32_reader` to `adler32`.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## [0.2.3 - 2020-07-11](https://github.com/jonas-schievink/adler/releases/tag/v0.2.3)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- Process 4 Bytes at a time, improving performance by up to 50% ([#2]).
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## [0.2.2 - 2020-06-27](https://github.com/jonas-schievink/adler/releases/tag/v0.2.2)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- Bump MSRV to 1.31.0.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## [0.2.1 - 2020-06-27](https://github.com/jonas-schievink/adler/releases/tag/v0.2.1)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- Add a few `#[inline]` annotations to small functions.
 | 
					 | 
				
			||||||
- Fix CI badge.
 | 
					 | 
				
			||||||
- Allow integration into libstd.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## [0.2.0 - 2020-06-27](https://github.com/jonas-schievink/adler/releases/tag/v0.2.0)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- Support `#![no_std]` when using `default-features = false`.
 | 
					 | 
				
			||||||
- Improve performance by around 7x.
 | 
					 | 
				
			||||||
- Support Rust 1.8.0.
 | 
					 | 
				
			||||||
- Improve API naming.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## [0.1.0 - 2020-06-26](https://github.com/jonas-schievink/adler/releases/tag/v0.1.0)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Initial release.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[#2]: https://github.com/jonas-schievink/adler/pull/2
 | 
					 | 
				
			||||||
[#5]: https://github.com/jonas-schievink/adler/pull/5
 | 
					 | 
				
			||||||
							
								
								
									
										64
									
								
								vendor/adler/Cargo.toml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										64
									
								
								vendor/adler/Cargo.toml
									
									
									
									
										vendored
									
									
								
							@@ -1,64 +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 believe there's an error in this file please file an
 | 
					 | 
				
			||||||
# issue against the rust-lang/cargo repository. If you're
 | 
					 | 
				
			||||||
# editing this file be aware that the upstream Cargo.toml
 | 
					 | 
				
			||||||
# will likely look very different (and much more reasonable)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[package]
 | 
					 | 
				
			||||||
name = "adler"
 | 
					 | 
				
			||||||
version = "1.0.2"
 | 
					 | 
				
			||||||
authors = ["Jonas Schievink <jonasschievink@gmail.com>"]
 | 
					 | 
				
			||||||
description = "A simple clean-room implementation of the Adler-32 checksum"
 | 
					 | 
				
			||||||
documentation = "https://docs.rs/adler/"
 | 
					 | 
				
			||||||
readme = "README.md"
 | 
					 | 
				
			||||||
keywords = ["checksum", "integrity", "hash", "adler32", "zlib"]
 | 
					 | 
				
			||||||
categories = ["algorithms"]
 | 
					 | 
				
			||||||
license = "0BSD OR MIT OR Apache-2.0"
 | 
					 | 
				
			||||||
repository = "https://github.com/jonas-schievink/adler.git"
 | 
					 | 
				
			||||||
[package.metadata.docs.rs]
 | 
					 | 
				
			||||||
rustdoc-args = ["--cfg=docsrs"]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[package.metadata.release]
 | 
					 | 
				
			||||||
no-dev-version = true
 | 
					 | 
				
			||||||
pre-release-commit-message = "Release {{version}}"
 | 
					 | 
				
			||||||
tag-message = "{{version}}"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package.metadata.release.pre-release-replacements]]
 | 
					 | 
				
			||||||
file = "CHANGELOG.md"
 | 
					 | 
				
			||||||
replace = "## Unreleased\n\nNo changes.\n\n## [{{version}} - {{date}}](https://github.com/jonas-schievink/adler/releases/tag/v{{version}})\n"
 | 
					 | 
				
			||||||
search = "## Unreleased\n"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package.metadata.release.pre-release-replacements]]
 | 
					 | 
				
			||||||
file = "README.md"
 | 
					 | 
				
			||||||
replace = "adler = \"{{version}}\""
 | 
					 | 
				
			||||||
search = "adler = \"[a-z0-9\\\\.-]+\""
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package.metadata.release.pre-release-replacements]]
 | 
					 | 
				
			||||||
file = "src/lib.rs"
 | 
					 | 
				
			||||||
replace = "https://docs.rs/adler/{{version}}"
 | 
					 | 
				
			||||||
search = "https://docs.rs/adler/[a-z0-9\\.-]+"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[bench]]
 | 
					 | 
				
			||||||
name = "bench"
 | 
					 | 
				
			||||||
harness = false
 | 
					 | 
				
			||||||
[dependencies.compiler_builtins]
 | 
					 | 
				
			||||||
version = "0.1.2"
 | 
					 | 
				
			||||||
optional = true
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[dependencies.core]
 | 
					 | 
				
			||||||
version = "1.0.0"
 | 
					 | 
				
			||||||
optional = true
 | 
					 | 
				
			||||||
package = "rustc-std-workspace-core"
 | 
					 | 
				
			||||||
[dev-dependencies.criterion]
 | 
					 | 
				
			||||||
version = "0.3.2"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[features]
 | 
					 | 
				
			||||||
default = ["std"]
 | 
					 | 
				
			||||||
rustc-dep-of-std = ["core", "compiler_builtins"]
 | 
					 | 
				
			||||||
std = []
 | 
					 | 
				
			||||||
							
								
								
									
										12
									
								
								vendor/adler/LICENSE-0BSD
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										12
									
								
								vendor/adler/LICENSE-0BSD
									
									
									
									
										vendored
									
									
								
							@@ -1,12 +0,0 @@
 | 
				
			|||||||
Copyright (C) Jonas Schievink <jonasschievink@gmail.com>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Permission to use, copy, modify, and/or distribute this software for
 | 
					 | 
				
			||||||
any purpose with or without fee is hereby granted.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
					 | 
				
			||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
					 | 
				
			||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
					 | 
				
			||||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
					 | 
				
			||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
 | 
					 | 
				
			||||||
AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
 | 
					 | 
				
			||||||
OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
					 | 
				
			||||||
							
								
								
									
										201
									
								
								vendor/adler/LICENSE-APACHE
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										201
									
								
								vendor/adler/LICENSE-APACHE
									
									
									
									
										vendored
									
									
								
							@@ -1,201 +0,0 @@
 | 
				
			|||||||
                              Apache License
 | 
					 | 
				
			||||||
                        Version 2.0, January 2004
 | 
					 | 
				
			||||||
                     https://www.apache.org/licenses/LICENSE-2.0
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
1. Definitions.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   "License" shall mean the terms and conditions for use, reproduction,
 | 
					 | 
				
			||||||
   and distribution as defined by Sections 1 through 9 of this document.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   "Licensor" shall mean the copyright owner or entity authorized by
 | 
					 | 
				
			||||||
   the copyright owner that is granting the License.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   "Legal Entity" shall mean the union of the acting entity and all
 | 
					 | 
				
			||||||
   other entities that control, are controlled by, or are under common
 | 
					 | 
				
			||||||
   control with that entity. For the purposes of this definition,
 | 
					 | 
				
			||||||
   "control" means (i) the power, direct or indirect, to cause the
 | 
					 | 
				
			||||||
   direction or management of such entity, whether by contract or
 | 
					 | 
				
			||||||
   otherwise, or (ii) ownership of fifty percent (50%) or more of the
 | 
					 | 
				
			||||||
   outstanding shares, or (iii) beneficial ownership of such entity.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   "You" (or "Your") shall mean an individual or Legal Entity
 | 
					 | 
				
			||||||
   exercising permissions granted by this License.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   "Source" form shall mean the preferred form for making modifications,
 | 
					 | 
				
			||||||
   including but not limited to software source code, documentation
 | 
					 | 
				
			||||||
   source, and configuration files.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   "Object" form shall mean any form resulting from mechanical
 | 
					 | 
				
			||||||
   transformation or translation of a Source form, including but
 | 
					 | 
				
			||||||
   not limited to compiled object code, generated documentation,
 | 
					 | 
				
			||||||
   and conversions to other media types.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   "Work" shall mean the work of authorship, whether in Source or
 | 
					 | 
				
			||||||
   Object form, made available under the License, as indicated by a
 | 
					 | 
				
			||||||
   copyright notice that is included in or attached to the work
 | 
					 | 
				
			||||||
   (an example is provided in the Appendix below).
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   "Derivative Works" shall mean any work, whether in Source or Object
 | 
					 | 
				
			||||||
   form, that is based on (or derived from) the Work and for which the
 | 
					 | 
				
			||||||
   editorial revisions, annotations, elaborations, or other modifications
 | 
					 | 
				
			||||||
   represent, as a whole, an original work of authorship. For the purposes
 | 
					 | 
				
			||||||
   of this License, Derivative Works shall not include works that remain
 | 
					 | 
				
			||||||
   separable from, or merely link (or bind by name) to the interfaces of,
 | 
					 | 
				
			||||||
   the Work and Derivative Works thereof.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   "Contribution" shall mean any work of authorship, including
 | 
					 | 
				
			||||||
   the original version of the Work and any modifications or additions
 | 
					 | 
				
			||||||
   to that Work or Derivative Works thereof, that is intentionally
 | 
					 | 
				
			||||||
   submitted to Licensor for inclusion in the Work by the copyright owner
 | 
					 | 
				
			||||||
   or by an individual or Legal Entity authorized to submit on behalf of
 | 
					 | 
				
			||||||
   the copyright owner. For the purposes of this definition, "submitted"
 | 
					 | 
				
			||||||
   means any form of electronic, verbal, or written communication sent
 | 
					 | 
				
			||||||
   to the Licensor or its representatives, including but not limited to
 | 
					 | 
				
			||||||
   communication on electronic mailing lists, source code control systems,
 | 
					 | 
				
			||||||
   and issue tracking systems that are managed by, or on behalf of, the
 | 
					 | 
				
			||||||
   Licensor for the purpose of discussing and improving the Work, but
 | 
					 | 
				
			||||||
   excluding communication that is conspicuously marked or otherwise
 | 
					 | 
				
			||||||
   designated in writing by the copyright owner as "Not a Contribution."
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   "Contributor" shall mean Licensor and any individual or Legal Entity
 | 
					 | 
				
			||||||
   on behalf of whom a Contribution has been received by Licensor and
 | 
					 | 
				
			||||||
   subsequently incorporated within the Work.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
2. Grant of Copyright License. Subject to the terms and conditions of
 | 
					 | 
				
			||||||
   this License, each Contributor hereby grants to You a perpetual,
 | 
					 | 
				
			||||||
   worldwide, non-exclusive, no-charge, royalty-free, irrevocable
 | 
					 | 
				
			||||||
   copyright license to reproduce, prepare Derivative Works of,
 | 
					 | 
				
			||||||
   publicly display, publicly perform, sublicense, and distribute the
 | 
					 | 
				
			||||||
   Work and such Derivative Works in Source or Object form.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
3. Grant of Patent License. Subject to the terms and conditions of
 | 
					 | 
				
			||||||
   this License, each Contributor hereby grants to You a perpetual,
 | 
					 | 
				
			||||||
   worldwide, non-exclusive, no-charge, royalty-free, irrevocable
 | 
					 | 
				
			||||||
   (except as stated in this section) patent license to make, have made,
 | 
					 | 
				
			||||||
   use, offer to sell, sell, import, and otherwise transfer the Work,
 | 
					 | 
				
			||||||
   where such license applies only to those patent claims licensable
 | 
					 | 
				
			||||||
   by such Contributor that are necessarily infringed by their
 | 
					 | 
				
			||||||
   Contribution(s) alone or by combination of their Contribution(s)
 | 
					 | 
				
			||||||
   with the Work to which such Contribution(s) was submitted. If You
 | 
					 | 
				
			||||||
   institute patent litigation against any entity (including a
 | 
					 | 
				
			||||||
   cross-claim or counterclaim in a lawsuit) alleging that the Work
 | 
					 | 
				
			||||||
   or a Contribution incorporated within the Work constitutes direct
 | 
					 | 
				
			||||||
   or contributory patent infringement, then any patent licenses
 | 
					 | 
				
			||||||
   granted to You under this License for that Work shall terminate
 | 
					 | 
				
			||||||
   as of the date such litigation is filed.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
4. Redistribution. You may reproduce and distribute copies of the
 | 
					 | 
				
			||||||
   Work or Derivative Works thereof in any medium, with or without
 | 
					 | 
				
			||||||
   modifications, and in Source or Object form, provided that You
 | 
					 | 
				
			||||||
   meet the following conditions:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   (a) You must give any other recipients of the Work or
 | 
					 | 
				
			||||||
       Derivative Works a copy of this License; and
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   (b) You must cause any modified files to carry prominent notices
 | 
					 | 
				
			||||||
       stating that You changed the files; and
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   (c) You must retain, in the Source form of any Derivative Works
 | 
					 | 
				
			||||||
       that You distribute, all copyright, patent, trademark, and
 | 
					 | 
				
			||||||
       attribution notices from the Source form of the Work,
 | 
					 | 
				
			||||||
       excluding those notices that do not pertain to any part of
 | 
					 | 
				
			||||||
       the Derivative Works; and
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   (d) If the Work includes a "NOTICE" text file as part of its
 | 
					 | 
				
			||||||
       distribution, then any Derivative Works that You distribute must
 | 
					 | 
				
			||||||
       include a readable copy of the attribution notices contained
 | 
					 | 
				
			||||||
       within such NOTICE file, excluding those notices that do not
 | 
					 | 
				
			||||||
       pertain to any part of the Derivative Works, in at least one
 | 
					 | 
				
			||||||
       of the following places: within a NOTICE text file distributed
 | 
					 | 
				
			||||||
       as part of the Derivative Works; within the Source form or
 | 
					 | 
				
			||||||
       documentation, if provided along with the Derivative Works; or,
 | 
					 | 
				
			||||||
       within a display generated by the Derivative Works, if and
 | 
					 | 
				
			||||||
       wherever such third-party notices normally appear. The contents
 | 
					 | 
				
			||||||
       of the NOTICE file are for informational purposes only and
 | 
					 | 
				
			||||||
       do not modify the License. You may add Your own attribution
 | 
					 | 
				
			||||||
       notices within Derivative Works that You distribute, alongside
 | 
					 | 
				
			||||||
       or as an addendum to the NOTICE text from the Work, provided
 | 
					 | 
				
			||||||
       that such additional attribution notices cannot be construed
 | 
					 | 
				
			||||||
       as modifying the License.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   You may add Your own copyright statement to Your modifications and
 | 
					 | 
				
			||||||
   may provide additional or different license terms and conditions
 | 
					 | 
				
			||||||
   for use, reproduction, or distribution of Your modifications, or
 | 
					 | 
				
			||||||
   for any such Derivative Works as a whole, provided Your use,
 | 
					 | 
				
			||||||
   reproduction, and distribution of the Work otherwise complies with
 | 
					 | 
				
			||||||
   the conditions stated in this License.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
5. Submission of Contributions. Unless You explicitly state otherwise,
 | 
					 | 
				
			||||||
   any Contribution intentionally submitted for inclusion in the Work
 | 
					 | 
				
			||||||
   by You to the Licensor shall be under the terms and conditions of
 | 
					 | 
				
			||||||
   this License, without any additional terms or conditions.
 | 
					 | 
				
			||||||
   Notwithstanding the above, nothing herein shall supersede or modify
 | 
					 | 
				
			||||||
   the terms of any separate license agreement you may have executed
 | 
					 | 
				
			||||||
   with Licensor regarding such Contributions.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
6. Trademarks. This License does not grant permission to use the trade
 | 
					 | 
				
			||||||
   names, trademarks, service marks, or product names of the Licensor,
 | 
					 | 
				
			||||||
   except as required for reasonable and customary use in describing the
 | 
					 | 
				
			||||||
   origin of the Work and reproducing the content of the NOTICE file.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
7. Disclaimer of Warranty. Unless required by applicable law or
 | 
					 | 
				
			||||||
   agreed to in writing, Licensor provides the Work (and each
 | 
					 | 
				
			||||||
   Contributor provides its Contributions) on an "AS IS" BASIS,
 | 
					 | 
				
			||||||
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 | 
					 | 
				
			||||||
   implied, including, without limitation, any warranties or conditions
 | 
					 | 
				
			||||||
   of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
 | 
					 | 
				
			||||||
   PARTICULAR PURPOSE. You are solely responsible for determining the
 | 
					 | 
				
			||||||
   appropriateness of using or redistributing the Work and assume any
 | 
					 | 
				
			||||||
   risks associated with Your exercise of permissions under this License.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
8. Limitation of Liability. In no event and under no legal theory,
 | 
					 | 
				
			||||||
   whether in tort (including negligence), contract, or otherwise,
 | 
					 | 
				
			||||||
   unless required by applicable law (such as deliberate and grossly
 | 
					 | 
				
			||||||
   negligent acts) or agreed to in writing, shall any Contributor be
 | 
					 | 
				
			||||||
   liable to You for damages, including any direct, indirect, special,
 | 
					 | 
				
			||||||
   incidental, or consequential damages of any character arising as a
 | 
					 | 
				
			||||||
   result of this License or out of the use or inability to use the
 | 
					 | 
				
			||||||
   Work (including but not limited to damages for loss of goodwill,
 | 
					 | 
				
			||||||
   work stoppage, computer failure or malfunction, or any and all
 | 
					 | 
				
			||||||
   other commercial damages or losses), even if such Contributor
 | 
					 | 
				
			||||||
   has been advised of the possibility of such damages.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
9. Accepting Warranty or Additional Liability. While redistributing
 | 
					 | 
				
			||||||
   the Work or Derivative Works thereof, You may choose to offer,
 | 
					 | 
				
			||||||
   and charge a fee for, acceptance of support, warranty, indemnity,
 | 
					 | 
				
			||||||
   or other liability obligations and/or rights consistent with this
 | 
					 | 
				
			||||||
   License. However, in accepting such obligations, You may act only
 | 
					 | 
				
			||||||
   on Your own behalf and on Your sole responsibility, not on behalf
 | 
					 | 
				
			||||||
   of any other Contributor, and only if You agree to indemnify,
 | 
					 | 
				
			||||||
   defend, and hold each Contributor harmless for any liability
 | 
					 | 
				
			||||||
   incurred by, or claims asserted against, such Contributor by reason
 | 
					 | 
				
			||||||
   of your accepting any such warranty or additional liability.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
END OF TERMS AND CONDITIONS
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
APPENDIX: How to apply the Apache License to your work.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   To apply the Apache License to your work, attach the following
 | 
					 | 
				
			||||||
   boilerplate notice, with the fields enclosed by brackets "[]"
 | 
					 | 
				
			||||||
   replaced with your own identifying information. (Don't include
 | 
					 | 
				
			||||||
   the brackets!)  The text should be enclosed in the appropriate
 | 
					 | 
				
			||||||
   comment syntax for the file format. We also recommend that a
 | 
					 | 
				
			||||||
   file or class name and description of purpose be included on the
 | 
					 | 
				
			||||||
   same "printed page" as the copyright notice for easier
 | 
					 | 
				
			||||||
   identification within third-party archives.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Copyright [yyyy] [name of copyright owner]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Licensed under the Apache License, Version 2.0 (the "License");
 | 
					 | 
				
			||||||
you may not use this file except in compliance with the License.
 | 
					 | 
				
			||||||
You may obtain a copy of the License at
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	https://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.
 | 
					 | 
				
			||||||
							
								
								
									
										23
									
								
								vendor/adler/LICENSE-MIT
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										23
									
								
								vendor/adler/LICENSE-MIT
									
									
									
									
										vendored
									
									
								
							@@ -1,23 +0,0 @@
 | 
				
			|||||||
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.
 | 
					 | 
				
			||||||
							
								
								
									
										39
									
								
								vendor/adler/README.md
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										39
									
								
								vendor/adler/README.md
									
									
									
									
										vendored
									
									
								
							@@ -1,39 +0,0 @@
 | 
				
			|||||||
# Adler-32 checksums for Rust
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[](https://crates.io/crates/adler)
 | 
					 | 
				
			||||||
[](https://docs.rs/adler/)
 | 
					 | 
				
			||||||

 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
This crate provides a simple implementation of the Adler-32 checksum, used in
 | 
					 | 
				
			||||||
the zlib compression format.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Please refer to the [changelog](CHANGELOG.md) to see what changed in the last
 | 
					 | 
				
			||||||
releases.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## Features
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- Permissively licensed (0BSD) clean-room implementation.
 | 
					 | 
				
			||||||
- Zero dependencies.
 | 
					 | 
				
			||||||
- Zero `unsafe`.
 | 
					 | 
				
			||||||
- Decent performance (3-4 GB/s).
 | 
					 | 
				
			||||||
- Supports `#![no_std]` (with `default-features = false`).
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## Usage
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Add an entry to your `Cargo.toml`:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
```toml
 | 
					 | 
				
			||||||
[dependencies]
 | 
					 | 
				
			||||||
adler = "1.0.2"
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Check the [API Documentation](https://docs.rs/adler/) for how to use the
 | 
					 | 
				
			||||||
crate's functionality.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## Rust version support
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Currently, this crate supports all Rust versions starting at Rust 1.31.0.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Bumping the Minimum Supported Rust Version (MSRV) is *not* considered a breaking
 | 
					 | 
				
			||||||
change, but will not be done without good reasons. The latest 3 stable Rust
 | 
					 | 
				
			||||||
versions will always be supported no matter what.
 | 
					 | 
				
			||||||
							
								
								
									
										13
									
								
								vendor/adler/RELEASE_PROCESS.md
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										13
									
								
								vendor/adler/RELEASE_PROCESS.md
									
									
									
									
										vendored
									
									
								
							@@ -1,13 +0,0 @@
 | 
				
			|||||||
# What to do to publish a new release
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
1. Ensure all notable changes are in the changelog under "Unreleased".
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
2. Execute `cargo release <level>` to bump version(s), tag and publish
 | 
					 | 
				
			||||||
   everything. External subcommand, must be installed with `cargo install
 | 
					 | 
				
			||||||
   cargo-release`.
 | 
					 | 
				
			||||||
   
 | 
					 | 
				
			||||||
   `<level>` can be one of `major|minor|patch`. If this is the first release
 | 
					 | 
				
			||||||
   (`0.1.0`), use `minor`, since the version starts out as `0.0.0`.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
3. Go to the GitHub releases, edit the just-pushed tag. Copy the release notes
 | 
					 | 
				
			||||||
   from the changelog.
 | 
					 | 
				
			||||||
							
								
								
									
										109
									
								
								vendor/adler/benches/bench.rs
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										109
									
								
								vendor/adler/benches/bench.rs
									
									
									
									
										vendored
									
									
								
							@@ -1,109 +0,0 @@
 | 
				
			|||||||
extern crate adler;
 | 
					 | 
				
			||||||
extern crate criterion;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use adler::{adler32_slice, Adler32};
 | 
					 | 
				
			||||||
use criterion::{criterion_group, criterion_main, Criterion, Throughput};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
fn simple(c: &mut Criterion) {
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        const SIZE: usize = 100;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        let mut group = c.benchmark_group("simple-100b");
 | 
					 | 
				
			||||||
        group.throughput(Throughput::Bytes(SIZE as u64));
 | 
					 | 
				
			||||||
        group.bench_function("zeroes-100", |bencher| {
 | 
					 | 
				
			||||||
            bencher.iter(|| {
 | 
					 | 
				
			||||||
                adler32_slice(&[0; SIZE]);
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
        group.bench_function("ones-100", |bencher| {
 | 
					 | 
				
			||||||
            bencher.iter(|| {
 | 
					 | 
				
			||||||
                adler32_slice(&[0xff; SIZE]);
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        const SIZE: usize = 1024;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        let mut group = c.benchmark_group("simple-1k");
 | 
					 | 
				
			||||||
        group.throughput(Throughput::Bytes(SIZE as u64));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        group.bench_function("zeroes-1k", |bencher| {
 | 
					 | 
				
			||||||
            bencher.iter(|| {
 | 
					 | 
				
			||||||
                adler32_slice(&[0; SIZE]);
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        group.bench_function("ones-1k", |bencher| {
 | 
					 | 
				
			||||||
            bencher.iter(|| {
 | 
					 | 
				
			||||||
                adler32_slice(&[0xff; SIZE]);
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        const SIZE: usize = 1024 * 1024;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        let mut group = c.benchmark_group("simple-1m");
 | 
					 | 
				
			||||||
        group.throughput(Throughput::Bytes(SIZE as u64));
 | 
					 | 
				
			||||||
        group.bench_function("zeroes-1m", |bencher| {
 | 
					 | 
				
			||||||
            bencher.iter(|| {
 | 
					 | 
				
			||||||
                adler32_slice(&[0; SIZE]);
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        group.bench_function("ones-1m", |bencher| {
 | 
					 | 
				
			||||||
            bencher.iter(|| {
 | 
					 | 
				
			||||||
                adler32_slice(&[0xff; SIZE]);
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
fn chunked(c: &mut Criterion) {
 | 
					 | 
				
			||||||
    const SIZE: usize = 16 * 1024 * 1024;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let data = vec![0xAB; SIZE];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let mut group = c.benchmark_group("chunked-16m");
 | 
					 | 
				
			||||||
    group.throughput(Throughput::Bytes(SIZE as u64));
 | 
					 | 
				
			||||||
    group.bench_function("5552", |bencher| {
 | 
					 | 
				
			||||||
        bencher.iter(|| {
 | 
					 | 
				
			||||||
            let mut h = Adler32::new();
 | 
					 | 
				
			||||||
            for chunk in data.chunks(5552) {
 | 
					 | 
				
			||||||
                h.write_slice(chunk);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            h.checksum()
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
    group.bench_function("8k", |bencher| {
 | 
					 | 
				
			||||||
        bencher.iter(|| {
 | 
					 | 
				
			||||||
            let mut h = Adler32::new();
 | 
					 | 
				
			||||||
            for chunk in data.chunks(8 * 1024) {
 | 
					 | 
				
			||||||
                h.write_slice(chunk);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            h.checksum()
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
    group.bench_function("64k", |bencher| {
 | 
					 | 
				
			||||||
        bencher.iter(|| {
 | 
					 | 
				
			||||||
            let mut h = Adler32::new();
 | 
					 | 
				
			||||||
            for chunk in data.chunks(64 * 1024) {
 | 
					 | 
				
			||||||
                h.write_slice(chunk);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            h.checksum()
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
    group.bench_function("1m", |bencher| {
 | 
					 | 
				
			||||||
        bencher.iter(|| {
 | 
					 | 
				
			||||||
            let mut h = Adler32::new();
 | 
					 | 
				
			||||||
            for chunk in data.chunks(1024 * 1024) {
 | 
					 | 
				
			||||||
                h.write_slice(chunk);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            h.checksum()
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
criterion_group!(benches, simple, chunked);
 | 
					 | 
				
			||||||
criterion_main!(benches);
 | 
					 | 
				
			||||||
							
								
								
									
										146
									
								
								vendor/adler/src/algo.rs
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										146
									
								
								vendor/adler/src/algo.rs
									
									
									
									
										vendored
									
									
								
							@@ -1,146 +0,0 @@
 | 
				
			|||||||
use crate::Adler32;
 | 
					 | 
				
			||||||
use std::ops::{AddAssign, MulAssign, RemAssign};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl Adler32 {
 | 
					 | 
				
			||||||
    pub(crate) fn compute(&mut self, bytes: &[u8]) {
 | 
					 | 
				
			||||||
        // The basic algorithm is, for every byte:
 | 
					 | 
				
			||||||
        //   a = (a + byte) % MOD
 | 
					 | 
				
			||||||
        //   b = (b + a) % MOD
 | 
					 | 
				
			||||||
        // where MOD = 65521.
 | 
					 | 
				
			||||||
        //
 | 
					 | 
				
			||||||
        // For efficiency, we can defer the `% MOD` operations as long as neither a nor b overflows:
 | 
					 | 
				
			||||||
        // - Between calls to `write`, we ensure that a and b are always in range 0..MOD.
 | 
					 | 
				
			||||||
        // - We use 32-bit arithmetic in this function.
 | 
					 | 
				
			||||||
        // - Therefore, a and b must not increase by more than 2^32-MOD without performing a `% MOD`
 | 
					 | 
				
			||||||
        //   operation.
 | 
					 | 
				
			||||||
        //
 | 
					 | 
				
			||||||
        // According to Wikipedia, b is calculated as follows for non-incremental checksumming:
 | 
					 | 
				
			||||||
        //   b = n×D1 + (n−1)×D2 + (n−2)×D3 + ... + Dn + n*1 (mod 65521)
 | 
					 | 
				
			||||||
        // Where n is the number of bytes and Di is the i-th Byte. We need to change this to account
 | 
					 | 
				
			||||||
        // for the previous values of a and b, as well as treat every input Byte as being 255:
 | 
					 | 
				
			||||||
        //   b_inc = n×255 + (n-1)×255 + ... + 255 + n*65520
 | 
					 | 
				
			||||||
        // Or in other words:
 | 
					 | 
				
			||||||
        //   b_inc = n*65520 + n(n+1)/2*255
 | 
					 | 
				
			||||||
        // The max chunk size is thus the largest value of n so that b_inc <= 2^32-65521.
 | 
					 | 
				
			||||||
        //   2^32-65521 = n*65520 + n(n+1)/2*255
 | 
					 | 
				
			||||||
        // Plugging this into an equation solver since I can't math gives n = 5552.18..., so 5552.
 | 
					 | 
				
			||||||
        //
 | 
					 | 
				
			||||||
        // On top of the optimization outlined above, the algorithm can also be parallelized with a
 | 
					 | 
				
			||||||
        // bit more work:
 | 
					 | 
				
			||||||
        //
 | 
					 | 
				
			||||||
        // Note that b is a linear combination of a vector of input bytes (D1, ..., Dn).
 | 
					 | 
				
			||||||
        //
 | 
					 | 
				
			||||||
        // If we fix some value k<N and rewrite indices 1, ..., N as
 | 
					 | 
				
			||||||
        //
 | 
					 | 
				
			||||||
        //   1_1, 1_2, ..., 1_k, 2_1, ..., 2_k, ..., (N/k)_k,
 | 
					 | 
				
			||||||
        //
 | 
					 | 
				
			||||||
        // then we can express a and b in terms of sums of smaller sequences kb and ka:
 | 
					 | 
				
			||||||
        //
 | 
					 | 
				
			||||||
        //   ka(j) := D1_j + D2_j + ... + D(N/k)_j where j <= k
 | 
					 | 
				
			||||||
        //   kb(j) := (N/k)*D1_j + (N/k-1)*D2_j + ... + D(N/k)_j where j <= k
 | 
					 | 
				
			||||||
        //
 | 
					 | 
				
			||||||
        //  a = ka(1) + ka(2) + ... + ka(k) + 1
 | 
					 | 
				
			||||||
        //  b = k*(kb(1) + kb(2) + ... + kb(k)) - 1*ka(2) - ...  - (k-1)*ka(k) + N
 | 
					 | 
				
			||||||
        //
 | 
					 | 
				
			||||||
        // We use this insight to unroll the main loop and process k=4 bytes at a time.
 | 
					 | 
				
			||||||
        // The resulting code is highly amenable to SIMD acceleration, although the immediate speedups
 | 
					 | 
				
			||||||
        // stem from increased pipeline parallelism rather than auto-vectorization.
 | 
					 | 
				
			||||||
        //
 | 
					 | 
				
			||||||
        // This technique is described in-depth (here:)[https://software.intel.com/content/www/us/\
 | 
					 | 
				
			||||||
        // en/develop/articles/fast-computation-of-fletcher-checksums.html]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        const MOD: u32 = 65521;
 | 
					 | 
				
			||||||
        const CHUNK_SIZE: usize = 5552 * 4;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        let mut a = u32::from(self.a);
 | 
					 | 
				
			||||||
        let mut b = u32::from(self.b);
 | 
					 | 
				
			||||||
        let mut a_vec = U32X4([0; 4]);
 | 
					 | 
				
			||||||
        let mut b_vec = a_vec;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        let (bytes, remainder) = bytes.split_at(bytes.len() - bytes.len() % 4);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // iterate over 4 bytes at a time
 | 
					 | 
				
			||||||
        let chunk_iter = bytes.chunks_exact(CHUNK_SIZE);
 | 
					 | 
				
			||||||
        let remainder_chunk = chunk_iter.remainder();
 | 
					 | 
				
			||||||
        for chunk in chunk_iter {
 | 
					 | 
				
			||||||
            for byte_vec in chunk.chunks_exact(4) {
 | 
					 | 
				
			||||||
                let val = U32X4::from(byte_vec);
 | 
					 | 
				
			||||||
                a_vec += val;
 | 
					 | 
				
			||||||
                b_vec += a_vec;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            b += CHUNK_SIZE as u32 * a;
 | 
					 | 
				
			||||||
            a_vec %= MOD;
 | 
					 | 
				
			||||||
            b_vec %= MOD;
 | 
					 | 
				
			||||||
            b %= MOD;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        // special-case the final chunk because it may be shorter than the rest
 | 
					 | 
				
			||||||
        for byte_vec in remainder_chunk.chunks_exact(4) {
 | 
					 | 
				
			||||||
            let val = U32X4::from(byte_vec);
 | 
					 | 
				
			||||||
            a_vec += val;
 | 
					 | 
				
			||||||
            b_vec += a_vec;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        b += remainder_chunk.len() as u32 * a;
 | 
					 | 
				
			||||||
        a_vec %= MOD;
 | 
					 | 
				
			||||||
        b_vec %= MOD;
 | 
					 | 
				
			||||||
        b %= MOD;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // combine the sub-sum results into the main sum
 | 
					 | 
				
			||||||
        b_vec *= 4;
 | 
					 | 
				
			||||||
        b_vec.0[1] += MOD - a_vec.0[1];
 | 
					 | 
				
			||||||
        b_vec.0[2] += (MOD - a_vec.0[2]) * 2;
 | 
					 | 
				
			||||||
        b_vec.0[3] += (MOD - a_vec.0[3]) * 3;
 | 
					 | 
				
			||||||
        for &av in a_vec.0.iter() {
 | 
					 | 
				
			||||||
            a += av;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        for &bv in b_vec.0.iter() {
 | 
					 | 
				
			||||||
            b += bv;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // iterate over the remaining few bytes in serial
 | 
					 | 
				
			||||||
        for &byte in remainder.iter() {
 | 
					 | 
				
			||||||
            a += u32::from(byte);
 | 
					 | 
				
			||||||
            b += a;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.a = (a % MOD) as u16;
 | 
					 | 
				
			||||||
        self.b = (b % MOD) as u16;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[derive(Copy, Clone)]
 | 
					 | 
				
			||||||
struct U32X4([u32; 4]);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl U32X4 {
 | 
					 | 
				
			||||||
    fn from(bytes: &[u8]) -> Self {
 | 
					 | 
				
			||||||
        U32X4([
 | 
					 | 
				
			||||||
            u32::from(bytes[0]),
 | 
					 | 
				
			||||||
            u32::from(bytes[1]),
 | 
					 | 
				
			||||||
            u32::from(bytes[2]),
 | 
					 | 
				
			||||||
            u32::from(bytes[3]),
 | 
					 | 
				
			||||||
        ])
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl AddAssign<Self> for U32X4 {
 | 
					 | 
				
			||||||
    fn add_assign(&mut self, other: Self) {
 | 
					 | 
				
			||||||
        for (s, o) in self.0.iter_mut().zip(other.0.iter()) {
 | 
					 | 
				
			||||||
            *s += o;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl RemAssign<u32> for U32X4 {
 | 
					 | 
				
			||||||
    fn rem_assign(&mut self, quotient: u32) {
 | 
					 | 
				
			||||||
        for s in self.0.iter_mut() {
 | 
					 | 
				
			||||||
            *s %= quotient;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl MulAssign<u32> for U32X4 {
 | 
					 | 
				
			||||||
    fn mul_assign(&mut self, rhs: u32) {
 | 
					 | 
				
			||||||
        for s in self.0.iter_mut() {
 | 
					 | 
				
			||||||
            *s *= rhs;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										287
									
								
								vendor/adler/src/lib.rs
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										287
									
								
								vendor/adler/src/lib.rs
									
									
									
									
										vendored
									
									
								
							@@ -1,287 +0,0 @@
 | 
				
			|||||||
//! Adler-32 checksum implementation.
 | 
					 | 
				
			||||||
//!
 | 
					 | 
				
			||||||
//! This implementation features:
 | 
					 | 
				
			||||||
//!
 | 
					 | 
				
			||||||
//! - Permissively licensed (0BSD) clean-room implementation.
 | 
					 | 
				
			||||||
//! - Zero dependencies.
 | 
					 | 
				
			||||||
//! - Zero `unsafe`.
 | 
					 | 
				
			||||||
//! - Decent performance (3-4 GB/s).
 | 
					 | 
				
			||||||
//! - `#![no_std]` support (with `default-features = false`).
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#![doc(html_root_url = "https://docs.rs/adler/1.0.2")]
 | 
					 | 
				
			||||||
// Deny a few warnings in doctests, since rustdoc `allow`s many warnings by default
 | 
					 | 
				
			||||||
#![doc(test(attr(deny(unused_imports, unused_must_use))))]
 | 
					 | 
				
			||||||
#![cfg_attr(docsrs, feature(doc_cfg))]
 | 
					 | 
				
			||||||
#![warn(missing_debug_implementations)]
 | 
					 | 
				
			||||||
#![forbid(unsafe_code)]
 | 
					 | 
				
			||||||
#![cfg_attr(not(feature = "std"), no_std)]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[cfg(not(feature = "std"))]
 | 
					 | 
				
			||||||
extern crate core as std;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
mod algo;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use std::hash::Hasher;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[cfg(feature = "std")]
 | 
					 | 
				
			||||||
use std::io::{self, BufRead};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// Adler-32 checksum calculator.
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// An instance of this type is equivalent to an Adler-32 checksum: It can be created in the default
 | 
					 | 
				
			||||||
/// state via [`new`] (or the provided `Default` impl), or from a precalculated checksum via
 | 
					 | 
				
			||||||
/// [`from_checksum`], and the currently stored checksum can be fetched via [`checksum`].
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// This type also implements `Hasher`, which makes it easy to calculate Adler-32 checksums of any
 | 
					 | 
				
			||||||
/// type that implements or derives `Hash`. This also allows using Adler-32 in a `HashMap`, although
 | 
					 | 
				
			||||||
/// that is not recommended (while every checksum is a hash function, they are not necessarily a
 | 
					 | 
				
			||||||
/// good one).
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// # Examples
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// Basic, piecewise checksum calculation:
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// ```
 | 
					 | 
				
			||||||
/// use adler::Adler32;
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// let mut adler = Adler32::new();
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// adler.write_slice(&[0, 1, 2]);
 | 
					 | 
				
			||||||
/// adler.write_slice(&[3, 4, 5]);
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// assert_eq!(adler.checksum(), 0x00290010);
 | 
					 | 
				
			||||||
/// ```
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// Using `Hash` to process structures:
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// ```
 | 
					 | 
				
			||||||
/// use std::hash::Hash;
 | 
					 | 
				
			||||||
/// use adler::Adler32;
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// #[derive(Hash)]
 | 
					 | 
				
			||||||
/// struct Data {
 | 
					 | 
				
			||||||
///     byte: u8,
 | 
					 | 
				
			||||||
///     word: u16,
 | 
					 | 
				
			||||||
///     big: u64,
 | 
					 | 
				
			||||||
/// }
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// let mut adler = Adler32::new();
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// let data = Data { byte: 0x1F, word: 0xABCD, big: !0 };
 | 
					 | 
				
			||||||
/// data.hash(&mut adler);
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// // hash value depends on architecture endianness
 | 
					 | 
				
			||||||
/// if cfg!(target_endian = "little") {
 | 
					 | 
				
			||||||
///     assert_eq!(adler.checksum(), 0x33410990);
 | 
					 | 
				
			||||||
/// }
 | 
					 | 
				
			||||||
/// if cfg!(target_endian = "big") {
 | 
					 | 
				
			||||||
///     assert_eq!(adler.checksum(), 0x331F0990);
 | 
					 | 
				
			||||||
/// }
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// ```
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// [`new`]: #method.new
 | 
					 | 
				
			||||||
/// [`from_checksum`]: #method.from_checksum
 | 
					 | 
				
			||||||
/// [`checksum`]: #method.checksum
 | 
					 | 
				
			||||||
#[derive(Debug, Copy, Clone)]
 | 
					 | 
				
			||||||
pub struct Adler32 {
 | 
					 | 
				
			||||||
    a: u16,
 | 
					 | 
				
			||||||
    b: u16,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl Adler32 {
 | 
					 | 
				
			||||||
    /// Creates a new Adler-32 instance with default state.
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub fn new() -> Self {
 | 
					 | 
				
			||||||
        Self::default()
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Creates an `Adler32` instance from a precomputed Adler-32 checksum.
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// This allows resuming checksum calculation without having to keep the `Adler32` instance
 | 
					 | 
				
			||||||
    /// around.
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// # Example
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// ```
 | 
					 | 
				
			||||||
    /// # use adler::Adler32;
 | 
					 | 
				
			||||||
    /// let parts = [
 | 
					 | 
				
			||||||
    ///     "rust",
 | 
					 | 
				
			||||||
    ///     "acean",
 | 
					 | 
				
			||||||
    /// ];
 | 
					 | 
				
			||||||
    /// let whole = adler::adler32_slice(b"rustacean");
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// let mut sum = Adler32::new();
 | 
					 | 
				
			||||||
    /// sum.write_slice(parts[0].as_bytes());
 | 
					 | 
				
			||||||
    /// let partial = sum.checksum();
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// // ...later
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// let mut sum = Adler32::from_checksum(partial);
 | 
					 | 
				
			||||||
    /// sum.write_slice(parts[1].as_bytes());
 | 
					 | 
				
			||||||
    /// assert_eq!(sum.checksum(), whole);
 | 
					 | 
				
			||||||
    /// ```
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub fn from_checksum(sum: u32) -> Self {
 | 
					 | 
				
			||||||
        Adler32 {
 | 
					 | 
				
			||||||
            a: sum as u16,
 | 
					 | 
				
			||||||
            b: (sum >> 16) as u16,
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Returns the calculated checksum at this point in time.
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub fn checksum(&self) -> u32 {
 | 
					 | 
				
			||||||
        (u32::from(self.b) << 16) | u32::from(self.a)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Adds `bytes` to the checksum calculation.
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// If efficiency matters, this should be called with Byte slices that contain at least a few
 | 
					 | 
				
			||||||
    /// thousand Bytes.
 | 
					 | 
				
			||||||
    pub fn write_slice(&mut self, bytes: &[u8]) {
 | 
					 | 
				
			||||||
        self.compute(bytes);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl Default for Adler32 {
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn default() -> Self {
 | 
					 | 
				
			||||||
        Adler32 { a: 1, b: 0 }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl Hasher for Adler32 {
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn finish(&self) -> u64 {
 | 
					 | 
				
			||||||
        u64::from(self.checksum())
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    fn write(&mut self, bytes: &[u8]) {
 | 
					 | 
				
			||||||
        self.write_slice(bytes);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// Calculates the Adler-32 checksum of a byte slice.
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// This is a convenience function around the [`Adler32`] type.
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// [`Adler32`]: struct.Adler32.html
 | 
					 | 
				
			||||||
pub fn adler32_slice(data: &[u8]) -> u32 {
 | 
					 | 
				
			||||||
    let mut h = Adler32::new();
 | 
					 | 
				
			||||||
    h.write_slice(data);
 | 
					 | 
				
			||||||
    h.checksum()
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// Calculates the Adler-32 checksum of a `BufRead`'s contents.
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// The passed `BufRead` implementor will be read until it reaches EOF (or until it reports an
 | 
					 | 
				
			||||||
/// error).
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// If you only have a `Read` implementor, you can wrap it in `std::io::BufReader` before calling
 | 
					 | 
				
			||||||
/// this function.
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// # Errors
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// Any error returned by the reader are bubbled up by this function.
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// # Examples
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// ```no_run
 | 
					 | 
				
			||||||
/// # fn run() -> Result<(), Box<dyn std::error::Error>> {
 | 
					 | 
				
			||||||
/// use adler::adler32;
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// use std::fs::File;
 | 
					 | 
				
			||||||
/// use std::io::BufReader;
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// let file = File::open("input.txt")?;
 | 
					 | 
				
			||||||
/// let mut file = BufReader::new(file);
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// adler32(&mut file)?;
 | 
					 | 
				
			||||||
/// # Ok(()) }
 | 
					 | 
				
			||||||
/// # fn main() { run().unwrap() }
 | 
					 | 
				
			||||||
/// ```
 | 
					 | 
				
			||||||
#[cfg(feature = "std")]
 | 
					 | 
				
			||||||
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
 | 
					 | 
				
			||||||
pub fn adler32<R: BufRead>(mut reader: R) -> io::Result<u32> {
 | 
					 | 
				
			||||||
    let mut h = Adler32::new();
 | 
					 | 
				
			||||||
    loop {
 | 
					 | 
				
			||||||
        let len = {
 | 
					 | 
				
			||||||
            let buf = reader.fill_buf()?;
 | 
					 | 
				
			||||||
            if buf.is_empty() {
 | 
					 | 
				
			||||||
                return Ok(h.checksum());
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            h.write_slice(buf);
 | 
					 | 
				
			||||||
            buf.len()
 | 
					 | 
				
			||||||
        };
 | 
					 | 
				
			||||||
        reader.consume(len);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[cfg(test)]
 | 
					 | 
				
			||||||
mod tests {
 | 
					 | 
				
			||||||
    use super::*;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[test]
 | 
					 | 
				
			||||||
    fn zeroes() {
 | 
					 | 
				
			||||||
        assert_eq!(adler32_slice(&[]), 1);
 | 
					 | 
				
			||||||
        assert_eq!(adler32_slice(&[0]), 1 | 1 << 16);
 | 
					 | 
				
			||||||
        assert_eq!(adler32_slice(&[0, 0]), 1 | 2 << 16);
 | 
					 | 
				
			||||||
        assert_eq!(adler32_slice(&[0; 100]), 0x00640001);
 | 
					 | 
				
			||||||
        assert_eq!(adler32_slice(&[0; 1024]), 0x04000001);
 | 
					 | 
				
			||||||
        assert_eq!(adler32_slice(&[0; 1024 * 1024]), 0x00f00001);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[test]
 | 
					 | 
				
			||||||
    fn ones() {
 | 
					 | 
				
			||||||
        assert_eq!(adler32_slice(&[0xff; 1024]), 0x79a6fc2e);
 | 
					 | 
				
			||||||
        assert_eq!(adler32_slice(&[0xff; 1024 * 1024]), 0x8e88ef11);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[test]
 | 
					 | 
				
			||||||
    fn mixed() {
 | 
					 | 
				
			||||||
        assert_eq!(adler32_slice(&[1]), 2 | 2 << 16);
 | 
					 | 
				
			||||||
        assert_eq!(adler32_slice(&[40]), 41 | 41 << 16);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        assert_eq!(adler32_slice(&[0xA5; 1024 * 1024]), 0xd5009ab1);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Example calculation from https://en.wikipedia.org/wiki/Adler-32.
 | 
					 | 
				
			||||||
    #[test]
 | 
					 | 
				
			||||||
    fn wiki() {
 | 
					 | 
				
			||||||
        assert_eq!(adler32_slice(b"Wikipedia"), 0x11E60398);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[test]
 | 
					 | 
				
			||||||
    fn resume() {
 | 
					 | 
				
			||||||
        let mut adler = Adler32::new();
 | 
					 | 
				
			||||||
        adler.write_slice(&[0xff; 1024]);
 | 
					 | 
				
			||||||
        let partial = adler.checksum();
 | 
					 | 
				
			||||||
        assert_eq!(partial, 0x79a6fc2e); // from above
 | 
					 | 
				
			||||||
        adler.write_slice(&[0xff; 1024 * 1024 - 1024]);
 | 
					 | 
				
			||||||
        assert_eq!(adler.checksum(), 0x8e88ef11); // from above
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Make sure that we can resume computing from the partial checksum via `from_checksum`.
 | 
					 | 
				
			||||||
        let mut adler = Adler32::from_checksum(partial);
 | 
					 | 
				
			||||||
        adler.write_slice(&[0xff; 1024 * 1024 - 1024]);
 | 
					 | 
				
			||||||
        assert_eq!(adler.checksum(), 0x8e88ef11); // from above
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[cfg(feature = "std")]
 | 
					 | 
				
			||||||
    #[test]
 | 
					 | 
				
			||||||
    fn bufread() {
 | 
					 | 
				
			||||||
        use std::io::BufReader;
 | 
					 | 
				
			||||||
        fn test(data: &[u8], checksum: u32) {
 | 
					 | 
				
			||||||
            // `BufReader` uses an 8 KB buffer, so this will test buffer refilling.
 | 
					 | 
				
			||||||
            let mut buf = BufReader::new(data);
 | 
					 | 
				
			||||||
            let real_sum = adler32(&mut buf).unwrap();
 | 
					 | 
				
			||||||
            assert_eq!(checksum, real_sum);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        test(&[], 1);
 | 
					 | 
				
			||||||
        test(&[0; 1024], 0x04000001);
 | 
					 | 
				
			||||||
        test(&[0; 1024 * 1024], 0x00f00001);
 | 
					 | 
				
			||||||
        test(&[0xA5; 1024 * 1024], 0xd5009ab1);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										1
									
								
								vendor/anstream/.cargo-checksum.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								vendor/anstream/.cargo-checksum.json
									
									
									
									
										vendored
									
									
								
							@@ -1 +0,0 @@
 | 
				
			|||||||
{"files":{"Cargo.lock":"e89078a9d7e89f125bea210c74fd30ef1167c208b9b240baa3fe76ec1170f6ec","Cargo.toml":"38deb1bfcca1eaef87c409274c63f9b25df94f6faaebc74061fa7ef1e4f078f1","LICENSE-APACHE":"c6596eb7be8581c18be736c846fb9173b69eccf6ef94c5135893ec56bd92ba08","LICENSE-MIT":"6efb0476a1cc085077ed49357026d8c173bf33017278ef440f222fb9cbcb66e6","README.md":"b230c2257d0c7a49b9bd97f2fa73abedcdc055757b5cedd2b0eb1a7a448ff461","benches/stream.rs":"7e666c4f4b79ddb5237361ed25264a966ee241192fbb2c1baea3006e3e0326b4","benches/strip.rs":"9603bd5ca1ae4661c2ccab50315dbfdec0c661ac2624262172bbd8f5d0bd87c9","benches/wincon.rs":"680e86933c008b242a3286c5149c33d3c086426eb99fe134b6e79f7578f96663","examples/dump-stream.rs":"54b2bce2409fc1a1f00dbdcab7abbbb6cde447fa20b5c829d1b17ce2e15eefd1","examples/query-stream.rs":"16f38843083174fbefa974a5aa38a5f3ffa51bd6e6db3dc1d91164462219399e","src/adapter/mod.rs":"baf4237ea0b18df63609e49d93572ca27c2202a4cbec0220adb5a7e815c7d8ed","src/adapter/strip.rs":"010972f96708c56da9bced98287f134ce43a4f6459c22c1697abdc4fd6f82d00","src/adapter/wincon.rs":"07d75878ca9edcef4f473a5ff6113b40aab681dcbcd1ae9de1ec895332f7cc2a","src/auto.rs":"71c249ab6b0af64c3946817ea9f1719d4b789128c244611a05075b1e13413007","src/buffer.rs":"83e7088b50dd3e2941c06a417d9eef75fda45311a2912ba94f480ec98d6f0183","src/fmt.rs":"cc11b005c4559843bd908a57958a13c8d0922fae6aff5261f3583c90e60da73c","src/lib.rs":"649b86b187835e0e33baaaf2242c5f331b7dff133fae8fc419c52b7add797c57","src/macros.rs":"a26ababe32a39732d0aade9674f6e5e267bd26c6ea06603ff9e61e80681195e0","src/stream.rs":"cbe8f61fba4c3c60934339c8bda5d1ff43320f57cdc4ed409aa173945a941b3d","src/strip.rs":"56e6516283b6c0dfa72a8e0e6679da8424295f50a3e56c44281e76de6aa0344b","src/wincon.rs":"fe5aff7bfd80b14c9a6b07143079d59b81831293ad766b845e46fad2e1459c9a"},"package":"d664a92ecae85fd0a7392615844904654d1d5f5514837f471ddef4a057aba1b6"}
 | 
					 | 
				
			||||||
							
								
								
									
										1094
									
								
								vendor/anstream/Cargo.lock
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1094
									
								
								vendor/anstream/Cargo.lock
									
									
									
										generated
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										144
									
								
								vendor/anstream/Cargo.toml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										144
									
								
								vendor/anstream/Cargo.toml
									
									
									
									
										vendored
									
									
								
							@@ -1,144 +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.70.0"
 | 
					 | 
				
			||||||
name = "anstream"
 | 
					 | 
				
			||||||
version = "0.6.5"
 | 
					 | 
				
			||||||
include = [
 | 
					 | 
				
			||||||
    "build.rs",
 | 
					 | 
				
			||||||
    "src/**/*",
 | 
					 | 
				
			||||||
    "Cargo.toml",
 | 
					 | 
				
			||||||
    "Cargo.lock",
 | 
					 | 
				
			||||||
    "LICENSE*",
 | 
					 | 
				
			||||||
    "README.md",
 | 
					 | 
				
			||||||
    "benches/**/*",
 | 
					 | 
				
			||||||
    "examples/**/*",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
description = "A simple cross platform library for writing colored text to a terminal."
 | 
					 | 
				
			||||||
homepage = "https://github.com/rust-cli/anstyle"
 | 
					 | 
				
			||||||
readme = "README.md"
 | 
					 | 
				
			||||||
keywords = [
 | 
					 | 
				
			||||||
    "ansi",
 | 
					 | 
				
			||||||
    "terminal",
 | 
					 | 
				
			||||||
    "color",
 | 
					 | 
				
			||||||
    "strip",
 | 
					 | 
				
			||||||
    "wincon",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
categories = ["command-line-interface"]
 | 
					 | 
				
			||||||
license = "MIT OR Apache-2.0"
 | 
					 | 
				
			||||||
repository = "https://github.com/rust-cli/anstyle.git"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[package.metadata.docs.rs]
 | 
					 | 
				
			||||||
cargo-args = [
 | 
					 | 
				
			||||||
    "-Zunstable-options",
 | 
					 | 
				
			||||||
    "-Zrustdoc-scrape-examples",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
rustdoc-args = [
 | 
					 | 
				
			||||||
    "--cfg",
 | 
					 | 
				
			||||||
    "docsrs",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package.metadata.release.pre-release-replacements]]
 | 
					 | 
				
			||||||
file = "CHANGELOG.md"
 | 
					 | 
				
			||||||
min = 1
 | 
					 | 
				
			||||||
replace = "{{version}}"
 | 
					 | 
				
			||||||
search = "Unreleased"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package.metadata.release.pre-release-replacements]]
 | 
					 | 
				
			||||||
exactly = 1
 | 
					 | 
				
			||||||
file = "CHANGELOG.md"
 | 
					 | 
				
			||||||
replace = "...{{tag_name}}"
 | 
					 | 
				
			||||||
search = '\.\.\.HEAD'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package.metadata.release.pre-release-replacements]]
 | 
					 | 
				
			||||||
file = "CHANGELOG.md"
 | 
					 | 
				
			||||||
min = 1
 | 
					 | 
				
			||||||
replace = "{{date}}"
 | 
					 | 
				
			||||||
search = "ReleaseDate"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package.metadata.release.pre-release-replacements]]
 | 
					 | 
				
			||||||
exactly = 1
 | 
					 | 
				
			||||||
file = "CHANGELOG.md"
 | 
					 | 
				
			||||||
replace = """
 | 
					 | 
				
			||||||
<!-- next-header -->
 | 
					 | 
				
			||||||
## [Unreleased] - ReleaseDate
 | 
					 | 
				
			||||||
"""
 | 
					 | 
				
			||||||
search = "<!-- next-header -->"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package.metadata.release.pre-release-replacements]]
 | 
					 | 
				
			||||||
exactly = 1
 | 
					 | 
				
			||||||
file = "CHANGELOG.md"
 | 
					 | 
				
			||||||
replace = """
 | 
					 | 
				
			||||||
<!-- next-url -->
 | 
					 | 
				
			||||||
[Unreleased]: https://github.com/rust-cli/anstyle/compare/{{tag_name}}...HEAD"""
 | 
					 | 
				
			||||||
search = "<!-- next-url -->"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[bench]]
 | 
					 | 
				
			||||||
name = "strip"
 | 
					 | 
				
			||||||
harness = false
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[bench]]
 | 
					 | 
				
			||||||
name = "wincon"
 | 
					 | 
				
			||||||
harness = false
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[bench]]
 | 
					 | 
				
			||||||
name = "stream"
 | 
					 | 
				
			||||||
harness = false
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[dependencies.anstyle]
 | 
					 | 
				
			||||||
version = "1.0.0"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[dependencies.anstyle-parse]
 | 
					 | 
				
			||||||
version = "0.2.0"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[dependencies.anstyle-query]
 | 
					 | 
				
			||||||
version = "1.0.0"
 | 
					 | 
				
			||||||
optional = true
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[dependencies.colorchoice]
 | 
					 | 
				
			||||||
version = "1.0.0"
 | 
					 | 
				
			||||||
optional = true
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[dependencies.utf8parse]
 | 
					 | 
				
			||||||
version = "0.2.1"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[dev-dependencies.criterion]
 | 
					 | 
				
			||||||
version = "0.5.1"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[dev-dependencies.lexopt]
 | 
					 | 
				
			||||||
version = "0.3.0"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[dev-dependencies.owo-colors]
 | 
					 | 
				
			||||||
version = "3.5.0"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[dev-dependencies.proptest]
 | 
					 | 
				
			||||||
version = "1.4.0"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[dev-dependencies.strip-ansi-escapes]
 | 
					 | 
				
			||||||
version = "0.2.0"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[features]
 | 
					 | 
				
			||||||
auto = [
 | 
					 | 
				
			||||||
    "dep:anstyle-query",
 | 
					 | 
				
			||||||
    "dep:colorchoice",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
default = [
 | 
					 | 
				
			||||||
    "auto",
 | 
					 | 
				
			||||||
    "wincon",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
test = []
 | 
					 | 
				
			||||||
wincon = ["dep:anstyle-wincon"]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[target."cfg(windows)".dependencies.anstyle-wincon]
 | 
					 | 
				
			||||||
version = "3.0.1"
 | 
					 | 
				
			||||||
optional = true
 | 
					 | 
				
			||||||
							
								
								
									
										202
									
								
								vendor/anstream/LICENSE-APACHE
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										202
									
								
								vendor/anstream/LICENSE-APACHE
									
									
									
									
										vendored
									
									
								
							@@ -1,202 +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
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   APPENDIX: How to apply the Apache License to your work.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      To apply the Apache License to your work, attach the following
 | 
					 | 
				
			||||||
      boilerplate notice, with the fields enclosed by brackets "{}"
 | 
					 | 
				
			||||||
      replaced with your own identifying information. (Don't include
 | 
					 | 
				
			||||||
      the brackets!)  The text should be enclosed in the appropriate
 | 
					 | 
				
			||||||
      comment syntax for the file format. We also recommend that a
 | 
					 | 
				
			||||||
      file or class name and description of purpose be included on the
 | 
					 | 
				
			||||||
      same "printed page" as the copyright notice for easier
 | 
					 | 
				
			||||||
      identification within third-party archives.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   Copyright {yyyy} {name of copyright owner}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   Licensed under the Apache License, Version 2.0 (the "License");
 | 
					 | 
				
			||||||
   you may not use this file except in compliance with the License.
 | 
					 | 
				
			||||||
   You may obtain a copy of the License at
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
       http://www.apache.org/licenses/LICENSE-2.0
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   Unless required by applicable law or agreed to in writing, software
 | 
					 | 
				
			||||||
   distributed under the License is distributed on an "AS IS" BASIS,
 | 
					 | 
				
			||||||
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
					 | 
				
			||||||
   See the License for the specific language governing permissions and
 | 
					 | 
				
			||||||
   limitations under the License.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
							
								
								
									
										19
									
								
								vendor/anstream/LICENSE-MIT
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										19
									
								
								vendor/anstream/LICENSE-MIT
									
									
									
									
										vendored
									
									
								
							@@ -1,19 +0,0 @@
 | 
				
			|||||||
Copyright (c) Individual 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.
 | 
					 | 
				
			||||||
							
								
								
									
										34
									
								
								vendor/anstream/README.md
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										34
									
								
								vendor/anstream/README.md
									
									
									
									
										vendored
									
									
								
							@@ -1,34 +0,0 @@
 | 
				
			|||||||
# anstream
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
> A simple cross platform library for writing colored text to a terminal.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
*A portmanteau of "ansi stream"*
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[][Documentation]
 | 
					 | 
				
			||||||

 | 
					 | 
				
			||||||
[](https://crates.io/crates/anstream)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Specialized `stdout` and `stderr` that accept ANSI escape codes and adapt them
 | 
					 | 
				
			||||||
based on the terminal's capabilities.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
`anstream::adapter::strip_str` may also be of interest on its own for low
 | 
					 | 
				
			||||||
overhead stripping of ANSI escape codes.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## License
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Licensed under either of
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
 | 
					 | 
				
			||||||
 * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
at your option.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### Contribution
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Unless you explicitly state otherwise, any contribution intentionally
 | 
					 | 
				
			||||||
submitted for inclusion in the work by you, as defined in the Apache-2.0
 | 
					 | 
				
			||||||
license, shall be dual licensed as above, without any additional terms or
 | 
					 | 
				
			||||||
conditions.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[Crates.io]: https://crates.io/crates/anstream
 | 
					 | 
				
			||||||
[Documentation]: https://docs.rs/anstream
 | 
					 | 
				
			||||||
							
								
								
									
										81
									
								
								vendor/anstream/benches/stream.rs
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										81
									
								
								vendor/anstream/benches/stream.rs
									
									
									
									
										vendored
									
									
								
							@@ -1,81 +0,0 @@
 | 
				
			|||||||
use std::io::Write as _;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use criterion::{black_box, Criterion};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
fn stream(c: &mut Criterion) {
 | 
					 | 
				
			||||||
    for (name, content) in [
 | 
					 | 
				
			||||||
        ("demo.vte", &include_bytes!("../tests/demo.vte")[..]),
 | 
					 | 
				
			||||||
        ("rg_help.vte", &include_bytes!("../tests/rg_help.vte")[..]),
 | 
					 | 
				
			||||||
        ("rg_linus.vte", &include_bytes!("../tests/rg_linus.vte")[..]),
 | 
					 | 
				
			||||||
        (
 | 
					 | 
				
			||||||
            "state_changes",
 | 
					 | 
				
			||||||
            &b"\x1b]2;X\x1b\\ \x1b[0m \x1bP0@\x1b\\"[..],
 | 
					 | 
				
			||||||
        ),
 | 
					 | 
				
			||||||
    ] {
 | 
					 | 
				
			||||||
        let mut group = c.benchmark_group(name);
 | 
					 | 
				
			||||||
        group.bench_function("nop", |b| {
 | 
					 | 
				
			||||||
            b.iter(|| {
 | 
					 | 
				
			||||||
                let buffer = Vec::with_capacity(content.len());
 | 
					 | 
				
			||||||
                let mut stream = buffer;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                stream.write_all(content).unwrap();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                black_box(stream)
 | 
					 | 
				
			||||||
            })
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
        group.bench_function("StripStream", |b| {
 | 
					 | 
				
			||||||
            b.iter(|| {
 | 
					 | 
				
			||||||
                let buffer = Vec::with_capacity(content.len());
 | 
					 | 
				
			||||||
                let mut stream = anstream::StripStream::new(buffer);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                stream.write_all(content).unwrap();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                black_box(stream)
 | 
					 | 
				
			||||||
            })
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
        #[cfg(all(windows, feature = "wincon"))]
 | 
					 | 
				
			||||||
        group.bench_function("WinconStream", |b| {
 | 
					 | 
				
			||||||
            b.iter(|| {
 | 
					 | 
				
			||||||
                let buffer = Vec::with_capacity(content.len());
 | 
					 | 
				
			||||||
                let mut stream = anstream::WinconStream::new(buffer);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                stream.write_all(content).unwrap();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                black_box(stream)
 | 
					 | 
				
			||||||
            })
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
        group.bench_function("AutoStream::always_ansi", |b| {
 | 
					 | 
				
			||||||
            b.iter(|| {
 | 
					 | 
				
			||||||
                let buffer = Vec::with_capacity(content.len());
 | 
					 | 
				
			||||||
                let mut stream = anstream::AutoStream::always_ansi(buffer);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                stream.write_all(content).unwrap();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                black_box(stream)
 | 
					 | 
				
			||||||
            })
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
        group.bench_function("AutoStream::always", |b| {
 | 
					 | 
				
			||||||
            b.iter(|| {
 | 
					 | 
				
			||||||
                let buffer = Vec::with_capacity(content.len());
 | 
					 | 
				
			||||||
                let mut stream = anstream::AutoStream::always(buffer);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                stream.write_all(content).unwrap();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                black_box(stream)
 | 
					 | 
				
			||||||
            })
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
        group.bench_function("AutoStream::never", |b| {
 | 
					 | 
				
			||||||
            b.iter(|| {
 | 
					 | 
				
			||||||
                let buffer = Vec::with_capacity(content.len());
 | 
					 | 
				
			||||||
                let mut stream = anstream::AutoStream::never(buffer);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                stream.write_all(content).unwrap();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                black_box(stream)
 | 
					 | 
				
			||||||
            })
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
criterion::criterion_group!(benches, stream);
 | 
					 | 
				
			||||||
criterion::criterion_main!(benches);
 | 
					 | 
				
			||||||
							
								
								
									
										102
									
								
								vendor/anstream/benches/strip.rs
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										102
									
								
								vendor/anstream/benches/strip.rs
									
									
									
									
										vendored
									
									
								
							@@ -1,102 +0,0 @@
 | 
				
			|||||||
use criterion::{black_box, Criterion};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[derive(Default)]
 | 
					 | 
				
			||||||
struct Strip(String);
 | 
					 | 
				
			||||||
impl Strip {
 | 
					 | 
				
			||||||
    fn with_capacity(capacity: usize) -> Self {
 | 
					 | 
				
			||||||
        Self(String::with_capacity(capacity))
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
impl anstyle_parse::Perform for Strip {
 | 
					 | 
				
			||||||
    fn print(&mut self, c: char) {
 | 
					 | 
				
			||||||
        self.0.push(c);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    fn execute(&mut self, byte: u8) {
 | 
					 | 
				
			||||||
        if byte.is_ascii_whitespace() {
 | 
					 | 
				
			||||||
            self.0.push(byte as char);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
fn strip(c: &mut Criterion) {
 | 
					 | 
				
			||||||
    for (name, content) in [
 | 
					 | 
				
			||||||
        ("demo.vte", &include_bytes!("../tests/demo.vte")[..]),
 | 
					 | 
				
			||||||
        ("rg_help.vte", &include_bytes!("../tests/rg_help.vte")[..]),
 | 
					 | 
				
			||||||
        ("rg_linus.vte", &include_bytes!("../tests/rg_linus.vte")[..]),
 | 
					 | 
				
			||||||
        (
 | 
					 | 
				
			||||||
            "state_changes",
 | 
					 | 
				
			||||||
            &b"\x1b]2;X\x1b\\ \x1b[0m \x1bP0@\x1b\\"[..],
 | 
					 | 
				
			||||||
        ),
 | 
					 | 
				
			||||||
    ] {
 | 
					 | 
				
			||||||
        // Make sure the comparison is fair
 | 
					 | 
				
			||||||
        if let Ok(content) = std::str::from_utf8(content) {
 | 
					 | 
				
			||||||
            let mut stripped = Strip::with_capacity(content.len());
 | 
					 | 
				
			||||||
            let mut parser = anstyle_parse::Parser::<anstyle_parse::DefaultCharAccumulator>::new();
 | 
					 | 
				
			||||||
            for byte in content.as_bytes() {
 | 
					 | 
				
			||||||
                parser.advance(&mut stripped, *byte);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            assert_eq!(
 | 
					 | 
				
			||||||
                stripped.0,
 | 
					 | 
				
			||||||
                anstream::adapter::strip_str(content).to_string()
 | 
					 | 
				
			||||||
            );
 | 
					 | 
				
			||||||
            assert_eq!(
 | 
					 | 
				
			||||||
                stripped.0,
 | 
					 | 
				
			||||||
                String::from_utf8(anstream::adapter::strip_bytes(content.as_bytes()).into_vec())
 | 
					 | 
				
			||||||
                    .unwrap()
 | 
					 | 
				
			||||||
            );
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        let mut group = c.benchmark_group(name);
 | 
					 | 
				
			||||||
        group.bench_function("advance_strip", |b| {
 | 
					 | 
				
			||||||
            b.iter(|| {
 | 
					 | 
				
			||||||
                let mut stripped = Strip::with_capacity(content.len());
 | 
					 | 
				
			||||||
                let mut parser =
 | 
					 | 
				
			||||||
                    anstyle_parse::Parser::<anstyle_parse::DefaultCharAccumulator>::new();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                for byte in content {
 | 
					 | 
				
			||||||
                    parser.advance(&mut stripped, *byte);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                black_box(stripped.0)
 | 
					 | 
				
			||||||
            })
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
        group.bench_function("strip_ansi_escapes", |b| {
 | 
					 | 
				
			||||||
            b.iter(|| {
 | 
					 | 
				
			||||||
                let stripped = strip_ansi_escapes::strip(content);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                black_box(stripped)
 | 
					 | 
				
			||||||
            })
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
        if let Ok(content) = std::str::from_utf8(content) {
 | 
					 | 
				
			||||||
            group.bench_function("strip_str", |b| {
 | 
					 | 
				
			||||||
                b.iter(|| {
 | 
					 | 
				
			||||||
                    let stripped = anstream::adapter::strip_str(content).to_string();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    black_box(stripped)
 | 
					 | 
				
			||||||
                })
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
            group.bench_function("StripStr", |b| {
 | 
					 | 
				
			||||||
                b.iter(|| {
 | 
					 | 
				
			||||||
                    let mut stripped = String::with_capacity(content.len());
 | 
					 | 
				
			||||||
                    let mut state = anstream::adapter::StripStr::new();
 | 
					 | 
				
			||||||
                    for printable in state.strip_next(content) {
 | 
					 | 
				
			||||||
                        stripped.push_str(printable);
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    black_box(stripped)
 | 
					 | 
				
			||||||
                })
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        group.bench_function("strip_bytes", |b| {
 | 
					 | 
				
			||||||
            b.iter(|| {
 | 
					 | 
				
			||||||
                let stripped = anstream::adapter::strip_bytes(content).into_vec();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                black_box(stripped)
 | 
					 | 
				
			||||||
            })
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
criterion::criterion_group!(benches, strip);
 | 
					 | 
				
			||||||
criterion::criterion_main!(benches);
 | 
					 | 
				
			||||||
							
								
								
									
										26
									
								
								vendor/anstream/benches/wincon.rs
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										26
									
								
								vendor/anstream/benches/wincon.rs
									
									
									
									
										vendored
									
									
								
							@@ -1,26 +0,0 @@
 | 
				
			|||||||
use criterion::{black_box, Criterion};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
fn wincon(c: &mut Criterion) {
 | 
					 | 
				
			||||||
    for (name, content) in [
 | 
					 | 
				
			||||||
        ("demo.vte", &include_bytes!("../tests/demo.vte")[..]),
 | 
					 | 
				
			||||||
        ("rg_help.vte", &include_bytes!("../tests/rg_help.vte")[..]),
 | 
					 | 
				
			||||||
        ("rg_linus.vte", &include_bytes!("../tests/rg_linus.vte")[..]),
 | 
					 | 
				
			||||||
        (
 | 
					 | 
				
			||||||
            "state_changes",
 | 
					 | 
				
			||||||
            &b"\x1b]2;X\x1b\\ \x1b[0m \x1bP0@\x1b\\"[..],
 | 
					 | 
				
			||||||
        ),
 | 
					 | 
				
			||||||
    ] {
 | 
					 | 
				
			||||||
        let mut group = c.benchmark_group(name);
 | 
					 | 
				
			||||||
        group.bench_function("wincon_bytes", |b| {
 | 
					 | 
				
			||||||
            b.iter(|| {
 | 
					 | 
				
			||||||
                let mut state = anstream::adapter::WinconBytes::new();
 | 
					 | 
				
			||||||
                let stripped = state.extract_next(content).collect::<Vec<_>>();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                black_box(stripped)
 | 
					 | 
				
			||||||
            })
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
criterion::criterion_group!(benches, wincon);
 | 
					 | 
				
			||||||
criterion::criterion_main!(benches);
 | 
					 | 
				
			||||||
							
								
								
									
										128
									
								
								vendor/anstream/examples/dump-stream.rs
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										128
									
								
								vendor/anstream/examples/dump-stream.rs
									
									
									
									
										vendored
									
									
								
							@@ -1,128 +0,0 @@
 | 
				
			|||||||
use std::io::Write;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
fn main() -> Result<(), lexopt::Error> {
 | 
					 | 
				
			||||||
    let args = Args::parse()?;
 | 
					 | 
				
			||||||
    let stdout = anstream::stdout();
 | 
					 | 
				
			||||||
    let mut stdout = stdout.lock();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    for fixed in 0..16 {
 | 
					 | 
				
			||||||
        let style = style(fixed, args.layer, args.effects);
 | 
					 | 
				
			||||||
        let _ = print_number(&mut stdout, fixed, style);
 | 
					 | 
				
			||||||
        if fixed == 7 || fixed == 15 {
 | 
					 | 
				
			||||||
            let _ = writeln!(&mut stdout);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    for r in 0..6 {
 | 
					 | 
				
			||||||
        let _ = writeln!(stdout);
 | 
					 | 
				
			||||||
        for g in 0..6 {
 | 
					 | 
				
			||||||
            for b in 0..6 {
 | 
					 | 
				
			||||||
                let fixed = r * 36 + g * 6 + b + 16;
 | 
					 | 
				
			||||||
                let style = style(fixed, args.layer, args.effects);
 | 
					 | 
				
			||||||
                let _ = print_number(&mut stdout, fixed, style);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            let _ = writeln!(stdout);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    for c in 0..24 {
 | 
					 | 
				
			||||||
        if 0 == c % 8 {
 | 
					 | 
				
			||||||
            let _ = writeln!(stdout);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        let fixed = 232 + c;
 | 
					 | 
				
			||||||
        let style = style(fixed, args.layer, args.effects);
 | 
					 | 
				
			||||||
        let _ = print_number(&mut stdout, fixed, style);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Ok(())
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
fn style(fixed: u8, layer: Layer, effects: anstyle::Effects) -> anstyle::Style {
 | 
					 | 
				
			||||||
    let color = anstyle::Ansi256Color(fixed).into();
 | 
					 | 
				
			||||||
    (match layer {
 | 
					 | 
				
			||||||
        Layer::Fg => anstyle::Style::new().fg_color(Some(color)),
 | 
					 | 
				
			||||||
        Layer::Bg => anstyle::Style::new().bg_color(Some(color)),
 | 
					 | 
				
			||||||
        Layer::Underline => anstyle::Style::new().underline_color(Some(color)),
 | 
					 | 
				
			||||||
    }) | effects
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
fn print_number(stdout: &mut impl Write, fixed: u8, style: anstyle::Style) -> std::io::Result<()> {
 | 
					 | 
				
			||||||
    write!(
 | 
					 | 
				
			||||||
        stdout,
 | 
					 | 
				
			||||||
        "{}{:>4}{}",
 | 
					 | 
				
			||||||
        style.render(),
 | 
					 | 
				
			||||||
        fixed,
 | 
					 | 
				
			||||||
        anstyle::Reset.render()
 | 
					 | 
				
			||||||
    )
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[derive(Default)]
 | 
					 | 
				
			||||||
struct Args {
 | 
					 | 
				
			||||||
    effects: anstyle::Effects,
 | 
					 | 
				
			||||||
    layer: Layer,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[derive(Copy, Clone, Default)]
 | 
					 | 
				
			||||||
enum Layer {
 | 
					 | 
				
			||||||
    #[default]
 | 
					 | 
				
			||||||
    Fg,
 | 
					 | 
				
			||||||
    Bg,
 | 
					 | 
				
			||||||
    Underline,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl Args {
 | 
					 | 
				
			||||||
    fn parse() -> Result<Self, lexopt::Error> {
 | 
					 | 
				
			||||||
        use lexopt::prelude::*;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        let mut res = Args::default();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        let mut args = lexopt::Parser::from_env();
 | 
					 | 
				
			||||||
        while let Some(arg) = args.next()? {
 | 
					 | 
				
			||||||
            match arg {
 | 
					 | 
				
			||||||
                Long("layer") => {
 | 
					 | 
				
			||||||
                    res.layer = args.value()?.parse_with(|s| match s {
 | 
					 | 
				
			||||||
                        "fg" => Ok(Layer::Fg),
 | 
					 | 
				
			||||||
                        "bg" => Ok(Layer::Bg),
 | 
					 | 
				
			||||||
                        "underline" => Ok(Layer::Underline),
 | 
					 | 
				
			||||||
                        _ => Err("expected values fg, bg, underline"),
 | 
					 | 
				
			||||||
                    })?;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                Long("effect") => {
 | 
					 | 
				
			||||||
                    const EFFECTS: [(&str, anstyle::Effects); 12] = [
 | 
					 | 
				
			||||||
                        ("bold", anstyle::Effects::BOLD),
 | 
					 | 
				
			||||||
                        ("dimmed", anstyle::Effects::DIMMED),
 | 
					 | 
				
			||||||
                        ("italic", anstyle::Effects::ITALIC),
 | 
					 | 
				
			||||||
                        ("underline", anstyle::Effects::UNDERLINE),
 | 
					 | 
				
			||||||
                        ("double_underline", anstyle::Effects::DOUBLE_UNDERLINE),
 | 
					 | 
				
			||||||
                        ("curly_underline", anstyle::Effects::CURLY_UNDERLINE),
 | 
					 | 
				
			||||||
                        ("dotted_underline", anstyle::Effects::DOTTED_UNDERLINE),
 | 
					 | 
				
			||||||
                        ("dashed_underline", anstyle::Effects::DASHED_UNDERLINE),
 | 
					 | 
				
			||||||
                        ("blink", anstyle::Effects::BLINK),
 | 
					 | 
				
			||||||
                        ("invert", anstyle::Effects::INVERT),
 | 
					 | 
				
			||||||
                        ("hidden", anstyle::Effects::HIDDEN),
 | 
					 | 
				
			||||||
                        ("strikethrough", anstyle::Effects::STRIKETHROUGH),
 | 
					 | 
				
			||||||
                    ];
 | 
					 | 
				
			||||||
                    let effect = args.value()?.parse_with(|s| {
 | 
					 | 
				
			||||||
                        EFFECTS
 | 
					 | 
				
			||||||
                            .into_iter()
 | 
					 | 
				
			||||||
                            .find(|(name, _)| *name == s)
 | 
					 | 
				
			||||||
                            .map(|(_, effect)| effect)
 | 
					 | 
				
			||||||
                            .ok_or_else(|| {
 | 
					 | 
				
			||||||
                                format!(
 | 
					 | 
				
			||||||
                                    "expected one of {}",
 | 
					 | 
				
			||||||
                                    EFFECTS
 | 
					 | 
				
			||||||
                                        .into_iter()
 | 
					 | 
				
			||||||
                                        .map(|(n, _)| n)
 | 
					 | 
				
			||||||
                                        .collect::<Vec<_>>()
 | 
					 | 
				
			||||||
                                        .join(", ")
 | 
					 | 
				
			||||||
                                )
 | 
					 | 
				
			||||||
                            })
 | 
					 | 
				
			||||||
                    })?;
 | 
					 | 
				
			||||||
                    res.effects = res.effects.insert(effect);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                _ => return Err(arg.unexpected()),
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        Ok(res)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										20
									
								
								vendor/anstream/examples/query-stream.rs
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										20
									
								
								vendor/anstream/examples/query-stream.rs
									
									
									
									
										vendored
									
									
								
							@@ -1,20 +0,0 @@
 | 
				
			|||||||
fn main() {
 | 
					 | 
				
			||||||
    println!("stdout:");
 | 
					 | 
				
			||||||
    println!(
 | 
					 | 
				
			||||||
        "  choice: {:?}",
 | 
					 | 
				
			||||||
        anstream::AutoStream::choice(&std::io::stdout())
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
    println!(
 | 
					 | 
				
			||||||
        "  choice: {:?}",
 | 
					 | 
				
			||||||
        anstream::AutoStream::auto(std::io::stdout()).current_choice()
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
    println!("stderr:");
 | 
					 | 
				
			||||||
    println!(
 | 
					 | 
				
			||||||
        "  choice: {:?}",
 | 
					 | 
				
			||||||
        anstream::AutoStream::choice(&std::io::stderr())
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
    println!(
 | 
					 | 
				
			||||||
        "  choice: {:?}",
 | 
					 | 
				
			||||||
        anstream::AutoStream::auto(std::io::stderr()).current_choice()
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										15
									
								
								vendor/anstream/src/adapter/mod.rs
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										15
									
								
								vendor/anstream/src/adapter/mod.rs
									
									
									
									
										vendored
									
									
								
							@@ -1,15 +0,0 @@
 | 
				
			|||||||
//! Gracefully degrade styled output
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
mod strip;
 | 
					 | 
				
			||||||
mod wincon;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pub use strip::strip_bytes;
 | 
					 | 
				
			||||||
pub use strip::strip_str;
 | 
					 | 
				
			||||||
pub use strip::StripBytes;
 | 
					 | 
				
			||||||
pub use strip::StripBytesIter;
 | 
					 | 
				
			||||||
pub use strip::StripStr;
 | 
					 | 
				
			||||||
pub use strip::StripStrIter;
 | 
					 | 
				
			||||||
pub use strip::StrippedBytes;
 | 
					 | 
				
			||||||
pub use strip::StrippedStr;
 | 
					 | 
				
			||||||
pub use wincon::WinconBytes;
 | 
					 | 
				
			||||||
pub use wincon::WinconBytesIter;
 | 
					 | 
				
			||||||
							
								
								
									
										513
									
								
								vendor/anstream/src/adapter/strip.rs
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										513
									
								
								vendor/anstream/src/adapter/strip.rs
									
									
									
									
										vendored
									
									
								
							@@ -1,513 +0,0 @@
 | 
				
			|||||||
use anstyle_parse::state::state_change;
 | 
					 | 
				
			||||||
use anstyle_parse::state::Action;
 | 
					 | 
				
			||||||
use anstyle_parse::state::State;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// Strip ANSI escapes from a `&str`, returning the printable content
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// This can be used to take output from a program that includes escape sequences and write it
 | 
					 | 
				
			||||||
/// somewhere that does not easily support them, such as a log file.
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// For non-contiguous data, see [`StripStr`].
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// # Example
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// ```rust
 | 
					 | 
				
			||||||
/// use std::io::Write as _;
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// let styled_text = "\x1b[32mfoo\x1b[m bar";
 | 
					 | 
				
			||||||
/// let plain_str = anstream::adapter::strip_str(&styled_text).to_string();
 | 
					 | 
				
			||||||
/// assert_eq!(plain_str, "foo bar");
 | 
					 | 
				
			||||||
/// ```
 | 
					 | 
				
			||||||
#[inline]
 | 
					 | 
				
			||||||
pub fn strip_str(data: &str) -> StrippedStr<'_> {
 | 
					 | 
				
			||||||
    StrippedStr::new(data)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// See [`strip_str`]
 | 
					 | 
				
			||||||
#[derive(Default, Clone, Debug, PartialEq, Eq)]
 | 
					 | 
				
			||||||
pub struct StrippedStr<'s> {
 | 
					 | 
				
			||||||
    bytes: &'s [u8],
 | 
					 | 
				
			||||||
    state: State,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl<'s> StrippedStr<'s> {
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn new(data: &'s str) -> Self {
 | 
					 | 
				
			||||||
        Self {
 | 
					 | 
				
			||||||
            bytes: data.as_bytes(),
 | 
					 | 
				
			||||||
            state: State::Ground,
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Create a [`String`] of the printable content
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    #[allow(clippy::inherent_to_string_shadow_display)] // Single-allocation implementation
 | 
					 | 
				
			||||||
    pub fn to_string(&self) -> String {
 | 
					 | 
				
			||||||
        use std::fmt::Write as _;
 | 
					 | 
				
			||||||
        let mut stripped = String::with_capacity(self.bytes.len());
 | 
					 | 
				
			||||||
        let _ = write!(&mut stripped, "{}", self);
 | 
					 | 
				
			||||||
        stripped
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl<'s> std::fmt::Display for StrippedStr<'s> {
 | 
					 | 
				
			||||||
    /// **Note:** this does *not* exhaust the [`Iterator`]
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
 | 
					 | 
				
			||||||
        let iter = Self {
 | 
					 | 
				
			||||||
            bytes: self.bytes,
 | 
					 | 
				
			||||||
            state: self.state,
 | 
					 | 
				
			||||||
        };
 | 
					 | 
				
			||||||
        for printable in iter {
 | 
					 | 
				
			||||||
            printable.fmt(f)?;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        Ok(())
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl<'s> Iterator for StrippedStr<'s> {
 | 
					 | 
				
			||||||
    type Item = &'s str;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn next(&mut self) -> Option<Self::Item> {
 | 
					 | 
				
			||||||
        next_str(&mut self.bytes, &mut self.state)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// Incrementally strip non-contiguous data
 | 
					 | 
				
			||||||
#[derive(Default, Clone, Debug, PartialEq, Eq)]
 | 
					 | 
				
			||||||
pub struct StripStr {
 | 
					 | 
				
			||||||
    state: State,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl StripStr {
 | 
					 | 
				
			||||||
    /// Initial state
 | 
					 | 
				
			||||||
    pub fn new() -> Self {
 | 
					 | 
				
			||||||
        Default::default()
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Strip the next segment of data
 | 
					 | 
				
			||||||
    pub fn strip_next<'s>(&'s mut self, data: &'s str) -> StripStrIter<'s> {
 | 
					 | 
				
			||||||
        StripStrIter {
 | 
					 | 
				
			||||||
            bytes: data.as_bytes(),
 | 
					 | 
				
			||||||
            state: &mut self.state,
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// See [`StripStr`]
 | 
					 | 
				
			||||||
#[derive(Debug, PartialEq, Eq)]
 | 
					 | 
				
			||||||
pub struct StripStrIter<'s> {
 | 
					 | 
				
			||||||
    bytes: &'s [u8],
 | 
					 | 
				
			||||||
    state: &'s mut State,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl<'s> Iterator for StripStrIter<'s> {
 | 
					 | 
				
			||||||
    type Item = &'s str;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn next(&mut self) -> Option<Self::Item> {
 | 
					 | 
				
			||||||
        next_str(&mut self.bytes, self.state)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[inline]
 | 
					 | 
				
			||||||
fn next_str<'s>(bytes: &mut &'s [u8], state: &mut State) -> Option<&'s str> {
 | 
					 | 
				
			||||||
    let offset = bytes.iter().copied().position(|b| {
 | 
					 | 
				
			||||||
        let (next_state, action) = state_change(*state, b);
 | 
					 | 
				
			||||||
        if next_state != State::Anywhere {
 | 
					 | 
				
			||||||
            *state = next_state;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        is_printable_str(action, b)
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
    let (_, next) = bytes.split_at(offset.unwrap_or(bytes.len()));
 | 
					 | 
				
			||||||
    *bytes = next;
 | 
					 | 
				
			||||||
    *state = State::Ground;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let offset = bytes.iter().copied().position(|b| {
 | 
					 | 
				
			||||||
        let (_next_state, action) = state_change(State::Ground, b);
 | 
					 | 
				
			||||||
        !is_printable_str(action, b)
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
    let (printable, next) = bytes.split_at(offset.unwrap_or(bytes.len()));
 | 
					 | 
				
			||||||
    *bytes = next;
 | 
					 | 
				
			||||||
    if printable.is_empty() {
 | 
					 | 
				
			||||||
        None
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
        let printable = unsafe {
 | 
					 | 
				
			||||||
            from_utf8_unchecked(
 | 
					 | 
				
			||||||
                printable,
 | 
					 | 
				
			||||||
                "`bytes` was validated as UTF-8, the parser preserves UTF-8 continuations",
 | 
					 | 
				
			||||||
            )
 | 
					 | 
				
			||||||
        };
 | 
					 | 
				
			||||||
        Some(printable)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[inline]
 | 
					 | 
				
			||||||
unsafe fn from_utf8_unchecked<'b>(bytes: &'b [u8], safety_justification: &'static str) -> &'b str {
 | 
					 | 
				
			||||||
    if cfg!(debug_assertions) {
 | 
					 | 
				
			||||||
        // Catch problems more quickly when testing
 | 
					 | 
				
			||||||
        std::str::from_utf8(bytes).expect(safety_justification)
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
        std::str::from_utf8_unchecked(bytes)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[inline]
 | 
					 | 
				
			||||||
fn is_printable_str(action: Action, byte: u8) -> bool {
 | 
					 | 
				
			||||||
    // VT320 considered 0x7f to be `Print`able but we expect to be working in UTF-8 systems and not
 | 
					 | 
				
			||||||
    // ISO Latin-1, making it DEL and non-printable
 | 
					 | 
				
			||||||
    const DEL: u8 = 0x7f;
 | 
					 | 
				
			||||||
    (action == Action::Print && byte != DEL)
 | 
					 | 
				
			||||||
        || action == Action::BeginUtf8
 | 
					 | 
				
			||||||
        // since we know the input is valid UTF-8, the only thing  we can do with
 | 
					 | 
				
			||||||
        // continuations is to print them
 | 
					 | 
				
			||||||
        || is_utf8_continuation(byte)
 | 
					 | 
				
			||||||
        || (action == Action::Execute && byte.is_ascii_whitespace())
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[inline]
 | 
					 | 
				
			||||||
fn is_utf8_continuation(b: u8) -> bool {
 | 
					 | 
				
			||||||
    matches!(b, 0x80..=0xbf)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// Strip ANSI escapes from bytes, returning the printable content
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// This can be used to take output from a program that includes escape sequences and write it
 | 
					 | 
				
			||||||
/// somewhere that does not easily support them, such as a log file.
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// # Example
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// ```rust
 | 
					 | 
				
			||||||
/// use std::io::Write as _;
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// let styled_text = "\x1b[32mfoo\x1b[m bar";
 | 
					 | 
				
			||||||
/// let plain_str = anstream::adapter::strip_bytes(styled_text.as_bytes()).into_vec();
 | 
					 | 
				
			||||||
/// assert_eq!(plain_str.as_slice(), &b"foo bar"[..]);
 | 
					 | 
				
			||||||
/// ```
 | 
					 | 
				
			||||||
#[inline]
 | 
					 | 
				
			||||||
pub fn strip_bytes(data: &[u8]) -> StrippedBytes<'_> {
 | 
					 | 
				
			||||||
    StrippedBytes::new(data)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// See [`strip_bytes`]
 | 
					 | 
				
			||||||
#[derive(Default, Clone, Debug, PartialEq, Eq)]
 | 
					 | 
				
			||||||
pub struct StrippedBytes<'s> {
 | 
					 | 
				
			||||||
    bytes: &'s [u8],
 | 
					 | 
				
			||||||
    state: State,
 | 
					 | 
				
			||||||
    utf8parser: Utf8Parser,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl<'s> StrippedBytes<'s> {
 | 
					 | 
				
			||||||
    /// See [`strip_bytes`]
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub fn new(bytes: &'s [u8]) -> Self {
 | 
					 | 
				
			||||||
        Self {
 | 
					 | 
				
			||||||
            bytes,
 | 
					 | 
				
			||||||
            state: State::Ground,
 | 
					 | 
				
			||||||
            utf8parser: Default::default(),
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Strip the next slice of bytes
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// Used when the content is in several non-contiguous slices
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// # Panic
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// May panic if it is not exhausted / empty
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub fn extend(&mut self, bytes: &'s [u8]) {
 | 
					 | 
				
			||||||
        debug_assert!(
 | 
					 | 
				
			||||||
            self.is_empty(),
 | 
					 | 
				
			||||||
            "current bytes must be processed to ensure we end at the right state"
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
        self.bytes = bytes;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Report the bytes has been exhausted
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub fn is_empty(&self) -> bool {
 | 
					 | 
				
			||||||
        self.bytes.is_empty()
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Create a [`Vec`] of the printable content
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub fn into_vec(self) -> Vec<u8> {
 | 
					 | 
				
			||||||
        let mut stripped = Vec::with_capacity(self.bytes.len());
 | 
					 | 
				
			||||||
        for printable in self {
 | 
					 | 
				
			||||||
            stripped.extend(printable);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        stripped
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl<'s> Iterator for StrippedBytes<'s> {
 | 
					 | 
				
			||||||
    type Item = &'s [u8];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn next(&mut self) -> Option<Self::Item> {
 | 
					 | 
				
			||||||
        next_bytes(&mut self.bytes, &mut self.state, &mut self.utf8parser)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// Incrementally strip non-contiguous data
 | 
					 | 
				
			||||||
#[derive(Default, Clone, Debug, PartialEq, Eq)]
 | 
					 | 
				
			||||||
pub struct StripBytes {
 | 
					 | 
				
			||||||
    state: State,
 | 
					 | 
				
			||||||
    utf8parser: Utf8Parser,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl StripBytes {
 | 
					 | 
				
			||||||
    /// Initial state
 | 
					 | 
				
			||||||
    pub fn new() -> Self {
 | 
					 | 
				
			||||||
        Default::default()
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Strip the next segment of data
 | 
					 | 
				
			||||||
    pub fn strip_next<'s>(&'s mut self, bytes: &'s [u8]) -> StripBytesIter<'s> {
 | 
					 | 
				
			||||||
        StripBytesIter {
 | 
					 | 
				
			||||||
            bytes,
 | 
					 | 
				
			||||||
            state: &mut self.state,
 | 
					 | 
				
			||||||
            utf8parser: &mut self.utf8parser,
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// See [`StripBytes`]
 | 
					 | 
				
			||||||
#[derive(Debug, PartialEq, Eq)]
 | 
					 | 
				
			||||||
pub struct StripBytesIter<'s> {
 | 
					 | 
				
			||||||
    bytes: &'s [u8],
 | 
					 | 
				
			||||||
    state: &'s mut State,
 | 
					 | 
				
			||||||
    utf8parser: &'s mut Utf8Parser,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl<'s> Iterator for StripBytesIter<'s> {
 | 
					 | 
				
			||||||
    type Item = &'s [u8];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn next(&mut self) -> Option<Self::Item> {
 | 
					 | 
				
			||||||
        next_bytes(&mut self.bytes, self.state, self.utf8parser)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[inline]
 | 
					 | 
				
			||||||
fn next_bytes<'s>(
 | 
					 | 
				
			||||||
    bytes: &mut &'s [u8],
 | 
					 | 
				
			||||||
    state: &mut State,
 | 
					 | 
				
			||||||
    utf8parser: &mut Utf8Parser,
 | 
					 | 
				
			||||||
) -> Option<&'s [u8]> {
 | 
					 | 
				
			||||||
    let offset = bytes.iter().copied().position(|b| {
 | 
					 | 
				
			||||||
        if *state == State::Utf8 {
 | 
					 | 
				
			||||||
            true
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            let (next_state, action) = state_change(*state, b);
 | 
					 | 
				
			||||||
            if next_state != State::Anywhere {
 | 
					 | 
				
			||||||
                *state = next_state;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            is_printable_bytes(action, b)
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
    let (_, next) = bytes.split_at(offset.unwrap_or(bytes.len()));
 | 
					 | 
				
			||||||
    *bytes = next;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let offset = bytes.iter().copied().position(|b| {
 | 
					 | 
				
			||||||
        if *state == State::Utf8 {
 | 
					 | 
				
			||||||
            if utf8parser.add(b) {
 | 
					 | 
				
			||||||
                *state = State::Ground;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            false
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            let (next_state, action) = state_change(State::Ground, b);
 | 
					 | 
				
			||||||
            if next_state != State::Anywhere {
 | 
					 | 
				
			||||||
                *state = next_state;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            if *state == State::Utf8 {
 | 
					 | 
				
			||||||
                utf8parser.add(b);
 | 
					 | 
				
			||||||
                false
 | 
					 | 
				
			||||||
            } else {
 | 
					 | 
				
			||||||
                !is_printable_bytes(action, b)
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
    let (printable, next) = bytes.split_at(offset.unwrap_or(bytes.len()));
 | 
					 | 
				
			||||||
    *bytes = next;
 | 
					 | 
				
			||||||
    if printable.is_empty() {
 | 
					 | 
				
			||||||
        None
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
        Some(printable)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[derive(Default, Clone, Debug, PartialEq, Eq)]
 | 
					 | 
				
			||||||
pub struct Utf8Parser {
 | 
					 | 
				
			||||||
    utf8_parser: utf8parse::Parser,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl Utf8Parser {
 | 
					 | 
				
			||||||
    fn add(&mut self, byte: u8) -> bool {
 | 
					 | 
				
			||||||
        let mut b = false;
 | 
					 | 
				
			||||||
        let mut receiver = VtUtf8Receiver(&mut b);
 | 
					 | 
				
			||||||
        self.utf8_parser.advance(&mut receiver, byte);
 | 
					 | 
				
			||||||
        b
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct VtUtf8Receiver<'a>(&'a mut bool);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl<'a> utf8parse::Receiver for VtUtf8Receiver<'a> {
 | 
					 | 
				
			||||||
    fn codepoint(&mut self, _: char) {
 | 
					 | 
				
			||||||
        *self.0 = true;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    fn invalid_sequence(&mut self) {
 | 
					 | 
				
			||||||
        *self.0 = true;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[inline]
 | 
					 | 
				
			||||||
fn is_printable_bytes(action: Action, byte: u8) -> bool {
 | 
					 | 
				
			||||||
    // VT320 considered 0x7f to be `Print`able but we expect to be working in UTF-8 systems and not
 | 
					 | 
				
			||||||
    // ISO Latin-1, making it DEL and non-printable
 | 
					 | 
				
			||||||
    const DEL: u8 = 0x7f;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // Continuations aren't included as they may also be control codes, requiring more context
 | 
					 | 
				
			||||||
    (action == Action::Print && byte != DEL)
 | 
					 | 
				
			||||||
        || action == Action::BeginUtf8
 | 
					 | 
				
			||||||
        || (action == Action::Execute && byte.is_ascii_whitespace())
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[cfg(test)]
 | 
					 | 
				
			||||||
mod test {
 | 
					 | 
				
			||||||
    use super::*;
 | 
					 | 
				
			||||||
    use proptest::prelude::*;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Model based off full parser
 | 
					 | 
				
			||||||
    fn parser_strip(bytes: &[u8]) -> String {
 | 
					 | 
				
			||||||
        #[derive(Default)]
 | 
					 | 
				
			||||||
        struct Strip(String);
 | 
					 | 
				
			||||||
        impl Strip {
 | 
					 | 
				
			||||||
            fn with_capacity(capacity: usize) -> Self {
 | 
					 | 
				
			||||||
                Self(String::with_capacity(capacity))
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        impl anstyle_parse::Perform for Strip {
 | 
					 | 
				
			||||||
            fn print(&mut self, c: char) {
 | 
					 | 
				
			||||||
                self.0.push(c);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            fn execute(&mut self, byte: u8) {
 | 
					 | 
				
			||||||
                if byte.is_ascii_whitespace() {
 | 
					 | 
				
			||||||
                    self.0.push(byte as char);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        let mut stripped = Strip::with_capacity(bytes.len());
 | 
					 | 
				
			||||||
        let mut parser = anstyle_parse::Parser::<anstyle_parse::DefaultCharAccumulator>::new();
 | 
					 | 
				
			||||||
        for byte in bytes {
 | 
					 | 
				
			||||||
            parser.advance(&mut stripped, *byte);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        stripped.0
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Model verifying incremental parsing
 | 
					 | 
				
			||||||
    fn strip_char(mut s: &str) -> String {
 | 
					 | 
				
			||||||
        let mut result = String::new();
 | 
					 | 
				
			||||||
        let mut state = StripStr::new();
 | 
					 | 
				
			||||||
        while !s.is_empty() {
 | 
					 | 
				
			||||||
            let mut indices = s.char_indices();
 | 
					 | 
				
			||||||
            indices.next(); // current
 | 
					 | 
				
			||||||
            let offset = indices.next().map(|(i, _)| i).unwrap_or_else(|| s.len());
 | 
					 | 
				
			||||||
            let (current, remainder) = s.split_at(offset);
 | 
					 | 
				
			||||||
            for printable in state.strip_next(current) {
 | 
					 | 
				
			||||||
                result.push_str(printable);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            s = remainder;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        result
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Model verifying incremental parsing
 | 
					 | 
				
			||||||
    fn strip_byte(s: &[u8]) -> Vec<u8> {
 | 
					 | 
				
			||||||
        let mut result = Vec::new();
 | 
					 | 
				
			||||||
        let mut state = StripBytes::default();
 | 
					 | 
				
			||||||
        for start in 0..s.len() {
 | 
					 | 
				
			||||||
            let current = &s[start..=start];
 | 
					 | 
				
			||||||
            for printable in state.strip_next(current) {
 | 
					 | 
				
			||||||
                result.extend(printable);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        result
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[test]
 | 
					 | 
				
			||||||
    fn test_strip_bytes_multibyte() {
 | 
					 | 
				
			||||||
        let bytes = [240, 145, 141, 139];
 | 
					 | 
				
			||||||
        let expected = parser_strip(&bytes);
 | 
					 | 
				
			||||||
        let actual = String::from_utf8(strip_bytes(&bytes).into_vec()).unwrap();
 | 
					 | 
				
			||||||
        assert_eq!(expected, actual);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[test]
 | 
					 | 
				
			||||||
    fn test_strip_byte_multibyte() {
 | 
					 | 
				
			||||||
        let bytes = [240, 145, 141, 139];
 | 
					 | 
				
			||||||
        let expected = parser_strip(&bytes);
 | 
					 | 
				
			||||||
        let actual = String::from_utf8(strip_byte(&bytes).to_vec()).unwrap();
 | 
					 | 
				
			||||||
        assert_eq!(expected, actual);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[test]
 | 
					 | 
				
			||||||
    fn test_strip_str_del() {
 | 
					 | 
				
			||||||
        let input = std::str::from_utf8(&[0x7f]).unwrap();
 | 
					 | 
				
			||||||
        let expected = "";
 | 
					 | 
				
			||||||
        let actual = strip_str(input).to_string();
 | 
					 | 
				
			||||||
        assert_eq!(expected, actual);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[test]
 | 
					 | 
				
			||||||
    fn test_strip_byte_del() {
 | 
					 | 
				
			||||||
        let bytes = [0x7f];
 | 
					 | 
				
			||||||
        let expected = "";
 | 
					 | 
				
			||||||
        let actual = String::from_utf8(strip_byte(&bytes).to_vec()).unwrap();
 | 
					 | 
				
			||||||
        assert_eq!(expected, actual);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    proptest! {
 | 
					 | 
				
			||||||
        #[test]
 | 
					 | 
				
			||||||
        #[cfg_attr(miri, ignore)]  // See https://github.com/AltSysrq/proptest/issues/253
 | 
					 | 
				
			||||||
        fn strip_str_no_escapes(s in "\\PC*") {
 | 
					 | 
				
			||||||
            let expected = parser_strip(s.as_bytes());
 | 
					 | 
				
			||||||
            let actual = strip_str(&s).to_string();
 | 
					 | 
				
			||||||
            assert_eq!(expected, actual);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        #[test]
 | 
					 | 
				
			||||||
        #[cfg_attr(miri, ignore)]  // See https://github.com/AltSysrq/proptest/issues/253
 | 
					 | 
				
			||||||
        fn strip_char_no_escapes(s in "\\PC*") {
 | 
					 | 
				
			||||||
            let expected = parser_strip(s.as_bytes());
 | 
					 | 
				
			||||||
            let actual = strip_char(&s);
 | 
					 | 
				
			||||||
            assert_eq!(expected, actual);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        #[test]
 | 
					 | 
				
			||||||
        #[cfg_attr(miri, ignore)]  // See https://github.com/AltSysrq/proptest/issues/253
 | 
					 | 
				
			||||||
        fn strip_bytes_no_escapes(s in "\\PC*") {
 | 
					 | 
				
			||||||
            dbg!(&s);
 | 
					 | 
				
			||||||
            dbg!(s.as_bytes());
 | 
					 | 
				
			||||||
            let expected = parser_strip(s.as_bytes());
 | 
					 | 
				
			||||||
            let actual = String::from_utf8(strip_bytes(s.as_bytes()).into_vec()).unwrap();
 | 
					 | 
				
			||||||
            assert_eq!(expected, actual);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        #[test]
 | 
					 | 
				
			||||||
        #[cfg_attr(miri, ignore)]  // See https://github.com/AltSysrq/proptest/issues/253
 | 
					 | 
				
			||||||
        fn strip_byte_no_escapes(s in "\\PC*") {
 | 
					 | 
				
			||||||
            dbg!(&s);
 | 
					 | 
				
			||||||
            dbg!(s.as_bytes());
 | 
					 | 
				
			||||||
            let expected = parser_strip(s.as_bytes());
 | 
					 | 
				
			||||||
            let actual = String::from_utf8(strip_byte(s.as_bytes()).to_vec()).unwrap();
 | 
					 | 
				
			||||||
            assert_eq!(expected, actual);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										320
									
								
								vendor/anstream/src/adapter/wincon.rs
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										320
									
								
								vendor/anstream/src/adapter/wincon.rs
									
									
									
									
										vendored
									
									
								
							@@ -1,320 +0,0 @@
 | 
				
			|||||||
/// Incrementally convert to wincon calls for non-contiguous data
 | 
					 | 
				
			||||||
#[derive(Default, Clone, Debug, PartialEq, Eq)]
 | 
					 | 
				
			||||||
pub struct WinconBytes {
 | 
					 | 
				
			||||||
    parser: anstyle_parse::Parser,
 | 
					 | 
				
			||||||
    capture: WinconCapture,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl WinconBytes {
 | 
					 | 
				
			||||||
    /// Initial state
 | 
					 | 
				
			||||||
    pub fn new() -> Self {
 | 
					 | 
				
			||||||
        Default::default()
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Strip the next segment of data
 | 
					 | 
				
			||||||
    pub fn extract_next<'s>(&'s mut self, bytes: &'s [u8]) -> WinconBytesIter<'s> {
 | 
					 | 
				
			||||||
        self.capture.reset();
 | 
					 | 
				
			||||||
        self.capture.printable.reserve(bytes.len());
 | 
					 | 
				
			||||||
        WinconBytesIter {
 | 
					 | 
				
			||||||
            bytes,
 | 
					 | 
				
			||||||
            parser: &mut self.parser,
 | 
					 | 
				
			||||||
            capture: &mut self.capture,
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// See [`WinconBytes`]
 | 
					 | 
				
			||||||
#[derive(Debug, PartialEq, Eq)]
 | 
					 | 
				
			||||||
pub struct WinconBytesIter<'s> {
 | 
					 | 
				
			||||||
    bytes: &'s [u8],
 | 
					 | 
				
			||||||
    parser: &'s mut anstyle_parse::Parser,
 | 
					 | 
				
			||||||
    capture: &'s mut WinconCapture,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl<'s> Iterator for WinconBytesIter<'s> {
 | 
					 | 
				
			||||||
    type Item = (anstyle::Style, String);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn next(&mut self) -> Option<Self::Item> {
 | 
					 | 
				
			||||||
        next_bytes(&mut self.bytes, self.parser, self.capture)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[inline]
 | 
					 | 
				
			||||||
fn next_bytes(
 | 
					 | 
				
			||||||
    bytes: &mut &[u8],
 | 
					 | 
				
			||||||
    parser: &mut anstyle_parse::Parser,
 | 
					 | 
				
			||||||
    capture: &mut WinconCapture,
 | 
					 | 
				
			||||||
) -> Option<(anstyle::Style, String)> {
 | 
					 | 
				
			||||||
    capture.reset();
 | 
					 | 
				
			||||||
    while capture.ready.is_none() {
 | 
					 | 
				
			||||||
        let byte = if let Some((byte, remainder)) = (*bytes).split_first() {
 | 
					 | 
				
			||||||
            *bytes = remainder;
 | 
					 | 
				
			||||||
            *byte
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        };
 | 
					 | 
				
			||||||
        parser.advance(capture, byte);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if capture.printable.is_empty() {
 | 
					 | 
				
			||||||
        return None;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let style = capture.ready.unwrap_or(capture.style);
 | 
					 | 
				
			||||||
    Some((style, std::mem::take(&mut capture.printable)))
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[derive(Default, Clone, Debug, PartialEq, Eq)]
 | 
					 | 
				
			||||||
struct WinconCapture {
 | 
					 | 
				
			||||||
    style: anstyle::Style,
 | 
					 | 
				
			||||||
    printable: String,
 | 
					 | 
				
			||||||
    ready: Option<anstyle::Style>,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl WinconCapture {
 | 
					 | 
				
			||||||
    fn reset(&mut self) {
 | 
					 | 
				
			||||||
        self.ready = None;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl anstyle_parse::Perform for WinconCapture {
 | 
					 | 
				
			||||||
    /// Draw a character to the screen and update states.
 | 
					 | 
				
			||||||
    fn print(&mut self, c: char) {
 | 
					 | 
				
			||||||
        self.printable.push(c);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Execute a C0 or C1 control function.
 | 
					 | 
				
			||||||
    fn execute(&mut self, byte: u8) {
 | 
					 | 
				
			||||||
        if byte.is_ascii_whitespace() {
 | 
					 | 
				
			||||||
            self.printable.push(byte as char);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    fn csi_dispatch(
 | 
					 | 
				
			||||||
        &mut self,
 | 
					 | 
				
			||||||
        params: &anstyle_parse::Params,
 | 
					 | 
				
			||||||
        _intermediates: &[u8],
 | 
					 | 
				
			||||||
        ignore: bool,
 | 
					 | 
				
			||||||
        action: u8,
 | 
					 | 
				
			||||||
    ) {
 | 
					 | 
				
			||||||
        if ignore {
 | 
					 | 
				
			||||||
            return;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        if action != b'm' {
 | 
					 | 
				
			||||||
            return;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        let mut style = self.style;
 | 
					 | 
				
			||||||
        // param/value differences are dependent on the escape code
 | 
					 | 
				
			||||||
        let mut state = State::Normal;
 | 
					 | 
				
			||||||
        let mut r = None;
 | 
					 | 
				
			||||||
        let mut g = None;
 | 
					 | 
				
			||||||
        let mut is_bg = false;
 | 
					 | 
				
			||||||
        for param in params {
 | 
					 | 
				
			||||||
            for value in param {
 | 
					 | 
				
			||||||
                match (state, *value) {
 | 
					 | 
				
			||||||
                    (State::Normal, 0) => {
 | 
					 | 
				
			||||||
                        style = anstyle::Style::default();
 | 
					 | 
				
			||||||
                        break;
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    (State::Normal, 1) => {
 | 
					 | 
				
			||||||
                        style = style.bold();
 | 
					 | 
				
			||||||
                        break;
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    (State::Normal, 4) => {
 | 
					 | 
				
			||||||
                        style = style.underline();
 | 
					 | 
				
			||||||
                        break;
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    (State::Normal, 30..=37) => {
 | 
					 | 
				
			||||||
                        let color = to_ansi_color(value - 30).unwrap();
 | 
					 | 
				
			||||||
                        style = style.fg_color(Some(color.into()));
 | 
					 | 
				
			||||||
                        break;
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    (State::Normal, 38) => {
 | 
					 | 
				
			||||||
                        is_bg = false;
 | 
					 | 
				
			||||||
                        state = State::PrepareCustomColor;
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    (State::Normal, 39) => {
 | 
					 | 
				
			||||||
                        style = style.fg_color(None);
 | 
					 | 
				
			||||||
                        break;
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    (State::Normal, 40..=47) => {
 | 
					 | 
				
			||||||
                        let color = to_ansi_color(value - 40).unwrap();
 | 
					 | 
				
			||||||
                        style = style.bg_color(Some(color.into()));
 | 
					 | 
				
			||||||
                        break;
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    (State::Normal, 48) => {
 | 
					 | 
				
			||||||
                        is_bg = true;
 | 
					 | 
				
			||||||
                        state = State::PrepareCustomColor;
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    (State::Normal, 49) => {
 | 
					 | 
				
			||||||
                        style = style.bg_color(None);
 | 
					 | 
				
			||||||
                        break;
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    (State::Normal, 90..=97) => {
 | 
					 | 
				
			||||||
                        let color = to_ansi_color(value - 90).unwrap().bright(true);
 | 
					 | 
				
			||||||
                        style = style.fg_color(Some(color.into()));
 | 
					 | 
				
			||||||
                        break;
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    (State::Normal, 100..=107) => {
 | 
					 | 
				
			||||||
                        let color = to_ansi_color(value - 100).unwrap().bright(true);
 | 
					 | 
				
			||||||
                        style = style.bg_color(Some(color.into()));
 | 
					 | 
				
			||||||
                        break;
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    (State::PrepareCustomColor, 5) => {
 | 
					 | 
				
			||||||
                        state = State::Ansi256;
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    (State::PrepareCustomColor, 2) => {
 | 
					 | 
				
			||||||
                        state = State::Rgb;
 | 
					 | 
				
			||||||
                        r = None;
 | 
					 | 
				
			||||||
                        g = None;
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    (State::Ansi256, n) => {
 | 
					 | 
				
			||||||
                        let color = anstyle::Ansi256Color(n as u8);
 | 
					 | 
				
			||||||
                        if is_bg {
 | 
					 | 
				
			||||||
                            style = style.bg_color(Some(color.into()));
 | 
					 | 
				
			||||||
                        } else {
 | 
					 | 
				
			||||||
                            style = style.fg_color(Some(color.into()));
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                        break;
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    (State::Rgb, b) => match (r, g) {
 | 
					 | 
				
			||||||
                        (None, _) => {
 | 
					 | 
				
			||||||
                            r = Some(b);
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                        (Some(_), None) => {
 | 
					 | 
				
			||||||
                            g = Some(b);
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                        (Some(r), Some(g)) => {
 | 
					 | 
				
			||||||
                            let color = anstyle::RgbColor(r as u8, g as u8, b as u8);
 | 
					 | 
				
			||||||
                            if is_bg {
 | 
					 | 
				
			||||||
                                style = style.bg_color(Some(color.into()));
 | 
					 | 
				
			||||||
                            } else {
 | 
					 | 
				
			||||||
                                style = style.fg_color(Some(color.into()));
 | 
					 | 
				
			||||||
                            }
 | 
					 | 
				
			||||||
                            break;
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                    },
 | 
					 | 
				
			||||||
                    _ => {
 | 
					 | 
				
			||||||
                        break;
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if style != self.style && !self.printable.is_empty() {
 | 
					 | 
				
			||||||
            self.ready = Some(self.style);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        self.style = style;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
 | 
					 | 
				
			||||||
enum State {
 | 
					 | 
				
			||||||
    Normal,
 | 
					 | 
				
			||||||
    PrepareCustomColor,
 | 
					 | 
				
			||||||
    Ansi256,
 | 
					 | 
				
			||||||
    Rgb,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
fn to_ansi_color(digit: u16) -> Option<anstyle::AnsiColor> {
 | 
					 | 
				
			||||||
    match digit {
 | 
					 | 
				
			||||||
        0 => Some(anstyle::AnsiColor::Black),
 | 
					 | 
				
			||||||
        1 => Some(anstyle::AnsiColor::Red),
 | 
					 | 
				
			||||||
        2 => Some(anstyle::AnsiColor::Green),
 | 
					 | 
				
			||||||
        3 => Some(anstyle::AnsiColor::Yellow),
 | 
					 | 
				
			||||||
        4 => Some(anstyle::AnsiColor::Blue),
 | 
					 | 
				
			||||||
        5 => Some(anstyle::AnsiColor::Magenta),
 | 
					 | 
				
			||||||
        6 => Some(anstyle::AnsiColor::Cyan),
 | 
					 | 
				
			||||||
        7 => Some(anstyle::AnsiColor::White),
 | 
					 | 
				
			||||||
        _ => None,
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[cfg(test)]
 | 
					 | 
				
			||||||
mod test {
 | 
					 | 
				
			||||||
    use super::*;
 | 
					 | 
				
			||||||
    use owo_colors::OwoColorize as _;
 | 
					 | 
				
			||||||
    use proptest::prelude::*;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[track_caller]
 | 
					 | 
				
			||||||
    fn verify(input: &str, expected: Vec<(anstyle::Style, &str)>) {
 | 
					 | 
				
			||||||
        let expected = expected
 | 
					 | 
				
			||||||
            .into_iter()
 | 
					 | 
				
			||||||
            .map(|(style, value)| (style, value.to_owned()))
 | 
					 | 
				
			||||||
            .collect::<Vec<_>>();
 | 
					 | 
				
			||||||
        let mut state = WinconBytes::new();
 | 
					 | 
				
			||||||
        let actual = state.extract_next(input.as_bytes()).collect::<Vec<_>>();
 | 
					 | 
				
			||||||
        assert_eq!(expected, actual, "{input:?}");
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[test]
 | 
					 | 
				
			||||||
    fn start() {
 | 
					 | 
				
			||||||
        let input = format!("{} world!", "Hello".green().on_red());
 | 
					 | 
				
			||||||
        let expected = vec![
 | 
					 | 
				
			||||||
            (
 | 
					 | 
				
			||||||
                anstyle::AnsiColor::Green.on(anstyle::AnsiColor::Red),
 | 
					 | 
				
			||||||
                "Hello",
 | 
					 | 
				
			||||||
            ),
 | 
					 | 
				
			||||||
            (anstyle::Style::default(), " world!"),
 | 
					 | 
				
			||||||
        ];
 | 
					 | 
				
			||||||
        verify(&input, expected);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[test]
 | 
					 | 
				
			||||||
    fn middle() {
 | 
					 | 
				
			||||||
        let input = format!("Hello {}!", "world".green().on_red());
 | 
					 | 
				
			||||||
        let expected = vec![
 | 
					 | 
				
			||||||
            (anstyle::Style::default(), "Hello "),
 | 
					 | 
				
			||||||
            (
 | 
					 | 
				
			||||||
                anstyle::AnsiColor::Green.on(anstyle::AnsiColor::Red),
 | 
					 | 
				
			||||||
                "world",
 | 
					 | 
				
			||||||
            ),
 | 
					 | 
				
			||||||
            (anstyle::Style::default(), "!"),
 | 
					 | 
				
			||||||
        ];
 | 
					 | 
				
			||||||
        verify(&input, expected);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[test]
 | 
					 | 
				
			||||||
    fn end() {
 | 
					 | 
				
			||||||
        let input = format!("Hello {}", "world!".green().on_red());
 | 
					 | 
				
			||||||
        let expected = vec![
 | 
					 | 
				
			||||||
            (anstyle::Style::default(), "Hello "),
 | 
					 | 
				
			||||||
            (
 | 
					 | 
				
			||||||
                anstyle::AnsiColor::Green.on(anstyle::AnsiColor::Red),
 | 
					 | 
				
			||||||
                "world!",
 | 
					 | 
				
			||||||
            ),
 | 
					 | 
				
			||||||
        ];
 | 
					 | 
				
			||||||
        verify(&input, expected);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[test]
 | 
					 | 
				
			||||||
    fn ansi256_colors() {
 | 
					 | 
				
			||||||
        // termcolor only supports "brights" via these
 | 
					 | 
				
			||||||
        let input = format!(
 | 
					 | 
				
			||||||
            "Hello {}!",
 | 
					 | 
				
			||||||
            "world".color(owo_colors::XtermColors::UserBrightYellow)
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
        let expected = vec![
 | 
					 | 
				
			||||||
            (anstyle::Style::default(), "Hello "),
 | 
					 | 
				
			||||||
            (anstyle::Ansi256Color(11).on_default(), "world"),
 | 
					 | 
				
			||||||
            (anstyle::Style::default(), "!"),
 | 
					 | 
				
			||||||
        ];
 | 
					 | 
				
			||||||
        verify(&input, expected);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    proptest! {
 | 
					 | 
				
			||||||
        #[test]
 | 
					 | 
				
			||||||
        #[cfg_attr(miri, ignore)]  // See https://github.com/AltSysrq/proptest/issues/253
 | 
					 | 
				
			||||||
        fn wincon_no_escapes(s in "\\PC*") {
 | 
					 | 
				
			||||||
            let expected = if s.is_empty() {
 | 
					 | 
				
			||||||
                vec![]
 | 
					 | 
				
			||||||
            } else {
 | 
					 | 
				
			||||||
                vec![(anstyle::Style::default(), s.clone())]
 | 
					 | 
				
			||||||
            };
 | 
					 | 
				
			||||||
            let mut state = WinconBytes::new();
 | 
					 | 
				
			||||||
            let actual = state.extract_next(s.as_bytes()).collect::<Vec<_>>();
 | 
					 | 
				
			||||||
            assert_eq!(expected, actual);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										263
									
								
								vendor/anstream/src/auto.rs
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										263
									
								
								vendor/anstream/src/auto.rs
									
									
									
									
										vendored
									
									
								
							@@ -1,263 +0,0 @@
 | 
				
			|||||||
use crate::stream::AsLockedWrite;
 | 
					 | 
				
			||||||
use crate::stream::RawStream;
 | 
					 | 
				
			||||||
#[cfg(feature = "auto")]
 | 
					 | 
				
			||||||
use crate::ColorChoice;
 | 
					 | 
				
			||||||
use crate::StripStream;
 | 
					 | 
				
			||||||
#[cfg(all(windows, feature = "wincon"))]
 | 
					 | 
				
			||||||
use crate::WinconStream;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// [`std::io::Write`] that adapts ANSI escape codes to the underlying `Write`s capabilities
 | 
					 | 
				
			||||||
#[derive(Debug)]
 | 
					 | 
				
			||||||
pub struct AutoStream<S: RawStream> {
 | 
					 | 
				
			||||||
    inner: StreamInner<S>,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[derive(Debug)]
 | 
					 | 
				
			||||||
enum StreamInner<S: RawStream> {
 | 
					 | 
				
			||||||
    PassThrough(S),
 | 
					 | 
				
			||||||
    Strip(StripStream<S>),
 | 
					 | 
				
			||||||
    #[cfg(all(windows, feature = "wincon"))]
 | 
					 | 
				
			||||||
    Wincon(WinconStream<S>),
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl<S> AutoStream<S>
 | 
					 | 
				
			||||||
where
 | 
					 | 
				
			||||||
    S: RawStream,
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    /// Runtime control over styling behavior
 | 
					 | 
				
			||||||
    #[cfg(feature = "auto")]
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub fn new(raw: S, choice: ColorChoice) -> Self {
 | 
					 | 
				
			||||||
        match choice {
 | 
					 | 
				
			||||||
            ColorChoice::Auto => Self::auto(raw),
 | 
					 | 
				
			||||||
            ColorChoice::AlwaysAnsi => Self::always_ansi(raw),
 | 
					 | 
				
			||||||
            ColorChoice::Always => Self::always(raw),
 | 
					 | 
				
			||||||
            ColorChoice::Never => Self::never(raw),
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Auto-adapt for the stream's capabilities
 | 
					 | 
				
			||||||
    #[cfg(feature = "auto")]
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub fn auto(raw: S) -> Self {
 | 
					 | 
				
			||||||
        let choice = Self::choice(&raw);
 | 
					 | 
				
			||||||
        debug_assert_ne!(choice, ColorChoice::Auto);
 | 
					 | 
				
			||||||
        Self::new(raw, choice)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Report the desired choice for the given stream
 | 
					 | 
				
			||||||
    #[cfg(feature = "auto")]
 | 
					 | 
				
			||||||
    pub fn choice(raw: &S) -> ColorChoice {
 | 
					 | 
				
			||||||
        choice(raw)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Force ANSI escape codes to be passed through as-is, no matter what the inner `Write`
 | 
					 | 
				
			||||||
    /// supports.
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub fn always_ansi(raw: S) -> Self {
 | 
					 | 
				
			||||||
        #[cfg(feature = "auto")]
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            if raw.is_terminal() {
 | 
					 | 
				
			||||||
                let _ = anstyle_query::windows::enable_ansi_colors();
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        Self::always_ansi_(raw)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn always_ansi_(raw: S) -> Self {
 | 
					 | 
				
			||||||
        let inner = StreamInner::PassThrough(raw);
 | 
					 | 
				
			||||||
        AutoStream { inner }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Force color, no matter what the inner `Write` supports.
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub fn always(raw: S) -> Self {
 | 
					 | 
				
			||||||
        if cfg!(windows) {
 | 
					 | 
				
			||||||
            #[cfg(feature = "auto")]
 | 
					 | 
				
			||||||
            let use_wincon = raw.is_terminal()
 | 
					 | 
				
			||||||
                && !anstyle_query::windows::enable_ansi_colors().unwrap_or(true)
 | 
					 | 
				
			||||||
                && !anstyle_query::term_supports_ansi_color();
 | 
					 | 
				
			||||||
            #[cfg(not(feature = "auto"))]
 | 
					 | 
				
			||||||
            let use_wincon = true;
 | 
					 | 
				
			||||||
            if use_wincon {
 | 
					 | 
				
			||||||
                Self::wincon(raw).unwrap_or_else(|raw| Self::always_ansi_(raw))
 | 
					 | 
				
			||||||
            } else {
 | 
					 | 
				
			||||||
                Self::always_ansi_(raw)
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            Self::always_ansi(raw)
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Only pass printable data to the inner `Write`.
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub fn never(raw: S) -> Self {
 | 
					 | 
				
			||||||
        let inner = StreamInner::Strip(StripStream::new(raw));
 | 
					 | 
				
			||||||
        AutoStream { inner }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn wincon(raw: S) -> Result<Self, S> {
 | 
					 | 
				
			||||||
        #[cfg(all(windows, feature = "wincon"))]
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            Ok(Self {
 | 
					 | 
				
			||||||
                inner: StreamInner::Wincon(WinconStream::new(raw)),
 | 
					 | 
				
			||||||
            })
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        #[cfg(not(all(windows, feature = "wincon")))]
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            Err(raw)
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Get the wrapped [`RawStream`]
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub fn into_inner(self) -> S {
 | 
					 | 
				
			||||||
        match self.inner {
 | 
					 | 
				
			||||||
            StreamInner::PassThrough(w) => w,
 | 
					 | 
				
			||||||
            StreamInner::Strip(w) => w.into_inner(),
 | 
					 | 
				
			||||||
            #[cfg(all(windows, feature = "wincon"))]
 | 
					 | 
				
			||||||
            StreamInner::Wincon(w) => w.into_inner(),
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub fn is_terminal(&self) -> bool {
 | 
					 | 
				
			||||||
        match &self.inner {
 | 
					 | 
				
			||||||
            StreamInner::PassThrough(w) => w.is_terminal(),
 | 
					 | 
				
			||||||
            StreamInner::Strip(w) => w.is_terminal(),
 | 
					 | 
				
			||||||
            #[cfg(all(windows, feature = "wincon"))]
 | 
					 | 
				
			||||||
            StreamInner::Wincon(_) => true, // its only ever a terminal
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Prefer [`AutoStream::choice`]
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// This doesn't report what is requested but what is currently active.
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    #[cfg(feature = "auto")]
 | 
					 | 
				
			||||||
    pub fn current_choice(&self) -> ColorChoice {
 | 
					 | 
				
			||||||
        match &self.inner {
 | 
					 | 
				
			||||||
            StreamInner::PassThrough(_) => ColorChoice::AlwaysAnsi,
 | 
					 | 
				
			||||||
            StreamInner::Strip(_) => ColorChoice::Never,
 | 
					 | 
				
			||||||
            #[cfg(all(windows, feature = "wincon"))]
 | 
					 | 
				
			||||||
            StreamInner::Wincon(_) => ColorChoice::Always,
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[cfg(feature = "auto")]
 | 
					 | 
				
			||||||
fn choice(raw: &dyn RawStream) -> ColorChoice {
 | 
					 | 
				
			||||||
    let choice = ColorChoice::global();
 | 
					 | 
				
			||||||
    match choice {
 | 
					 | 
				
			||||||
        ColorChoice::Auto => {
 | 
					 | 
				
			||||||
            let clicolor = anstyle_query::clicolor();
 | 
					 | 
				
			||||||
            let clicolor_enabled = clicolor.unwrap_or(false);
 | 
					 | 
				
			||||||
            let clicolor_disabled = !clicolor.unwrap_or(true);
 | 
					 | 
				
			||||||
            if raw.is_terminal()
 | 
					 | 
				
			||||||
                && !anstyle_query::no_color()
 | 
					 | 
				
			||||||
                && !clicolor_disabled
 | 
					 | 
				
			||||||
                && (anstyle_query::term_supports_color()
 | 
					 | 
				
			||||||
                    || clicolor_enabled
 | 
					 | 
				
			||||||
                    || anstyle_query::is_ci())
 | 
					 | 
				
			||||||
                || anstyle_query::clicolor_force()
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                ColorChoice::Always
 | 
					 | 
				
			||||||
            } else {
 | 
					 | 
				
			||||||
                ColorChoice::Never
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        ColorChoice::AlwaysAnsi | ColorChoice::Always | ColorChoice::Never => choice,
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl AutoStream<std::io::Stdout> {
 | 
					 | 
				
			||||||
    /// Get exclusive access to the `AutoStream`
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// Why?
 | 
					 | 
				
			||||||
    /// - Faster performance when writing in a loop
 | 
					 | 
				
			||||||
    /// - Avoid other threads interleaving output with the current thread
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub fn lock(self) -> AutoStream<std::io::StdoutLock<'static>> {
 | 
					 | 
				
			||||||
        let inner = match self.inner {
 | 
					 | 
				
			||||||
            StreamInner::PassThrough(w) => StreamInner::PassThrough(w.lock()),
 | 
					 | 
				
			||||||
            StreamInner::Strip(w) => StreamInner::Strip(w.lock()),
 | 
					 | 
				
			||||||
            #[cfg(all(windows, feature = "wincon"))]
 | 
					 | 
				
			||||||
            StreamInner::Wincon(w) => StreamInner::Wincon(w.lock()),
 | 
					 | 
				
			||||||
        };
 | 
					 | 
				
			||||||
        AutoStream { inner }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl AutoStream<std::io::Stderr> {
 | 
					 | 
				
			||||||
    /// Get exclusive access to the `AutoStream`
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// Why?
 | 
					 | 
				
			||||||
    /// - Faster performance when writing in a loop
 | 
					 | 
				
			||||||
    /// - Avoid other threads interleaving output with the current thread
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub fn lock(self) -> AutoStream<std::io::StderrLock<'static>> {
 | 
					 | 
				
			||||||
        let inner = match self.inner {
 | 
					 | 
				
			||||||
            StreamInner::PassThrough(w) => StreamInner::PassThrough(w.lock()),
 | 
					 | 
				
			||||||
            StreamInner::Strip(w) => StreamInner::Strip(w.lock()),
 | 
					 | 
				
			||||||
            #[cfg(all(windows, feature = "wincon"))]
 | 
					 | 
				
			||||||
            StreamInner::Wincon(w) => StreamInner::Wincon(w.lock()),
 | 
					 | 
				
			||||||
        };
 | 
					 | 
				
			||||||
        AutoStream { inner }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl<S> std::io::Write for AutoStream<S>
 | 
					 | 
				
			||||||
where
 | 
					 | 
				
			||||||
    S: RawStream + AsLockedWrite,
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    // Must forward all calls to ensure locking happens appropriately
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
 | 
					 | 
				
			||||||
        match &mut self.inner {
 | 
					 | 
				
			||||||
            StreamInner::PassThrough(w) => w.as_locked_write().write(buf),
 | 
					 | 
				
			||||||
            StreamInner::Strip(w) => w.write(buf),
 | 
					 | 
				
			||||||
            #[cfg(all(windows, feature = "wincon"))]
 | 
					 | 
				
			||||||
            StreamInner::Wincon(w) => w.write(buf),
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn write_vectored(&mut self, bufs: &[std::io::IoSlice<'_>]) -> std::io::Result<usize> {
 | 
					 | 
				
			||||||
        match &mut self.inner {
 | 
					 | 
				
			||||||
            StreamInner::PassThrough(w) => w.as_locked_write().write_vectored(bufs),
 | 
					 | 
				
			||||||
            StreamInner::Strip(w) => w.write_vectored(bufs),
 | 
					 | 
				
			||||||
            #[cfg(all(windows, feature = "wincon"))]
 | 
					 | 
				
			||||||
            StreamInner::Wincon(w) => w.write_vectored(bufs),
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    // is_write_vectored: nightly only
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn flush(&mut self) -> std::io::Result<()> {
 | 
					 | 
				
			||||||
        match &mut self.inner {
 | 
					 | 
				
			||||||
            StreamInner::PassThrough(w) => w.as_locked_write().flush(),
 | 
					 | 
				
			||||||
            StreamInner::Strip(w) => w.flush(),
 | 
					 | 
				
			||||||
            #[cfg(all(windows, feature = "wincon"))]
 | 
					 | 
				
			||||||
            StreamInner::Wincon(w) => w.flush(),
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn write_all(&mut self, buf: &[u8]) -> std::io::Result<()> {
 | 
					 | 
				
			||||||
        match &mut self.inner {
 | 
					 | 
				
			||||||
            StreamInner::PassThrough(w) => w.as_locked_write().write_all(buf),
 | 
					 | 
				
			||||||
            StreamInner::Strip(w) => w.write_all(buf),
 | 
					 | 
				
			||||||
            #[cfg(all(windows, feature = "wincon"))]
 | 
					 | 
				
			||||||
            StreamInner::Wincon(w) => w.write_all(buf),
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    // write_all_vectored: nightly only
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn write_fmt(&mut self, args: std::fmt::Arguments<'_>) -> std::io::Result<()> {
 | 
					 | 
				
			||||||
        match &mut self.inner {
 | 
					 | 
				
			||||||
            StreamInner::PassThrough(w) => w.as_locked_write().write_fmt(args),
 | 
					 | 
				
			||||||
            StreamInner::Strip(w) => w.write_fmt(args),
 | 
					 | 
				
			||||||
            #[cfg(all(windows, feature = "wincon"))]
 | 
					 | 
				
			||||||
            StreamInner::Wincon(w) => w.write_fmt(args),
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										68
									
								
								vendor/anstream/src/buffer.rs
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										68
									
								
								vendor/anstream/src/buffer.rs
									
									
									
									
										vendored
									
									
								
							@@ -1,68 +0,0 @@
 | 
				
			|||||||
#![allow(deprecated)]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// In-memory [`RawStream`][crate::stream::RawStream]
 | 
					 | 
				
			||||||
#[derive(Clone, Default, Debug, PartialEq, Eq)]
 | 
					 | 
				
			||||||
#[deprecated(since = "0.6.2", note = "Use Vec")]
 | 
					 | 
				
			||||||
#[doc(hidden)]
 | 
					 | 
				
			||||||
pub struct Buffer(Vec<u8>);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl Buffer {
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub fn new() -> Self {
 | 
					 | 
				
			||||||
        Default::default()
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub fn with_capacity(capacity: usize) -> Self {
 | 
					 | 
				
			||||||
        Self(Vec::with_capacity(capacity))
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub fn as_bytes(&self) -> &[u8] {
 | 
					 | 
				
			||||||
        &self.0
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl AsRef<[u8]> for Buffer {
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn as_ref(&self) -> &[u8] {
 | 
					 | 
				
			||||||
        self.as_bytes()
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl std::io::Write for Buffer {
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
 | 
					 | 
				
			||||||
        self.0.extend(buf);
 | 
					 | 
				
			||||||
        Ok(buf.len())
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn flush(&mut self) -> std::io::Result<()> {
 | 
					 | 
				
			||||||
        Ok(())
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[cfg(all(windows, feature = "wincon"))]
 | 
					 | 
				
			||||||
impl anstyle_wincon::WinconStream for Buffer {
 | 
					 | 
				
			||||||
    fn write_colored(
 | 
					 | 
				
			||||||
        &mut self,
 | 
					 | 
				
			||||||
        fg: Option<anstyle::AnsiColor>,
 | 
					 | 
				
			||||||
        bg: Option<anstyle::AnsiColor>,
 | 
					 | 
				
			||||||
        data: &[u8],
 | 
					 | 
				
			||||||
    ) -> std::io::Result<usize> {
 | 
					 | 
				
			||||||
        self.0.write_colored(fg, bg, data)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[cfg(all(windows, feature = "wincon"))]
 | 
					 | 
				
			||||||
impl anstyle_wincon::WinconStream for &'_ mut Buffer {
 | 
					 | 
				
			||||||
    fn write_colored(
 | 
					 | 
				
			||||||
        &mut self,
 | 
					 | 
				
			||||||
        fg: Option<anstyle::AnsiColor>,
 | 
					 | 
				
			||||||
        bg: Option<anstyle::AnsiColor>,
 | 
					 | 
				
			||||||
        data: &[u8],
 | 
					 | 
				
			||||||
    ) -> std::io::Result<usize> {
 | 
					 | 
				
			||||||
        (**self).write_colored(fg, bg, data)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										54
									
								
								vendor/anstream/src/fmt.rs
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										54
									
								
								vendor/anstream/src/fmt.rs
									
									
									
									
										vendored
									
									
								
							@@ -1,54 +0,0 @@
 | 
				
			|||||||
/// A shim which allows a [`std::io::Write`] to be implemented in terms of a [`std::fmt::Write`]
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// This saves off I/O errors. instead of discarding them
 | 
					 | 
				
			||||||
pub(crate) struct Adapter<W>
 | 
					 | 
				
			||||||
where
 | 
					 | 
				
			||||||
    W: FnMut(&[u8]) -> std::io::Result<()>,
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    writer: W,
 | 
					 | 
				
			||||||
    error: std::io::Result<()>,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl<W> Adapter<W>
 | 
					 | 
				
			||||||
where
 | 
					 | 
				
			||||||
    W: FnMut(&[u8]) -> std::io::Result<()>,
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    pub(crate) fn new(writer: W) -> Self {
 | 
					 | 
				
			||||||
        Adapter {
 | 
					 | 
				
			||||||
            writer,
 | 
					 | 
				
			||||||
            error: Ok(()),
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    pub(crate) fn write_fmt(mut self, fmt: std::fmt::Arguments<'_>) -> std::io::Result<()> {
 | 
					 | 
				
			||||||
        match std::fmt::write(&mut self, fmt) {
 | 
					 | 
				
			||||||
            Ok(()) => Ok(()),
 | 
					 | 
				
			||||||
            Err(..) => {
 | 
					 | 
				
			||||||
                // check if the error came from the underlying `Write` or not
 | 
					 | 
				
			||||||
                if self.error.is_err() {
 | 
					 | 
				
			||||||
                    self.error
 | 
					 | 
				
			||||||
                } else {
 | 
					 | 
				
			||||||
                    Err(std::io::Error::new(
 | 
					 | 
				
			||||||
                        std::io::ErrorKind::Other,
 | 
					 | 
				
			||||||
                        "formatter error",
 | 
					 | 
				
			||||||
                    ))
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl<W> std::fmt::Write for Adapter<W>
 | 
					 | 
				
			||||||
where
 | 
					 | 
				
			||||||
    W: FnMut(&[u8]) -> std::io::Result<()>,
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    fn write_str(&mut self, s: &str) -> std::fmt::Result {
 | 
					 | 
				
			||||||
        match (self.writer)(s.as_bytes()) {
 | 
					 | 
				
			||||||
            Ok(()) => Ok(()),
 | 
					 | 
				
			||||||
            Err(e) => {
 | 
					 | 
				
			||||||
                self.error = Err(e);
 | 
					 | 
				
			||||||
                Err(std::fmt::Error)
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										79
									
								
								vendor/anstream/src/lib.rs
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										79
									
								
								vendor/anstream/src/lib.rs
									
									
									
									
										vendored
									
									
								
							@@ -1,79 +0,0 @@
 | 
				
			|||||||
//! **Auto-adapting [`stdout`] / [`stderr`] streams**
 | 
					 | 
				
			||||||
//!
 | 
					 | 
				
			||||||
//! *A portmanteau of "ansi stream"*
 | 
					 | 
				
			||||||
//!
 | 
					 | 
				
			||||||
//! [`AutoStream`] always accepts [ANSI escape codes](https://en.wikipedia.org/wiki/ANSI_escape_code),
 | 
					 | 
				
			||||||
//! adapting to the user's terminal's capabilities.
 | 
					 | 
				
			||||||
//!
 | 
					 | 
				
			||||||
//! Benefits
 | 
					 | 
				
			||||||
//! - Allows the caller to not be concerned with the terminal's capabilities
 | 
					 | 
				
			||||||
//! - Semver safe way of passing styled text between crates as ANSI escape codes offer more
 | 
					 | 
				
			||||||
//!   compatibility than most crate APIs.
 | 
					 | 
				
			||||||
//!
 | 
					 | 
				
			||||||
//! Available styling crates:
 | 
					 | 
				
			||||||
//! - [anstyle](https://docs.rs/anstyle) for minimal runtime styling, designed to go in public APIs
 | 
					 | 
				
			||||||
//!   (once it hits 1.0)
 | 
					 | 
				
			||||||
//! - [owo-colors](https://docs.rs/owo-colors) for feature-rich runtime styling
 | 
					 | 
				
			||||||
//! - [color-print](https://docs.rs/color-print) for feature-rich compile-time styling
 | 
					 | 
				
			||||||
//!
 | 
					 | 
				
			||||||
//! # Example
 | 
					 | 
				
			||||||
//!
 | 
					 | 
				
			||||||
//! ```
 | 
					 | 
				
			||||||
//! #  #[cfg(feature = "auto")] {
 | 
					 | 
				
			||||||
//! use anstream::println;
 | 
					 | 
				
			||||||
//! use owo_colors::OwoColorize as _;
 | 
					 | 
				
			||||||
//!
 | 
					 | 
				
			||||||
//! // Foreground colors
 | 
					 | 
				
			||||||
//! println!("My number is {:#x}!", 10.green());
 | 
					 | 
				
			||||||
//! // Background colors
 | 
					 | 
				
			||||||
//! println!("My number is not {}!", 4.on_red());
 | 
					 | 
				
			||||||
//! # }
 | 
					 | 
				
			||||||
//! ```
 | 
					 | 
				
			||||||
//!
 | 
					 | 
				
			||||||
//! And this will correctly handle piping to a file, etc
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pub mod adapter;
 | 
					 | 
				
			||||||
pub mod stream;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
mod buffer;
 | 
					 | 
				
			||||||
#[macro_use]
 | 
					 | 
				
			||||||
mod macros;
 | 
					 | 
				
			||||||
mod auto;
 | 
					 | 
				
			||||||
mod fmt;
 | 
					 | 
				
			||||||
mod strip;
 | 
					 | 
				
			||||||
#[cfg(all(windows, feature = "wincon"))]
 | 
					 | 
				
			||||||
mod wincon;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pub use auto::AutoStream;
 | 
					 | 
				
			||||||
pub use strip::StripStream;
 | 
					 | 
				
			||||||
#[cfg(all(windows, feature = "wincon"))]
 | 
					 | 
				
			||||||
pub use wincon::WinconStream;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[allow(deprecated)]
 | 
					 | 
				
			||||||
pub use buffer::Buffer;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// Create an ANSI escape code compatible stdout
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// **Note:** Call [`AutoStream::lock`] in loops to avoid the performance hit of acquiring/releasing
 | 
					 | 
				
			||||||
/// from the implicit locking in each [`std::io::Write`] call
 | 
					 | 
				
			||||||
#[cfg(feature = "auto")]
 | 
					 | 
				
			||||||
pub fn stdout() -> AutoStream<std::io::Stdout> {
 | 
					 | 
				
			||||||
    let stdout = std::io::stdout();
 | 
					 | 
				
			||||||
    AutoStream::auto(stdout)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// Create an ANSI escape code compatible stderr
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// **Note:** Call [`AutoStream::lock`] in loops to avoid the performance hit of acquiring/releasing
 | 
					 | 
				
			||||||
/// from the implicit locking in each [`std::io::Write`] call
 | 
					 | 
				
			||||||
#[cfg(feature = "auto")]
 | 
					 | 
				
			||||||
pub fn stderr() -> AutoStream<std::io::Stderr> {
 | 
					 | 
				
			||||||
    let stderr = std::io::stderr();
 | 
					 | 
				
			||||||
    AutoStream::auto(stderr)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// Selection for overriding color output
 | 
					 | 
				
			||||||
#[cfg(feature = "auto")]
 | 
					 | 
				
			||||||
pub use colorchoice::ColorChoice;
 | 
					 | 
				
			||||||
							
								
								
									
										389
									
								
								vendor/anstream/src/macros.rs
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										389
									
								
								vendor/anstream/src/macros.rs
									
									
									
									
										vendored
									
									
								
							@@ -1,389 +0,0 @@
 | 
				
			|||||||
/// Prints to [`stdout`][crate::stdout].
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// Equivalent to the [`println!`] macro except that a newline is not printed at
 | 
					 | 
				
			||||||
/// the end of the message.
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// Note that stdout is frequently line-buffered by default so it may be
 | 
					 | 
				
			||||||
/// necessary to use [`std::io::Write::flush()`] to ensure the output is emitted
 | 
					 | 
				
			||||||
/// immediately.
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// **NOTE:** The `print!` macro will lock the standard output on each call. If you call
 | 
					 | 
				
			||||||
/// `print!` within a hot loop, this behavior may be the bottleneck of the loop.
 | 
					 | 
				
			||||||
/// To avoid this, lock stdout with [`AutoStream::lock`][crate::AutoStream::lock]:
 | 
					 | 
				
			||||||
/// ```
 | 
					 | 
				
			||||||
/// #  #[cfg(feature = "auto")] {
 | 
					 | 
				
			||||||
/// use std::io::Write as _;
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// let mut lock = anstream::stdout().lock();
 | 
					 | 
				
			||||||
/// write!(lock, "hello world").unwrap();
 | 
					 | 
				
			||||||
/// # }
 | 
					 | 
				
			||||||
/// ```
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// Use `print!` only for the primary output of your program. Use
 | 
					 | 
				
			||||||
/// [`eprint!`] instead to print error and progress messages.
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// **NOTE:** Not all `print!` calls will be captured in tests like [`std::print!`]
 | 
					 | 
				
			||||||
/// - Capturing will automatically be activated in test binaries
 | 
					 | 
				
			||||||
/// - Otherwise, only when the `test` feature is enabled
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// # Panics
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// Panics if writing to `stdout` fails for any reason **except** broken pipe.
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// Writing to non-blocking stdout can cause an error, which will lead
 | 
					 | 
				
			||||||
/// this macro to panic.
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// # Examples
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// ```
 | 
					 | 
				
			||||||
/// #  #[cfg(feature = "auto")] {
 | 
					 | 
				
			||||||
/// use std::io::Write as _;
 | 
					 | 
				
			||||||
/// use anstream::print;
 | 
					 | 
				
			||||||
/// use anstream::stdout;
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// print!("this ");
 | 
					 | 
				
			||||||
/// print!("will ");
 | 
					 | 
				
			||||||
/// print!("be ");
 | 
					 | 
				
			||||||
/// print!("on ");
 | 
					 | 
				
			||||||
/// print!("the ");
 | 
					 | 
				
			||||||
/// print!("same ");
 | 
					 | 
				
			||||||
/// print!("line ");
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// stdout().flush().unwrap();
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// print!("this string has a newline, why not choose println! instead?\n");
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// stdout().flush().unwrap();
 | 
					 | 
				
			||||||
/// # }
 | 
					 | 
				
			||||||
/// ```
 | 
					 | 
				
			||||||
#[cfg(feature = "auto")]
 | 
					 | 
				
			||||||
#[macro_export]
 | 
					 | 
				
			||||||
macro_rules! print {
 | 
					 | 
				
			||||||
    ($($arg:tt)*) => {{
 | 
					 | 
				
			||||||
        if cfg!(any(feature = "test", test)) {
 | 
					 | 
				
			||||||
            use std::io::Write as _;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            let stdio = std::io::stdout();
 | 
					 | 
				
			||||||
            let choice = $crate::AutoStream::choice(&stdio);
 | 
					 | 
				
			||||||
            let buffer = Vec::new();
 | 
					 | 
				
			||||||
            let mut stream = $crate::AutoStream::new(buffer, choice);
 | 
					 | 
				
			||||||
            // Ignore errors rather than panic
 | 
					 | 
				
			||||||
            let _ = ::std::write!(&mut stream, $($arg)*);
 | 
					 | 
				
			||||||
            let buffer = stream.into_inner();
 | 
					 | 
				
			||||||
            // Should be UTF-8 but not wanting to panic
 | 
					 | 
				
			||||||
            let buffer = String::from_utf8_lossy(&buffer);
 | 
					 | 
				
			||||||
            ::std::print!("{}", buffer)
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            use std::io::Write as _;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            let mut stream = $crate::stdout();
 | 
					 | 
				
			||||||
            match ::std::write!(&mut stream, $($arg)*) {
 | 
					 | 
				
			||||||
                Err(e) if e.kind() != ::std::io::ErrorKind::BrokenPipe => {
 | 
					 | 
				
			||||||
                    ::std::panic!("failed printing to stdout: {e}");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                Err(_) | Ok(_) => {}
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }};
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// Prints to [`stdout`][crate::stdout], with a newline.
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// On all platforms, the newline is the LINE FEED character (`\n`/`U+000A`) alone
 | 
					 | 
				
			||||||
/// (no additional CARRIAGE RETURN (`\r`/`U+000D`)).
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// This macro uses the same syntax as [`format!`], but writes to the standard output instead.
 | 
					 | 
				
			||||||
/// See [`std::fmt`] for more information.
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// **NOTE:** The `println!` macro will lock the standard output on each call. If you call
 | 
					 | 
				
			||||||
/// `println!` within a hot loop, this behavior may be the bottleneck of the loop.
 | 
					 | 
				
			||||||
/// To avoid this, lock stdout with [`AutoStream::lock`][crate::AutoStream::lock]:
 | 
					 | 
				
			||||||
/// ```
 | 
					 | 
				
			||||||
/// #  #[cfg(feature = "auto")] {
 | 
					 | 
				
			||||||
/// use std::io::Write as _;
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// let mut lock = anstream::stdout().lock();
 | 
					 | 
				
			||||||
/// writeln!(lock, "hello world").unwrap();
 | 
					 | 
				
			||||||
/// # }
 | 
					 | 
				
			||||||
/// ```
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// Use `println!` only for the primary output of your program. Use
 | 
					 | 
				
			||||||
/// [`eprintln!`] instead to print error and progress messages.
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// **NOTE:** Not all `println!` calls will be captured in tests like [`std::println!`]
 | 
					 | 
				
			||||||
/// - Capturing will automatically be activated in test binaries
 | 
					 | 
				
			||||||
/// - Otherwise, only when the `test` feature is enabled
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// # Panics
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// Panics if writing to `stdout` fails for any reason **except** broken pipe.
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// Writing to non-blocking stdout can cause an error, which will lead
 | 
					 | 
				
			||||||
/// this macro to panic.
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// # Examples
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// ```
 | 
					 | 
				
			||||||
/// #  #[cfg(feature = "auto")] {
 | 
					 | 
				
			||||||
/// use anstream::println;
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// println!(); // prints just a newline
 | 
					 | 
				
			||||||
/// println!("hello there!");
 | 
					 | 
				
			||||||
/// println!("format {} arguments", "some");
 | 
					 | 
				
			||||||
/// let local_variable = "some";
 | 
					 | 
				
			||||||
/// println!("format {local_variable} arguments");
 | 
					 | 
				
			||||||
/// # }
 | 
					 | 
				
			||||||
/// ```
 | 
					 | 
				
			||||||
#[cfg(feature = "auto")]
 | 
					 | 
				
			||||||
#[macro_export]
 | 
					 | 
				
			||||||
macro_rules! println {
 | 
					 | 
				
			||||||
    () => {
 | 
					 | 
				
			||||||
        $crate::print!("\n")
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
    ($($arg:tt)*) => {{
 | 
					 | 
				
			||||||
        if cfg!(any(feature = "test", test)) {
 | 
					 | 
				
			||||||
            use std::io::Write as _;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            let stdio = std::io::stdout();
 | 
					 | 
				
			||||||
            let choice = $crate::AutoStream::choice(&stdio);
 | 
					 | 
				
			||||||
            let buffer = Vec::new();
 | 
					 | 
				
			||||||
            let mut stream = $crate::AutoStream::new(buffer, choice);
 | 
					 | 
				
			||||||
            // Ignore errors rather than panic
 | 
					 | 
				
			||||||
            let _ = ::std::write!(&mut stream, $($arg)*);
 | 
					 | 
				
			||||||
            let buffer = stream.into_inner();
 | 
					 | 
				
			||||||
            // Should be UTF-8 but not wanting to panic
 | 
					 | 
				
			||||||
            let buffer = String::from_utf8_lossy(&buffer);
 | 
					 | 
				
			||||||
            ::std::println!("{}", buffer)
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            use std::io::Write as _;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            let mut stream = $crate::stdout();
 | 
					 | 
				
			||||||
            match ::std::writeln!(&mut stream, $($arg)*) {
 | 
					 | 
				
			||||||
                Err(e) if e.kind() != ::std::io::ErrorKind::BrokenPipe => {
 | 
					 | 
				
			||||||
                    ::std::panic!("failed printing to stdout: {e}");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                Err(_) | Ok(_) => {}
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }};
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// Prints to [`stderr`][crate::stderr].
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// Equivalent to the [`print!`] macro, except that output goes to
 | 
					 | 
				
			||||||
/// `stderr` instead of `stdout`. See [`print!`] for
 | 
					 | 
				
			||||||
/// example usage.
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// Use `eprint!` only for error and progress messages. Use `print!`
 | 
					 | 
				
			||||||
/// instead for the primary output of your program.
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// **NOTE:** Not all `eprint!` calls will be captured in tests like [`std::eprint!`]
 | 
					 | 
				
			||||||
/// - Capturing will automatically be activated in test binaries
 | 
					 | 
				
			||||||
/// - Otherwise, only when the `test` feature is enabled
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// # Panics
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// Panics if writing to `stderr` fails for any reason **except** broken pipe.
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// Writing to non-blocking stdout can cause an error, which will lead
 | 
					 | 
				
			||||||
/// this macro to panic.
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// # Examples
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// ```
 | 
					 | 
				
			||||||
/// #  #[cfg(feature = "auto")] {
 | 
					 | 
				
			||||||
/// use anstream::eprint;
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// eprint!("Error: Could not complete task");
 | 
					 | 
				
			||||||
/// # }
 | 
					 | 
				
			||||||
/// ```
 | 
					 | 
				
			||||||
#[cfg(feature = "auto")]
 | 
					 | 
				
			||||||
#[macro_export]
 | 
					 | 
				
			||||||
macro_rules! eprint {
 | 
					 | 
				
			||||||
    ($($arg:tt)*) => {{
 | 
					 | 
				
			||||||
        if cfg!(any(feature = "test", test)) {
 | 
					 | 
				
			||||||
            use std::io::Write as _;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            let stdio = std::io::stderr();
 | 
					 | 
				
			||||||
            let choice = $crate::AutoStream::choice(&stdio);
 | 
					 | 
				
			||||||
            let buffer = Vec::new();
 | 
					 | 
				
			||||||
            let mut stream = $crate::AutoStream::new(buffer, choice);
 | 
					 | 
				
			||||||
            // Ignore errors rather than panic
 | 
					 | 
				
			||||||
            let _ = ::std::write!(&mut stream, $($arg)*);
 | 
					 | 
				
			||||||
            let buffer = stream.into_inner();
 | 
					 | 
				
			||||||
            // Should be UTF-8 but not wanting to panic
 | 
					 | 
				
			||||||
            let buffer = String::from_utf8_lossy(&buffer);
 | 
					 | 
				
			||||||
            ::std::eprint!("{}", buffer)
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            use std::io::Write as _;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            let mut stream = $crate::stderr();
 | 
					 | 
				
			||||||
            match ::std::write!(&mut stream, $($arg)*) {
 | 
					 | 
				
			||||||
                Err(e) if e.kind() != ::std::io::ErrorKind::BrokenPipe => {
 | 
					 | 
				
			||||||
                    ::std::panic!("failed printing to stdout: {e}");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                Err(_) | Ok(_) => {}
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }};
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// Prints to [`stderr`][crate::stderr], with a newline.
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// Equivalent to the [`println!`] macro, except that output goes to
 | 
					 | 
				
			||||||
/// `stderr` instead of `stdout`. See [`println!`] for
 | 
					 | 
				
			||||||
/// example usage.
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// Use `eprintln!` only for error and progress messages. Use `println!`
 | 
					 | 
				
			||||||
/// instead for the primary output of your program.
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// **NOTE:** Not all `eprintln!` calls will be captured in tests like [`std::eprintln!`]
 | 
					 | 
				
			||||||
/// - Capturing will automatically be activated in test binaries
 | 
					 | 
				
			||||||
/// - Otherwise, only when the `test` feature is enabled
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// # Panics
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// Panics if writing to `stderr` fails for any reason **except** broken pipe.
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// Writing to non-blocking stdout can cause an error, which will lead
 | 
					 | 
				
			||||||
/// this macro to panic.
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// # Examples
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// ```
 | 
					 | 
				
			||||||
/// #  #[cfg(feature = "auto")] {
 | 
					 | 
				
			||||||
/// use anstream::eprintln;
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// eprintln!("Error: Could not complete task");
 | 
					 | 
				
			||||||
/// # }
 | 
					 | 
				
			||||||
/// ```
 | 
					 | 
				
			||||||
#[cfg(feature = "auto")]
 | 
					 | 
				
			||||||
#[macro_export]
 | 
					 | 
				
			||||||
macro_rules! eprintln {
 | 
					 | 
				
			||||||
    () => {
 | 
					 | 
				
			||||||
        $crate::eprint!("\n")
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
    ($($arg:tt)*) => {{
 | 
					 | 
				
			||||||
        if cfg!(any(feature = "test", test)) {
 | 
					 | 
				
			||||||
            use std::io::Write as _;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            let stdio = std::io::stderr();
 | 
					 | 
				
			||||||
            let choice = $crate::AutoStream::choice(&stdio);
 | 
					 | 
				
			||||||
            let buffer = Vec::new();
 | 
					 | 
				
			||||||
            let mut stream = $crate::AutoStream::new(buffer, choice);
 | 
					 | 
				
			||||||
            // Ignore errors rather than panic
 | 
					 | 
				
			||||||
            let _ = ::std::write!(&mut stream, $($arg)*);
 | 
					 | 
				
			||||||
            let buffer = stream.into_inner();
 | 
					 | 
				
			||||||
            // Should be UTF-8 but not wanting to panic
 | 
					 | 
				
			||||||
            let buffer = String::from_utf8_lossy(&buffer);
 | 
					 | 
				
			||||||
            ::std::eprintln!("{}", buffer)
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            use std::io::Write as _;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            let mut stream = $crate::stderr();
 | 
					 | 
				
			||||||
            match ::std::writeln!(&mut stream, $($arg)*) {
 | 
					 | 
				
			||||||
                Err(e) if e.kind() != ::std::io::ErrorKind::BrokenPipe => {
 | 
					 | 
				
			||||||
                    ::std::panic!("failed printing to stdout: {e}");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                Err(_) | Ok(_) => {}
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }};
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// Panics the current thread.
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// This allows a program to terminate immediately and provide feedback
 | 
					 | 
				
			||||||
/// to the caller of the program.
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// This macro is the perfect way to assert conditions in example code and in
 | 
					 | 
				
			||||||
/// tests. `panic!` is closely tied with the `unwrap` method of both
 | 
					 | 
				
			||||||
/// [`Option`][ounwrap] and [`Result`][runwrap] enums. Both implementations call
 | 
					 | 
				
			||||||
/// `panic!` when they are set to [`None`] or [`Err`] variants.
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// When using `panic!()` you can specify a string payload, that is built using
 | 
					 | 
				
			||||||
/// the [`format!`] syntax. That payload is used when injecting the panic into
 | 
					 | 
				
			||||||
/// the calling Rust thread, causing the thread to panic entirely.
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// The behavior of the default `std` hook, i.e. the code that runs directly
 | 
					 | 
				
			||||||
/// after the panic is invoked, is to print the message payload to
 | 
					 | 
				
			||||||
/// `stderr` along with the file/line/column information of the `panic!()`
 | 
					 | 
				
			||||||
/// call. You can override the panic hook using [`std::panic::set_hook()`].
 | 
					 | 
				
			||||||
/// Inside the hook a panic can be accessed as a `&dyn Any + Send`,
 | 
					 | 
				
			||||||
/// which contains either a `&str` or `String` for regular `panic!()` invocations.
 | 
					 | 
				
			||||||
/// To panic with a value of another other type, [`panic_any`] can be used.
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// See also the macro [`compile_error!`], for raising errors during compilation.
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// # When to use `panic!` vs `Result`
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// The Rust language provides two complementary systems for constructing /
 | 
					 | 
				
			||||||
/// representing, reporting, propagating, reacting to, and discarding errors. These
 | 
					 | 
				
			||||||
/// responsibilities are collectively known as "error handling." `panic!` and
 | 
					 | 
				
			||||||
/// `Result` are similar in that they are each the primary interface of their
 | 
					 | 
				
			||||||
/// respective error handling systems; however, the meaning these interfaces attach
 | 
					 | 
				
			||||||
/// to their errors and the responsibilities they fulfill within their respective
 | 
					 | 
				
			||||||
/// error handling systems differ.
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// The `panic!` macro is used to construct errors that represent a bug that has
 | 
					 | 
				
			||||||
/// been detected in your program. With `panic!` you provide a message that
 | 
					 | 
				
			||||||
/// describes the bug and the language then constructs an error with that message,
 | 
					 | 
				
			||||||
/// reports it, and propagates it for you.
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// `Result` on the other hand is used to wrap other types that represent either
 | 
					 | 
				
			||||||
/// the successful result of some computation, `Ok(T)`, or error types that
 | 
					 | 
				
			||||||
/// represent an anticipated runtime failure mode of that computation, `Err(E)`.
 | 
					 | 
				
			||||||
/// `Result` is used alongside user defined types which represent the various
 | 
					 | 
				
			||||||
/// anticipated runtime failure modes that the associated computation could
 | 
					 | 
				
			||||||
/// encounter. `Result` must be propagated manually, often with the the help of the
 | 
					 | 
				
			||||||
/// `?` operator and `Try` trait, and they must be reported manually, often with
 | 
					 | 
				
			||||||
/// the help of the `Error` trait.
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// For more detailed information about error handling check out the [book] or the
 | 
					 | 
				
			||||||
/// [`std::result`] module docs.
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// [ounwrap]: Option::unwrap
 | 
					 | 
				
			||||||
/// [runwrap]: Result::unwrap
 | 
					 | 
				
			||||||
/// [`std::panic::set_hook()`]: ../std/panic/fn.set_hook.html
 | 
					 | 
				
			||||||
/// [`panic_any`]: ../std/panic/fn.panic_any.html
 | 
					 | 
				
			||||||
/// [`Box`]: ../std/boxed/struct.Box.html
 | 
					 | 
				
			||||||
/// [`Any`]: crate::any::Any
 | 
					 | 
				
			||||||
/// [`format!`]: ../std/macro.format.html
 | 
					 | 
				
			||||||
/// [book]: ../book/ch09-00-error-handling.html
 | 
					 | 
				
			||||||
/// [`std::result`]: ../std/result/index.html
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// # Current implementation
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// If the main thread panics it will terminate all your threads and end your
 | 
					 | 
				
			||||||
/// program with code `101`.
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// # Examples
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// ```should_panic
 | 
					 | 
				
			||||||
/// # #![allow(unreachable_code)]
 | 
					 | 
				
			||||||
/// use anstream::panic;
 | 
					 | 
				
			||||||
/// panic!();
 | 
					 | 
				
			||||||
/// panic!("this is a terrible mistake!");
 | 
					 | 
				
			||||||
/// panic!("this is a {} {message}", "fancy", message = "message");
 | 
					 | 
				
			||||||
/// ```
 | 
					 | 
				
			||||||
#[cfg(feature = "auto")]
 | 
					 | 
				
			||||||
#[macro_export]
 | 
					 | 
				
			||||||
macro_rules! panic {
 | 
					 | 
				
			||||||
    () => {
 | 
					 | 
				
			||||||
        ::std::panic!()
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
    ($($arg:tt)*) => {{
 | 
					 | 
				
			||||||
        use std::io::Write as _;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        let panic_stream = std::io::stderr();
 | 
					 | 
				
			||||||
        let choice = $crate::AutoStream::choice(&panic_stream);
 | 
					 | 
				
			||||||
        let buffer = Vec::new();
 | 
					 | 
				
			||||||
        let mut stream = $crate::AutoStream::new(buffer, choice);
 | 
					 | 
				
			||||||
        // Ignore errors rather than panic
 | 
					 | 
				
			||||||
        let _ = ::std::write!(&mut stream, $($arg)*);
 | 
					 | 
				
			||||||
        let buffer = stream.into_inner();
 | 
					 | 
				
			||||||
        // Should be UTF-8 but not wanting to panic
 | 
					 | 
				
			||||||
        let buffer = String::from_utf8_lossy(&buffer).into_owned();
 | 
					 | 
				
			||||||
        ::std::panic!("{}", buffer)
 | 
					 | 
				
			||||||
    }};
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										261
									
								
								vendor/anstream/src/stream.rs
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										261
									
								
								vendor/anstream/src/stream.rs
									
									
									
									
										vendored
									
									
								
							@@ -1,261 +0,0 @@
 | 
				
			|||||||
//! Higher-level traits to describe writeable streams
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// Required functionality for underlying [`std::io::Write`] for adaptation
 | 
					 | 
				
			||||||
#[cfg(not(all(windows, feature = "wincon")))]
 | 
					 | 
				
			||||||
pub trait RawStream: std::io::Write + IsTerminal + private::Sealed {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// Required functionality for underlying [`std::io::Write`] for adaptation
 | 
					 | 
				
			||||||
#[cfg(all(windows, feature = "wincon"))]
 | 
					 | 
				
			||||||
pub trait RawStream:
 | 
					 | 
				
			||||||
    std::io::Write + IsTerminal + anstyle_wincon::WinconStream + private::Sealed
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl RawStream for std::io::Stdout {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl RawStream for std::io::StdoutLock<'_> {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl RawStream for &'_ mut std::io::StdoutLock<'_> {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl RawStream for std::io::Stderr {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl RawStream for std::io::StderrLock<'_> {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl RawStream for &'_ mut std::io::StderrLock<'_> {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl RawStream for Box<dyn std::io::Write> {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl RawStream for &'_ mut Box<dyn std::io::Write> {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl RawStream for Vec<u8> {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl RawStream for &'_ mut Vec<u8> {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl RawStream for std::fs::File {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl RawStream for &'_ mut std::fs::File {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[allow(deprecated)]
 | 
					 | 
				
			||||||
impl RawStream for crate::Buffer {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[allow(deprecated)]
 | 
					 | 
				
			||||||
impl RawStream for &'_ mut crate::Buffer {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pub trait IsTerminal: private::Sealed {
 | 
					 | 
				
			||||||
    fn is_terminal(&self) -> bool;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl IsTerminal for std::io::Stdout {
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn is_terminal(&self) -> bool {
 | 
					 | 
				
			||||||
        std::io::IsTerminal::is_terminal(self)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl IsTerminal for std::io::StdoutLock<'_> {
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn is_terminal(&self) -> bool {
 | 
					 | 
				
			||||||
        std::io::IsTerminal::is_terminal(self)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl IsTerminal for &'_ mut std::io::StdoutLock<'_> {
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn is_terminal(&self) -> bool {
 | 
					 | 
				
			||||||
        (**self).is_terminal()
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl IsTerminal for std::io::Stderr {
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn is_terminal(&self) -> bool {
 | 
					 | 
				
			||||||
        std::io::IsTerminal::is_terminal(self)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl IsTerminal for std::io::StderrLock<'_> {
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn is_terminal(&self) -> bool {
 | 
					 | 
				
			||||||
        std::io::IsTerminal::is_terminal(self)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl IsTerminal for &'_ mut std::io::StderrLock<'_> {
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn is_terminal(&self) -> bool {
 | 
					 | 
				
			||||||
        (**self).is_terminal()
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl IsTerminal for Box<dyn std::io::Write> {
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn is_terminal(&self) -> bool {
 | 
					 | 
				
			||||||
        false
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl IsTerminal for &'_ mut Box<dyn std::io::Write> {
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn is_terminal(&self) -> bool {
 | 
					 | 
				
			||||||
        false
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl IsTerminal for Vec<u8> {
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn is_terminal(&self) -> bool {
 | 
					 | 
				
			||||||
        false
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl IsTerminal for &'_ mut Vec<u8> {
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn is_terminal(&self) -> bool {
 | 
					 | 
				
			||||||
        false
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl IsTerminal for std::fs::File {
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn is_terminal(&self) -> bool {
 | 
					 | 
				
			||||||
        std::io::IsTerminal::is_terminal(self)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl IsTerminal for &'_ mut std::fs::File {
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn is_terminal(&self) -> bool {
 | 
					 | 
				
			||||||
        (**self).is_terminal()
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[allow(deprecated)]
 | 
					 | 
				
			||||||
impl IsTerminal for crate::Buffer {
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn is_terminal(&self) -> bool {
 | 
					 | 
				
			||||||
        false
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[allow(deprecated)]
 | 
					 | 
				
			||||||
impl IsTerminal for &'_ mut crate::Buffer {
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn is_terminal(&self) -> bool {
 | 
					 | 
				
			||||||
        (**self).is_terminal()
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pub trait AsLockedWrite: private::Sealed {
 | 
					 | 
				
			||||||
    type Write<'w>: RawStream + 'w
 | 
					 | 
				
			||||||
    where
 | 
					 | 
				
			||||||
        Self: 'w;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    fn as_locked_write(&mut self) -> Self::Write<'_>;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl AsLockedWrite for std::io::Stdout {
 | 
					 | 
				
			||||||
    type Write<'w> = std::io::StdoutLock<'w>;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn as_locked_write(&mut self) -> Self::Write<'_> {
 | 
					 | 
				
			||||||
        self.lock()
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl AsLockedWrite for std::io::StdoutLock<'static> {
 | 
					 | 
				
			||||||
    type Write<'w> = &'w mut Self;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn as_locked_write(&mut self) -> Self::Write<'_> {
 | 
					 | 
				
			||||||
        self
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl AsLockedWrite for std::io::Stderr {
 | 
					 | 
				
			||||||
    type Write<'w> = std::io::StderrLock<'w>;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn as_locked_write(&mut self) -> Self::Write<'_> {
 | 
					 | 
				
			||||||
        self.lock()
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl AsLockedWrite for std::io::StderrLock<'static> {
 | 
					 | 
				
			||||||
    type Write<'w> = &'w mut Self;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn as_locked_write(&mut self) -> Self::Write<'_> {
 | 
					 | 
				
			||||||
        self
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl AsLockedWrite for Box<dyn std::io::Write> {
 | 
					 | 
				
			||||||
    type Write<'w> = &'w mut Self;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn as_locked_write(&mut self) -> Self::Write<'_> {
 | 
					 | 
				
			||||||
        self
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl AsLockedWrite for Vec<u8> {
 | 
					 | 
				
			||||||
    type Write<'w> = &'w mut Self;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn as_locked_write(&mut self) -> Self::Write<'_> {
 | 
					 | 
				
			||||||
        self
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl AsLockedWrite for std::fs::File {
 | 
					 | 
				
			||||||
    type Write<'w> = &'w mut Self;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn as_locked_write(&mut self) -> Self::Write<'_> {
 | 
					 | 
				
			||||||
        self
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[allow(deprecated)]
 | 
					 | 
				
			||||||
impl AsLockedWrite for crate::Buffer {
 | 
					 | 
				
			||||||
    type Write<'w> = &'w mut Self;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn as_locked_write(&mut self) -> Self::Write<'_> {
 | 
					 | 
				
			||||||
        self
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
mod private {
 | 
					 | 
				
			||||||
    pub trait Sealed {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    impl Sealed for std::io::Stdout {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    impl Sealed for std::io::StdoutLock<'_> {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    impl Sealed for &'_ mut std::io::StdoutLock<'_> {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    impl Sealed for std::io::Stderr {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    impl Sealed for std::io::StderrLock<'_> {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    impl Sealed for &'_ mut std::io::StderrLock<'_> {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    impl Sealed for Box<dyn std::io::Write> {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    impl Sealed for &'_ mut Box<dyn std::io::Write> {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    impl Sealed for Vec<u8> {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    impl Sealed for &'_ mut Vec<u8> {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    impl Sealed for std::fs::File {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    impl Sealed for &'_ mut std::fs::File {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[allow(deprecated)]
 | 
					 | 
				
			||||||
    impl Sealed for crate::Buffer {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[allow(deprecated)]
 | 
					 | 
				
			||||||
    impl Sealed for &'_ mut crate::Buffer {}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										219
									
								
								vendor/anstream/src/strip.rs
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										219
									
								
								vendor/anstream/src/strip.rs
									
									
									
									
										vendored
									
									
								
							@@ -1,219 +0,0 @@
 | 
				
			|||||||
use crate::adapter::StripBytes;
 | 
					 | 
				
			||||||
use crate::stream::AsLockedWrite;
 | 
					 | 
				
			||||||
use crate::stream::RawStream;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// Only pass printable data to the inner `Write`
 | 
					 | 
				
			||||||
#[derive(Debug)]
 | 
					 | 
				
			||||||
pub struct StripStream<S>
 | 
					 | 
				
			||||||
where
 | 
					 | 
				
			||||||
    S: RawStream,
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    raw: S,
 | 
					 | 
				
			||||||
    state: StripBytes,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl<S> StripStream<S>
 | 
					 | 
				
			||||||
where
 | 
					 | 
				
			||||||
    S: RawStream,
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    /// Only pass printable data to the inner `Write`
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub fn new(raw: S) -> Self {
 | 
					 | 
				
			||||||
        Self {
 | 
					 | 
				
			||||||
            raw,
 | 
					 | 
				
			||||||
            state: Default::default(),
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Get the wrapped [`RawStream`]
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub fn into_inner(self) -> S {
 | 
					 | 
				
			||||||
        self.raw
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub fn is_terminal(&self) -> bool {
 | 
					 | 
				
			||||||
        self.raw.is_terminal()
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl StripStream<std::io::Stdout> {
 | 
					 | 
				
			||||||
    /// Get exclusive access to the `StripStream`
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// Why?
 | 
					 | 
				
			||||||
    /// - Faster performance when writing in a loop
 | 
					 | 
				
			||||||
    /// - Avoid other threads interleaving output with the current thread
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub fn lock(self) -> StripStream<std::io::StdoutLock<'static>> {
 | 
					 | 
				
			||||||
        StripStream {
 | 
					 | 
				
			||||||
            raw: self.raw.lock(),
 | 
					 | 
				
			||||||
            state: self.state,
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl StripStream<std::io::Stderr> {
 | 
					 | 
				
			||||||
    /// Get exclusive access to the `StripStream`
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// Why?
 | 
					 | 
				
			||||||
    /// - Faster performance when writing in a loop
 | 
					 | 
				
			||||||
    /// - Avoid other threads interleaving output with the current thread
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub fn lock(self) -> StripStream<std::io::StderrLock<'static>> {
 | 
					 | 
				
			||||||
        StripStream {
 | 
					 | 
				
			||||||
            raw: self.raw.lock(),
 | 
					 | 
				
			||||||
            state: self.state,
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl<S> std::io::Write for StripStream<S>
 | 
					 | 
				
			||||||
where
 | 
					 | 
				
			||||||
    S: RawStream + AsLockedWrite,
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    // Must forward all calls to ensure locking happens appropriately
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
 | 
					 | 
				
			||||||
        write(&mut self.raw.as_locked_write(), &mut self.state, buf)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn write_vectored(&mut self, bufs: &[std::io::IoSlice<'_>]) -> std::io::Result<usize> {
 | 
					 | 
				
			||||||
        let buf = bufs
 | 
					 | 
				
			||||||
            .iter()
 | 
					 | 
				
			||||||
            .find(|b| !b.is_empty())
 | 
					 | 
				
			||||||
            .map(|b| &**b)
 | 
					 | 
				
			||||||
            .unwrap_or(&[][..]);
 | 
					 | 
				
			||||||
        self.write(buf)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    // is_write_vectored: nightly only
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn flush(&mut self) -> std::io::Result<()> {
 | 
					 | 
				
			||||||
        self.raw.as_locked_write().flush()
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn write_all(&mut self, buf: &[u8]) -> std::io::Result<()> {
 | 
					 | 
				
			||||||
        write_all(&mut self.raw.as_locked_write(), &mut self.state, buf)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    // write_all_vectored: nightly only
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn write_fmt(&mut self, args: std::fmt::Arguments<'_>) -> std::io::Result<()> {
 | 
					 | 
				
			||||||
        write_fmt(&mut self.raw.as_locked_write(), &mut self.state, args)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
fn write(
 | 
					 | 
				
			||||||
    raw: &mut dyn std::io::Write,
 | 
					 | 
				
			||||||
    state: &mut StripBytes,
 | 
					 | 
				
			||||||
    buf: &[u8],
 | 
					 | 
				
			||||||
) -> std::io::Result<usize> {
 | 
					 | 
				
			||||||
    let initial_state = state.clone();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    for printable in state.strip_next(buf) {
 | 
					 | 
				
			||||||
        let possible = printable.len();
 | 
					 | 
				
			||||||
        let written = raw.write(printable)?;
 | 
					 | 
				
			||||||
        if possible != written {
 | 
					 | 
				
			||||||
            let divergence = &printable[written..];
 | 
					 | 
				
			||||||
            let offset = offset_to(buf, divergence);
 | 
					 | 
				
			||||||
            let consumed = &buf[offset..];
 | 
					 | 
				
			||||||
            *state = initial_state;
 | 
					 | 
				
			||||||
            state.strip_next(consumed).last();
 | 
					 | 
				
			||||||
            return Ok(offset);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    Ok(buf.len())
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
fn write_all(
 | 
					 | 
				
			||||||
    raw: &mut dyn std::io::Write,
 | 
					 | 
				
			||||||
    state: &mut StripBytes,
 | 
					 | 
				
			||||||
    buf: &[u8],
 | 
					 | 
				
			||||||
) -> std::io::Result<()> {
 | 
					 | 
				
			||||||
    for printable in state.strip_next(buf) {
 | 
					 | 
				
			||||||
        raw.write_all(printable)?;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    Ok(())
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
fn write_fmt(
 | 
					 | 
				
			||||||
    raw: &mut dyn std::io::Write,
 | 
					 | 
				
			||||||
    state: &mut StripBytes,
 | 
					 | 
				
			||||||
    args: std::fmt::Arguments<'_>,
 | 
					 | 
				
			||||||
) -> std::io::Result<()> {
 | 
					 | 
				
			||||||
    let write_all = |buf: &[u8]| write_all(raw, state, buf);
 | 
					 | 
				
			||||||
    crate::fmt::Adapter::new(write_all).write_fmt(args)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[inline]
 | 
					 | 
				
			||||||
fn offset_to(total: &[u8], subslice: &[u8]) -> usize {
 | 
					 | 
				
			||||||
    let total = total.as_ptr();
 | 
					 | 
				
			||||||
    let subslice = subslice.as_ptr();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    debug_assert!(
 | 
					 | 
				
			||||||
        total <= subslice,
 | 
					 | 
				
			||||||
        "`Offset::offset_to` only accepts slices of `self`"
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
    subslice as usize - total as usize
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[cfg(test)]
 | 
					 | 
				
			||||||
mod test {
 | 
					 | 
				
			||||||
    use super::*;
 | 
					 | 
				
			||||||
    use proptest::prelude::*;
 | 
					 | 
				
			||||||
    use std::io::Write as _;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    proptest! {
 | 
					 | 
				
			||||||
        #[test]
 | 
					 | 
				
			||||||
        #[cfg_attr(miri, ignore)]  // See https://github.com/AltSysrq/proptest/issues/253
 | 
					 | 
				
			||||||
        fn write_all_no_escapes(s in "\\PC*") {
 | 
					 | 
				
			||||||
            let buffer = Vec::new();
 | 
					 | 
				
			||||||
            let mut stream = StripStream::new(buffer);
 | 
					 | 
				
			||||||
            stream.write_all(s.as_bytes()).unwrap();
 | 
					 | 
				
			||||||
            let buffer = stream.into_inner();
 | 
					 | 
				
			||||||
            let actual = std::str::from_utf8(buffer.as_ref()).unwrap();
 | 
					 | 
				
			||||||
            assert_eq!(s, actual);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        #[test]
 | 
					 | 
				
			||||||
        #[cfg_attr(miri, ignore)]  // See https://github.com/AltSysrq/proptest/issues/253
 | 
					 | 
				
			||||||
        fn write_byte_no_escapes(s in "\\PC*") {
 | 
					 | 
				
			||||||
            let buffer = Vec::new();
 | 
					 | 
				
			||||||
            let mut stream = StripStream::new(buffer);
 | 
					 | 
				
			||||||
            for byte in s.as_bytes() {
 | 
					 | 
				
			||||||
                stream.write_all(&[*byte]).unwrap();
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            let buffer = stream.into_inner();
 | 
					 | 
				
			||||||
            let actual = std::str::from_utf8(buffer.as_ref()).unwrap();
 | 
					 | 
				
			||||||
            assert_eq!(s, actual);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        #[test]
 | 
					 | 
				
			||||||
        #[cfg_attr(miri, ignore)]  // See https://github.com/AltSysrq/proptest/issues/253
 | 
					 | 
				
			||||||
        fn write_all_random(s in any::<Vec<u8>>()) {
 | 
					 | 
				
			||||||
            let buffer = Vec::new();
 | 
					 | 
				
			||||||
            let mut stream = StripStream::new(buffer);
 | 
					 | 
				
			||||||
            stream.write_all(s.as_slice()).unwrap();
 | 
					 | 
				
			||||||
            let buffer = stream.into_inner();
 | 
					 | 
				
			||||||
            if let Ok(actual) = std::str::from_utf8(buffer.as_ref()) {
 | 
					 | 
				
			||||||
                for char in actual.chars() {
 | 
					 | 
				
			||||||
                    assert!(!char.is_ascii() || !char.is_control() || char.is_ascii_whitespace(), "{:?} -> {:?}: {:?}", String::from_utf8_lossy(&s), actual, char);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        #[test]
 | 
					 | 
				
			||||||
        #[cfg_attr(miri, ignore)]  // See https://github.com/AltSysrq/proptest/issues/253
 | 
					 | 
				
			||||||
        fn write_byte_random(s in any::<Vec<u8>>()) {
 | 
					 | 
				
			||||||
            let buffer = Vec::new();
 | 
					 | 
				
			||||||
            let mut stream = StripStream::new(buffer);
 | 
					 | 
				
			||||||
            for byte in s.as_slice() {
 | 
					 | 
				
			||||||
                stream.write_all(&[*byte]).unwrap();
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            let buffer = stream.into_inner();
 | 
					 | 
				
			||||||
            if let Ok(actual) = std::str::from_utf8(buffer.as_ref()) {
 | 
					 | 
				
			||||||
                for char in actual.chars() {
 | 
					 | 
				
			||||||
                    assert!(!char.is_ascii() || !char.is_control() || char.is_ascii_whitespace(), "{:?} -> {:?}: {:?}", String::from_utf8_lossy(&s), actual, char);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										210
									
								
								vendor/anstream/src/wincon.rs
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										210
									
								
								vendor/anstream/src/wincon.rs
									
									
									
									
										vendored
									
									
								
							@@ -1,210 +0,0 @@
 | 
				
			|||||||
use crate::adapter::WinconBytes;
 | 
					 | 
				
			||||||
use crate::stream::AsLockedWrite;
 | 
					 | 
				
			||||||
use crate::stream::RawStream;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// Only pass printable data to the inner `Write`
 | 
					 | 
				
			||||||
#[cfg(feature = "wincon")] // here mostly for documentation purposes
 | 
					 | 
				
			||||||
#[derive(Debug)]
 | 
					 | 
				
			||||||
pub struct WinconStream<S>
 | 
					 | 
				
			||||||
where
 | 
					 | 
				
			||||||
    S: RawStream,
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    raw: S,
 | 
					 | 
				
			||||||
    // `WinconBytes` is especially large compared to other variants of `AutoStream`, so boxing it
 | 
					 | 
				
			||||||
    // here so `AutoStream` doesn't have to discard one allocation and create another one when
 | 
					 | 
				
			||||||
    // calling `AutoStream::lock`
 | 
					 | 
				
			||||||
    state: Box<WinconBytes>,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl<S> WinconStream<S>
 | 
					 | 
				
			||||||
where
 | 
					 | 
				
			||||||
    S: RawStream,
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    /// Only pass printable data to the inner `Write`
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub fn new(raw: S) -> Self {
 | 
					 | 
				
			||||||
        Self {
 | 
					 | 
				
			||||||
            raw,
 | 
					 | 
				
			||||||
            state: Default::default(),
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Get the wrapped [`RawStream`]
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub fn into_inner(self) -> S {
 | 
					 | 
				
			||||||
        self.raw
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub fn is_terminal(&self) -> bool {
 | 
					 | 
				
			||||||
        self.raw.is_terminal()
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl WinconStream<std::io::Stdout> {
 | 
					 | 
				
			||||||
    /// Get exclusive access to the `WinconStream`
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// Why?
 | 
					 | 
				
			||||||
    /// - Faster performance when writing in a loop
 | 
					 | 
				
			||||||
    /// - Avoid other threads interleaving output with the current thread
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub fn lock(self) -> WinconStream<std::io::StdoutLock<'static>> {
 | 
					 | 
				
			||||||
        WinconStream {
 | 
					 | 
				
			||||||
            raw: self.raw.lock(),
 | 
					 | 
				
			||||||
            state: self.state,
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl WinconStream<std::io::Stderr> {
 | 
					 | 
				
			||||||
    /// Get exclusive access to the `WinconStream`
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// Why?
 | 
					 | 
				
			||||||
    /// - Faster performance when writing in a loop
 | 
					 | 
				
			||||||
    /// - Avoid other threads interleaving output with the current thread
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub fn lock(self) -> WinconStream<std::io::StderrLock<'static>> {
 | 
					 | 
				
			||||||
        WinconStream {
 | 
					 | 
				
			||||||
            raw: self.raw.lock(),
 | 
					 | 
				
			||||||
            state: self.state,
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl<S> std::io::Write for WinconStream<S>
 | 
					 | 
				
			||||||
where
 | 
					 | 
				
			||||||
    S: RawStream + AsLockedWrite,
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    // Must forward all calls to ensure locking happens appropriately
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
 | 
					 | 
				
			||||||
        write(&mut self.raw.as_locked_write(), &mut self.state, buf)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn write_vectored(&mut self, bufs: &[std::io::IoSlice<'_>]) -> std::io::Result<usize> {
 | 
					 | 
				
			||||||
        let buf = bufs
 | 
					 | 
				
			||||||
            .iter()
 | 
					 | 
				
			||||||
            .find(|b| !b.is_empty())
 | 
					 | 
				
			||||||
            .map(|b| &**b)
 | 
					 | 
				
			||||||
            .unwrap_or(&[][..]);
 | 
					 | 
				
			||||||
        self.write(buf)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    // is_write_vectored: nightly only
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn flush(&mut self) -> std::io::Result<()> {
 | 
					 | 
				
			||||||
        self.raw.as_locked_write().flush()
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn write_all(&mut self, buf: &[u8]) -> std::io::Result<()> {
 | 
					 | 
				
			||||||
        write_all(&mut self.raw.as_locked_write(), &mut self.state, buf)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    // write_all_vectored: nightly only
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn write_fmt(&mut self, args: std::fmt::Arguments<'_>) -> std::io::Result<()> {
 | 
					 | 
				
			||||||
        write_fmt(&mut self.raw.as_locked_write(), &mut self.state, args)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
fn write(raw: &mut dyn RawStream, state: &mut WinconBytes, buf: &[u8]) -> std::io::Result<usize> {
 | 
					 | 
				
			||||||
    for (style, printable) in state.extract_next(buf) {
 | 
					 | 
				
			||||||
        let fg = style.get_fg_color().and_then(cap_wincon_color);
 | 
					 | 
				
			||||||
        let bg = style.get_bg_color().and_then(cap_wincon_color);
 | 
					 | 
				
			||||||
        let written = raw.write_colored(fg, bg, printable.as_bytes())?;
 | 
					 | 
				
			||||||
        let possible = printable.len();
 | 
					 | 
				
			||||||
        if possible != written {
 | 
					 | 
				
			||||||
            // HACK: Unsupported atm
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    Ok(buf.len())
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
fn write_all(raw: &mut dyn RawStream, state: &mut WinconBytes, buf: &[u8]) -> std::io::Result<()> {
 | 
					 | 
				
			||||||
    for (style, printable) in state.extract_next(buf) {
 | 
					 | 
				
			||||||
        let mut buf = printable.as_bytes();
 | 
					 | 
				
			||||||
        let fg = style.get_fg_color().and_then(cap_wincon_color);
 | 
					 | 
				
			||||||
        let bg = style.get_bg_color().and_then(cap_wincon_color);
 | 
					 | 
				
			||||||
        while !buf.is_empty() {
 | 
					 | 
				
			||||||
            match raw.write_colored(fg, bg, buf) {
 | 
					 | 
				
			||||||
                Ok(0) => {
 | 
					 | 
				
			||||||
                    return Err(std::io::Error::new(
 | 
					 | 
				
			||||||
                        std::io::ErrorKind::WriteZero,
 | 
					 | 
				
			||||||
                        "failed to write whole buffer",
 | 
					 | 
				
			||||||
                    ));
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                Ok(n) => buf = &buf[n..],
 | 
					 | 
				
			||||||
                Err(ref e) if e.kind() == std::io::ErrorKind::Interrupted => {}
 | 
					 | 
				
			||||||
                Err(e) => return Err(e),
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    Ok(())
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
fn write_fmt(
 | 
					 | 
				
			||||||
    raw: &mut dyn RawStream,
 | 
					 | 
				
			||||||
    state: &mut WinconBytes,
 | 
					 | 
				
			||||||
    args: std::fmt::Arguments<'_>,
 | 
					 | 
				
			||||||
) -> std::io::Result<()> {
 | 
					 | 
				
			||||||
    let write_all = |buf: &[u8]| write_all(raw, state, buf);
 | 
					 | 
				
			||||||
    crate::fmt::Adapter::new(write_all).write_fmt(args)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
fn cap_wincon_color(color: anstyle::Color) -> Option<anstyle::AnsiColor> {
 | 
					 | 
				
			||||||
    match color {
 | 
					 | 
				
			||||||
        anstyle::Color::Ansi(c) => Some(c),
 | 
					 | 
				
			||||||
        anstyle::Color::Ansi256(c) => c.into_ansi(),
 | 
					 | 
				
			||||||
        anstyle::Color::Rgb(_) => None,
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[cfg(test)]
 | 
					 | 
				
			||||||
mod test {
 | 
					 | 
				
			||||||
    use super::*;
 | 
					 | 
				
			||||||
    use proptest::prelude::*;
 | 
					 | 
				
			||||||
    use std::io::Write as _;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    proptest! {
 | 
					 | 
				
			||||||
        #[test]
 | 
					 | 
				
			||||||
        #[cfg_attr(miri, ignore)]  // See https://github.com/AltSysrq/proptest/issues/253
 | 
					 | 
				
			||||||
        fn write_all_no_escapes(s in "\\PC*") {
 | 
					 | 
				
			||||||
            let buffer = Vec::new();
 | 
					 | 
				
			||||||
            let mut stream = WinconStream::new(buffer);
 | 
					 | 
				
			||||||
            stream.write_all(s.as_bytes()).unwrap();
 | 
					 | 
				
			||||||
            let buffer = stream.into_inner();
 | 
					 | 
				
			||||||
            let actual = std::str::from_utf8(buffer.as_ref()).unwrap();
 | 
					 | 
				
			||||||
            assert_eq!(s, actual);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        #[test]
 | 
					 | 
				
			||||||
        #[cfg_attr(miri, ignore)]  // See https://github.com/AltSysrq/proptest/issues/253
 | 
					 | 
				
			||||||
        fn write_byte_no_escapes(s in "\\PC*") {
 | 
					 | 
				
			||||||
            let buffer = Vec::new();
 | 
					 | 
				
			||||||
            let mut stream = WinconStream::new(buffer);
 | 
					 | 
				
			||||||
            for byte in s.as_bytes() {
 | 
					 | 
				
			||||||
                stream.write_all(&[*byte]).unwrap();
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            let buffer = stream.into_inner();
 | 
					 | 
				
			||||||
            let actual = std::str::from_utf8(buffer.as_ref()).unwrap();
 | 
					 | 
				
			||||||
            assert_eq!(s, actual);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        #[test]
 | 
					 | 
				
			||||||
        #[cfg_attr(miri, ignore)]  // See https://github.com/AltSysrq/proptest/issues/253
 | 
					 | 
				
			||||||
        fn write_all_random(s in any::<Vec<u8>>()) {
 | 
					 | 
				
			||||||
            let buffer = Vec::new();
 | 
					 | 
				
			||||||
            let mut stream = WinconStream::new(buffer);
 | 
					 | 
				
			||||||
            stream.write_all(s.as_slice()).unwrap();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        #[test]
 | 
					 | 
				
			||||||
        #[cfg_attr(miri, ignore)]  // See https://github.com/AltSysrq/proptest/issues/253
 | 
					 | 
				
			||||||
        fn write_byte_random(s in any::<Vec<u8>>()) {
 | 
					 | 
				
			||||||
            let buffer = Vec::new();
 | 
					 | 
				
			||||||
            let mut stream = WinconStream::new(buffer);
 | 
					 | 
				
			||||||
            for byte in s.as_slice() {
 | 
					 | 
				
			||||||
                stream.write_all(&[*byte]).unwrap();
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										1
									
								
								vendor/anstyle-parse/.cargo-checksum.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								vendor/anstyle-parse/.cargo-checksum.json
									
									
									
									
										vendored
									
									
								
							@@ -1 +0,0 @@
 | 
				
			|||||||
{"files":{"Cargo.lock":"7f68b5328c460caf1d2198b10fe1761e5f0282262f92d04076b30b25539970b0","Cargo.toml":"2834f39b7169c03b03da1e209f56133783ce00ea64d5f2c14381d93984ca20bf","LICENSE-APACHE":"b40930bbcf80744c86c46a12bc9da056641d722716c378f5659b9e555ef833e1","LICENSE-MIT":"c1d4bc00896473e0109ccb4c3c7d21addb55a4ff1a644be204dcfce26612af2a","README.md":"abc82171d436ee0eb221838e8d21a21a2e392504e87f0c130b5eca6a35671e1e","benches/parse.rs":"336c808d51c90db2497fa87e571df7f71c844a1b09be88839fe4255066c632f4","examples/parselog.rs":"58b7db739deed701aa0ab386d0d0c1772511b8aed1c08d31ec5b35a1c8cd4321","src/lib.rs":"c89f2afa0e982276dc47ca8d8a76d47516aa39aa9d3354254c87fdbf2f8ef4cc","src/params.rs":"8cfef4e2ab1961ca2d9f210da553fc6ac64bb6dbd03321f0ee7d6089ab45389c","src/state/codegen.rs":"8530124c8f998f391e47950f130590376321dcade810990f4312c3b1c0a61968","src/state/definitions.rs":"dc3dbb3244def74430a72b0108f019e22cc02e0ae5f563ee14d38300ff82b814","src/state/mod.rs":"be07c2ea393a971dd54117dc2ce8a3ffb5b803cb557ab468389b74570855fa37","src/state/table.rs":"673b7e9242c5248efc076086cc6923578ec2f059c0c26da21363528e20e4285c"},"package":"c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c"}
 | 
					 | 
				
			||||||
							
								
								
									
										1202
									
								
								vendor/anstyle-parse/Cargo.lock
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1202
									
								
								vendor/anstyle-parse/Cargo.lock
									
									
									
										generated
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										108
									
								
								vendor/anstyle-parse/Cargo.toml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										108
									
								
								vendor/anstyle-parse/Cargo.toml
									
									
									
									
										vendored
									
									
								
							@@ -1,108 +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.70.0"
 | 
					 | 
				
			||||||
name = "anstyle-parse"
 | 
					 | 
				
			||||||
version = "0.2.3"
 | 
					 | 
				
			||||||
include = [
 | 
					 | 
				
			||||||
    "build.rs",
 | 
					 | 
				
			||||||
    "src/**/*",
 | 
					 | 
				
			||||||
    "Cargo.toml",
 | 
					 | 
				
			||||||
    "Cargo.lock",
 | 
					 | 
				
			||||||
    "LICENSE*",
 | 
					 | 
				
			||||||
    "README.md",
 | 
					 | 
				
			||||||
    "benches/**/*",
 | 
					 | 
				
			||||||
    "examples/**/*",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
description = "Parse ANSI Style Escapes"
 | 
					 | 
				
			||||||
homepage = "https://github.com/rust-cli/anstyle"
 | 
					 | 
				
			||||||
readme = "README.md"
 | 
					 | 
				
			||||||
keywords = [
 | 
					 | 
				
			||||||
    "ansi",
 | 
					 | 
				
			||||||
    "terminal",
 | 
					 | 
				
			||||||
    "color",
 | 
					 | 
				
			||||||
    "vte",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
categories = ["command-line-interface"]
 | 
					 | 
				
			||||||
license = "MIT OR Apache-2.0"
 | 
					 | 
				
			||||||
repository = "https://github.com/rust-cli/anstyle.git"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package.metadata.release.pre-release-replacements]]
 | 
					 | 
				
			||||||
file = "CHANGELOG.md"
 | 
					 | 
				
			||||||
min = 1
 | 
					 | 
				
			||||||
replace = "{{version}}"
 | 
					 | 
				
			||||||
search = "Unreleased"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package.metadata.release.pre-release-replacements]]
 | 
					 | 
				
			||||||
exactly = 1
 | 
					 | 
				
			||||||
file = "CHANGELOG.md"
 | 
					 | 
				
			||||||
replace = "...{{tag_name}}"
 | 
					 | 
				
			||||||
search = '\.\.\.HEAD'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package.metadata.release.pre-release-replacements]]
 | 
					 | 
				
			||||||
file = "CHANGELOG.md"
 | 
					 | 
				
			||||||
min = 1
 | 
					 | 
				
			||||||
replace = "{{date}}"
 | 
					 | 
				
			||||||
search = "ReleaseDate"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package.metadata.release.pre-release-replacements]]
 | 
					 | 
				
			||||||
exactly = 1
 | 
					 | 
				
			||||||
file = "CHANGELOG.md"
 | 
					 | 
				
			||||||
replace = """
 | 
					 | 
				
			||||||
<!-- next-header -->
 | 
					 | 
				
			||||||
## [Unreleased] - ReleaseDate
 | 
					 | 
				
			||||||
"""
 | 
					 | 
				
			||||||
search = "<!-- next-header -->"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package.metadata.release.pre-release-replacements]]
 | 
					 | 
				
			||||||
exactly = 1
 | 
					 | 
				
			||||||
file = "CHANGELOG.md"
 | 
					 | 
				
			||||||
replace = """
 | 
					 | 
				
			||||||
<!-- next-url -->
 | 
					 | 
				
			||||||
[Unreleased]: https://github.com/rust-cli/anstyle/compare/{{tag_name}}...HEAD"""
 | 
					 | 
				
			||||||
search = "<!-- next-url -->"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[bench]]
 | 
					 | 
				
			||||||
name = "parse"
 | 
					 | 
				
			||||||
harness = false
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[dependencies.arrayvec]
 | 
					 | 
				
			||||||
version = "0.7.2"
 | 
					 | 
				
			||||||
optional = true
 | 
					 | 
				
			||||||
default-features = false
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[dependencies.utf8parse]
 | 
					 | 
				
			||||||
version = "0.2.1"
 | 
					 | 
				
			||||||
optional = true
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[dev-dependencies.codegenrs]
 | 
					 | 
				
			||||||
version = "3.0.1"
 | 
					 | 
				
			||||||
default-features = false
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[dev-dependencies.criterion]
 | 
					 | 
				
			||||||
version = "0.5.1"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[dev-dependencies.proptest]
 | 
					 | 
				
			||||||
version = "1.4.0"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[dev-dependencies.snapbox]
 | 
					 | 
				
			||||||
version = "0.4.14"
 | 
					 | 
				
			||||||
features = ["path"]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[dev-dependencies.vte_generate_state_changes]
 | 
					 | 
				
			||||||
version = "0.1.1"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[features]
 | 
					 | 
				
			||||||
core = ["dep:arrayvec"]
 | 
					 | 
				
			||||||
default = ["utf8"]
 | 
					 | 
				
			||||||
utf8 = ["dep:utf8parse"]
 | 
					 | 
				
			||||||
							
								
								
									
										201
									
								
								vendor/anstyle-parse/LICENSE-APACHE
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										201
									
								
								vendor/anstyle-parse/LICENSE-APACHE
									
									
									
									
										vendored
									
									
								
							@@ -1,201 +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
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   APPENDIX: How to apply the Apache License to your work.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      To apply the Apache License to your work, attach the following
 | 
					 | 
				
			||||||
      boilerplate notice, with the fields enclosed by brackets "{}"
 | 
					 | 
				
			||||||
      replaced with your own identifying information. (Don't include
 | 
					 | 
				
			||||||
      the brackets!)  The text should be enclosed in the appropriate
 | 
					 | 
				
			||||||
      comment syntax for the file format. We also recommend that a
 | 
					 | 
				
			||||||
      file or class name and description of purpose be included on the
 | 
					 | 
				
			||||||
      same "printed page" as the copyright notice for easier
 | 
					 | 
				
			||||||
      identification within third-party archives.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   Copyright {yyyy} {name of copyright owner}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   Licensed under the Apache License, Version 2.0 (the "License");
 | 
					 | 
				
			||||||
   you may not use this file except in compliance with the License.
 | 
					 | 
				
			||||||
   You may obtain a copy of the License at
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
       http://www.apache.org/licenses/LICENSE-2.0
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   Unless required by applicable law or agreed to in writing, software
 | 
					 | 
				
			||||||
   distributed under the License is distributed on an "AS IS" BASIS,
 | 
					 | 
				
			||||||
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
					 | 
				
			||||||
   See the License for the specific language governing permissions and
 | 
					 | 
				
			||||||
   limitations under the License.
 | 
					 | 
				
			||||||
							
								
								
									
										25
									
								
								vendor/anstyle-parse/LICENSE-MIT
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										25
									
								
								vendor/anstyle-parse/LICENSE-MIT
									
									
									
									
										vendored
									
									
								
							@@ -1,25 +0,0 @@
 | 
				
			|||||||
Copyright (c) 2016 Joe Wilm and individual 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.
 | 
					 | 
				
			||||||
							
								
								
									
										33
									
								
								vendor/anstyle-parse/README.md
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										33
									
								
								vendor/anstyle-parse/README.md
									
									
									
									
										vendored
									
									
								
							@@ -1,33 +0,0 @@
 | 
				
			|||||||
# anstyle-parse
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
> Parse [Parse ANSI Style Escapes](https://vt100.net/emu/dec_ansi_parser)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[][Documentation]
 | 
					 | 
				
			||||||

 | 
					 | 
				
			||||||
[](https://crates.io/crates/anstyle-parse)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## License
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Licensed under either of
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
 | 
					 | 
				
			||||||
 * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
at your option.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### Contribution
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Unless you explicitly state otherwise, any contribution intentionally
 | 
					 | 
				
			||||||
submitted for inclusion in the work by you, as defined in the Apache-2.0
 | 
					 | 
				
			||||||
license, shall be dual licensed as above, without any additional terms or
 | 
					 | 
				
			||||||
conditions.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### Special Thanks
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[chrisduerr](https://github.com/alacritty/vte/commits?author=chrisduerr) and the
 | 
					 | 
				
			||||||
[alacritty project](https://github.com/alacritty/alacritty) for
 | 
					 | 
				
			||||||
[vte](https://crates.io/crates/vte) which
 | 
					 | 
				
			||||||
[this was forked from](https://github.com/alacritty/vte/issues/82)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[Crates.io]: https://crates.io/crates/anstyle-parse
 | 
					 | 
				
			||||||
[Documentation]: https://docs.rs/anstyle-parse
 | 
					 | 
				
			||||||
							
								
								
									
										169
									
								
								vendor/anstyle-parse/benches/parse.rs
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										169
									
								
								vendor/anstyle-parse/benches/parse.rs
									
									
									
									
										vendored
									
									
								
							@@ -1,169 +0,0 @@
 | 
				
			|||||||
use criterion::{black_box, Criterion};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use anstyle_parse::*;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct BenchDispatcher;
 | 
					 | 
				
			||||||
impl Perform for BenchDispatcher {
 | 
					 | 
				
			||||||
    fn print(&mut self, c: char) {
 | 
					 | 
				
			||||||
        black_box(c);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    fn execute(&mut self, byte: u8) {
 | 
					 | 
				
			||||||
        black_box(byte);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    fn hook(&mut self, params: &Params, intermediates: &[u8], ignore: bool, c: u8) {
 | 
					 | 
				
			||||||
        black_box((params, intermediates, ignore, c));
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    fn put(&mut self, byte: u8) {
 | 
					 | 
				
			||||||
        black_box(byte);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    fn osc_dispatch(&mut self, params: &[&[u8]], bell_terminated: bool) {
 | 
					 | 
				
			||||||
        black_box((params, bell_terminated));
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    fn csi_dispatch(&mut self, params: &Params, intermediates: &[u8], ignore: bool, c: u8) {
 | 
					 | 
				
			||||||
        black_box((params, intermediates, ignore, c));
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    fn esc_dispatch(&mut self, intermediates: &[u8], ignore: bool, byte: u8) {
 | 
					 | 
				
			||||||
        black_box((intermediates, ignore, byte));
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[derive(Default)]
 | 
					 | 
				
			||||||
struct Strip(String);
 | 
					 | 
				
			||||||
impl Strip {
 | 
					 | 
				
			||||||
    fn with_capacity(capacity: usize) -> Self {
 | 
					 | 
				
			||||||
        Self(String::with_capacity(capacity))
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
impl Perform for Strip {
 | 
					 | 
				
			||||||
    fn print(&mut self, c: char) {
 | 
					 | 
				
			||||||
        self.0.push(c);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    fn execute(&mut self, byte: u8) {
 | 
					 | 
				
			||||||
        if byte.is_ascii_whitespace() {
 | 
					 | 
				
			||||||
            self.0.push(byte as char);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
fn strip_str(content: &str) -> String {
 | 
					 | 
				
			||||||
    use anstyle_parse::state::state_change;
 | 
					 | 
				
			||||||
    use anstyle_parse::state::Action;
 | 
					 | 
				
			||||||
    use anstyle_parse::state::State;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn is_utf8_continuation(b: u8) -> bool {
 | 
					 | 
				
			||||||
        matches!(b, 0x80..=0xbf)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn is_printable(action: Action, byte: u8) -> bool {
 | 
					 | 
				
			||||||
        action == Action::Print
 | 
					 | 
				
			||||||
                    || action == Action::BeginUtf8
 | 
					 | 
				
			||||||
                    // since we know the input is valid UTF-8, the only thing  we can do with
 | 
					 | 
				
			||||||
                    // continuations is to print them
 | 
					 | 
				
			||||||
                    || is_utf8_continuation(byte)
 | 
					 | 
				
			||||||
                    || (action == Action::Execute && byte.is_ascii_whitespace())
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let mut stripped = Vec::with_capacity(content.len());
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let mut bytes = content.as_bytes();
 | 
					 | 
				
			||||||
    while !bytes.is_empty() {
 | 
					 | 
				
			||||||
        let offset = bytes.iter().copied().position(|b| {
 | 
					 | 
				
			||||||
            let (_next_state, action) = state_change(State::Ground, b);
 | 
					 | 
				
			||||||
            !is_printable(action, b)
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
        let (printable, next) = bytes.split_at(offset.unwrap_or(bytes.len()));
 | 
					 | 
				
			||||||
        stripped.extend(printable);
 | 
					 | 
				
			||||||
        bytes = next;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        let mut state = State::Ground;
 | 
					 | 
				
			||||||
        let offset = bytes.iter().copied().position(|b| {
 | 
					 | 
				
			||||||
            let (next_state, action) = state_change(state, b);
 | 
					 | 
				
			||||||
            if next_state != State::Anywhere {
 | 
					 | 
				
			||||||
                state = next_state;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            is_printable(action, b)
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
        let (_, next) = bytes.split_at(offset.unwrap_or(bytes.len()));
 | 
					 | 
				
			||||||
        bytes = next;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    String::from_utf8(stripped).unwrap()
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
fn parse(c: &mut Criterion) {
 | 
					 | 
				
			||||||
    for (name, content) in [
 | 
					 | 
				
			||||||
        #[cfg(feature = "utf8")]
 | 
					 | 
				
			||||||
        ("demo.vte", &include_bytes!("../tests/demo.vte")[..]),
 | 
					 | 
				
			||||||
        ("rg_help.vte", &include_bytes!("../tests/rg_help.vte")[..]),
 | 
					 | 
				
			||||||
        ("rg_linus.vte", &include_bytes!("../tests/rg_linus.vte")[..]),
 | 
					 | 
				
			||||||
        (
 | 
					 | 
				
			||||||
            "state_changes",
 | 
					 | 
				
			||||||
            &b"\x1b]2;X\x1b\\ \x1b[0m \x1bP0@\x1b\\"[..],
 | 
					 | 
				
			||||||
        ),
 | 
					 | 
				
			||||||
    ] {
 | 
					 | 
				
			||||||
        // Make sure the comparison is fair
 | 
					 | 
				
			||||||
        if let Ok(content) = std::str::from_utf8(content) {
 | 
					 | 
				
			||||||
            let mut stripped = Strip::with_capacity(content.len());
 | 
					 | 
				
			||||||
            let mut parser = Parser::<DefaultCharAccumulator>::new();
 | 
					 | 
				
			||||||
            for byte in content.as_bytes() {
 | 
					 | 
				
			||||||
                parser.advance(&mut stripped, *byte);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            assert_eq!(stripped.0, strip_str(content));
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        let mut group = c.benchmark_group(name);
 | 
					 | 
				
			||||||
        group.bench_function("advance", |b| {
 | 
					 | 
				
			||||||
            b.iter(|| {
 | 
					 | 
				
			||||||
                let mut dispatcher = BenchDispatcher;
 | 
					 | 
				
			||||||
                let mut parser = Parser::<DefaultCharAccumulator>::new();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                for byte in content {
 | 
					 | 
				
			||||||
                    parser.advance(&mut dispatcher, *byte);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            })
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
        group.bench_function("advance_strip", |b| {
 | 
					 | 
				
			||||||
            b.iter(|| {
 | 
					 | 
				
			||||||
                let mut stripped = Strip::with_capacity(content.len());
 | 
					 | 
				
			||||||
                let mut parser = Parser::<DefaultCharAccumulator>::new();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                for byte in content {
 | 
					 | 
				
			||||||
                    parser.advance(&mut stripped, *byte);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                black_box(stripped.0)
 | 
					 | 
				
			||||||
            })
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
        group.bench_function("state_change", |b| {
 | 
					 | 
				
			||||||
            b.iter(|| {
 | 
					 | 
				
			||||||
                let mut state = anstyle_parse::state::State::default();
 | 
					 | 
				
			||||||
                for byte in content {
 | 
					 | 
				
			||||||
                    let (next_state, action) = anstyle_parse::state::state_change(state, *byte);
 | 
					 | 
				
			||||||
                    state = next_state;
 | 
					 | 
				
			||||||
                    black_box(action);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            })
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
        if let Ok(content) = std::str::from_utf8(content) {
 | 
					 | 
				
			||||||
            group.bench_function("state_change_strip_str", |b| {
 | 
					 | 
				
			||||||
                b.iter(|| {
 | 
					 | 
				
			||||||
                    let stripped = strip_str(content);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    black_box(stripped)
 | 
					 | 
				
			||||||
                })
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
criterion::criterion_group!(benches, parse);
 | 
					 | 
				
			||||||
criterion::criterion_main!(benches);
 | 
					 | 
				
			||||||
							
								
								
									
										78
									
								
								vendor/anstyle-parse/examples/parselog.rs
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										78
									
								
								vendor/anstyle-parse/examples/parselog.rs
									
									
									
									
										vendored
									
									
								
							@@ -1,78 +0,0 @@
 | 
				
			|||||||
//! Parse input from stdin and log actions on stdout
 | 
					 | 
				
			||||||
use std::io::{self, Read};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use anstyle_parse::{DefaultCharAccumulator, Params, Parser, Perform};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// A type implementing Perform that just logs actions
 | 
					 | 
				
			||||||
struct Log;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl Perform for Log {
 | 
					 | 
				
			||||||
    fn print(&mut self, c: char) {
 | 
					 | 
				
			||||||
        println!("[print] {:?}", c);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    fn execute(&mut self, byte: u8) {
 | 
					 | 
				
			||||||
        println!("[execute] {:02x}", byte);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    fn hook(&mut self, params: &Params, intermediates: &[u8], ignore: bool, c: u8) {
 | 
					 | 
				
			||||||
        println!(
 | 
					 | 
				
			||||||
            "[hook] params={:?}, intermediates={:?}, ignore={:?}, char={:?}",
 | 
					 | 
				
			||||||
            params, intermediates, ignore, c
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    fn put(&mut self, byte: u8) {
 | 
					 | 
				
			||||||
        println!("[put] {:02x}", byte);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    fn unhook(&mut self) {
 | 
					 | 
				
			||||||
        println!("[unhook]");
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    fn osc_dispatch(&mut self, params: &[&[u8]], bell_terminated: bool) {
 | 
					 | 
				
			||||||
        println!(
 | 
					 | 
				
			||||||
            "[osc_dispatch] params={:?} bell_terminated={}",
 | 
					 | 
				
			||||||
            params, bell_terminated
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    fn csi_dispatch(&mut self, params: &Params, intermediates: &[u8], ignore: bool, c: u8) {
 | 
					 | 
				
			||||||
        println!(
 | 
					 | 
				
			||||||
            "[csi_dispatch] params={:#?}, intermediates={:?}, ignore={:?}, char={:?}",
 | 
					 | 
				
			||||||
            params, intermediates, ignore, c
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    fn esc_dispatch(&mut self, intermediates: &[u8], ignore: bool, byte: u8) {
 | 
					 | 
				
			||||||
        println!(
 | 
					 | 
				
			||||||
            "[esc_dispatch] intermediates={:?}, ignore={:?}, byte={:02x}",
 | 
					 | 
				
			||||||
            intermediates, ignore, byte
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
fn main() {
 | 
					 | 
				
			||||||
    let input = io::stdin();
 | 
					 | 
				
			||||||
    let mut handle = input.lock();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let mut statemachine = Parser::<DefaultCharAccumulator>::new();
 | 
					 | 
				
			||||||
    let mut performer = Log;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let mut buf = [0; 2048];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    loop {
 | 
					 | 
				
			||||||
        match handle.read(&mut buf) {
 | 
					 | 
				
			||||||
            Ok(0) => break,
 | 
					 | 
				
			||||||
            Ok(n) => {
 | 
					 | 
				
			||||||
                for byte in &buf[..n] {
 | 
					 | 
				
			||||||
                    statemachine.advance(&mut performer, *byte);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            Err(err) => {
 | 
					 | 
				
			||||||
                println!("err: {}", err);
 | 
					 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										431
									
								
								vendor/anstyle-parse/src/lib.rs
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										431
									
								
								vendor/anstyle-parse/src/lib.rs
									
									
									
									
										vendored
									
									
								
							@@ -1,431 +0,0 @@
 | 
				
			|||||||
//! Parser for implementing virtual terminal emulators
 | 
					 | 
				
			||||||
//!
 | 
					 | 
				
			||||||
//! [`Parser`] is implemented according to [Paul Williams' ANSI parser
 | 
					 | 
				
			||||||
//! state machine]. The state machine doesn't assign meaning to the parsed data
 | 
					 | 
				
			||||||
//! and is thus not itself sufficient for writing a terminal emulator. Instead,
 | 
					 | 
				
			||||||
//! it is expected that an implementation of [`Perform`] is provided which does
 | 
					 | 
				
			||||||
//! something useful with the parsed data. The [`Parser`] handles the book
 | 
					 | 
				
			||||||
//! keeping, and the [`Perform`] gets to simply handle actions.
 | 
					 | 
				
			||||||
//!
 | 
					 | 
				
			||||||
//! # Examples
 | 
					 | 
				
			||||||
//!
 | 
					 | 
				
			||||||
//! For an example of using the [`Parser`] please see the examples folder. The example included
 | 
					 | 
				
			||||||
//! there simply logs all the actions [`Perform`] does. One quick thing to see it in action is to
 | 
					 | 
				
			||||||
//! pipe `vim` into it
 | 
					 | 
				
			||||||
//!
 | 
					 | 
				
			||||||
//! ```sh
 | 
					 | 
				
			||||||
//! cargo build --release --example parselog
 | 
					 | 
				
			||||||
//! vim | target/release/examples/parselog
 | 
					 | 
				
			||||||
//! ```
 | 
					 | 
				
			||||||
//!
 | 
					 | 
				
			||||||
//! Just type `:q` to exit.
 | 
					 | 
				
			||||||
//!
 | 
					 | 
				
			||||||
//! # Differences from original state machine description
 | 
					 | 
				
			||||||
//!
 | 
					 | 
				
			||||||
//! * UTF-8 Support for Input
 | 
					 | 
				
			||||||
//! * OSC Strings can be terminated by 0x07
 | 
					 | 
				
			||||||
//! * Only supports 7-bit codes. Some 8-bit codes are still supported, but they no longer work in
 | 
					 | 
				
			||||||
//!   all states.
 | 
					 | 
				
			||||||
//!
 | 
					 | 
				
			||||||
//! [Paul Williams' ANSI parser state machine]: https://vt100.net/emu/dec_ansi_parser
 | 
					 | 
				
			||||||
#![cfg_attr(not(test), no_std)]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[cfg(not(feature = "core"))]
 | 
					 | 
				
			||||||
extern crate alloc;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use core::mem::MaybeUninit;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[cfg(feature = "core")]
 | 
					 | 
				
			||||||
use arrayvec::ArrayVec;
 | 
					 | 
				
			||||||
#[cfg(feature = "utf8")]
 | 
					 | 
				
			||||||
use utf8parse as utf8;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
mod params;
 | 
					 | 
				
			||||||
pub mod state;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pub use params::{Params, ParamsIter};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use state::{state_change, Action, State};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const MAX_INTERMEDIATES: usize = 2;
 | 
					 | 
				
			||||||
const MAX_OSC_PARAMS: usize = 16;
 | 
					 | 
				
			||||||
#[cfg(feature = "core")]
 | 
					 | 
				
			||||||
const MAX_OSC_RAW: usize = 1024;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// Parser for raw _VTE_ protocol which delegates actions to a [`Perform`]
 | 
					 | 
				
			||||||
#[derive(Default, Clone, Debug, PartialEq, Eq)]
 | 
					 | 
				
			||||||
pub struct Parser<C = DefaultCharAccumulator> {
 | 
					 | 
				
			||||||
    state: State,
 | 
					 | 
				
			||||||
    intermediates: [u8; MAX_INTERMEDIATES],
 | 
					 | 
				
			||||||
    intermediate_idx: usize,
 | 
					 | 
				
			||||||
    params: Params,
 | 
					 | 
				
			||||||
    param: u16,
 | 
					 | 
				
			||||||
    #[cfg(feature = "core")]
 | 
					 | 
				
			||||||
    osc_raw: ArrayVec<u8, MAX_OSC_RAW>,
 | 
					 | 
				
			||||||
    #[cfg(not(feature = "core"))]
 | 
					 | 
				
			||||||
    osc_raw: alloc::vec::Vec<u8>,
 | 
					 | 
				
			||||||
    osc_params: [(usize, usize); MAX_OSC_PARAMS],
 | 
					 | 
				
			||||||
    osc_num_params: usize,
 | 
					 | 
				
			||||||
    ignoring: bool,
 | 
					 | 
				
			||||||
    utf8_parser: C,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl<C> Parser<C>
 | 
					 | 
				
			||||||
where
 | 
					 | 
				
			||||||
    C: CharAccumulator,
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    /// Create a new Parser
 | 
					 | 
				
			||||||
    pub fn new() -> Parser {
 | 
					 | 
				
			||||||
        Parser::default()
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn params(&self) -> &Params {
 | 
					 | 
				
			||||||
        &self.params
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn intermediates(&self) -> &[u8] {
 | 
					 | 
				
			||||||
        &self.intermediates[..self.intermediate_idx]
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Advance the parser state
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// Requires a [`Perform`] in case `byte` triggers an action
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub fn advance<P: Perform>(&mut self, performer: &mut P, byte: u8) {
 | 
					 | 
				
			||||||
        // Utf8 characters are handled out-of-band.
 | 
					 | 
				
			||||||
        if let State::Utf8 = self.state {
 | 
					 | 
				
			||||||
            self.process_utf8(performer, byte);
 | 
					 | 
				
			||||||
            return;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        let (state, action) = state_change(self.state, byte);
 | 
					 | 
				
			||||||
        self.perform_state_change(performer, state, action, byte);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn process_utf8<P>(&mut self, performer: &mut P, byte: u8)
 | 
					 | 
				
			||||||
    where
 | 
					 | 
				
			||||||
        P: Perform,
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        if let Some(c) = self.utf8_parser.add(byte) {
 | 
					 | 
				
			||||||
            performer.print(c);
 | 
					 | 
				
			||||||
            self.state = State::Ground;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn perform_state_change<P>(&mut self, performer: &mut P, state: State, action: Action, byte: u8)
 | 
					 | 
				
			||||||
    where
 | 
					 | 
				
			||||||
        P: Perform,
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        match state {
 | 
					 | 
				
			||||||
            State::Anywhere => {
 | 
					 | 
				
			||||||
                // Just run the action
 | 
					 | 
				
			||||||
                self.perform_action(performer, action, byte);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            state => {
 | 
					 | 
				
			||||||
                match self.state {
 | 
					 | 
				
			||||||
                    State::DcsPassthrough => {
 | 
					 | 
				
			||||||
                        self.perform_action(performer, Action::Unhook, byte);
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    State::OscString => {
 | 
					 | 
				
			||||||
                        self.perform_action(performer, Action::OscEnd, byte);
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    _ => (),
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                match action {
 | 
					 | 
				
			||||||
                    Action::Nop => (),
 | 
					 | 
				
			||||||
                    action => {
 | 
					 | 
				
			||||||
                        self.perform_action(performer, action, byte);
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                match state {
 | 
					 | 
				
			||||||
                    State::CsiEntry | State::DcsEntry | State::Escape => {
 | 
					 | 
				
			||||||
                        self.perform_action(performer, Action::Clear, byte);
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    State::DcsPassthrough => {
 | 
					 | 
				
			||||||
                        self.perform_action(performer, Action::Hook, byte);
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    State::OscString => {
 | 
					 | 
				
			||||||
                        self.perform_action(performer, Action::OscStart, byte);
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    _ => (),
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                // Assume the new state
 | 
					 | 
				
			||||||
                self.state = state;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Separate method for osc_dispatch that borrows self as read-only
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// The aliasing is needed here for multiple slices into self.osc_raw
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn osc_dispatch<P: Perform>(&self, performer: &mut P, byte: u8) {
 | 
					 | 
				
			||||||
        let mut slices: [MaybeUninit<&[u8]>; MAX_OSC_PARAMS] =
 | 
					 | 
				
			||||||
            unsafe { MaybeUninit::uninit().assume_init() };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        for (i, slice) in slices.iter_mut().enumerate().take(self.osc_num_params) {
 | 
					 | 
				
			||||||
            let indices = self.osc_params[i];
 | 
					 | 
				
			||||||
            *slice = MaybeUninit::new(&self.osc_raw[indices.0..indices.1]);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
            let num_params = self.osc_num_params;
 | 
					 | 
				
			||||||
            let params = &slices[..num_params] as *const [MaybeUninit<&[u8]>] as *const [&[u8]];
 | 
					 | 
				
			||||||
            performer.osc_dispatch(&*params, byte == 0x07);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn perform_action<P: Perform>(&mut self, performer: &mut P, action: Action, byte: u8) {
 | 
					 | 
				
			||||||
        match action {
 | 
					 | 
				
			||||||
            Action::Print => performer.print(byte as char),
 | 
					 | 
				
			||||||
            Action::Execute => performer.execute(byte),
 | 
					 | 
				
			||||||
            Action::Hook => {
 | 
					 | 
				
			||||||
                if self.params.is_full() {
 | 
					 | 
				
			||||||
                    self.ignoring = true;
 | 
					 | 
				
			||||||
                } else {
 | 
					 | 
				
			||||||
                    self.params.push(self.param);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                performer.hook(self.params(), self.intermediates(), self.ignoring, byte);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            Action::Put => performer.put(byte),
 | 
					 | 
				
			||||||
            Action::OscStart => {
 | 
					 | 
				
			||||||
                self.osc_raw.clear();
 | 
					 | 
				
			||||||
                self.osc_num_params = 0;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            Action::OscPut => {
 | 
					 | 
				
			||||||
                #[cfg(feature = "core")]
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    if self.osc_raw.is_full() {
 | 
					 | 
				
			||||||
                        return;
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                let idx = self.osc_raw.len();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                // Param separator
 | 
					 | 
				
			||||||
                if byte == b';' {
 | 
					 | 
				
			||||||
                    let param_idx = self.osc_num_params;
 | 
					 | 
				
			||||||
                    match param_idx {
 | 
					 | 
				
			||||||
                        // Only process up to MAX_OSC_PARAMS
 | 
					 | 
				
			||||||
                        MAX_OSC_PARAMS => return,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                        // First param is special - 0 to current byte index
 | 
					 | 
				
			||||||
                        0 => {
 | 
					 | 
				
			||||||
                            self.osc_params[param_idx] = (0, idx);
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                        // All other params depend on previous indexing
 | 
					 | 
				
			||||||
                        _ => {
 | 
					 | 
				
			||||||
                            let prev = self.osc_params[param_idx - 1];
 | 
					 | 
				
			||||||
                            let begin = prev.1;
 | 
					 | 
				
			||||||
                            self.osc_params[param_idx] = (begin, idx);
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    self.osc_num_params += 1;
 | 
					 | 
				
			||||||
                } else {
 | 
					 | 
				
			||||||
                    self.osc_raw.push(byte);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            Action::OscEnd => {
 | 
					 | 
				
			||||||
                let param_idx = self.osc_num_params;
 | 
					 | 
				
			||||||
                let idx = self.osc_raw.len();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                match param_idx {
 | 
					 | 
				
			||||||
                    // Finish last parameter if not already maxed
 | 
					 | 
				
			||||||
                    MAX_OSC_PARAMS => (),
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    // First param is special - 0 to current byte index
 | 
					 | 
				
			||||||
                    0 => {
 | 
					 | 
				
			||||||
                        self.osc_params[param_idx] = (0, idx);
 | 
					 | 
				
			||||||
                        self.osc_num_params += 1;
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    // All other params depend on previous indexing
 | 
					 | 
				
			||||||
                    _ => {
 | 
					 | 
				
			||||||
                        let prev = self.osc_params[param_idx - 1];
 | 
					 | 
				
			||||||
                        let begin = prev.1;
 | 
					 | 
				
			||||||
                        self.osc_params[param_idx] = (begin, idx);
 | 
					 | 
				
			||||||
                        self.osc_num_params += 1;
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                self.osc_dispatch(performer, byte);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            Action::Unhook => performer.unhook(),
 | 
					 | 
				
			||||||
            Action::CsiDispatch => {
 | 
					 | 
				
			||||||
                if self.params.is_full() {
 | 
					 | 
				
			||||||
                    self.ignoring = true;
 | 
					 | 
				
			||||||
                } else {
 | 
					 | 
				
			||||||
                    self.params.push(self.param);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                performer.csi_dispatch(self.params(), self.intermediates(), self.ignoring, byte);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            Action::EscDispatch => {
 | 
					 | 
				
			||||||
                performer.esc_dispatch(self.intermediates(), self.ignoring, byte);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            Action::Collect => {
 | 
					 | 
				
			||||||
                if self.intermediate_idx == MAX_INTERMEDIATES {
 | 
					 | 
				
			||||||
                    self.ignoring = true;
 | 
					 | 
				
			||||||
                } else {
 | 
					 | 
				
			||||||
                    self.intermediates[self.intermediate_idx] = byte;
 | 
					 | 
				
			||||||
                    self.intermediate_idx += 1;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            Action::Param => {
 | 
					 | 
				
			||||||
                if self.params.is_full() {
 | 
					 | 
				
			||||||
                    self.ignoring = true;
 | 
					 | 
				
			||||||
                    return;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                if byte == b';' {
 | 
					 | 
				
			||||||
                    self.params.push(self.param);
 | 
					 | 
				
			||||||
                    self.param = 0;
 | 
					 | 
				
			||||||
                } else if byte == b':' {
 | 
					 | 
				
			||||||
                    self.params.extend(self.param);
 | 
					 | 
				
			||||||
                    self.param = 0;
 | 
					 | 
				
			||||||
                } else {
 | 
					 | 
				
			||||||
                    // Continue collecting bytes into param
 | 
					 | 
				
			||||||
                    self.param = self.param.saturating_mul(10);
 | 
					 | 
				
			||||||
                    self.param = self.param.saturating_add((byte - b'0') as u16);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            Action::Clear => {
 | 
					 | 
				
			||||||
                // Reset everything on ESC/CSI/DCS entry
 | 
					 | 
				
			||||||
                self.intermediate_idx = 0;
 | 
					 | 
				
			||||||
                self.ignoring = false;
 | 
					 | 
				
			||||||
                self.param = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                self.params.clear();
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            Action::BeginUtf8 => self.process_utf8(performer, byte),
 | 
					 | 
				
			||||||
            Action::Ignore => (),
 | 
					 | 
				
			||||||
            Action::Nop => (),
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// Build a `char` out of bytes
 | 
					 | 
				
			||||||
pub trait CharAccumulator: Default {
 | 
					 | 
				
			||||||
    /// Build a `char` out of bytes
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// Return `None` when more data is needed
 | 
					 | 
				
			||||||
    fn add(&mut self, byte: u8) -> Option<char>;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[cfg(feature = "utf8")]
 | 
					 | 
				
			||||||
pub type DefaultCharAccumulator = Utf8Parser;
 | 
					 | 
				
			||||||
#[cfg(not(feature = "utf8"))]
 | 
					 | 
				
			||||||
pub type DefaultCharAccumulator = AsciiParser;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// Only allow parsing 7-bit ASCII
 | 
					 | 
				
			||||||
#[derive(Default, Clone, Debug, PartialEq, Eq)]
 | 
					 | 
				
			||||||
pub struct AsciiParser;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl CharAccumulator for AsciiParser {
 | 
					 | 
				
			||||||
    fn add(&mut self, _byte: u8) -> Option<char> {
 | 
					 | 
				
			||||||
        unreachable!("multi-byte UTF8 characters are unsupported")
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// Allow parsing UTF-8
 | 
					 | 
				
			||||||
#[cfg(feature = "utf8")]
 | 
					 | 
				
			||||||
#[derive(Default, Clone, Debug, PartialEq, Eq)]
 | 
					 | 
				
			||||||
pub struct Utf8Parser {
 | 
					 | 
				
			||||||
    utf8_parser: utf8::Parser,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[cfg(feature = "utf8")]
 | 
					 | 
				
			||||||
impl CharAccumulator for Utf8Parser {
 | 
					 | 
				
			||||||
    fn add(&mut self, byte: u8) -> Option<char> {
 | 
					 | 
				
			||||||
        let mut c = None;
 | 
					 | 
				
			||||||
        let mut receiver = VtUtf8Receiver(&mut c);
 | 
					 | 
				
			||||||
        self.utf8_parser.advance(&mut receiver, byte);
 | 
					 | 
				
			||||||
        c
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[cfg(feature = "utf8")]
 | 
					 | 
				
			||||||
struct VtUtf8Receiver<'a>(&'a mut Option<char>);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[cfg(feature = "utf8")]
 | 
					 | 
				
			||||||
impl<'a> utf8::Receiver for VtUtf8Receiver<'a> {
 | 
					 | 
				
			||||||
    fn codepoint(&mut self, c: char) {
 | 
					 | 
				
			||||||
        *self.0 = Some(c);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    fn invalid_sequence(&mut self) {
 | 
					 | 
				
			||||||
        *self.0 = Some('<27>');
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// Performs actions requested by the [`Parser`]
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// Actions in this case mean, for example, handling a CSI escape sequence describing cursor
 | 
					 | 
				
			||||||
/// movement, or simply printing characters to the screen.
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// The methods on this type correspond to actions described in
 | 
					 | 
				
			||||||
/// <http://vt100.net/emu/dec_ansi_parser>. I've done my best to describe them in
 | 
					 | 
				
			||||||
/// a useful way in my own words for completeness, but the site should be
 | 
					 | 
				
			||||||
/// referenced if something isn't clear. If the site disappears at some point in
 | 
					 | 
				
			||||||
/// the future, consider checking archive.org.
 | 
					 | 
				
			||||||
pub trait Perform {
 | 
					 | 
				
			||||||
    /// Draw a character to the screen and update states.
 | 
					 | 
				
			||||||
    fn print(&mut self, _c: char) {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Execute a C0 or C1 control function.
 | 
					 | 
				
			||||||
    fn execute(&mut self, _byte: u8) {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Invoked when a final character arrives in first part of device control string.
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// The control function should be determined from the private marker, final character, and
 | 
					 | 
				
			||||||
    /// execute with a parameter list. A handler should be selected for remaining characters in the
 | 
					 | 
				
			||||||
    /// string; the handler function should subsequently be called by `put` for every character in
 | 
					 | 
				
			||||||
    /// the control string.
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// The `ignore` flag indicates that more than two intermediates arrived and
 | 
					 | 
				
			||||||
    /// subsequent characters were ignored.
 | 
					 | 
				
			||||||
    fn hook(&mut self, _params: &Params, _intermediates: &[u8], _ignore: bool, _action: u8) {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Pass bytes as part of a device control string to the handle chosen in `hook`. C0 controls
 | 
					 | 
				
			||||||
    /// will also be passed to the handler.
 | 
					 | 
				
			||||||
    fn put(&mut self, _byte: u8) {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Called when a device control string is terminated.
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// The previously selected handler should be notified that the DCS has
 | 
					 | 
				
			||||||
    /// terminated.
 | 
					 | 
				
			||||||
    fn unhook(&mut self) {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Dispatch an operating system command.
 | 
					 | 
				
			||||||
    fn osc_dispatch(&mut self, _params: &[&[u8]], _bell_terminated: bool) {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// A final character has arrived for a CSI sequence
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// The `ignore` flag indicates that either more than two intermediates arrived
 | 
					 | 
				
			||||||
    /// or the number of parameters exceeded the maximum supported length,
 | 
					 | 
				
			||||||
    /// and subsequent characters were ignored.
 | 
					 | 
				
			||||||
    fn csi_dispatch(
 | 
					 | 
				
			||||||
        &mut self,
 | 
					 | 
				
			||||||
        _params: &Params,
 | 
					 | 
				
			||||||
        _intermediates: &[u8],
 | 
					 | 
				
			||||||
        _ignore: bool,
 | 
					 | 
				
			||||||
        _action: u8,
 | 
					 | 
				
			||||||
    ) {
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// The final character of an escape sequence has arrived.
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// The `ignore` flag indicates that more than two intermediates arrived and
 | 
					 | 
				
			||||||
    /// subsequent characters were ignored.
 | 
					 | 
				
			||||||
    fn esc_dispatch(&mut self, _intermediates: &[u8], _ignore: bool, _byte: u8) {}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										143
									
								
								vendor/anstyle-parse/src/params.rs
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										143
									
								
								vendor/anstyle-parse/src/params.rs
									
									
									
									
										vendored
									
									
								
							@@ -1,143 +0,0 @@
 | 
				
			|||||||
//! Fixed size parameters list with optional subparameters.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use core::fmt::{self, Debug, Formatter};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pub(crate) const MAX_PARAMS: usize = 32;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[derive(Default, Clone, PartialEq, Eq)]
 | 
					 | 
				
			||||||
pub struct Params {
 | 
					 | 
				
			||||||
    /// Number of subparameters for each parameter.
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// For each entry in the `params` slice, this stores the length of the param as number of
 | 
					 | 
				
			||||||
    /// subparams at the same index as the param in the `params` slice.
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// At the subparam positions the length will always be `0`.
 | 
					 | 
				
			||||||
    subparams: [u8; MAX_PARAMS],
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// All parameters and subparameters.
 | 
					 | 
				
			||||||
    params: [u16; MAX_PARAMS],
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Number of suparameters in the current parameter.
 | 
					 | 
				
			||||||
    current_subparams: u8,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Total number of parameters and subparameters.
 | 
					 | 
				
			||||||
    len: usize,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl Params {
 | 
					 | 
				
			||||||
    /// Returns the number of parameters.
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub fn len(&self) -> usize {
 | 
					 | 
				
			||||||
        self.len
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Returns `true` if there are no parameters present.
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub fn is_empty(&self) -> bool {
 | 
					 | 
				
			||||||
        self.len == 0
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Returns an iterator over all parameters and subparameters.
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub fn iter(&self) -> ParamsIter<'_> {
 | 
					 | 
				
			||||||
        ParamsIter::new(self)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Returns `true` if there is no more space for additional parameters.
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub(crate) fn is_full(&self) -> bool {
 | 
					 | 
				
			||||||
        self.len == MAX_PARAMS
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Clear all parameters.
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub(crate) fn clear(&mut self) {
 | 
					 | 
				
			||||||
        self.current_subparams = 0;
 | 
					 | 
				
			||||||
        self.len = 0;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Add an additional parameter.
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub(crate) fn push(&mut self, item: u16) {
 | 
					 | 
				
			||||||
        self.subparams[self.len - self.current_subparams as usize] = self.current_subparams + 1;
 | 
					 | 
				
			||||||
        self.params[self.len] = item;
 | 
					 | 
				
			||||||
        self.current_subparams = 0;
 | 
					 | 
				
			||||||
        self.len += 1;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Add an additional subparameter to the current parameter.
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub(crate) fn extend(&mut self, item: u16) {
 | 
					 | 
				
			||||||
        self.subparams[self.len - self.current_subparams as usize] = self.current_subparams + 1;
 | 
					 | 
				
			||||||
        self.params[self.len] = item;
 | 
					 | 
				
			||||||
        self.current_subparams += 1;
 | 
					 | 
				
			||||||
        self.len += 1;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl<'a> IntoIterator for &'a Params {
 | 
					 | 
				
			||||||
    type IntoIter = ParamsIter<'a>;
 | 
					 | 
				
			||||||
    type Item = &'a [u16];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    fn into_iter(self) -> Self::IntoIter {
 | 
					 | 
				
			||||||
        self.iter()
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// Immutable subparameter iterator.
 | 
					 | 
				
			||||||
pub struct ParamsIter<'a> {
 | 
					 | 
				
			||||||
    params: &'a Params,
 | 
					 | 
				
			||||||
    index: usize,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl<'a> ParamsIter<'a> {
 | 
					 | 
				
			||||||
    fn new(params: &'a Params) -> Self {
 | 
					 | 
				
			||||||
        Self { params, index: 0 }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl<'a> Iterator for ParamsIter<'a> {
 | 
					 | 
				
			||||||
    type Item = &'a [u16];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    fn next(&mut self) -> Option<Self::Item> {
 | 
					 | 
				
			||||||
        if self.index >= self.params.len() {
 | 
					 | 
				
			||||||
            return None;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Get all subparameters for the current parameter.
 | 
					 | 
				
			||||||
        let num_subparams = self.params.subparams[self.index];
 | 
					 | 
				
			||||||
        let param = &self.params.params[self.index..self.index + num_subparams as usize];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Jump to the next parameter.
 | 
					 | 
				
			||||||
        self.index += num_subparams as usize;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Some(param)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    fn size_hint(&self) -> (usize, Option<usize>) {
 | 
					 | 
				
			||||||
        let remaining = self.params.len() - self.index;
 | 
					 | 
				
			||||||
        (remaining, Some(remaining))
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl Debug for Params {
 | 
					 | 
				
			||||||
    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
 | 
					 | 
				
			||||||
        write!(f, "[")?;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        for (i, param) in self.iter().enumerate() {
 | 
					 | 
				
			||||||
            if i != 0 {
 | 
					 | 
				
			||||||
                write!(f, ";")?;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            for (i, subparam) in param.iter().enumerate() {
 | 
					 | 
				
			||||||
                if i != 0 {
 | 
					 | 
				
			||||||
                    write!(f, ":")?;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                subparam.fmt(f)?;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        write!(f, "]")
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										217
									
								
								vendor/anstyle-parse/src/state/codegen.rs
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										217
									
								
								vendor/anstyle-parse/src/state/codegen.rs
									
									
									
									
										vendored
									
									
								
							@@ -1,217 +0,0 @@
 | 
				
			|||||||
use super::{pack, unpack, Action, State};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use vte_generate_state_changes::generate_state_changes;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[test]
 | 
					 | 
				
			||||||
fn table() {
 | 
					 | 
				
			||||||
    let mut content = vec![];
 | 
					 | 
				
			||||||
    generate_table(&mut content).unwrap();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let content = String::from_utf8(content).unwrap();
 | 
					 | 
				
			||||||
    let content = codegenrs::rustfmt(&content, None).unwrap();
 | 
					 | 
				
			||||||
    snapbox::assert_eq_path("./src/state/table.rs", content);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[allow(clippy::write_literal)]
 | 
					 | 
				
			||||||
fn generate_table(file: &mut impl std::io::Write) -> std::io::Result<()> {
 | 
					 | 
				
			||||||
    writeln!(
 | 
					 | 
				
			||||||
        file,
 | 
					 | 
				
			||||||
        "// This file is @generated by {}",
 | 
					 | 
				
			||||||
        file!().replace('\\', "/")
 | 
					 | 
				
			||||||
    )?;
 | 
					 | 
				
			||||||
    writeln!(file)?;
 | 
					 | 
				
			||||||
    writeln!(
 | 
					 | 
				
			||||||
        file,
 | 
					 | 
				
			||||||
        "{}",
 | 
					 | 
				
			||||||
        r#"#[rustfmt::skip]
 | 
					 | 
				
			||||||
pub(crate) const STATE_CHANGES: [[u8; 256]; 16] = ["#
 | 
					 | 
				
			||||||
    )?;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    for (state, entries) in STATE_CHANGES.iter().enumerate() {
 | 
					 | 
				
			||||||
        writeln!(file, "    // {:?}", State::try_from(state as u8).unwrap())?;
 | 
					 | 
				
			||||||
        write!(file, "    [")?;
 | 
					 | 
				
			||||||
        let mut last_entry = None;
 | 
					 | 
				
			||||||
        for packed in entries {
 | 
					 | 
				
			||||||
            let (next_state, action) = unpack(*packed);
 | 
					 | 
				
			||||||
            if last_entry != Some(packed) {
 | 
					 | 
				
			||||||
                writeln!(file)?;
 | 
					 | 
				
			||||||
                writeln!(file, "        // {:?} {:?}", next_state, action)?;
 | 
					 | 
				
			||||||
                write!(file, "        ")?;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            write!(file, "0x{:0>2x}, ", packed)?;
 | 
					 | 
				
			||||||
            last_entry = Some(packed);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        writeln!(file)?;
 | 
					 | 
				
			||||||
        writeln!(file, "    ],")?;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    writeln!(file, "{}", r#"];"#)?;
 | 
					 | 
				
			||||||
    Ok(())
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// This is the state change table. It's indexed first by current state and then by the next
 | 
					 | 
				
			||||||
/// character in the pty stream.
 | 
					 | 
				
			||||||
pub static STATE_CHANGES: [[u8; 256]; 16] = state_changes();
 | 
					 | 
				
			||||||
generate_state_changes!(state_changes, {
 | 
					 | 
				
			||||||
    Anywhere {
 | 
					 | 
				
			||||||
        0x18 => (Ground, Execute),
 | 
					 | 
				
			||||||
        0x1a => (Ground, Execute),
 | 
					 | 
				
			||||||
        0x1b => (Escape, Nop),
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Ground {
 | 
					 | 
				
			||||||
        0x00..=0x17 => (Anywhere, Execute),
 | 
					 | 
				
			||||||
        0x19        => (Anywhere, Execute),
 | 
					 | 
				
			||||||
        0x1c..=0x1f => (Anywhere, Execute),
 | 
					 | 
				
			||||||
        0x20..=0x7f => (Anywhere, Print),
 | 
					 | 
				
			||||||
        0x80..=0x8f => (Anywhere, Execute),
 | 
					 | 
				
			||||||
        0x91..=0x9a => (Anywhere, Execute),
 | 
					 | 
				
			||||||
        0x9c        => (Anywhere, Execute),
 | 
					 | 
				
			||||||
        // Beginning of UTF-8 2 byte sequence
 | 
					 | 
				
			||||||
        0xc2..=0xdf => (Utf8, BeginUtf8),
 | 
					 | 
				
			||||||
        // Beginning of UTF-8 3 byte sequence
 | 
					 | 
				
			||||||
        0xe0..=0xef => (Utf8, BeginUtf8),
 | 
					 | 
				
			||||||
        // Beginning of UTF-8 4 byte sequence
 | 
					 | 
				
			||||||
        0xf0..=0xf4 => (Utf8, BeginUtf8),
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Escape {
 | 
					 | 
				
			||||||
        0x00..=0x17 => (Anywhere, Execute),
 | 
					 | 
				
			||||||
        0x19        => (Anywhere, Execute),
 | 
					 | 
				
			||||||
        0x1c..=0x1f => (Anywhere, Execute),
 | 
					 | 
				
			||||||
        0x7f        => (Anywhere, Ignore),
 | 
					 | 
				
			||||||
        0x20..=0x2f => (EscapeIntermediate, Collect),
 | 
					 | 
				
			||||||
        0x30..=0x4f => (Ground, EscDispatch),
 | 
					 | 
				
			||||||
        0x51..=0x57 => (Ground, EscDispatch),
 | 
					 | 
				
			||||||
        0x59        => (Ground, EscDispatch),
 | 
					 | 
				
			||||||
        0x5a        => (Ground, EscDispatch),
 | 
					 | 
				
			||||||
        0x5c        => (Ground, EscDispatch),
 | 
					 | 
				
			||||||
        0x60..=0x7e => (Ground, EscDispatch),
 | 
					 | 
				
			||||||
        0x5b        => (CsiEntry, Nop),
 | 
					 | 
				
			||||||
        0x5d        => (OscString, Nop),
 | 
					 | 
				
			||||||
        0x50        => (DcsEntry, Nop),
 | 
					 | 
				
			||||||
        0x58        => (SosPmApcString, Nop),
 | 
					 | 
				
			||||||
        0x5e        => (SosPmApcString, Nop),
 | 
					 | 
				
			||||||
        0x5f        => (SosPmApcString, Nop),
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    EscapeIntermediate {
 | 
					 | 
				
			||||||
        0x00..=0x17 => (Anywhere, Execute),
 | 
					 | 
				
			||||||
        0x19        => (Anywhere, Execute),
 | 
					 | 
				
			||||||
        0x1c..=0x1f => (Anywhere, Execute),
 | 
					 | 
				
			||||||
        0x20..=0x2f => (Anywhere, Collect),
 | 
					 | 
				
			||||||
        0x7f        => (Anywhere, Ignore),
 | 
					 | 
				
			||||||
        0x30..=0x7e => (Ground, EscDispatch),
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    CsiEntry {
 | 
					 | 
				
			||||||
        0x00..=0x17 => (Anywhere, Execute),
 | 
					 | 
				
			||||||
        0x19        => (Anywhere, Execute),
 | 
					 | 
				
			||||||
        0x1c..=0x1f => (Anywhere, Execute),
 | 
					 | 
				
			||||||
        0x7f        => (Anywhere, Ignore),
 | 
					 | 
				
			||||||
        0x20..=0x2f => (CsiIntermediate, Collect),
 | 
					 | 
				
			||||||
        0x30..=0x39 => (CsiParam, Param),
 | 
					 | 
				
			||||||
        0x3a..=0x3b => (CsiParam, Param),
 | 
					 | 
				
			||||||
        0x3c..=0x3f => (CsiParam, Collect),
 | 
					 | 
				
			||||||
        0x40..=0x7e => (Ground, CsiDispatch),
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    CsiIgnore {
 | 
					 | 
				
			||||||
        0x00..=0x17 => (Anywhere, Execute),
 | 
					 | 
				
			||||||
        0x19        => (Anywhere, Execute),
 | 
					 | 
				
			||||||
        0x1c..=0x1f => (Anywhere, Execute),
 | 
					 | 
				
			||||||
        0x20..=0x3f => (Anywhere, Ignore),
 | 
					 | 
				
			||||||
        0x7f        => (Anywhere, Ignore),
 | 
					 | 
				
			||||||
        0x40..=0x7e => (Ground, Nop),
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    CsiParam {
 | 
					 | 
				
			||||||
        0x00..=0x17 => (Anywhere, Execute),
 | 
					 | 
				
			||||||
        0x19        => (Anywhere, Execute),
 | 
					 | 
				
			||||||
        0x1c..=0x1f => (Anywhere, Execute),
 | 
					 | 
				
			||||||
        0x30..=0x39 => (Anywhere, Param),
 | 
					 | 
				
			||||||
        0x3a..=0x3b => (Anywhere, Param),
 | 
					 | 
				
			||||||
        0x7f        => (Anywhere, Ignore),
 | 
					 | 
				
			||||||
        0x3c..=0x3f => (CsiIgnore, Nop),
 | 
					 | 
				
			||||||
        0x20..=0x2f => (CsiIntermediate, Collect),
 | 
					 | 
				
			||||||
        0x40..=0x7e => (Ground, CsiDispatch),
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    CsiIntermediate {
 | 
					 | 
				
			||||||
        0x00..=0x17 => (Anywhere, Execute),
 | 
					 | 
				
			||||||
        0x19        => (Anywhere, Execute),
 | 
					 | 
				
			||||||
        0x1c..=0x1f => (Anywhere, Execute),
 | 
					 | 
				
			||||||
        0x20..=0x2f => (Anywhere, Collect),
 | 
					 | 
				
			||||||
        0x7f        => (Anywhere, Ignore),
 | 
					 | 
				
			||||||
        0x30..=0x3f => (CsiIgnore, Nop),
 | 
					 | 
				
			||||||
        0x40..=0x7e => (Ground, CsiDispatch),
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    DcsEntry {
 | 
					 | 
				
			||||||
        0x00..=0x17 => (Anywhere, Ignore),
 | 
					 | 
				
			||||||
        0x19        => (Anywhere, Ignore),
 | 
					 | 
				
			||||||
        0x1c..=0x1f => (Anywhere, Ignore),
 | 
					 | 
				
			||||||
        0x7f        => (Anywhere, Ignore),
 | 
					 | 
				
			||||||
        0x20..=0x2f => (DcsIntermediate, Collect),
 | 
					 | 
				
			||||||
        0x30..=0x39 => (DcsParam, Param),
 | 
					 | 
				
			||||||
        0x3a..=0x3b => (DcsParam, Param),
 | 
					 | 
				
			||||||
        0x3c..=0x3f => (DcsParam, Collect),
 | 
					 | 
				
			||||||
        0x40..=0x7e => (DcsPassthrough, Nop),
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    DcsIntermediate {
 | 
					 | 
				
			||||||
        0x00..=0x17 => (Anywhere, Ignore),
 | 
					 | 
				
			||||||
        0x19        => (Anywhere, Ignore),
 | 
					 | 
				
			||||||
        0x1c..=0x1f => (Anywhere, Ignore),
 | 
					 | 
				
			||||||
        0x20..=0x2f => (Anywhere, Collect),
 | 
					 | 
				
			||||||
        0x7f        => (Anywhere, Ignore),
 | 
					 | 
				
			||||||
        0x30..=0x3f => (DcsIgnore, Nop),
 | 
					 | 
				
			||||||
        0x40..=0x7e => (DcsPassthrough, Nop),
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    DcsIgnore {
 | 
					 | 
				
			||||||
        0x00..=0x17 => (Anywhere, Ignore),
 | 
					 | 
				
			||||||
        0x19        => (Anywhere, Ignore),
 | 
					 | 
				
			||||||
        0x1c..=0x1f => (Anywhere, Ignore),
 | 
					 | 
				
			||||||
        0x20..=0x7f => (Anywhere, Ignore),
 | 
					 | 
				
			||||||
        0x9c        => (Ground, Nop),
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    DcsParam {
 | 
					 | 
				
			||||||
        0x00..=0x17 => (Anywhere, Ignore),
 | 
					 | 
				
			||||||
        0x19        => (Anywhere, Ignore),
 | 
					 | 
				
			||||||
        0x1c..=0x1f => (Anywhere, Ignore),
 | 
					 | 
				
			||||||
        0x30..=0x39 => (Anywhere, Param),
 | 
					 | 
				
			||||||
        0x3a..=0x3b => (Anywhere, Param),
 | 
					 | 
				
			||||||
        0x7f        => (Anywhere, Ignore),
 | 
					 | 
				
			||||||
        0x3c..=0x3f => (DcsIgnore, Nop),
 | 
					 | 
				
			||||||
        0x20..=0x2f => (DcsIntermediate, Collect),
 | 
					 | 
				
			||||||
        0x40..=0x7e => (DcsPassthrough, Nop),
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    DcsPassthrough {
 | 
					 | 
				
			||||||
        0x00..=0x17 => (Anywhere, Put),
 | 
					 | 
				
			||||||
        0x19        => (Anywhere, Put),
 | 
					 | 
				
			||||||
        0x1c..=0x1f => (Anywhere, Put),
 | 
					 | 
				
			||||||
        0x20..=0x7e => (Anywhere, Put),
 | 
					 | 
				
			||||||
        0x7f        => (Anywhere, Ignore),
 | 
					 | 
				
			||||||
        0x9c        => (Ground, Nop),
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    SosPmApcString {
 | 
					 | 
				
			||||||
        0x00..=0x17 => (Anywhere, Ignore),
 | 
					 | 
				
			||||||
        0x19        => (Anywhere, Ignore),
 | 
					 | 
				
			||||||
        0x1c..=0x1f => (Anywhere, Ignore),
 | 
					 | 
				
			||||||
        0x20..=0x7f => (Anywhere, Ignore),
 | 
					 | 
				
			||||||
        0x9c        => (Ground, Nop),
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    OscString {
 | 
					 | 
				
			||||||
        0x00..=0x06 => (Anywhere, Ignore),
 | 
					 | 
				
			||||||
        0x07        => (Ground, Nop),
 | 
					 | 
				
			||||||
        0x08..=0x17 => (Anywhere, Ignore),
 | 
					 | 
				
			||||||
        0x19        => (Anywhere, Ignore),
 | 
					 | 
				
			||||||
        0x1c..=0x1f => (Anywhere, Ignore),
 | 
					 | 
				
			||||||
        0x20..=0xff => (Anywhere, OscPut),
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
							
								
								
									
										169
									
								
								vendor/anstyle-parse/src/state/definitions.rs
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										169
									
								
								vendor/anstyle-parse/src/state/definitions.rs
									
									
									
									
										vendored
									
									
								
							@@ -1,169 +0,0 @@
 | 
				
			|||||||
use core::mem;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
 | 
					 | 
				
			||||||
#[repr(u8)]
 | 
					 | 
				
			||||||
#[derive(Default)]
 | 
					 | 
				
			||||||
pub enum State {
 | 
					 | 
				
			||||||
    Anywhere = 0,
 | 
					 | 
				
			||||||
    CsiEntry = 1,
 | 
					 | 
				
			||||||
    CsiIgnore = 2,
 | 
					 | 
				
			||||||
    CsiIntermediate = 3,
 | 
					 | 
				
			||||||
    CsiParam = 4,
 | 
					 | 
				
			||||||
    DcsEntry = 5,
 | 
					 | 
				
			||||||
    DcsIgnore = 6,
 | 
					 | 
				
			||||||
    DcsIntermediate = 7,
 | 
					 | 
				
			||||||
    DcsParam = 8,
 | 
					 | 
				
			||||||
    DcsPassthrough = 9,
 | 
					 | 
				
			||||||
    Escape = 10,
 | 
					 | 
				
			||||||
    EscapeIntermediate = 11,
 | 
					 | 
				
			||||||
    #[default]
 | 
					 | 
				
			||||||
    Ground = 12,
 | 
					 | 
				
			||||||
    OscString = 13,
 | 
					 | 
				
			||||||
    SosPmApcString = 14,
 | 
					 | 
				
			||||||
    Utf8 = 15,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl TryFrom<u8> for State {
 | 
					 | 
				
			||||||
    type Error = u8;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[inline(always)]
 | 
					 | 
				
			||||||
    fn try_from(raw: u8) -> Result<Self, Self::Error> {
 | 
					 | 
				
			||||||
        STATES.get(raw as usize).ok_or(raw).copied()
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const STATES: [State; 16] = [
 | 
					 | 
				
			||||||
    State::Anywhere,
 | 
					 | 
				
			||||||
    State::CsiEntry,
 | 
					 | 
				
			||||||
    State::CsiIgnore,
 | 
					 | 
				
			||||||
    State::CsiIntermediate,
 | 
					 | 
				
			||||||
    State::CsiParam,
 | 
					 | 
				
			||||||
    State::DcsEntry,
 | 
					 | 
				
			||||||
    State::DcsIgnore,
 | 
					 | 
				
			||||||
    State::DcsIntermediate,
 | 
					 | 
				
			||||||
    State::DcsParam,
 | 
					 | 
				
			||||||
    State::DcsPassthrough,
 | 
					 | 
				
			||||||
    State::Escape,
 | 
					 | 
				
			||||||
    State::EscapeIntermediate,
 | 
					 | 
				
			||||||
    State::Ground,
 | 
					 | 
				
			||||||
    State::OscString,
 | 
					 | 
				
			||||||
    State::SosPmApcString,
 | 
					 | 
				
			||||||
    State::Utf8,
 | 
					 | 
				
			||||||
];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
 | 
					 | 
				
			||||||
#[repr(u8)]
 | 
					 | 
				
			||||||
#[derive(Default)]
 | 
					 | 
				
			||||||
pub enum Action {
 | 
					 | 
				
			||||||
    #[default]
 | 
					 | 
				
			||||||
    Nop = 0,
 | 
					 | 
				
			||||||
    Clear = 1,
 | 
					 | 
				
			||||||
    Collect = 2,
 | 
					 | 
				
			||||||
    CsiDispatch = 3,
 | 
					 | 
				
			||||||
    EscDispatch = 4,
 | 
					 | 
				
			||||||
    Execute = 5,
 | 
					 | 
				
			||||||
    Hook = 6,
 | 
					 | 
				
			||||||
    Ignore = 7,
 | 
					 | 
				
			||||||
    OscEnd = 8,
 | 
					 | 
				
			||||||
    OscPut = 9,
 | 
					 | 
				
			||||||
    OscStart = 10,
 | 
					 | 
				
			||||||
    Param = 11,
 | 
					 | 
				
			||||||
    Print = 12,
 | 
					 | 
				
			||||||
    Put = 13,
 | 
					 | 
				
			||||||
    Unhook = 14,
 | 
					 | 
				
			||||||
    BeginUtf8 = 15,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl TryFrom<u8> for Action {
 | 
					 | 
				
			||||||
    type Error = u8;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[inline(always)]
 | 
					 | 
				
			||||||
    fn try_from(raw: u8) -> Result<Self, Self::Error> {
 | 
					 | 
				
			||||||
        ACTIONS.get(raw as usize).ok_or(raw).copied()
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const ACTIONS: [Action; 16] = [
 | 
					 | 
				
			||||||
    Action::Nop,
 | 
					 | 
				
			||||||
    Action::Clear,
 | 
					 | 
				
			||||||
    Action::Collect,
 | 
					 | 
				
			||||||
    Action::CsiDispatch,
 | 
					 | 
				
			||||||
    Action::EscDispatch,
 | 
					 | 
				
			||||||
    Action::Execute,
 | 
					 | 
				
			||||||
    Action::Hook,
 | 
					 | 
				
			||||||
    Action::Ignore,
 | 
					 | 
				
			||||||
    Action::OscEnd,
 | 
					 | 
				
			||||||
    Action::OscPut,
 | 
					 | 
				
			||||||
    Action::OscStart,
 | 
					 | 
				
			||||||
    Action::Param,
 | 
					 | 
				
			||||||
    Action::Print,
 | 
					 | 
				
			||||||
    Action::Put,
 | 
					 | 
				
			||||||
    Action::Unhook,
 | 
					 | 
				
			||||||
    Action::BeginUtf8,
 | 
					 | 
				
			||||||
];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// Unpack a u8 into a State and Action
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// The implementation of this assumes that there are *precisely* 16 variants for both Action and
 | 
					 | 
				
			||||||
/// State. Furthermore, it assumes that the enums are tag-only; that is, there is no data in any
 | 
					 | 
				
			||||||
/// variant.
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// Bad things will happen if those invariants are violated.
 | 
					 | 
				
			||||||
#[inline(always)]
 | 
					 | 
				
			||||||
pub const fn unpack(delta: u8) -> (State, Action) {
 | 
					 | 
				
			||||||
    unsafe {
 | 
					 | 
				
			||||||
        (
 | 
					 | 
				
			||||||
            // State is stored in bottom 4 bits
 | 
					 | 
				
			||||||
            mem::transmute(delta & 0x0f),
 | 
					 | 
				
			||||||
            // Action is stored in top 4 bits
 | 
					 | 
				
			||||||
            mem::transmute(delta >> 4),
 | 
					 | 
				
			||||||
        )
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[inline(always)]
 | 
					 | 
				
			||||||
#[cfg(test)]
 | 
					 | 
				
			||||||
pub const fn pack(state: State, action: Action) -> u8 {
 | 
					 | 
				
			||||||
    (action as u8) << 4 | state as u8
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[cfg(test)]
 | 
					 | 
				
			||||||
mod tests {
 | 
					 | 
				
			||||||
    use super::*;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[test]
 | 
					 | 
				
			||||||
    fn unpack_state_action() {
 | 
					 | 
				
			||||||
        match unpack(0xee) {
 | 
					 | 
				
			||||||
            (State::SosPmApcString, Action::Unhook) => (),
 | 
					 | 
				
			||||||
            _ => panic!("unpack failed"),
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        match unpack(0x0f) {
 | 
					 | 
				
			||||||
            (State::Utf8, Action::Nop) => (),
 | 
					 | 
				
			||||||
            _ => panic!("unpack failed"),
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        match unpack(0xff) {
 | 
					 | 
				
			||||||
            (State::Utf8, Action::BeginUtf8) => (),
 | 
					 | 
				
			||||||
            _ => panic!("unpack failed"),
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[test]
 | 
					 | 
				
			||||||
    fn pack_state_action() {
 | 
					 | 
				
			||||||
        match unpack(0xee) {
 | 
					 | 
				
			||||||
            (State::SosPmApcString, Action::Unhook) => (),
 | 
					 | 
				
			||||||
            _ => panic!("unpack failed"),
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        match unpack(0x0f) {
 | 
					 | 
				
			||||||
            (State::Utf8, Action::Nop) => (),
 | 
					 | 
				
			||||||
            _ => panic!("unpack failed"),
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        match unpack(0xff) {
 | 
					 | 
				
			||||||
            (State::Utf8, Action::BeginUtf8) => (),
 | 
					 | 
				
			||||||
            _ => panic!("unpack failed"),
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										41
									
								
								vendor/anstyle-parse/src/state/mod.rs
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										41
									
								
								vendor/anstyle-parse/src/state/mod.rs
									
									
									
									
										vendored
									
									
								
							@@ -1,41 +0,0 @@
 | 
				
			|||||||
#[cfg(test)]
 | 
					 | 
				
			||||||
mod codegen;
 | 
					 | 
				
			||||||
mod definitions;
 | 
					 | 
				
			||||||
mod table;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[cfg(test)]
 | 
					 | 
				
			||||||
pub(crate) use definitions::pack;
 | 
					 | 
				
			||||||
pub(crate) use definitions::unpack;
 | 
					 | 
				
			||||||
pub use definitions::Action;
 | 
					 | 
				
			||||||
pub use definitions::State;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// Transition to next [`State`]
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// Note: This does not directly support UTF-8.
 | 
					 | 
				
			||||||
/// - If the data is validated as UTF-8 (e.g. `str`) or single-byte C1 control codes are
 | 
					 | 
				
			||||||
///   unsupported, then treat [`Action::BeginUtf8`] and [`Action::Execute`] for UTF-8 continuations
 | 
					 | 
				
			||||||
///   as [`Action::Print`].
 | 
					 | 
				
			||||||
/// - If the data is not validated, then a UTF-8 state machine will need to be implemented on top,
 | 
					 | 
				
			||||||
///   starting with [`Action::BeginUtf8`].
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// Note: When [`State::Anywhere`] is returned, revert back to the prior state.
 | 
					 | 
				
			||||||
#[inline]
 | 
					 | 
				
			||||||
pub const fn state_change(state: State, byte: u8) -> (State, Action) {
 | 
					 | 
				
			||||||
    // Handle state changes in the anywhere state before evaluating changes
 | 
					 | 
				
			||||||
    // for current state.
 | 
					 | 
				
			||||||
    let mut change = state_change_(State::Anywhere, byte);
 | 
					 | 
				
			||||||
    if change == 0 {
 | 
					 | 
				
			||||||
        change = state_change_(state, byte);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // Unpack into a state and action
 | 
					 | 
				
			||||||
    unpack(change)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[inline]
 | 
					 | 
				
			||||||
const fn state_change_(state: State, byte: u8) -> u8 {
 | 
					 | 
				
			||||||
    let state_idx = state as usize;
 | 
					 | 
				
			||||||
    let byte_idx = byte as usize;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    table::STATE_CHANGES[state_idx][byte_idx]
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										361
									
								
								vendor/anstyle-parse/src/state/table.rs
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										361
									
								
								vendor/anstyle-parse/src/state/table.rs
									
									
									
									
										vendored
									
									
								
							@@ -1,361 +0,0 @@
 | 
				
			|||||||
// This file is @generated by crates/anstyle-parse/src/state/codegen.rs
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[rustfmt::skip]
 | 
					 | 
				
			||||||
pub(crate) const STATE_CHANGES: [[u8; 256]; 16] = [
 | 
					 | 
				
			||||||
    // Anywhere
 | 
					 | 
				
			||||||
    [
 | 
					 | 
				
			||||||
        // Anywhere Nop
 | 
					 | 
				
			||||||
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
 | 
					 | 
				
			||||||
        // Ground Execute
 | 
					 | 
				
			||||||
        0x5c, 
 | 
					 | 
				
			||||||
        // Anywhere Nop
 | 
					 | 
				
			||||||
        0x00, 
 | 
					 | 
				
			||||||
        // Ground Execute
 | 
					 | 
				
			||||||
        0x5c, 
 | 
					 | 
				
			||||||
        // Escape Nop
 | 
					 | 
				
			||||||
        0x0a, 
 | 
					 | 
				
			||||||
        // Anywhere Nop
 | 
					 | 
				
			||||||
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
    // CsiEntry
 | 
					 | 
				
			||||||
    [
 | 
					 | 
				
			||||||
        // Anywhere Execute
 | 
					 | 
				
			||||||
        0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 
 | 
					 | 
				
			||||||
        // Anywhere Nop
 | 
					 | 
				
			||||||
        0x00, 
 | 
					 | 
				
			||||||
        // Anywhere Execute
 | 
					 | 
				
			||||||
        0x50, 
 | 
					 | 
				
			||||||
        // Anywhere Nop
 | 
					 | 
				
			||||||
        0x00, 0x00, 
 | 
					 | 
				
			||||||
        // Anywhere Execute
 | 
					 | 
				
			||||||
        0x50, 0x50, 0x50, 0x50, 
 | 
					 | 
				
			||||||
        // CsiIntermediate Collect
 | 
					 | 
				
			||||||
        0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 
 | 
					 | 
				
			||||||
        // CsiParam Param
 | 
					 | 
				
			||||||
        0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 
 | 
					 | 
				
			||||||
        // CsiParam Collect
 | 
					 | 
				
			||||||
        0x24, 0x24, 0x24, 0x24, 
 | 
					 | 
				
			||||||
        // Ground CsiDispatch
 | 
					 | 
				
			||||||
        0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 
 | 
					 | 
				
			||||||
        // Anywhere Ignore
 | 
					 | 
				
			||||||
        0x70, 
 | 
					 | 
				
			||||||
        // Anywhere Nop
 | 
					 | 
				
			||||||
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
    // CsiIgnore
 | 
					 | 
				
			||||||
    [
 | 
					 | 
				
			||||||
        // Anywhere Execute
 | 
					 | 
				
			||||||
        0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 
 | 
					 | 
				
			||||||
        // Anywhere Nop
 | 
					 | 
				
			||||||
        0x00, 
 | 
					 | 
				
			||||||
        // Anywhere Execute
 | 
					 | 
				
			||||||
        0x50, 
 | 
					 | 
				
			||||||
        // Anywhere Nop
 | 
					 | 
				
			||||||
        0x00, 0x00, 
 | 
					 | 
				
			||||||
        // Anywhere Execute
 | 
					 | 
				
			||||||
        0x50, 0x50, 0x50, 0x50, 
 | 
					 | 
				
			||||||
        // Anywhere Ignore
 | 
					 | 
				
			||||||
        0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 
 | 
					 | 
				
			||||||
        // Ground Nop
 | 
					 | 
				
			||||||
        0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 
 | 
					 | 
				
			||||||
        // Anywhere Ignore
 | 
					 | 
				
			||||||
        0x70, 
 | 
					 | 
				
			||||||
        // Anywhere Nop
 | 
					 | 
				
			||||||
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
    // CsiIntermediate
 | 
					 | 
				
			||||||
    [
 | 
					 | 
				
			||||||
        // Anywhere Execute
 | 
					 | 
				
			||||||
        0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 
 | 
					 | 
				
			||||||
        // Anywhere Nop
 | 
					 | 
				
			||||||
        0x00, 
 | 
					 | 
				
			||||||
        // Anywhere Execute
 | 
					 | 
				
			||||||
        0x50, 
 | 
					 | 
				
			||||||
        // Anywhere Nop
 | 
					 | 
				
			||||||
        0x00, 0x00, 
 | 
					 | 
				
			||||||
        // Anywhere Execute
 | 
					 | 
				
			||||||
        0x50, 0x50, 0x50, 0x50, 
 | 
					 | 
				
			||||||
        // Anywhere Collect
 | 
					 | 
				
			||||||
        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
 | 
					 | 
				
			||||||
        // CsiIgnore Nop
 | 
					 | 
				
			||||||
        0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 
 | 
					 | 
				
			||||||
        // Ground CsiDispatch
 | 
					 | 
				
			||||||
        0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 
 | 
					 | 
				
			||||||
        // Anywhere Ignore
 | 
					 | 
				
			||||||
        0x70, 
 | 
					 | 
				
			||||||
        // Anywhere Nop
 | 
					 | 
				
			||||||
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
    // CsiParam
 | 
					 | 
				
			||||||
    [
 | 
					 | 
				
			||||||
        // Anywhere Execute
 | 
					 | 
				
			||||||
        0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 
 | 
					 | 
				
			||||||
        // Anywhere Nop
 | 
					 | 
				
			||||||
        0x00, 
 | 
					 | 
				
			||||||
        // Anywhere Execute
 | 
					 | 
				
			||||||
        0x50, 
 | 
					 | 
				
			||||||
        // Anywhere Nop
 | 
					 | 
				
			||||||
        0x00, 0x00, 
 | 
					 | 
				
			||||||
        // Anywhere Execute
 | 
					 | 
				
			||||||
        0x50, 0x50, 0x50, 0x50, 
 | 
					 | 
				
			||||||
        // CsiIntermediate Collect
 | 
					 | 
				
			||||||
        0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 
 | 
					 | 
				
			||||||
        // Anywhere Param
 | 
					 | 
				
			||||||
        0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 
 | 
					 | 
				
			||||||
        // CsiIgnore Nop
 | 
					 | 
				
			||||||
        0x02, 0x02, 0x02, 0x02, 
 | 
					 | 
				
			||||||
        // Ground CsiDispatch
 | 
					 | 
				
			||||||
        0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 
 | 
					 | 
				
			||||||
        // Anywhere Ignore
 | 
					 | 
				
			||||||
        0x70, 
 | 
					 | 
				
			||||||
        // Anywhere Nop
 | 
					 | 
				
			||||||
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
    // DcsEntry
 | 
					 | 
				
			||||||
    [
 | 
					 | 
				
			||||||
        // Anywhere Ignore
 | 
					 | 
				
			||||||
        0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 
 | 
					 | 
				
			||||||
        // Anywhere Nop
 | 
					 | 
				
			||||||
        0x00, 
 | 
					 | 
				
			||||||
        // Anywhere Ignore
 | 
					 | 
				
			||||||
        0x70, 
 | 
					 | 
				
			||||||
        // Anywhere Nop
 | 
					 | 
				
			||||||
        0x00, 0x00, 
 | 
					 | 
				
			||||||
        // Anywhere Ignore
 | 
					 | 
				
			||||||
        0x70, 0x70, 0x70, 0x70, 
 | 
					 | 
				
			||||||
        // DcsIntermediate Collect
 | 
					 | 
				
			||||||
        0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 
 | 
					 | 
				
			||||||
        // DcsParam Param
 | 
					 | 
				
			||||||
        0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 
 | 
					 | 
				
			||||||
        // DcsParam Collect
 | 
					 | 
				
			||||||
        0x28, 0x28, 0x28, 0x28, 
 | 
					 | 
				
			||||||
        // DcsPassthrough Nop
 | 
					 | 
				
			||||||
        0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 
 | 
					 | 
				
			||||||
        // Anywhere Ignore
 | 
					 | 
				
			||||||
        0x70, 
 | 
					 | 
				
			||||||
        // Anywhere Nop
 | 
					 | 
				
			||||||
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
    // DcsIgnore
 | 
					 | 
				
			||||||
    [
 | 
					 | 
				
			||||||
        // Anywhere Ignore
 | 
					 | 
				
			||||||
        0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 
 | 
					 | 
				
			||||||
        // Anywhere Nop
 | 
					 | 
				
			||||||
        0x00, 
 | 
					 | 
				
			||||||
        // Anywhere Ignore
 | 
					 | 
				
			||||||
        0x70, 
 | 
					 | 
				
			||||||
        // Anywhere Nop
 | 
					 | 
				
			||||||
        0x00, 0x00, 
 | 
					 | 
				
			||||||
        // Anywhere Ignore
 | 
					 | 
				
			||||||
        0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 
 | 
					 | 
				
			||||||
        // Anywhere Nop
 | 
					 | 
				
			||||||
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
 | 
					 | 
				
			||||||
        // Ground Nop
 | 
					 | 
				
			||||||
        0x0c, 
 | 
					 | 
				
			||||||
        // Anywhere Nop
 | 
					 | 
				
			||||||
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
    // DcsIntermediate
 | 
					 | 
				
			||||||
    [
 | 
					 | 
				
			||||||
        // Anywhere Ignore
 | 
					 | 
				
			||||||
        0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 
 | 
					 | 
				
			||||||
        // Anywhere Nop
 | 
					 | 
				
			||||||
        0x00, 
 | 
					 | 
				
			||||||
        // Anywhere Ignore
 | 
					 | 
				
			||||||
        0x70, 
 | 
					 | 
				
			||||||
        // Anywhere Nop
 | 
					 | 
				
			||||||
        0x00, 0x00, 
 | 
					 | 
				
			||||||
        // Anywhere Ignore
 | 
					 | 
				
			||||||
        0x70, 0x70, 0x70, 0x70, 
 | 
					 | 
				
			||||||
        // Anywhere Collect
 | 
					 | 
				
			||||||
        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
 | 
					 | 
				
			||||||
        // DcsIgnore Nop
 | 
					 | 
				
			||||||
        0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 
 | 
					 | 
				
			||||||
        // DcsPassthrough Nop
 | 
					 | 
				
			||||||
        0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 
 | 
					 | 
				
			||||||
        // Anywhere Ignore
 | 
					 | 
				
			||||||
        0x70, 
 | 
					 | 
				
			||||||
        // Anywhere Nop
 | 
					 | 
				
			||||||
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
    // DcsParam
 | 
					 | 
				
			||||||
    [
 | 
					 | 
				
			||||||
        // Anywhere Ignore
 | 
					 | 
				
			||||||
        0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 
 | 
					 | 
				
			||||||
        // Anywhere Nop
 | 
					 | 
				
			||||||
        0x00, 
 | 
					 | 
				
			||||||
        // Anywhere Ignore
 | 
					 | 
				
			||||||
        0x70, 
 | 
					 | 
				
			||||||
        // Anywhere Nop
 | 
					 | 
				
			||||||
        0x00, 0x00, 
 | 
					 | 
				
			||||||
        // Anywhere Ignore
 | 
					 | 
				
			||||||
        0x70, 0x70, 0x70, 0x70, 
 | 
					 | 
				
			||||||
        // DcsIntermediate Collect
 | 
					 | 
				
			||||||
        0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 
 | 
					 | 
				
			||||||
        // Anywhere Param
 | 
					 | 
				
			||||||
        0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 
 | 
					 | 
				
			||||||
        // DcsIgnore Nop
 | 
					 | 
				
			||||||
        0x06, 0x06, 0x06, 0x06, 
 | 
					 | 
				
			||||||
        // DcsPassthrough Nop
 | 
					 | 
				
			||||||
        0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 
 | 
					 | 
				
			||||||
        // Anywhere Ignore
 | 
					 | 
				
			||||||
        0x70, 
 | 
					 | 
				
			||||||
        // Anywhere Nop
 | 
					 | 
				
			||||||
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
    // DcsPassthrough
 | 
					 | 
				
			||||||
    [
 | 
					 | 
				
			||||||
        // Anywhere Put
 | 
					 | 
				
			||||||
        0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 
 | 
					 | 
				
			||||||
        // Anywhere Nop
 | 
					 | 
				
			||||||
        0x00, 
 | 
					 | 
				
			||||||
        // Anywhere Put
 | 
					 | 
				
			||||||
        0xd0, 
 | 
					 | 
				
			||||||
        // Anywhere Nop
 | 
					 | 
				
			||||||
        0x00, 0x00, 
 | 
					 | 
				
			||||||
        // Anywhere Put
 | 
					 | 
				
			||||||
        0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 
 | 
					 | 
				
			||||||
        // Anywhere Ignore
 | 
					 | 
				
			||||||
        0x70, 
 | 
					 | 
				
			||||||
        // Anywhere Nop
 | 
					 | 
				
			||||||
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
 | 
					 | 
				
			||||||
        // Ground Nop
 | 
					 | 
				
			||||||
        0x0c, 
 | 
					 | 
				
			||||||
        // Anywhere Nop
 | 
					 | 
				
			||||||
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
    // Escape
 | 
					 | 
				
			||||||
    [
 | 
					 | 
				
			||||||
        // Anywhere Execute
 | 
					 | 
				
			||||||
        0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 
 | 
					 | 
				
			||||||
        // Anywhere Nop
 | 
					 | 
				
			||||||
        0x00, 
 | 
					 | 
				
			||||||
        // Anywhere Execute
 | 
					 | 
				
			||||||
        0x50, 
 | 
					 | 
				
			||||||
        // Anywhere Nop
 | 
					 | 
				
			||||||
        0x00, 0x00, 
 | 
					 | 
				
			||||||
        // Anywhere Execute
 | 
					 | 
				
			||||||
        0x50, 0x50, 0x50, 0x50, 
 | 
					 | 
				
			||||||
        // EscapeIntermediate Collect
 | 
					 | 
				
			||||||
        0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 
 | 
					 | 
				
			||||||
        // Ground EscDispatch
 | 
					 | 
				
			||||||
        0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 
 | 
					 | 
				
			||||||
        // DcsEntry Nop
 | 
					 | 
				
			||||||
        0x05, 
 | 
					 | 
				
			||||||
        // Ground EscDispatch
 | 
					 | 
				
			||||||
        0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 
 | 
					 | 
				
			||||||
        // SosPmApcString Nop
 | 
					 | 
				
			||||||
        0x0e, 
 | 
					 | 
				
			||||||
        // Ground EscDispatch
 | 
					 | 
				
			||||||
        0x4c, 0x4c, 
 | 
					 | 
				
			||||||
        // CsiEntry Nop
 | 
					 | 
				
			||||||
        0x01, 
 | 
					 | 
				
			||||||
        // Ground EscDispatch
 | 
					 | 
				
			||||||
        0x4c, 
 | 
					 | 
				
			||||||
        // OscString Nop
 | 
					 | 
				
			||||||
        0x0d, 
 | 
					 | 
				
			||||||
        // SosPmApcString Nop
 | 
					 | 
				
			||||||
        0x0e, 0x0e, 
 | 
					 | 
				
			||||||
        // Ground EscDispatch
 | 
					 | 
				
			||||||
        0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 
 | 
					 | 
				
			||||||
        // Anywhere Ignore
 | 
					 | 
				
			||||||
        0x70, 
 | 
					 | 
				
			||||||
        // Anywhere Nop
 | 
					 | 
				
			||||||
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
    // EscapeIntermediate
 | 
					 | 
				
			||||||
    [
 | 
					 | 
				
			||||||
        // Anywhere Execute
 | 
					 | 
				
			||||||
        0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 
 | 
					 | 
				
			||||||
        // Anywhere Nop
 | 
					 | 
				
			||||||
        0x00, 
 | 
					 | 
				
			||||||
        // Anywhere Execute
 | 
					 | 
				
			||||||
        0x50, 
 | 
					 | 
				
			||||||
        // Anywhere Nop
 | 
					 | 
				
			||||||
        0x00, 0x00, 
 | 
					 | 
				
			||||||
        // Anywhere Execute
 | 
					 | 
				
			||||||
        0x50, 0x50, 0x50, 0x50, 
 | 
					 | 
				
			||||||
        // Anywhere Collect
 | 
					 | 
				
			||||||
        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
 | 
					 | 
				
			||||||
        // Ground EscDispatch
 | 
					 | 
				
			||||||
        0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 
 | 
					 | 
				
			||||||
        // Anywhere Ignore
 | 
					 | 
				
			||||||
        0x70, 
 | 
					 | 
				
			||||||
        // Anywhere Nop
 | 
					 | 
				
			||||||
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
    // Ground
 | 
					 | 
				
			||||||
    [
 | 
					 | 
				
			||||||
        // Anywhere Execute
 | 
					 | 
				
			||||||
        0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 
 | 
					 | 
				
			||||||
        // Anywhere Nop
 | 
					 | 
				
			||||||
        0x00, 
 | 
					 | 
				
			||||||
        // Anywhere Execute
 | 
					 | 
				
			||||||
        0x50, 
 | 
					 | 
				
			||||||
        // Anywhere Nop
 | 
					 | 
				
			||||||
        0x00, 0x00, 
 | 
					 | 
				
			||||||
        // Anywhere Execute
 | 
					 | 
				
			||||||
        0x50, 0x50, 0x50, 0x50, 
 | 
					 | 
				
			||||||
        // Anywhere Print
 | 
					 | 
				
			||||||
        0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 
 | 
					 | 
				
			||||||
        // Anywhere Execute
 | 
					 | 
				
			||||||
        0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 
 | 
					 | 
				
			||||||
        // Anywhere Nop
 | 
					 | 
				
			||||||
        0x00, 
 | 
					 | 
				
			||||||
        // Anywhere Execute
 | 
					 | 
				
			||||||
        0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 
 | 
					 | 
				
			||||||
        // Anywhere Nop
 | 
					 | 
				
			||||||
        0x00, 
 | 
					 | 
				
			||||||
        // Anywhere Execute
 | 
					 | 
				
			||||||
        0x50, 
 | 
					 | 
				
			||||||
        // Anywhere Nop
 | 
					 | 
				
			||||||
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
 | 
					 | 
				
			||||||
        // Utf8 BeginUtf8
 | 
					 | 
				
			||||||
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
 | 
					 | 
				
			||||||
        // Anywhere Nop
 | 
					 | 
				
			||||||
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
    // OscString
 | 
					 | 
				
			||||||
    [
 | 
					 | 
				
			||||||
        // Anywhere Ignore
 | 
					 | 
				
			||||||
        0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 
 | 
					 | 
				
			||||||
        // Ground Nop
 | 
					 | 
				
			||||||
        0x0c, 
 | 
					 | 
				
			||||||
        // Anywhere Ignore
 | 
					 | 
				
			||||||
        0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 
 | 
					 | 
				
			||||||
        // Anywhere Nop
 | 
					 | 
				
			||||||
        0x00, 
 | 
					 | 
				
			||||||
        // Anywhere Ignore
 | 
					 | 
				
			||||||
        0x70, 
 | 
					 | 
				
			||||||
        // Anywhere Nop
 | 
					 | 
				
			||||||
        0x00, 0x00, 
 | 
					 | 
				
			||||||
        // Anywhere Ignore
 | 
					 | 
				
			||||||
        0x70, 0x70, 0x70, 0x70, 
 | 
					 | 
				
			||||||
        // Anywhere OscPut
 | 
					 | 
				
			||||||
        0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
    // SosPmApcString
 | 
					 | 
				
			||||||
    [
 | 
					 | 
				
			||||||
        // Anywhere Ignore
 | 
					 | 
				
			||||||
        0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 
 | 
					 | 
				
			||||||
        // Anywhere Nop
 | 
					 | 
				
			||||||
        0x00, 
 | 
					 | 
				
			||||||
        // Anywhere Ignore
 | 
					 | 
				
			||||||
        0x70, 
 | 
					 | 
				
			||||||
        // Anywhere Nop
 | 
					 | 
				
			||||||
        0x00, 0x00, 
 | 
					 | 
				
			||||||
        // Anywhere Ignore
 | 
					 | 
				
			||||||
        0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 
 | 
					 | 
				
			||||||
        // Anywhere Nop
 | 
					 | 
				
			||||||
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
 | 
					 | 
				
			||||||
        // Ground Nop
 | 
					 | 
				
			||||||
        0x0c, 
 | 
					 | 
				
			||||||
        // Anywhere Nop
 | 
					 | 
				
			||||||
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
    // Utf8
 | 
					 | 
				
			||||||
    [
 | 
					 | 
				
			||||||
        // Anywhere Nop
 | 
					 | 
				
			||||||
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
];
 | 
					 | 
				
			||||||
							
								
								
									
										1
									
								
								vendor/anstyle-query/.cargo-checksum.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								vendor/anstyle-query/.cargo-checksum.json
									
									
									
									
										vendored
									
									
								
							@@ -1 +0,0 @@
 | 
				
			|||||||
{"files":{"Cargo.lock":"dbef8401bf3e334d4f3a8230f2506dbc1439dd3aea07cbbc174125eb5fef0eed","Cargo.toml":"4b85a1d05db43bc0aa4ccc814c9e6b922d6a811aa79e02e614f5baccfa803a05","LICENSE-APACHE":"c6596eb7be8581c18be736c846fb9173b69eccf6ef94c5135893ec56bd92ba08","LICENSE-MIT":"6efb0476a1cc085077ed49357026d8c173bf33017278ef440f222fb9cbcb66e6","README.md":"94cda3914d2693b89e0b5855ffff04b971823f6cbae885a1610353254a269ed9","examples/query.rs":"d9f5b94967c7b9579ee399c481148b07fd0fb371f4a5d557017ff86cb5034543","src/lib.rs":"4dd716dbe701acc5644b25d84503d53ea8bc8fb9bf81914b2183526edc63826c","src/windows.rs":"44272f13079fbaed8c16426950c24d9de94d81eba0636138d8e44346eccc0acd"},"package":"e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648"}
 | 
					 | 
				
			||||||
							
								
								
									
										76
									
								
								vendor/anstyle-query/Cargo.lock
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										76
									
								
								vendor/anstyle-query/Cargo.lock
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,76 +0,0 @@
 | 
				
			|||||||
# This file is automatically @generated by Cargo.
 | 
					 | 
				
			||||||
# It is not intended for manual editing.
 | 
					 | 
				
			||||||
version = 3
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "anstyle-query"
 | 
					 | 
				
			||||||
version = "1.0.2"
 | 
					 | 
				
			||||||
dependencies = [
 | 
					 | 
				
			||||||
 "windows-sys",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[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"
 | 
					 | 
				
			||||||
							
								
								
									
										80
									
								
								vendor/anstyle-query/Cargo.toml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										80
									
								
								vendor/anstyle-query/Cargo.toml
									
									
									
									
										vendored
									
									
								
							@@ -1,80 +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.70.0"
 | 
					 | 
				
			||||||
name = "anstyle-query"
 | 
					 | 
				
			||||||
version = "1.0.2"
 | 
					 | 
				
			||||||
include = [
 | 
					 | 
				
			||||||
    "build.rs",
 | 
					 | 
				
			||||||
    "src/**/*",
 | 
					 | 
				
			||||||
    "Cargo.toml",
 | 
					 | 
				
			||||||
    "Cargo.lock",
 | 
					 | 
				
			||||||
    "LICENSE*",
 | 
					 | 
				
			||||||
    "README.md",
 | 
					 | 
				
			||||||
    "benches/**/*",
 | 
					 | 
				
			||||||
    "examples/**/*",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
description = "Look up colored console capabilities"
 | 
					 | 
				
			||||||
readme = "README.md"
 | 
					 | 
				
			||||||
keywords = [
 | 
					 | 
				
			||||||
    "cli",
 | 
					 | 
				
			||||||
    "color",
 | 
					 | 
				
			||||||
    "no-std",
 | 
					 | 
				
			||||||
    "terminal",
 | 
					 | 
				
			||||||
    "ansi",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
categories = ["command-line-interface"]
 | 
					 | 
				
			||||||
license = "MIT OR Apache-2.0"
 | 
					 | 
				
			||||||
repository = "https://github.com/rust-cli/anstyle"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package.metadata.release.pre-release-replacements]]
 | 
					 | 
				
			||||||
file = "CHANGELOG.md"
 | 
					 | 
				
			||||||
min = 1
 | 
					 | 
				
			||||||
replace = "{{version}}"
 | 
					 | 
				
			||||||
search = "Unreleased"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package.metadata.release.pre-release-replacements]]
 | 
					 | 
				
			||||||
exactly = 1
 | 
					 | 
				
			||||||
file = "CHANGELOG.md"
 | 
					 | 
				
			||||||
replace = "...{{tag_name}}"
 | 
					 | 
				
			||||||
search = '\.\.\.HEAD'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package.metadata.release.pre-release-replacements]]
 | 
					 | 
				
			||||||
file = "CHANGELOG.md"
 | 
					 | 
				
			||||||
min = 1
 | 
					 | 
				
			||||||
replace = "{{date}}"
 | 
					 | 
				
			||||||
search = "ReleaseDate"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package.metadata.release.pre-release-replacements]]
 | 
					 | 
				
			||||||
exactly = 1
 | 
					 | 
				
			||||||
file = "CHANGELOG.md"
 | 
					 | 
				
			||||||
replace = """
 | 
					 | 
				
			||||||
<!-- next-header -->
 | 
					 | 
				
			||||||
## [Unreleased] - ReleaseDate
 | 
					 | 
				
			||||||
"""
 | 
					 | 
				
			||||||
search = "<!-- next-header -->"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package.metadata.release.pre-release-replacements]]
 | 
					 | 
				
			||||||
exactly = 1
 | 
					 | 
				
			||||||
file = "CHANGELOG.md"
 | 
					 | 
				
			||||||
replace = """
 | 
					 | 
				
			||||||
<!-- next-url -->
 | 
					 | 
				
			||||||
[Unreleased]: https://github.com/rust-cli/anstyle/compare/{{tag_name}}...HEAD"""
 | 
					 | 
				
			||||||
search = "<!-- next-url -->"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[target."cfg(windows)".dependencies.windows-sys]
 | 
					 | 
				
			||||||
version = "0.52.0"
 | 
					 | 
				
			||||||
features = [
 | 
					 | 
				
			||||||
    "Win32_System_Console",
 | 
					 | 
				
			||||||
    "Win32_Foundation",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
							
								
								
									
										202
									
								
								vendor/anstyle-query/LICENSE-APACHE
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										202
									
								
								vendor/anstyle-query/LICENSE-APACHE
									
									
									
									
										vendored
									
									
								
							@@ -1,202 +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
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   APPENDIX: How to apply the Apache License to your work.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      To apply the Apache License to your work, attach the following
 | 
					 | 
				
			||||||
      boilerplate notice, with the fields enclosed by brackets "{}"
 | 
					 | 
				
			||||||
      replaced with your own identifying information. (Don't include
 | 
					 | 
				
			||||||
      the brackets!)  The text should be enclosed in the appropriate
 | 
					 | 
				
			||||||
      comment syntax for the file format. We also recommend that a
 | 
					 | 
				
			||||||
      file or class name and description of purpose be included on the
 | 
					 | 
				
			||||||
      same "printed page" as the copyright notice for easier
 | 
					 | 
				
			||||||
      identification within third-party archives.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   Copyright {yyyy} {name of copyright owner}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   Licensed under the Apache License, Version 2.0 (the "License");
 | 
					 | 
				
			||||||
   you may not use this file except in compliance with the License.
 | 
					 | 
				
			||||||
   You may obtain a copy of the License at
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
       http://www.apache.org/licenses/LICENSE-2.0
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   Unless required by applicable law or agreed to in writing, software
 | 
					 | 
				
			||||||
   distributed under the License is distributed on an "AS IS" BASIS,
 | 
					 | 
				
			||||||
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
					 | 
				
			||||||
   See the License for the specific language governing permissions and
 | 
					 | 
				
			||||||
   limitations under the License.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
							
								
								
									
										19
									
								
								vendor/anstyle-query/LICENSE-MIT
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										19
									
								
								vendor/anstyle-query/LICENSE-MIT
									
									
									
									
										vendored
									
									
								
							@@ -1,19 +0,0 @@
 | 
				
			|||||||
Copyright (c) Individual 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.
 | 
					 | 
				
			||||||
							
								
								
									
										15
									
								
								vendor/anstyle-query/README.md
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										15
									
								
								vendor/anstyle-query/README.md
									
									
									
									
										vendored
									
									
								
							@@ -1,15 +0,0 @@
 | 
				
			|||||||
# anstyle-query
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
> **Low level terminal capability lookups**
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[][Documentation]
 | 
					 | 
				
			||||||

 | 
					 | 
				
			||||||
[](https://crates.io/crates/anstyle-query)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## [Contribute](../../CONTRIBUTING.md)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## License
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Dual-licensed under [MIT](../../LICENSE-MIT) or [Apache 2.0](../../LICENSE-APACHE)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[Documentation]: https://docs.rs/anstyle-query
 | 
					 | 
				
			||||||
							
								
								
									
										24
									
								
								vendor/anstyle-query/examples/query.rs
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										24
									
								
								vendor/anstyle-query/examples/query.rs
									
									
									
									
										vendored
									
									
								
							@@ -1,24 +0,0 @@
 | 
				
			|||||||
fn main() {
 | 
					 | 
				
			||||||
    println!("clicolor: {:?}", anstyle_query::clicolor());
 | 
					 | 
				
			||||||
    println!("clicolor_force: {}", anstyle_query::clicolor_force());
 | 
					 | 
				
			||||||
    println!("no_color: {}", anstyle_query::no_color());
 | 
					 | 
				
			||||||
    println!(
 | 
					 | 
				
			||||||
        "term_supports_ansi_color: {}",
 | 
					 | 
				
			||||||
        anstyle_query::term_supports_ansi_color()
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
    println!(
 | 
					 | 
				
			||||||
        "term_supports_color: {}",
 | 
					 | 
				
			||||||
        anstyle_query::term_supports_color()
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
    println!("truecolor: {}", anstyle_query::truecolor());
 | 
					 | 
				
			||||||
    println!(
 | 
					 | 
				
			||||||
        "enable_ansi_colors: {:?}",
 | 
					 | 
				
			||||||
        anstyle_query::windows::enable_ansi_colors()
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
    #[cfg(windows)]
 | 
					 | 
				
			||||||
    println!(
 | 
					 | 
				
			||||||
        "  enable_virtual_terminal_processing: {:?}",
 | 
					 | 
				
			||||||
        anstyle_query::windows::enable_virtual_terminal_processing()
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
    println!("is_ci: {:?}", anstyle_query::is_ci());
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										134
									
								
								vendor/anstyle-query/src/lib.rs
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										134
									
								
								vendor/anstyle-query/src/lib.rs
									
									
									
									
										vendored
									
									
								
							@@ -1,134 +0,0 @@
 | 
				
			|||||||
pub mod windows;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// Check [CLICOLOR] status
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// - When `true`, ANSI colors are supported and should be used when the program isn't piped,
 | 
					 | 
				
			||||||
///   similar to [`term_supports_color`]
 | 
					 | 
				
			||||||
/// - When `false`, don’t output ANSI color escape codes, similar to [`no_color`]
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// See also:
 | 
					 | 
				
			||||||
/// - [terminfo](https://crates.io/crates/terminfo) or [term](https://crates.io/crates/term) for
 | 
					 | 
				
			||||||
///   checking termcaps
 | 
					 | 
				
			||||||
/// - [termbg](https://crates.io/crates/termbg) for detecting background color
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// [CLICOLOR]: https://bixense.com/clicolors/
 | 
					 | 
				
			||||||
#[inline]
 | 
					 | 
				
			||||||
pub fn clicolor() -> Option<bool> {
 | 
					 | 
				
			||||||
    let value = std::env::var_os("CLICOLOR")?;
 | 
					 | 
				
			||||||
    Some(value != "0")
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// Check [CLICOLOR_FORCE] status
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// ANSI colors should be enabled no matter what.
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// [CLICOLOR_FORCE]: https://bixense.com/clicolors/
 | 
					 | 
				
			||||||
#[inline]
 | 
					 | 
				
			||||||
pub fn clicolor_force() -> bool {
 | 
					 | 
				
			||||||
    let value = std::env::var_os("CLICOLOR_FORCE");
 | 
					 | 
				
			||||||
    value
 | 
					 | 
				
			||||||
        .as_deref()
 | 
					 | 
				
			||||||
        .unwrap_or_else(|| std::ffi::OsStr::new("0"))
 | 
					 | 
				
			||||||
        != "0"
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// Check [NO_COLOR] status
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// When `true`, should prevent the addition of ANSI color.
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// User-level configuration files and per-instance command-line arguments should override
 | 
					 | 
				
			||||||
/// [NO_COLOR]. A user should be able to export `$NO_COLOR` in their shell configuration file as a
 | 
					 | 
				
			||||||
/// default, but configure a specific program in its configuration file to specifically enable
 | 
					 | 
				
			||||||
/// color.
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// [NO_COLOR]: https://no-color.org/
 | 
					 | 
				
			||||||
#[inline]
 | 
					 | 
				
			||||||
pub fn no_color() -> bool {
 | 
					 | 
				
			||||||
    let value = std::env::var_os("NO_COLOR");
 | 
					 | 
				
			||||||
    value.as_deref().unwrap_or_else(|| std::ffi::OsStr::new("")) != ""
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// Check `TERM` for color support
 | 
					 | 
				
			||||||
#[inline]
 | 
					 | 
				
			||||||
#[cfg(not(windows))]
 | 
					 | 
				
			||||||
pub fn term_supports_color() -> bool {
 | 
					 | 
				
			||||||
    match std::env::var_os("TERM") {
 | 
					 | 
				
			||||||
        // If TERM isn't set, then we are in a weird environment that
 | 
					 | 
				
			||||||
        // probably doesn't support colors.
 | 
					 | 
				
			||||||
        None => return false,
 | 
					 | 
				
			||||||
        Some(k) => {
 | 
					 | 
				
			||||||
            if k == "dumb" {
 | 
					 | 
				
			||||||
                return false;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    true
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// Check `TERM` for color support
 | 
					 | 
				
			||||||
#[inline]
 | 
					 | 
				
			||||||
#[cfg(windows)]
 | 
					 | 
				
			||||||
pub fn term_supports_color() -> bool {
 | 
					 | 
				
			||||||
    // On Windows, if TERM isn't set, then we shouldn't automatically
 | 
					 | 
				
			||||||
    // assume that colors aren't allowed. This is unlike Unix environments
 | 
					 | 
				
			||||||
    // where TERM is more rigorously set.
 | 
					 | 
				
			||||||
    if let Some(k) = std::env::var_os("TERM") {
 | 
					 | 
				
			||||||
        if k == "dumb" {
 | 
					 | 
				
			||||||
            return false;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    true
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// Check `TERM` for ANSI color support
 | 
					 | 
				
			||||||
#[inline]
 | 
					 | 
				
			||||||
#[cfg(not(windows))]
 | 
					 | 
				
			||||||
pub fn term_supports_ansi_color() -> bool {
 | 
					 | 
				
			||||||
    term_supports_color()
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// Check `TERM` for ANSI color support
 | 
					 | 
				
			||||||
#[inline]
 | 
					 | 
				
			||||||
#[cfg(windows)]
 | 
					 | 
				
			||||||
pub fn term_supports_ansi_color() -> bool {
 | 
					 | 
				
			||||||
    match std::env::var_os("TERM") {
 | 
					 | 
				
			||||||
        // If TERM isn't set, then we are in a weird environment that
 | 
					 | 
				
			||||||
        // probably doesn't support ansi.
 | 
					 | 
				
			||||||
        None => return false,
 | 
					 | 
				
			||||||
        Some(k) => {
 | 
					 | 
				
			||||||
            // cygwin doesn't seem to support ANSI escape sequences
 | 
					 | 
				
			||||||
            // and instead has its own variety. However, the Windows
 | 
					 | 
				
			||||||
            // console API may be available.
 | 
					 | 
				
			||||||
            if k == "dumb" || k == "cygwin" {
 | 
					 | 
				
			||||||
                return false;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    true
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// Check [COLORTERM] for truecolor support
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// [COLORTERM]: https://github.com/termstandard/colors
 | 
					 | 
				
			||||||
#[inline]
 | 
					 | 
				
			||||||
pub fn truecolor() -> bool {
 | 
					 | 
				
			||||||
    let value = std::env::var_os("COLORTERM");
 | 
					 | 
				
			||||||
    let value = value.as_deref().unwrap_or_default();
 | 
					 | 
				
			||||||
    value == "truecolor" || value == "24bit"
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// Report whether this is running in CI
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// CI is a common environment where, despite being piped, ansi color codes are supported
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// This is not as exhaustive as you'd find in a crate like `is_ci` but it should work in enough
 | 
					 | 
				
			||||||
/// cases.
 | 
					 | 
				
			||||||
#[inline]
 | 
					 | 
				
			||||||
pub fn is_ci() -> bool {
 | 
					 | 
				
			||||||
    // Assuming its CI based on presence because who would be setting `CI=false`?
 | 
					 | 
				
			||||||
    //
 | 
					 | 
				
			||||||
    // This makes it easier to all of the potential values when considering our known values:
 | 
					 | 
				
			||||||
    // - Gitlab and Github set it to `true`
 | 
					 | 
				
			||||||
    // - Woodpecker sets it to `woodpecker`
 | 
					 | 
				
			||||||
    std::env::var_os("CI").is_some()
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										78
									
								
								vendor/anstyle-query/src/windows.rs
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										78
									
								
								vendor/anstyle-query/src/windows.rs
									
									
									
									
										vendored
									
									
								
							@@ -1,78 +0,0 @@
 | 
				
			|||||||
//! Windows-specific style queries
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[cfg(windows)]
 | 
					 | 
				
			||||||
mod windows_console {
 | 
					 | 
				
			||||||
    use std::os::windows::io::AsRawHandle;
 | 
					 | 
				
			||||||
    use std::os::windows::io::RawHandle;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    use windows_sys::Win32::System::Console::CONSOLE_MODE;
 | 
					 | 
				
			||||||
    use windows_sys::Win32::System::Console::ENABLE_VIRTUAL_TERMINAL_PROCESSING;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    fn enable_vt(handle: RawHandle) -> std::io::Result<()> {
 | 
					 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
            let handle = std::mem::transmute(handle);
 | 
					 | 
				
			||||||
            if handle == 0 {
 | 
					 | 
				
			||||||
                return Err(std::io::Error::new(
 | 
					 | 
				
			||||||
                    std::io::ErrorKind::BrokenPipe,
 | 
					 | 
				
			||||||
                    "console is detached",
 | 
					 | 
				
			||||||
                ));
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            let mut dwmode: CONSOLE_MODE = 0;
 | 
					 | 
				
			||||||
            if windows_sys::Win32::System::Console::GetConsoleMode(handle, &mut dwmode) == 0 {
 | 
					 | 
				
			||||||
                return Err(std::io::Error::last_os_error());
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            dwmode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
 | 
					 | 
				
			||||||
            if windows_sys::Win32::System::Console::SetConsoleMode(handle, dwmode) == 0 {
 | 
					 | 
				
			||||||
                return Err(std::io::Error::last_os_error());
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            Ok(())
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    pub fn enable_virtual_terminal_processing() -> std::io::Result<()> {
 | 
					 | 
				
			||||||
        let stdout = std::io::stdout();
 | 
					 | 
				
			||||||
        let stdout_handle = stdout.as_raw_handle();
 | 
					 | 
				
			||||||
        let stderr = std::io::stderr();
 | 
					 | 
				
			||||||
        let stderr_handle = stderr.as_raw_handle();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        enable_vt(stdout_handle)?;
 | 
					 | 
				
			||||||
        if stdout_handle != stderr_handle {
 | 
					 | 
				
			||||||
            enable_vt(stderr_handle)?;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Ok(())
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub(crate) fn enable_ansi_colors() -> Option<bool> {
 | 
					 | 
				
			||||||
        Some(
 | 
					 | 
				
			||||||
            enable_virtual_terminal_processing()
 | 
					 | 
				
			||||||
                .map(|_| true)
 | 
					 | 
				
			||||||
                .unwrap_or(false),
 | 
					 | 
				
			||||||
        )
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[cfg(not(windows))]
 | 
					 | 
				
			||||||
mod windows_console {
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub(crate) fn enable_ansi_colors() -> Option<bool> {
 | 
					 | 
				
			||||||
        None
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// Enable ANSI escape codes (ENABLE_VIRTUAL_TERMINAL_PROCESSING)
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// For non-windows systems, returns `None`
 | 
					 | 
				
			||||||
pub fn enable_ansi_colors() -> Option<bool> {
 | 
					 | 
				
			||||||
    windows_console::enable_ansi_colors()
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// Raw ENABLE_VIRTUAL_TERMINAL_PROCESSING on stdout/stderr
 | 
					 | 
				
			||||||
#[cfg(windows)]
 | 
					 | 
				
			||||||
pub fn enable_virtual_terminal_processing() -> std::io::Result<()> {
 | 
					 | 
				
			||||||
    windows_console::enable_virtual_terminal_processing()
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										1
									
								
								vendor/anstyle-wincon/.cargo-checksum.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								vendor/anstyle-wincon/.cargo-checksum.json
									
									
									
									
										vendored
									
									
								
							@@ -1 +0,0 @@
 | 
				
			|||||||
{"files":{"Cargo.lock":"3cc0f5705ebb0bb446d6f88f71832d2db70bee8c78a545343a755e2a969212a3","Cargo.toml":"5a090b294286cb22bed379e818f8657da219f62fe0e1e8eb21e91aaaf875c139","LICENSE-APACHE":"c6596eb7be8581c18be736c846fb9173b69eccf6ef94c5135893ec56bd92ba08","LICENSE-MIT":"73b0d84e4b954ce904a00043379767ae2a5f8d4f40564639cee230f639fe4dae","README.md":"513a578c6c2ea39a811e2038358e512cbc0c709e3a7c18303871ec2c52ebbeec","examples/dump-wincon.rs":"bd0ffadd14eed711fc74d64caff5ce98bb5c5b3f0b313b54ac759b5a6c6a289b","examples/set-wincon.rs":"b8bc444537449bf334a1e26dd010986c16cb260567f87ae9597fc869c936fe6a","src/ansi.rs":"1b0166d064fe261bc012acca2f3ff442703a774e5fa4b8e96f63dce87b7e73d1","src/lib.rs":"4b4415a0684901bab712dbe94aec960792760aa1db5505adacfdc43db2cd93a7","src/stream.rs":"afdbd6e314127bd412e81894a857cb95fe3140e2b994e17e4e5580ef113a4159","src/windows.rs":"e4aeae1b32f6348b6b9c54e0cd54d9a3c08c6f250c7313fcaa59e3d8a8f51c97"},"package":"1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7"}
 | 
					 | 
				
			||||||
							
								
								
									
										90
									
								
								vendor/anstyle-wincon/Cargo.lock
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										90
									
								
								vendor/anstyle-wincon/Cargo.lock
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,90 +0,0 @@
 | 
				
			|||||||
# This file is automatically @generated by Cargo.
 | 
					 | 
				
			||||||
# It is not intended for manual editing.
 | 
					 | 
				
			||||||
version = 3
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "anstyle"
 | 
					 | 
				
			||||||
version = "1.0.0"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "41ed9a86bf92ae6580e0a31281f65a1b1d867c0cc68d5346e2ae128dddfa6a7d"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "anstyle-wincon"
 | 
					 | 
				
			||||||
version = "3.0.2"
 | 
					 | 
				
			||||||
dependencies = [
 | 
					 | 
				
			||||||
 "anstyle",
 | 
					 | 
				
			||||||
 "lexopt",
 | 
					 | 
				
			||||||
 "windows-sys",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "lexopt"
 | 
					 | 
				
			||||||
version = "0.3.0"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "baff4b617f7df3d896f97fe922b64817f6cd9a756bb81d40f8883f2f66dcb401"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[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"
 | 
					 | 
				
			||||||
							
								
								
									
										94
									
								
								vendor/anstyle-wincon/Cargo.toml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										94
									
								
								vendor/anstyle-wincon/Cargo.toml
									
									
									
									
										vendored
									
									
								
							@@ -1,94 +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.70.0"
 | 
					 | 
				
			||||||
name = "anstyle-wincon"
 | 
					 | 
				
			||||||
version = "3.0.2"
 | 
					 | 
				
			||||||
include = [
 | 
					 | 
				
			||||||
    "build.rs",
 | 
					 | 
				
			||||||
    "src/**/*",
 | 
					 | 
				
			||||||
    "Cargo.toml",
 | 
					 | 
				
			||||||
    "Cargo.lock",
 | 
					 | 
				
			||||||
    "LICENSE*",
 | 
					 | 
				
			||||||
    "README.md",
 | 
					 | 
				
			||||||
    "benches/**/*",
 | 
					 | 
				
			||||||
    "examples/**/*",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
description = "Styling legacy Windows terminals"
 | 
					 | 
				
			||||||
homepage = "https://github.com/rust-cli/anstyle"
 | 
					 | 
				
			||||||
readme = "README.md"
 | 
					 | 
				
			||||||
keywords = [
 | 
					 | 
				
			||||||
    "ansi",
 | 
					 | 
				
			||||||
    "terminal",
 | 
					 | 
				
			||||||
    "color",
 | 
					 | 
				
			||||||
    "windows",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
categories = ["command-line-interface"]
 | 
					 | 
				
			||||||
license = "MIT OR Apache-2.0"
 | 
					 | 
				
			||||||
repository = "https://github.com/rust-cli/anstyle.git"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[package.metadata.docs.rs]
 | 
					 | 
				
			||||||
features = []
 | 
					 | 
				
			||||||
rustdoc-args = [
 | 
					 | 
				
			||||||
    "--cfg",
 | 
					 | 
				
			||||||
    "docsrs",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
targets = ["x86_64-pc-windows-msvc"]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package.metadata.release.pre-release-replacements]]
 | 
					 | 
				
			||||||
file = "CHANGELOG.md"
 | 
					 | 
				
			||||||
min = 1
 | 
					 | 
				
			||||||
replace = "{{version}}"
 | 
					 | 
				
			||||||
search = "Unreleased"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package.metadata.release.pre-release-replacements]]
 | 
					 | 
				
			||||||
exactly = 1
 | 
					 | 
				
			||||||
file = "CHANGELOG.md"
 | 
					 | 
				
			||||||
replace = "...{{tag_name}}"
 | 
					 | 
				
			||||||
search = '\.\.\.HEAD'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package.metadata.release.pre-release-replacements]]
 | 
					 | 
				
			||||||
file = "CHANGELOG.md"
 | 
					 | 
				
			||||||
min = 1
 | 
					 | 
				
			||||||
replace = "{{date}}"
 | 
					 | 
				
			||||||
search = "ReleaseDate"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package.metadata.release.pre-release-replacements]]
 | 
					 | 
				
			||||||
exactly = 1
 | 
					 | 
				
			||||||
file = "CHANGELOG.md"
 | 
					 | 
				
			||||||
replace = """
 | 
					 | 
				
			||||||
<!-- next-header -->
 | 
					 | 
				
			||||||
## [Unreleased] - ReleaseDate
 | 
					 | 
				
			||||||
"""
 | 
					 | 
				
			||||||
search = "<!-- next-header -->"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package.metadata.release.pre-release-replacements]]
 | 
					 | 
				
			||||||
exactly = 1
 | 
					 | 
				
			||||||
file = "CHANGELOG.md"
 | 
					 | 
				
			||||||
replace = """
 | 
					 | 
				
			||||||
<!-- next-url -->
 | 
					 | 
				
			||||||
[Unreleased]: https://github.com/rust-cli/anstyle/compare/{{tag_name}}...HEAD"""
 | 
					 | 
				
			||||||
search = "<!-- next-url -->"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[dependencies.anstyle]
 | 
					 | 
				
			||||||
version = "1.0.0"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[dev-dependencies.lexopt]
 | 
					 | 
				
			||||||
version = "0.3.0"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[target."cfg(windows)".dependencies.windows-sys]
 | 
					 | 
				
			||||||
version = "0.52.0"
 | 
					 | 
				
			||||||
features = [
 | 
					 | 
				
			||||||
    "Win32_System_Console",
 | 
					 | 
				
			||||||
    "Win32_Foundation",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
							
								
								
									
										202
									
								
								vendor/anstyle-wincon/LICENSE-APACHE
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										202
									
								
								vendor/anstyle-wincon/LICENSE-APACHE
									
									
									
									
										vendored
									
									
								
							@@ -1,202 +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
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   APPENDIX: How to apply the Apache License to your work.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      To apply the Apache License to your work, attach the following
 | 
					 | 
				
			||||||
      boilerplate notice, with the fields enclosed by brackets "{}"
 | 
					 | 
				
			||||||
      replaced with your own identifying information. (Don't include
 | 
					 | 
				
			||||||
      the brackets!)  The text should be enclosed in the appropriate
 | 
					 | 
				
			||||||
      comment syntax for the file format. We also recommend that a
 | 
					 | 
				
			||||||
      file or class name and description of purpose be included on the
 | 
					 | 
				
			||||||
      same "printed page" as the copyright notice for easier
 | 
					 | 
				
			||||||
      identification within third-party archives.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   Copyright {yyyy} {name of copyright owner}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   Licensed under the Apache License, Version 2.0 (the "License");
 | 
					 | 
				
			||||||
   you may not use this file except in compliance with the License.
 | 
					 | 
				
			||||||
   You may obtain a copy of the License at
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
       http://www.apache.org/licenses/LICENSE-2.0
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   Unless required by applicable law or agreed to in writing, software
 | 
					 | 
				
			||||||
   distributed under the License is distributed on an "AS IS" BASIS,
 | 
					 | 
				
			||||||
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
					 | 
				
			||||||
   See the License for the specific language governing permissions and
 | 
					 | 
				
			||||||
   limitations under the License.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
							
								
								
									
										19
									
								
								vendor/anstyle-wincon/LICENSE-MIT
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										19
									
								
								vendor/anstyle-wincon/LICENSE-MIT
									
									
									
									
										vendored
									
									
								
							@@ -1,19 +0,0 @@
 | 
				
			|||||||
Copyright (c) 2015 Josh Triplett, 2022 The rust-cli Developers
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
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.
 | 
					 | 
				
			||||||
							
								
								
									
										30
									
								
								vendor/anstyle-wincon/README.md
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										30
									
								
								vendor/anstyle-wincon/README.md
									
									
									
									
										vendored
									
									
								
							@@ -1,30 +0,0 @@
 | 
				
			|||||||
# anstyle-wincon
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
> Styling legacy Windows terminals
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[][Documentation]
 | 
					 | 
				
			||||||

 | 
					 | 
				
			||||||
[](https://crates.io/crates/anstyle-wincon)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## License
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Licensed under either of
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
 | 
					 | 
				
			||||||
 * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
at your option.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### Contribution
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Unless you explicitly state otherwise, any contribution intentionally
 | 
					 | 
				
			||||||
submitted for inclusion in the work by you, as defined in the Apache-2.0
 | 
					 | 
				
			||||||
license, shall be dual licensed as above, without any additional terms or
 | 
					 | 
				
			||||||
conditions.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### Special Thanks
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[burntsushi](https://github.com/burntsushi) for [termcolor](https://github.com/burntsushi/termcolor) as I don't know Windows either :)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[Crates.io]: https://crates.io/crates/anstyle-wincon
 | 
					 | 
				
			||||||
[Documentation]: https://docs.rs/anstyle-wincon
 | 
					 | 
				
			||||||
							
								
								
									
										139
									
								
								vendor/anstyle-wincon/examples/dump-wincon.rs
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										139
									
								
								vendor/anstyle-wincon/examples/dump-wincon.rs
									
									
									
									
										vendored
									
									
								
							@@ -1,139 +0,0 @@
 | 
				
			|||||||
use anstyle_wincon::WinconStream as _;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
fn main() -> Result<(), lexopt::Error> {
 | 
					 | 
				
			||||||
    let args = Args::parse()?;
 | 
					 | 
				
			||||||
    let stdout = std::io::stdout();
 | 
					 | 
				
			||||||
    let mut stdout = stdout.lock();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    for fixed in 0..16 {
 | 
					 | 
				
			||||||
        let style = style(fixed, args.layer, args.effects);
 | 
					 | 
				
			||||||
        let _ = print_number(&mut stdout, fixed, style);
 | 
					 | 
				
			||||||
        if fixed == 7 || fixed == 15 {
 | 
					 | 
				
			||||||
            let _ = stdout.write_colored(None, None, &b"\n"[..]);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    for r in 0..6 {
 | 
					 | 
				
			||||||
        let _ = stdout.write_colored(None, None, &b"\n"[..]);
 | 
					 | 
				
			||||||
        for g in 0..6 {
 | 
					 | 
				
			||||||
            for b in 0..6 {
 | 
					 | 
				
			||||||
                let fixed = r * 36 + g * 6 + b + 16;
 | 
					 | 
				
			||||||
                let style = style(fixed, args.layer, args.effects);
 | 
					 | 
				
			||||||
                let _ = print_number(&mut stdout, fixed, style);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            let _ = stdout.write_colored(None, None, &b"\n"[..]);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    for c in 0..24 {
 | 
					 | 
				
			||||||
        if 0 == c % 8 {
 | 
					 | 
				
			||||||
            let _ = stdout.write_colored(None, None, &b"\n"[..]);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        let fixed = 232 + c;
 | 
					 | 
				
			||||||
        let style = style(fixed, args.layer, args.effects);
 | 
					 | 
				
			||||||
        let _ = print_number(&mut stdout, fixed, style);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Ok(())
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
fn style(fixed: u8, layer: Layer, effects: anstyle::Effects) -> anstyle::Style {
 | 
					 | 
				
			||||||
    let color = anstyle::Ansi256Color(fixed).into();
 | 
					 | 
				
			||||||
    (match layer {
 | 
					 | 
				
			||||||
        Layer::Fg => anstyle::Style::new().fg_color(Some(color)),
 | 
					 | 
				
			||||||
        Layer::Bg => anstyle::Style::new().bg_color(Some(color)),
 | 
					 | 
				
			||||||
        Layer::Underline => anstyle::Style::new().underline_color(Some(color)),
 | 
					 | 
				
			||||||
    }) | effects
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
fn print_number(
 | 
					 | 
				
			||||||
    stdout: &mut std::io::StdoutLock<'static>,
 | 
					 | 
				
			||||||
    fixed: u8,
 | 
					 | 
				
			||||||
    style: anstyle::Style,
 | 
					 | 
				
			||||||
) -> std::io::Result<()> {
 | 
					 | 
				
			||||||
    let fg = style.get_fg_color().and_then(|c| match c {
 | 
					 | 
				
			||||||
        anstyle::Color::Ansi(c) => Some(c),
 | 
					 | 
				
			||||||
        anstyle::Color::Ansi256(c) => c.into_ansi(),
 | 
					 | 
				
			||||||
        anstyle::Color::Rgb(_) => None,
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
    let bg = style.get_bg_color().and_then(|c| match c {
 | 
					 | 
				
			||||||
        anstyle::Color::Ansi(c) => Some(c),
 | 
					 | 
				
			||||||
        anstyle::Color::Ansi256(c) => c.into_ansi(),
 | 
					 | 
				
			||||||
        anstyle::Color::Rgb(_) => None,
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    stdout
 | 
					 | 
				
			||||||
        .write_colored(fg, bg, format!("{:>4}", fixed).as_bytes())
 | 
					 | 
				
			||||||
        .map(|_| ())
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[derive(Default)]
 | 
					 | 
				
			||||||
struct Args {
 | 
					 | 
				
			||||||
    effects: anstyle::Effects,
 | 
					 | 
				
			||||||
    layer: Layer,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[derive(Copy, Clone, Default)]
 | 
					 | 
				
			||||||
enum Layer {
 | 
					 | 
				
			||||||
    #[default]
 | 
					 | 
				
			||||||
    Fg,
 | 
					 | 
				
			||||||
    Bg,
 | 
					 | 
				
			||||||
    Underline,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl Args {
 | 
					 | 
				
			||||||
    fn parse() -> Result<Self, lexopt::Error> {
 | 
					 | 
				
			||||||
        use lexopt::prelude::*;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        let mut res = Args::default();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        let mut args = lexopt::Parser::from_env();
 | 
					 | 
				
			||||||
        while let Some(arg) = args.next()? {
 | 
					 | 
				
			||||||
            match arg {
 | 
					 | 
				
			||||||
                Long("layer") => {
 | 
					 | 
				
			||||||
                    res.layer = args.value()?.parse_with(|s| match s {
 | 
					 | 
				
			||||||
                        "fg" => Ok(Layer::Fg),
 | 
					 | 
				
			||||||
                        "bg" => Ok(Layer::Bg),
 | 
					 | 
				
			||||||
                        "underline" => Ok(Layer::Underline),
 | 
					 | 
				
			||||||
                        _ => Err("expected values fg, bg, underline"),
 | 
					 | 
				
			||||||
                    })?;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                Long("effect") => {
 | 
					 | 
				
			||||||
                    const EFFECTS: [(&str, anstyle::Effects); 12] = [
 | 
					 | 
				
			||||||
                        ("bold", anstyle::Effects::BOLD),
 | 
					 | 
				
			||||||
                        ("dimmed", anstyle::Effects::DIMMED),
 | 
					 | 
				
			||||||
                        ("italic", anstyle::Effects::ITALIC),
 | 
					 | 
				
			||||||
                        ("underline", anstyle::Effects::UNDERLINE),
 | 
					 | 
				
			||||||
                        ("double_underline", anstyle::Effects::UNDERLINE),
 | 
					 | 
				
			||||||
                        ("curly_underline", anstyle::Effects::CURLY_UNDERLINE),
 | 
					 | 
				
			||||||
                        ("dotted_underline", anstyle::Effects::DOTTED_UNDERLINE),
 | 
					 | 
				
			||||||
                        ("dashed_underline", anstyle::Effects::DASHED_UNDERLINE),
 | 
					 | 
				
			||||||
                        ("blink", anstyle::Effects::BLINK),
 | 
					 | 
				
			||||||
                        ("invert", anstyle::Effects::INVERT),
 | 
					 | 
				
			||||||
                        ("hidden", anstyle::Effects::HIDDEN),
 | 
					 | 
				
			||||||
                        ("strikethrough", anstyle::Effects::STRIKETHROUGH),
 | 
					 | 
				
			||||||
                    ];
 | 
					 | 
				
			||||||
                    let effect = args.value()?.parse_with(|s| {
 | 
					 | 
				
			||||||
                        EFFECTS
 | 
					 | 
				
			||||||
                            .into_iter()
 | 
					 | 
				
			||||||
                            .find(|(name, _)| *name == s)
 | 
					 | 
				
			||||||
                            .map(|(_, effect)| effect)
 | 
					 | 
				
			||||||
                            .ok_or_else(|| {
 | 
					 | 
				
			||||||
                                format!(
 | 
					 | 
				
			||||||
                                    "expected one of {}",
 | 
					 | 
				
			||||||
                                    EFFECTS
 | 
					 | 
				
			||||||
                                        .into_iter()
 | 
					 | 
				
			||||||
                                        .map(|(n, _)| n)
 | 
					 | 
				
			||||||
                                        .collect::<Vec<_>>()
 | 
					 | 
				
			||||||
                                        .join(", ")
 | 
					 | 
				
			||||||
                                )
 | 
					 | 
				
			||||||
                            })
 | 
					 | 
				
			||||||
                    })?;
 | 
					 | 
				
			||||||
                    res.effects = res.effects.insert(effect);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                _ => return Err(arg.unexpected()),
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        Ok(res)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										58
									
								
								vendor/anstyle-wincon/examples/set-wincon.rs
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										58
									
								
								vendor/anstyle-wincon/examples/set-wincon.rs
									
									
									
									
										vendored
									
									
								
							@@ -1,58 +0,0 @@
 | 
				
			|||||||
#![cfg_attr(not(windows), allow(dead_code))]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[cfg(not(windows))]
 | 
					 | 
				
			||||||
fn main() {
 | 
					 | 
				
			||||||
    panic!("unsupported");
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[cfg(windows)]
 | 
					 | 
				
			||||||
fn main() -> Result<(), lexopt::Error> {
 | 
					 | 
				
			||||||
    use anstyle_wincon::WinconStream as _;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let args = Args::parse()?;
 | 
					 | 
				
			||||||
    let stdout = std::io::stdout();
 | 
					 | 
				
			||||||
    let mut stdout = stdout.lock();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let fg = args.fg.and_then(|c| c.into_ansi());
 | 
					 | 
				
			||||||
    let bg = args.bg.and_then(|c| c.into_ansi());
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let _ = stdout.write_colored(fg, bg, "".as_bytes());
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    std::mem::forget(stdout);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Ok(())
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[derive(Default)]
 | 
					 | 
				
			||||||
struct Args {
 | 
					 | 
				
			||||||
    fg: Option<anstyle::Ansi256Color>,
 | 
					 | 
				
			||||||
    bg: Option<anstyle::Ansi256Color>,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl Args {
 | 
					 | 
				
			||||||
    fn parse() -> Result<Self, lexopt::Error> {
 | 
					 | 
				
			||||||
        use lexopt::prelude::*;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        let mut res = Args::default();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        let mut args = lexopt::Parser::from_env();
 | 
					 | 
				
			||||||
        while let Some(arg) = args.next()? {
 | 
					 | 
				
			||||||
            match arg {
 | 
					 | 
				
			||||||
                Long("fg") => {
 | 
					 | 
				
			||||||
                    res.fg = Some(
 | 
					 | 
				
			||||||
                        args.value()?
 | 
					 | 
				
			||||||
                            .parse_with(|s| s.parse::<u8>().map(anstyle::Ansi256Color))?,
 | 
					 | 
				
			||||||
                    );
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                Long("bg") => {
 | 
					 | 
				
			||||||
                    res.fg = Some(
 | 
					 | 
				
			||||||
                        args.value()?
 | 
					 | 
				
			||||||
                            .parse_with(|s| s.parse::<u8>().map(anstyle::Ansi256Color))?,
 | 
					 | 
				
			||||||
                    );
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                _ => return Err(arg.unexpected()),
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        Ok(res)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										25
									
								
								vendor/anstyle-wincon/src/ansi.rs
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										25
									
								
								vendor/anstyle-wincon/src/ansi.rs
									
									
									
									
										vendored
									
									
								
							@@ -1,25 +0,0 @@
 | 
				
			|||||||
//! Low-level ANSI-styling
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// Write ANSI colored text to the stream
 | 
					 | 
				
			||||||
pub fn write_colored<S: std::io::Write>(
 | 
					 | 
				
			||||||
    stream: &mut S,
 | 
					 | 
				
			||||||
    fg: Option<anstyle::AnsiColor>,
 | 
					 | 
				
			||||||
    bg: Option<anstyle::AnsiColor>,
 | 
					 | 
				
			||||||
    data: &[u8],
 | 
					 | 
				
			||||||
) -> std::io::Result<usize> {
 | 
					 | 
				
			||||||
    let non_default = fg.is_some() || bg.is_some();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if non_default {
 | 
					 | 
				
			||||||
        if let Some(fg) = fg {
 | 
					 | 
				
			||||||
            write!(stream, "{}", fg.render_fg())?;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        if let Some(bg) = bg {
 | 
					 | 
				
			||||||
            write!(stream, "{}", bg.render_bg())?;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    let written = stream.write(data)?;
 | 
					 | 
				
			||||||
    if non_default {
 | 
					 | 
				
			||||||
        write!(stream, "{}", anstyle::Reset.render())?;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    Ok(written)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										18
									
								
								vendor/anstyle-wincon/src/lib.rs
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										18
									
								
								vendor/anstyle-wincon/src/lib.rs
									
									
									
									
										vendored
									
									
								
							@@ -1,18 +0,0 @@
 | 
				
			|||||||
//! Styling legacy Windows terminals
 | 
					 | 
				
			||||||
//!
 | 
					 | 
				
			||||||
//! See [`WinconStream`]
 | 
					 | 
				
			||||||
//!
 | 
					 | 
				
			||||||
//! This fills a similar role as [`winapi-util`](https://crates.io/crates/winapi-util) does for
 | 
					 | 
				
			||||||
//! [`termcolor`](https://crates.io/crates/termcolor) with the differences
 | 
					 | 
				
			||||||
//! - Uses `windows-sys` rather than `winapi`
 | 
					 | 
				
			||||||
//! - Uses [`anstyle`](https://crates.io/crates/termcolor) rather than defining its own types
 | 
					 | 
				
			||||||
//! - More focused, smaller
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pub mod ansi;
 | 
					 | 
				
			||||||
mod stream;
 | 
					 | 
				
			||||||
#[cfg(windows)]
 | 
					 | 
				
			||||||
pub mod windows;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pub use stream::WinconStream;
 | 
					 | 
				
			||||||
							
								
								
									
										178
									
								
								vendor/anstyle-wincon/src/stream.rs
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										178
									
								
								vendor/anstyle-wincon/src/stream.rs
									
									
									
									
										vendored
									
									
								
							@@ -1,178 +0,0 @@
 | 
				
			|||||||
/// Extend `std::io::Write` with wincon styling
 | 
					 | 
				
			||||||
pub trait WinconStream {
 | 
					 | 
				
			||||||
    /// Write colored text to the stream
 | 
					 | 
				
			||||||
    fn write_colored(
 | 
					 | 
				
			||||||
        &mut self,
 | 
					 | 
				
			||||||
        fg: Option<anstyle::AnsiColor>,
 | 
					 | 
				
			||||||
        bg: Option<anstyle::AnsiColor>,
 | 
					 | 
				
			||||||
        data: &[u8],
 | 
					 | 
				
			||||||
    ) -> std::io::Result<usize>;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl WinconStream for Box<dyn std::io::Write> {
 | 
					 | 
				
			||||||
    fn write_colored(
 | 
					 | 
				
			||||||
        &mut self,
 | 
					 | 
				
			||||||
        fg: Option<anstyle::AnsiColor>,
 | 
					 | 
				
			||||||
        bg: Option<anstyle::AnsiColor>,
 | 
					 | 
				
			||||||
        data: &[u8],
 | 
					 | 
				
			||||||
    ) -> std::io::Result<usize> {
 | 
					 | 
				
			||||||
        crate::ansi::write_colored(self, fg, bg, data)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl WinconStream for &'_ mut Box<dyn std::io::Write> {
 | 
					 | 
				
			||||||
    fn write_colored(
 | 
					 | 
				
			||||||
        &mut self,
 | 
					 | 
				
			||||||
        fg: Option<anstyle::AnsiColor>,
 | 
					 | 
				
			||||||
        bg: Option<anstyle::AnsiColor>,
 | 
					 | 
				
			||||||
        data: &[u8],
 | 
					 | 
				
			||||||
    ) -> std::io::Result<usize> {
 | 
					 | 
				
			||||||
        (**self).write_colored(fg, bg, data)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl WinconStream for std::fs::File {
 | 
					 | 
				
			||||||
    fn write_colored(
 | 
					 | 
				
			||||||
        &mut self,
 | 
					 | 
				
			||||||
        fg: Option<anstyle::AnsiColor>,
 | 
					 | 
				
			||||||
        bg: Option<anstyle::AnsiColor>,
 | 
					 | 
				
			||||||
        data: &[u8],
 | 
					 | 
				
			||||||
    ) -> std::io::Result<usize> {
 | 
					 | 
				
			||||||
        crate::ansi::write_colored(self, fg, bg, data)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl WinconStream for &'_ mut std::fs::File {
 | 
					 | 
				
			||||||
    fn write_colored(
 | 
					 | 
				
			||||||
        &mut self,
 | 
					 | 
				
			||||||
        fg: Option<anstyle::AnsiColor>,
 | 
					 | 
				
			||||||
        bg: Option<anstyle::AnsiColor>,
 | 
					 | 
				
			||||||
        data: &[u8],
 | 
					 | 
				
			||||||
    ) -> std::io::Result<usize> {
 | 
					 | 
				
			||||||
        (**self).write_colored(fg, bg, data)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl WinconStream for Vec<u8> {
 | 
					 | 
				
			||||||
    fn write_colored(
 | 
					 | 
				
			||||||
        &mut self,
 | 
					 | 
				
			||||||
        fg: Option<anstyle::AnsiColor>,
 | 
					 | 
				
			||||||
        bg: Option<anstyle::AnsiColor>,
 | 
					 | 
				
			||||||
        data: &[u8],
 | 
					 | 
				
			||||||
    ) -> std::io::Result<usize> {
 | 
					 | 
				
			||||||
        crate::ansi::write_colored(self, fg, bg, data)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl WinconStream for &'_ mut Vec<u8> {
 | 
					 | 
				
			||||||
    fn write_colored(
 | 
					 | 
				
			||||||
        &mut self,
 | 
					 | 
				
			||||||
        fg: Option<anstyle::AnsiColor>,
 | 
					 | 
				
			||||||
        bg: Option<anstyle::AnsiColor>,
 | 
					 | 
				
			||||||
        data: &[u8],
 | 
					 | 
				
			||||||
    ) -> std::io::Result<usize> {
 | 
					 | 
				
			||||||
        (**self).write_colored(fg, bg, data)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl WinconStream for std::io::Stdout {
 | 
					 | 
				
			||||||
    fn write_colored(
 | 
					 | 
				
			||||||
        &mut self,
 | 
					 | 
				
			||||||
        fg: Option<anstyle::AnsiColor>,
 | 
					 | 
				
			||||||
        bg: Option<anstyle::AnsiColor>,
 | 
					 | 
				
			||||||
        data: &[u8],
 | 
					 | 
				
			||||||
    ) -> std::io::Result<usize> {
 | 
					 | 
				
			||||||
        // Ensure exclusive access
 | 
					 | 
				
			||||||
        self.lock().write_colored(fg, bg, data)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl WinconStream for std::io::Stderr {
 | 
					 | 
				
			||||||
    fn write_colored(
 | 
					 | 
				
			||||||
        &mut self,
 | 
					 | 
				
			||||||
        fg: Option<anstyle::AnsiColor>,
 | 
					 | 
				
			||||||
        bg: Option<anstyle::AnsiColor>,
 | 
					 | 
				
			||||||
        data: &[u8],
 | 
					 | 
				
			||||||
    ) -> std::io::Result<usize> {
 | 
					 | 
				
			||||||
        // Ensure exclusive access
 | 
					 | 
				
			||||||
        self.lock().write_colored(fg, bg, data)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[cfg(not(windows))]
 | 
					 | 
				
			||||||
mod platform {
 | 
					 | 
				
			||||||
    use super::*;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    impl WinconStream for std::io::StdoutLock<'_> {
 | 
					 | 
				
			||||||
        fn write_colored(
 | 
					 | 
				
			||||||
            &mut self,
 | 
					 | 
				
			||||||
            fg: Option<anstyle::AnsiColor>,
 | 
					 | 
				
			||||||
            bg: Option<anstyle::AnsiColor>,
 | 
					 | 
				
			||||||
            data: &[u8],
 | 
					 | 
				
			||||||
        ) -> std::io::Result<usize> {
 | 
					 | 
				
			||||||
            crate::ansi::write_colored(self, fg, bg, data)
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    impl WinconStream for std::io::StderrLock<'_> {
 | 
					 | 
				
			||||||
        fn write_colored(
 | 
					 | 
				
			||||||
            &mut self,
 | 
					 | 
				
			||||||
            fg: Option<anstyle::AnsiColor>,
 | 
					 | 
				
			||||||
            bg: Option<anstyle::AnsiColor>,
 | 
					 | 
				
			||||||
            data: &[u8],
 | 
					 | 
				
			||||||
        ) -> std::io::Result<usize> {
 | 
					 | 
				
			||||||
            crate::ansi::write_colored(self, fg, bg, data)
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[cfg(windows)]
 | 
					 | 
				
			||||||
mod platform {
 | 
					 | 
				
			||||||
    use super::*;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    impl WinconStream for std::io::StdoutLock<'_> {
 | 
					 | 
				
			||||||
        fn write_colored(
 | 
					 | 
				
			||||||
            &mut self,
 | 
					 | 
				
			||||||
            fg: Option<anstyle::AnsiColor>,
 | 
					 | 
				
			||||||
            bg: Option<anstyle::AnsiColor>,
 | 
					 | 
				
			||||||
            data: &[u8],
 | 
					 | 
				
			||||||
        ) -> std::io::Result<usize> {
 | 
					 | 
				
			||||||
            let initial = crate::windows::stdout_initial_colors();
 | 
					 | 
				
			||||||
            crate::windows::write_colored(self, fg, bg, data, initial)
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    impl WinconStream for std::io::StderrLock<'_> {
 | 
					 | 
				
			||||||
        fn write_colored(
 | 
					 | 
				
			||||||
            &mut self,
 | 
					 | 
				
			||||||
            fg: Option<anstyle::AnsiColor>,
 | 
					 | 
				
			||||||
            bg: Option<anstyle::AnsiColor>,
 | 
					 | 
				
			||||||
            data: &[u8],
 | 
					 | 
				
			||||||
        ) -> std::io::Result<usize> {
 | 
					 | 
				
			||||||
            let initial = crate::windows::stderr_initial_colors();
 | 
					 | 
				
			||||||
            crate::windows::write_colored(self, fg, bg, data, initial)
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl WinconStream for &'_ mut std::io::StdoutLock<'_> {
 | 
					 | 
				
			||||||
    fn write_colored(
 | 
					 | 
				
			||||||
        &mut self,
 | 
					 | 
				
			||||||
        fg: Option<anstyle::AnsiColor>,
 | 
					 | 
				
			||||||
        bg: Option<anstyle::AnsiColor>,
 | 
					 | 
				
			||||||
        data: &[u8],
 | 
					 | 
				
			||||||
    ) -> std::io::Result<usize> {
 | 
					 | 
				
			||||||
        (**self).write_colored(fg, bg, data)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl WinconStream for &'_ mut std::io::StderrLock<'_> {
 | 
					 | 
				
			||||||
    fn write_colored(
 | 
					 | 
				
			||||||
        &mut self,
 | 
					 | 
				
			||||||
        fg: Option<anstyle::AnsiColor>,
 | 
					 | 
				
			||||||
        bg: Option<anstyle::AnsiColor>,
 | 
					 | 
				
			||||||
        data: &[u8],
 | 
					 | 
				
			||||||
    ) -> std::io::Result<usize> {
 | 
					 | 
				
			||||||
        (**self).write_colored(fg, bg, data)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										263
									
								
								vendor/anstyle-wincon/src/windows.rs
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										263
									
								
								vendor/anstyle-wincon/src/windows.rs
									
									
									
									
										vendored
									
									
								
							@@ -1,263 +0,0 @@
 | 
				
			|||||||
//! Low-level wincon-styling
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use std::os::windows::io::AsHandle;
 | 
					 | 
				
			||||||
use std::os::windows::io::AsRawHandle;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type StdioColorResult = std::io::Result<(anstyle::AnsiColor, anstyle::AnsiColor)>;
 | 
					 | 
				
			||||||
type StdioColorInnerResult = Result<(anstyle::AnsiColor, anstyle::AnsiColor), inner::IoError>;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// Cached [`get_colors`] call for [`std::io::stdout`]
 | 
					 | 
				
			||||||
pub fn stdout_initial_colors() -> StdioColorResult {
 | 
					 | 
				
			||||||
    static INITIAL: std::sync::OnceLock<StdioColorInnerResult> = std::sync::OnceLock::new();
 | 
					 | 
				
			||||||
    INITIAL
 | 
					 | 
				
			||||||
        .get_or_init(|| get_colors_(&std::io::stdout()))
 | 
					 | 
				
			||||||
        .clone()
 | 
					 | 
				
			||||||
        .map_err(Into::into)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// Cached [`get_colors`] call for [`std::io::stderr`]
 | 
					 | 
				
			||||||
pub fn stderr_initial_colors() -> StdioColorResult {
 | 
					 | 
				
			||||||
    static INITIAL: std::sync::OnceLock<StdioColorInnerResult> = std::sync::OnceLock::new();
 | 
					 | 
				
			||||||
    INITIAL
 | 
					 | 
				
			||||||
        .get_or_init(|| get_colors_(&std::io::stderr()))
 | 
					 | 
				
			||||||
        .clone()
 | 
					 | 
				
			||||||
        .map_err(Into::into)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// Apply colors to future writes
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// **Note:** Make sure any buffers are first flushed or else these colors will apply
 | 
					 | 
				
			||||||
pub fn set_colors<S: AsHandle>(
 | 
					 | 
				
			||||||
    stream: &mut S,
 | 
					 | 
				
			||||||
    fg: anstyle::AnsiColor,
 | 
					 | 
				
			||||||
    bg: anstyle::AnsiColor,
 | 
					 | 
				
			||||||
) -> std::io::Result<()> {
 | 
					 | 
				
			||||||
    set_colors_(stream, fg, bg).map_err(Into::into)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
fn set_colors_<S: AsHandle>(
 | 
					 | 
				
			||||||
    stream: &mut S,
 | 
					 | 
				
			||||||
    fg: anstyle::AnsiColor,
 | 
					 | 
				
			||||||
    bg: anstyle::AnsiColor,
 | 
					 | 
				
			||||||
) -> Result<(), inner::IoError> {
 | 
					 | 
				
			||||||
    let handle = stream.as_handle();
 | 
					 | 
				
			||||||
    let handle = handle.as_raw_handle();
 | 
					 | 
				
			||||||
    let attributes = inner::set_colors(fg, bg);
 | 
					 | 
				
			||||||
    inner::set_console_text_attributes(handle, attributes)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// Get the colors currently active on the console
 | 
					 | 
				
			||||||
pub fn get_colors<S: AsHandle>(stream: &S) -> StdioColorResult {
 | 
					 | 
				
			||||||
    get_colors_(stream).map_err(Into::into)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
fn get_colors_<S: AsHandle>(stream: &S) -> StdioColorInnerResult {
 | 
					 | 
				
			||||||
    let handle = stream.as_handle();
 | 
					 | 
				
			||||||
    let handle = handle.as_raw_handle();
 | 
					 | 
				
			||||||
    let info = inner::get_screen_buffer_info(handle)?;
 | 
					 | 
				
			||||||
    let (fg, bg) = inner::get_colors(&info);
 | 
					 | 
				
			||||||
    Ok((fg, bg))
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pub(crate) fn write_colored<S: AsHandle + std::io::Write>(
 | 
					 | 
				
			||||||
    stream: &mut S,
 | 
					 | 
				
			||||||
    fg: Option<anstyle::AnsiColor>,
 | 
					 | 
				
			||||||
    bg: Option<anstyle::AnsiColor>,
 | 
					 | 
				
			||||||
    data: &[u8],
 | 
					 | 
				
			||||||
    initial: StdioColorResult,
 | 
					 | 
				
			||||||
) -> std::io::Result<usize> {
 | 
					 | 
				
			||||||
    let (initial_fg, initial_bg) = initial?;
 | 
					 | 
				
			||||||
    let non_default = fg.is_some() || bg.is_some();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if non_default {
 | 
					 | 
				
			||||||
        let fg = fg.unwrap_or(initial_fg);
 | 
					 | 
				
			||||||
        let bg = bg.unwrap_or(initial_bg);
 | 
					 | 
				
			||||||
        // Ensure everything is written with the last set of colors before applying the next set
 | 
					 | 
				
			||||||
        stream.flush()?;
 | 
					 | 
				
			||||||
        set_colors(stream, fg, bg)?;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    let written = stream.write(data)?;
 | 
					 | 
				
			||||||
    if non_default {
 | 
					 | 
				
			||||||
        // Ensure everything is written with the last set of colors before applying the next set
 | 
					 | 
				
			||||||
        stream.flush()?;
 | 
					 | 
				
			||||||
        set_colors(stream, initial_fg, initial_bg)?;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    Ok(written)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
mod inner {
 | 
					 | 
				
			||||||
    use windows_sys::Win32::System::Console::CONSOLE_CHARACTER_ATTRIBUTES;
 | 
					 | 
				
			||||||
    use windows_sys::Win32::System::Console::CONSOLE_SCREEN_BUFFER_INFO;
 | 
					 | 
				
			||||||
    use windows_sys::Win32::System::Console::FOREGROUND_BLUE;
 | 
					 | 
				
			||||||
    use windows_sys::Win32::System::Console::FOREGROUND_GREEN;
 | 
					 | 
				
			||||||
    use windows_sys::Win32::System::Console::FOREGROUND_INTENSITY;
 | 
					 | 
				
			||||||
    use windows_sys::Win32::System::Console::FOREGROUND_RED;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    use std::os::windows::io::RawHandle;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const FOREGROUND_CYAN: CONSOLE_CHARACTER_ATTRIBUTES = FOREGROUND_BLUE | FOREGROUND_GREEN;
 | 
					 | 
				
			||||||
    const FOREGROUND_MAGENTA: CONSOLE_CHARACTER_ATTRIBUTES = FOREGROUND_BLUE | FOREGROUND_RED;
 | 
					 | 
				
			||||||
    const FOREGROUND_YELLOW: CONSOLE_CHARACTER_ATTRIBUTES = FOREGROUND_GREEN | FOREGROUND_RED;
 | 
					 | 
				
			||||||
    const FOREGROUND_WHITE: CONSOLE_CHARACTER_ATTRIBUTES =
 | 
					 | 
				
			||||||
        FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[derive(Copy, Clone, Debug)]
 | 
					 | 
				
			||||||
    pub(crate) enum IoError {
 | 
					 | 
				
			||||||
        BrokenPipe,
 | 
					 | 
				
			||||||
        RawOs(i32),
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    impl From<IoError> for std::io::Error {
 | 
					 | 
				
			||||||
        fn from(io: IoError) -> Self {
 | 
					 | 
				
			||||||
            match io {
 | 
					 | 
				
			||||||
                IoError::BrokenPipe => {
 | 
					 | 
				
			||||||
                    std::io::Error::new(std::io::ErrorKind::BrokenPipe, "console is detached")
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                IoError::RawOs(code) => std::io::Error::from_raw_os_error(code),
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    impl IoError {
 | 
					 | 
				
			||||||
        fn last_os_error() -> Self {
 | 
					 | 
				
			||||||
            Self::RawOs(std::io::Error::last_os_error().raw_os_error().unwrap())
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    pub(crate) fn get_screen_buffer_info(
 | 
					 | 
				
			||||||
        handle: RawHandle,
 | 
					 | 
				
			||||||
    ) -> Result<CONSOLE_SCREEN_BUFFER_INFO, IoError> {
 | 
					 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
            let handle = std::mem::transmute(handle);
 | 
					 | 
				
			||||||
            if handle == 0 {
 | 
					 | 
				
			||||||
                return Err(IoError::BrokenPipe);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            let mut info: CONSOLE_SCREEN_BUFFER_INFO = std::mem::zeroed();
 | 
					 | 
				
			||||||
            if windows_sys::Win32::System::Console::GetConsoleScreenBufferInfo(handle, &mut info)
 | 
					 | 
				
			||||||
                != 0
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                Ok(info)
 | 
					 | 
				
			||||||
            } else {
 | 
					 | 
				
			||||||
                Err(IoError::last_os_error())
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    pub(crate) fn set_console_text_attributes(
 | 
					 | 
				
			||||||
        handle: RawHandle,
 | 
					 | 
				
			||||||
        attributes: CONSOLE_CHARACTER_ATTRIBUTES,
 | 
					 | 
				
			||||||
    ) -> Result<(), IoError> {
 | 
					 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
            let handle = std::mem::transmute(handle);
 | 
					 | 
				
			||||||
            if handle == 0 {
 | 
					 | 
				
			||||||
                return Err(IoError::BrokenPipe);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if windows_sys::Win32::System::Console::SetConsoleTextAttribute(handle, attributes) != 0
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                Ok(())
 | 
					 | 
				
			||||||
            } else {
 | 
					 | 
				
			||||||
                Err(IoError::last_os_error())
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    pub(crate) fn get_colors(
 | 
					 | 
				
			||||||
        info: &CONSOLE_SCREEN_BUFFER_INFO,
 | 
					 | 
				
			||||||
    ) -> (anstyle::AnsiColor, anstyle::AnsiColor) {
 | 
					 | 
				
			||||||
        let attributes = info.wAttributes;
 | 
					 | 
				
			||||||
        let bg = from_nibble(attributes >> 4);
 | 
					 | 
				
			||||||
        let fg = from_nibble(attributes);
 | 
					 | 
				
			||||||
        (fg, bg)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    pub(crate) fn set_colors(
 | 
					 | 
				
			||||||
        fg: anstyle::AnsiColor,
 | 
					 | 
				
			||||||
        bg: anstyle::AnsiColor,
 | 
					 | 
				
			||||||
    ) -> CONSOLE_CHARACTER_ATTRIBUTES {
 | 
					 | 
				
			||||||
        to_nibble(bg) << 4 | to_nibble(fg)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    fn from_nibble(color: CONSOLE_CHARACTER_ATTRIBUTES) -> anstyle::AnsiColor {
 | 
					 | 
				
			||||||
        if color & FOREGROUND_WHITE == FOREGROUND_WHITE {
 | 
					 | 
				
			||||||
            // 3 bits high
 | 
					 | 
				
			||||||
            anstyle::AnsiColor::White
 | 
					 | 
				
			||||||
        } else if color & FOREGROUND_CYAN == FOREGROUND_CYAN {
 | 
					 | 
				
			||||||
            // 2 bits high
 | 
					 | 
				
			||||||
            anstyle::AnsiColor::Cyan
 | 
					 | 
				
			||||||
        } else if color & FOREGROUND_YELLOW == FOREGROUND_YELLOW {
 | 
					 | 
				
			||||||
            // 2 bits high
 | 
					 | 
				
			||||||
            anstyle::AnsiColor::Yellow
 | 
					 | 
				
			||||||
        } else if color & FOREGROUND_MAGENTA == FOREGROUND_MAGENTA {
 | 
					 | 
				
			||||||
            // 2 bits high
 | 
					 | 
				
			||||||
            anstyle::AnsiColor::Magenta
 | 
					 | 
				
			||||||
        } else if color & FOREGROUND_RED == FOREGROUND_RED {
 | 
					 | 
				
			||||||
            // 1 bit high
 | 
					 | 
				
			||||||
            anstyle::AnsiColor::Red
 | 
					 | 
				
			||||||
        } else if color & FOREGROUND_GREEN == FOREGROUND_GREEN {
 | 
					 | 
				
			||||||
            // 1 bit high
 | 
					 | 
				
			||||||
            anstyle::AnsiColor::Green
 | 
					 | 
				
			||||||
        } else if color & FOREGROUND_BLUE == FOREGROUND_BLUE {
 | 
					 | 
				
			||||||
            // 1 bit high
 | 
					 | 
				
			||||||
            anstyle::AnsiColor::Blue
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            // 0 bits high
 | 
					 | 
				
			||||||
            anstyle::AnsiColor::Black
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        .bright(color & FOREGROUND_INTENSITY == FOREGROUND_INTENSITY)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    fn to_nibble(color: anstyle::AnsiColor) -> CONSOLE_CHARACTER_ATTRIBUTES {
 | 
					 | 
				
			||||||
        let mut attributes = 0;
 | 
					 | 
				
			||||||
        attributes |= match color.bright(false) {
 | 
					 | 
				
			||||||
            anstyle::AnsiColor::Black => 0,
 | 
					 | 
				
			||||||
            anstyle::AnsiColor::Red => FOREGROUND_RED,
 | 
					 | 
				
			||||||
            anstyle::AnsiColor::Green => FOREGROUND_GREEN,
 | 
					 | 
				
			||||||
            anstyle::AnsiColor::Yellow => FOREGROUND_YELLOW,
 | 
					 | 
				
			||||||
            anstyle::AnsiColor::Blue => FOREGROUND_BLUE,
 | 
					 | 
				
			||||||
            anstyle::AnsiColor::Magenta => FOREGROUND_MAGENTA,
 | 
					 | 
				
			||||||
            anstyle::AnsiColor::Cyan => FOREGROUND_CYAN,
 | 
					 | 
				
			||||||
            anstyle::AnsiColor::White => FOREGROUND_WHITE,
 | 
					 | 
				
			||||||
            anstyle::AnsiColor::BrightBlack
 | 
					 | 
				
			||||||
            | anstyle::AnsiColor::BrightRed
 | 
					 | 
				
			||||||
            | anstyle::AnsiColor::BrightGreen
 | 
					 | 
				
			||||||
            | anstyle::AnsiColor::BrightYellow
 | 
					 | 
				
			||||||
            | anstyle::AnsiColor::BrightBlue
 | 
					 | 
				
			||||||
            | anstyle::AnsiColor::BrightMagenta
 | 
					 | 
				
			||||||
            | anstyle::AnsiColor::BrightCyan
 | 
					 | 
				
			||||||
            | anstyle::AnsiColor::BrightWhite => unreachable!("brights were toggled off"),
 | 
					 | 
				
			||||||
        };
 | 
					 | 
				
			||||||
        if color.is_bright() {
 | 
					 | 
				
			||||||
            attributes |= FOREGROUND_INTENSITY;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        attributes
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[test]
 | 
					 | 
				
			||||||
    fn to_from_nibble() {
 | 
					 | 
				
			||||||
        const COLORS: [anstyle::AnsiColor; 16] = [
 | 
					 | 
				
			||||||
            anstyle::AnsiColor::Black,
 | 
					 | 
				
			||||||
            anstyle::AnsiColor::Red,
 | 
					 | 
				
			||||||
            anstyle::AnsiColor::Green,
 | 
					 | 
				
			||||||
            anstyle::AnsiColor::Yellow,
 | 
					 | 
				
			||||||
            anstyle::AnsiColor::Blue,
 | 
					 | 
				
			||||||
            anstyle::AnsiColor::Magenta,
 | 
					 | 
				
			||||||
            anstyle::AnsiColor::Cyan,
 | 
					 | 
				
			||||||
            anstyle::AnsiColor::White,
 | 
					 | 
				
			||||||
            anstyle::AnsiColor::BrightBlack,
 | 
					 | 
				
			||||||
            anstyle::AnsiColor::BrightRed,
 | 
					 | 
				
			||||||
            anstyle::AnsiColor::BrightGreen,
 | 
					 | 
				
			||||||
            anstyle::AnsiColor::BrightYellow,
 | 
					 | 
				
			||||||
            anstyle::AnsiColor::BrightBlue,
 | 
					 | 
				
			||||||
            anstyle::AnsiColor::BrightMagenta,
 | 
					 | 
				
			||||||
            anstyle::AnsiColor::BrightCyan,
 | 
					 | 
				
			||||||
            anstyle::AnsiColor::BrightWhite,
 | 
					 | 
				
			||||||
        ];
 | 
					 | 
				
			||||||
        for expected in COLORS {
 | 
					 | 
				
			||||||
            let nibble = to_nibble(expected);
 | 
					 | 
				
			||||||
            let actual = from_nibble(nibble);
 | 
					 | 
				
			||||||
            assert_eq!(expected, actual, "Intermediate: {}", nibble);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										1
									
								
								vendor/anstyle/.cargo-checksum.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								vendor/anstyle/.cargo-checksum.json
									
									
									
									
										vendored
									
									
								
							@@ -1 +0,0 @@
 | 
				
			|||||||
{"files":{"Cargo.lock":"ccf805a1b70ac0205b4a5f39db4c21ff2b6c2420d58120f5b74ebd574de3beed","Cargo.toml":"cecc5e02aafb4fa8bcbbcd64eb0c91fada8bcb6ca2514504540e01227295b7b1","LICENSE-APACHE":"c6596eb7be8581c18be736c846fb9173b69eccf6ef94c5135893ec56bd92ba08","LICENSE-MIT":"3dad3b7606dec7ce40f54546e0dd485aeb52a45d4fcdfdaf830fd8349bbe43a5","README.md":"dcb157ba695dd8f1572944cc5bf84b8f67f8bb73925a5b725a9e274c755ce1a6","examples/dump.rs":"236dd2a3dce7512d1faeda5caec8d272299441b5d204696957940c687a021be8","src/color.rs":"8ac17093415630424ab61ca7a674aa98c39438bee51ae9d294072b1d2b17e743","src/effect.rs":"64573c03643af32ed5efe941ccdecb3f4c89685db1b4fbf35a0803e0347f06ee","src/lib.rs":"0106395ba7263dbee67458e5ff4038cab493a3d34f3dcf0cb75504b1531a58e1","src/macros.rs":"0c90b45626fe8331d5b3326abb831f4ba6e04bcc975b1b9c01e465715050caa2","src/reset.rs":"8f8c2f996e5f446d2bbcfb9926494fb2ad76701260225ab6b627960c53dfcb59","src/style.rs":"fecf7c3fcdd00a26727c62861f4ce532ff80df0e0c6a9b4e288d3d2a3d1e4d65"},"package":"7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87"}
 | 
					 | 
				
			||||||
							
								
								
									
										16
									
								
								vendor/anstyle/Cargo.lock
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										16
									
								
								vendor/anstyle/Cargo.lock
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,16 +0,0 @@
 | 
				
			|||||||
# This file is automatically @generated by Cargo.
 | 
					 | 
				
			||||||
# It is not intended for manual editing.
 | 
					 | 
				
			||||||
version = 3
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "anstyle"
 | 
					 | 
				
			||||||
version = "1.0.4"
 | 
					 | 
				
			||||||
dependencies = [
 | 
					 | 
				
			||||||
 "lexopt",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "lexopt"
 | 
					 | 
				
			||||||
version = "0.3.0"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "baff4b617f7df3d896f97fe922b64817f6cd9a756bb81d40f8883f2f66dcb401"
 | 
					 | 
				
			||||||
							
								
								
									
										85
									
								
								vendor/anstyle/Cargo.toml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										85
									
								
								vendor/anstyle/Cargo.toml
									
									
									
									
										vendored
									
									
								
							@@ -1,85 +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.70.0"
 | 
					 | 
				
			||||||
name = "anstyle"
 | 
					 | 
				
			||||||
version = "1.0.4"
 | 
					 | 
				
			||||||
include = [
 | 
					 | 
				
			||||||
    "build.rs",
 | 
					 | 
				
			||||||
    "src/**/*",
 | 
					 | 
				
			||||||
    "Cargo.toml",
 | 
					 | 
				
			||||||
    "Cargo.lock",
 | 
					 | 
				
			||||||
    "LICENSE*",
 | 
					 | 
				
			||||||
    "README.md",
 | 
					 | 
				
			||||||
    "benches/**/*",
 | 
					 | 
				
			||||||
    "examples/**/*",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
description = "ANSI text styling"
 | 
					 | 
				
			||||||
homepage = "https://github.com/rust-cli/anstyle"
 | 
					 | 
				
			||||||
readme = "README.md"
 | 
					 | 
				
			||||||
keywords = [
 | 
					 | 
				
			||||||
    "ansi",
 | 
					 | 
				
			||||||
    "terminal",
 | 
					 | 
				
			||||||
    "color",
 | 
					 | 
				
			||||||
    "no_std",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
categories = ["command-line-interface"]
 | 
					 | 
				
			||||||
license = "MIT OR Apache-2.0"
 | 
					 | 
				
			||||||
repository = "https://github.com/rust-cli/anstyle.git"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[package.metadata.release]
 | 
					 | 
				
			||||||
tag-prefix = ""
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package.metadata.release.pre-release-replacements]]
 | 
					 | 
				
			||||||
file = "CHANGELOG.md"
 | 
					 | 
				
			||||||
min = 1
 | 
					 | 
				
			||||||
replace = "{{version}}"
 | 
					 | 
				
			||||||
search = "Unreleased"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package.metadata.release.pre-release-replacements]]
 | 
					 | 
				
			||||||
exactly = 1
 | 
					 | 
				
			||||||
file = "CHANGELOG.md"
 | 
					 | 
				
			||||||
replace = "...{{tag_name}}"
 | 
					 | 
				
			||||||
search = '\.\.\.HEAD'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package.metadata.release.pre-release-replacements]]
 | 
					 | 
				
			||||||
file = "CHANGELOG.md"
 | 
					 | 
				
			||||||
min = 1
 | 
					 | 
				
			||||||
replace = "{{date}}"
 | 
					 | 
				
			||||||
search = "ReleaseDate"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package.metadata.release.pre-release-replacements]]
 | 
					 | 
				
			||||||
exactly = 1
 | 
					 | 
				
			||||||
file = "CHANGELOG.md"
 | 
					 | 
				
			||||||
replace = """
 | 
					 | 
				
			||||||
<!-- next-header -->
 | 
					 | 
				
			||||||
## [Unreleased] - ReleaseDate
 | 
					 | 
				
			||||||
"""
 | 
					 | 
				
			||||||
search = "<!-- next-header -->"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package.metadata.release.pre-release-replacements]]
 | 
					 | 
				
			||||||
exactly = 1
 | 
					 | 
				
			||||||
file = "CHANGELOG.md"
 | 
					 | 
				
			||||||
replace = """
 | 
					 | 
				
			||||||
<!-- next-url -->
 | 
					 | 
				
			||||||
[Unreleased]: https://github.com/rust-cli/anstyle/compare/{{tag_name}}...HEAD"""
 | 
					 | 
				
			||||||
search = "<!-- next-url -->"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[dependencies]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[dev-dependencies.lexopt]
 | 
					 | 
				
			||||||
version = "0.3.0"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[features]
 | 
					 | 
				
			||||||
default = ["std"]
 | 
					 | 
				
			||||||
std = []
 | 
					 | 
				
			||||||
							
								
								
									
										202
									
								
								vendor/anstyle/LICENSE-APACHE
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										202
									
								
								vendor/anstyle/LICENSE-APACHE
									
									
									
									
										vendored
									
									
								
							@@ -1,202 +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
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   APPENDIX: How to apply the Apache License to your work.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      To apply the Apache License to your work, attach the following
 | 
					 | 
				
			||||||
      boilerplate notice, with the fields enclosed by brackets "{}"
 | 
					 | 
				
			||||||
      replaced with your own identifying information. (Don't include
 | 
					 | 
				
			||||||
      the brackets!)  The text should be enclosed in the appropriate
 | 
					 | 
				
			||||||
      comment syntax for the file format. We also recommend that a
 | 
					 | 
				
			||||||
      file or class name and description of purpose be included on the
 | 
					 | 
				
			||||||
      same "printed page" as the copyright notice for easier
 | 
					 | 
				
			||||||
      identification within third-party archives.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   Copyright {yyyy} {name of copyright owner}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   Licensed under the Apache License, Version 2.0 (the "License");
 | 
					 | 
				
			||||||
   you may not use this file except in compliance with the License.
 | 
					 | 
				
			||||||
   You may obtain a copy of the License at
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
       http://www.apache.org/licenses/LICENSE-2.0
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   Unless required by applicable law or agreed to in writing, software
 | 
					 | 
				
			||||||
   distributed under the License is distributed on an "AS IS" BASIS,
 | 
					 | 
				
			||||||
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
					 | 
				
			||||||
   See the License for the specific language governing permissions and
 | 
					 | 
				
			||||||
   limitations under the License.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
							
								
								
									
										19
									
								
								vendor/anstyle/LICENSE-MIT
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										19
									
								
								vendor/anstyle/LICENSE-MIT
									
									
									
									
										vendored
									
									
								
							@@ -1,19 +0,0 @@
 | 
				
			|||||||
Copyright (c) 2022 The rust-cli Developers
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
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.
 | 
					 | 
				
			||||||
							
								
								
									
										42
									
								
								vendor/anstyle/README.md
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										42
									
								
								vendor/anstyle/README.md
									
									
									
									
										vendored
									
									
								
							@@ -1,42 +0,0 @@
 | 
				
			|||||||
# anstyle
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
> ANSI text styling
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
*A portmanteau of "ansi style"*
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[][Documentation]
 | 
					 | 
				
			||||||

 | 
					 | 
				
			||||||
[](https://crates.io/crates/anstyle)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
`anstyle` provides core types describing [ANSI styling escape
 | 
					 | 
				
			||||||
codes](https://en.wikipedia.org/wiki/ANSI_escape_code) for interoperability
 | 
					 | 
				
			||||||
between crates.  For example, this would allow a crate to provide an API for
 | 
					 | 
				
			||||||
customizing the colors used without putting the underlying text styling crate
 | 
					 | 
				
			||||||
in the API.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
For integration with your text styling crate, see:
 | 
					 | 
				
			||||||
- [anstyle-termcolor](crates/termcolor)
 | 
					 | 
				
			||||||
- [anstyle-owo-colors](crates/owo)
 | 
					 | 
				
			||||||
- [anstyle-yansi](crates/yansi)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
General utilities:
 | 
					 | 
				
			||||||
- [anstyle-git](crates/git): Parse Git style descriptions
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## License
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Licensed under either of
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
 | 
					 | 
				
			||||||
 * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
at your option.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### Contribution
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Unless you explicitly state otherwise, any contribution intentionally
 | 
					 | 
				
			||||||
submitted for inclusion in the work by you, as defined in the Apache-2.0
 | 
					 | 
				
			||||||
license, shall be dual licensed as above, without any additional terms or
 | 
					 | 
				
			||||||
conditions.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[Crates.io]: https://crates.io/crates/anstyle
 | 
					 | 
				
			||||||
[Documentation]: https://docs.rs/anstyle
 | 
					 | 
				
			||||||
							
								
								
									
										132
									
								
								vendor/anstyle/examples/dump.rs
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										132
									
								
								vendor/anstyle/examples/dump.rs
									
									
									
									
										vendored
									
									
								
							@@ -1,132 +0,0 @@
 | 
				
			|||||||
use std::io::Write;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
fn main() -> Result<(), lexopt::Error> {
 | 
					 | 
				
			||||||
    let args = Args::parse()?;
 | 
					 | 
				
			||||||
    let stdout = std::io::stdout();
 | 
					 | 
				
			||||||
    let mut stdout = stdout.lock();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    for fixed in 0..16 {
 | 
					 | 
				
			||||||
        let style = style(fixed, args.layer, args.effects);
 | 
					 | 
				
			||||||
        let _ = print_number(&mut stdout, fixed, style);
 | 
					 | 
				
			||||||
        if fixed == 7 || fixed == 15 {
 | 
					 | 
				
			||||||
            let _ = writeln!(&mut stdout);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    for r in 0..6 {
 | 
					 | 
				
			||||||
        let _ = writeln!(stdout);
 | 
					 | 
				
			||||||
        for g in 0..6 {
 | 
					 | 
				
			||||||
            for b in 0..6 {
 | 
					 | 
				
			||||||
                let fixed = r * 36 + g * 6 + b + 16;
 | 
					 | 
				
			||||||
                let style = style(fixed, args.layer, args.effects);
 | 
					 | 
				
			||||||
                let _ = print_number(&mut stdout, fixed, style);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            let _ = writeln!(stdout);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    for c in 0..24 {
 | 
					 | 
				
			||||||
        if 0 == c % 8 {
 | 
					 | 
				
			||||||
            let _ = writeln!(stdout);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        let fixed = 232 + c;
 | 
					 | 
				
			||||||
        let style = style(fixed, args.layer, args.effects);
 | 
					 | 
				
			||||||
        let _ = print_number(&mut stdout, fixed, style);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Ok(())
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
fn style(fixed: u8, layer: Layer, effects: anstyle::Effects) -> anstyle::Style {
 | 
					 | 
				
			||||||
    let color = anstyle::Ansi256Color(fixed).into();
 | 
					 | 
				
			||||||
    (match layer {
 | 
					 | 
				
			||||||
        Layer::Fg => anstyle::Style::new().fg_color(Some(color)),
 | 
					 | 
				
			||||||
        Layer::Bg => anstyle::Style::new().bg_color(Some(color)),
 | 
					 | 
				
			||||||
        Layer::Underline => anstyle::Style::new().underline_color(Some(color)),
 | 
					 | 
				
			||||||
    }) | effects
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
fn print_number(
 | 
					 | 
				
			||||||
    stdout: &mut std::io::StdoutLock<'_>,
 | 
					 | 
				
			||||||
    fixed: u8,
 | 
					 | 
				
			||||||
    style: anstyle::Style,
 | 
					 | 
				
			||||||
) -> std::io::Result<()> {
 | 
					 | 
				
			||||||
    write!(
 | 
					 | 
				
			||||||
        stdout,
 | 
					 | 
				
			||||||
        "{}{:>4}{}",
 | 
					 | 
				
			||||||
        style.render(),
 | 
					 | 
				
			||||||
        fixed,
 | 
					 | 
				
			||||||
        anstyle::Reset.render()
 | 
					 | 
				
			||||||
    )
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[derive(Default)]
 | 
					 | 
				
			||||||
struct Args {
 | 
					 | 
				
			||||||
    effects: anstyle::Effects,
 | 
					 | 
				
			||||||
    layer: Layer,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[derive(Copy, Clone, Default)]
 | 
					 | 
				
			||||||
enum Layer {
 | 
					 | 
				
			||||||
    #[default]
 | 
					 | 
				
			||||||
    Fg,
 | 
					 | 
				
			||||||
    Bg,
 | 
					 | 
				
			||||||
    Underline,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl Args {
 | 
					 | 
				
			||||||
    fn parse() -> Result<Self, lexopt::Error> {
 | 
					 | 
				
			||||||
        use lexopt::prelude::*;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        let mut res = Args::default();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        let mut args = lexopt::Parser::from_env();
 | 
					 | 
				
			||||||
        while let Some(arg) = args.next()? {
 | 
					 | 
				
			||||||
            match arg {
 | 
					 | 
				
			||||||
                Long("layer") => {
 | 
					 | 
				
			||||||
                    res.layer = args.value()?.parse_with(|s| match s {
 | 
					 | 
				
			||||||
                        "fg" => Ok(Layer::Fg),
 | 
					 | 
				
			||||||
                        "bg" => Ok(Layer::Bg),
 | 
					 | 
				
			||||||
                        "underline" => Ok(Layer::Underline),
 | 
					 | 
				
			||||||
                        _ => Err("expected values fg, bg, underline"),
 | 
					 | 
				
			||||||
                    })?;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                Long("effect") => {
 | 
					 | 
				
			||||||
                    const EFFECTS: [(&str, anstyle::Effects); 12] = [
 | 
					 | 
				
			||||||
                        ("bold", anstyle::Effects::BOLD),
 | 
					 | 
				
			||||||
                        ("dimmed", anstyle::Effects::DIMMED),
 | 
					 | 
				
			||||||
                        ("italic", anstyle::Effects::ITALIC),
 | 
					 | 
				
			||||||
                        ("underline", anstyle::Effects::UNDERLINE),
 | 
					 | 
				
			||||||
                        ("double_underline", anstyle::Effects::DOUBLE_UNDERLINE),
 | 
					 | 
				
			||||||
                        ("curly_underline", anstyle::Effects::CURLY_UNDERLINE),
 | 
					 | 
				
			||||||
                        ("dotted_underline", anstyle::Effects::DOTTED_UNDERLINE),
 | 
					 | 
				
			||||||
                        ("dashed_underline", anstyle::Effects::DASHED_UNDERLINE),
 | 
					 | 
				
			||||||
                        ("blink", anstyle::Effects::BLINK),
 | 
					 | 
				
			||||||
                        ("invert", anstyle::Effects::INVERT),
 | 
					 | 
				
			||||||
                        ("hidden", anstyle::Effects::HIDDEN),
 | 
					 | 
				
			||||||
                        ("strikethrough", anstyle::Effects::STRIKETHROUGH),
 | 
					 | 
				
			||||||
                    ];
 | 
					 | 
				
			||||||
                    let effect = args.value()?.parse_with(|s| {
 | 
					 | 
				
			||||||
                        EFFECTS
 | 
					 | 
				
			||||||
                            .into_iter()
 | 
					 | 
				
			||||||
                            .find(|(name, _)| *name == s)
 | 
					 | 
				
			||||||
                            .map(|(_, effect)| effect)
 | 
					 | 
				
			||||||
                            .ok_or_else(|| {
 | 
					 | 
				
			||||||
                                format!(
 | 
					 | 
				
			||||||
                                    "expected one of {}",
 | 
					 | 
				
			||||||
                                    EFFECTS
 | 
					 | 
				
			||||||
                                        .into_iter()
 | 
					 | 
				
			||||||
                                        .map(|(n, _)| n)
 | 
					 | 
				
			||||||
                                        .collect::<Vec<_>>()
 | 
					 | 
				
			||||||
                                        .join(", ")
 | 
					 | 
				
			||||||
                                )
 | 
					 | 
				
			||||||
                            })
 | 
					 | 
				
			||||||
                    })?;
 | 
					 | 
				
			||||||
                    res.effects = res.effects.insert(effect);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                _ => return Err(arg.unexpected()),
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        Ok(res)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										611
									
								
								vendor/anstyle/src/color.rs
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										611
									
								
								vendor/anstyle/src/color.rs
									
									
									
									
										vendored
									
									
								
							@@ -1,611 +0,0 @@
 | 
				
			|||||||
/// Any ANSI color code scheme
 | 
					 | 
				
			||||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
 | 
					 | 
				
			||||||
pub enum Color {
 | 
					 | 
				
			||||||
    Ansi(AnsiColor),
 | 
					 | 
				
			||||||
    Ansi256(Ansi256Color),
 | 
					 | 
				
			||||||
    Rgb(RgbColor),
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl Color {
 | 
					 | 
				
			||||||
    /// Create a [`Style`][crate::Style] with this as the foreground
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub fn on(self, background: impl Into<Color>) -> crate::Style {
 | 
					 | 
				
			||||||
        crate::Style::new()
 | 
					 | 
				
			||||||
            .fg_color(Some(self))
 | 
					 | 
				
			||||||
            .bg_color(Some(background.into()))
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Create a [`Style`][crate::Style] with this as the foreground
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub const fn on_default(self) -> crate::Style {
 | 
					 | 
				
			||||||
        crate::Style::new().fg_color(Some(self))
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Render the ANSI code for a foreground color
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub fn render_fg(self) -> impl core::fmt::Display + Copy + Clone {
 | 
					 | 
				
			||||||
        match self {
 | 
					 | 
				
			||||||
            Self::Ansi(color) => DisplayBuffer::default().write_str(color.as_fg_str()),
 | 
					 | 
				
			||||||
            Self::Ansi256(color) => color.as_fg_buffer(),
 | 
					 | 
				
			||||||
            Self::Rgb(color) => color.as_fg_buffer(),
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    #[cfg(feature = "std")]
 | 
					 | 
				
			||||||
    pub(crate) fn write_fg_to(self, write: &mut dyn std::io::Write) -> std::io::Result<()> {
 | 
					 | 
				
			||||||
        let buffer = match self {
 | 
					 | 
				
			||||||
            Self::Ansi(color) => DisplayBuffer::default().write_str(color.as_fg_str()),
 | 
					 | 
				
			||||||
            Self::Ansi256(color) => color.as_fg_buffer(),
 | 
					 | 
				
			||||||
            Self::Rgb(color) => color.as_fg_buffer(),
 | 
					 | 
				
			||||||
        };
 | 
					 | 
				
			||||||
        buffer.write_to(write)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Render the ANSI code for a background color
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub fn render_bg(self) -> impl core::fmt::Display + Copy + Clone {
 | 
					 | 
				
			||||||
        match self {
 | 
					 | 
				
			||||||
            Self::Ansi(color) => DisplayBuffer::default().write_str(color.as_bg_str()),
 | 
					 | 
				
			||||||
            Self::Ansi256(color) => color.as_bg_buffer(),
 | 
					 | 
				
			||||||
            Self::Rgb(color) => color.as_bg_buffer(),
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    #[cfg(feature = "std")]
 | 
					 | 
				
			||||||
    pub(crate) fn write_bg_to(self, write: &mut dyn std::io::Write) -> std::io::Result<()> {
 | 
					 | 
				
			||||||
        let buffer = match self {
 | 
					 | 
				
			||||||
            Self::Ansi(color) => DisplayBuffer::default().write_str(color.as_bg_str()),
 | 
					 | 
				
			||||||
            Self::Ansi256(color) => color.as_bg_buffer(),
 | 
					 | 
				
			||||||
            Self::Rgb(color) => color.as_bg_buffer(),
 | 
					 | 
				
			||||||
        };
 | 
					 | 
				
			||||||
        buffer.write_to(write)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub(crate) fn render_underline(self) -> impl core::fmt::Display + Copy + Clone {
 | 
					 | 
				
			||||||
        match self {
 | 
					 | 
				
			||||||
            Self::Ansi(color) => color.as_underline_buffer(),
 | 
					 | 
				
			||||||
            Self::Ansi256(color) => color.as_underline_buffer(),
 | 
					 | 
				
			||||||
            Self::Rgb(color) => color.as_underline_buffer(),
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    #[cfg(feature = "std")]
 | 
					 | 
				
			||||||
    pub(crate) fn write_underline_to(self, write: &mut dyn std::io::Write) -> std::io::Result<()> {
 | 
					 | 
				
			||||||
        let buffer = match self {
 | 
					 | 
				
			||||||
            Self::Ansi(color) => color.as_underline_buffer(),
 | 
					 | 
				
			||||||
            Self::Ansi256(color) => color.as_underline_buffer(),
 | 
					 | 
				
			||||||
            Self::Rgb(color) => color.as_underline_buffer(),
 | 
					 | 
				
			||||||
        };
 | 
					 | 
				
			||||||
        buffer.write_to(write)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl From<AnsiColor> for Color {
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn from(inner: AnsiColor) -> Self {
 | 
					 | 
				
			||||||
        Self::Ansi(inner)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl From<Ansi256Color> for Color {
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn from(inner: Ansi256Color) -> Self {
 | 
					 | 
				
			||||||
        Self::Ansi256(inner)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl From<RgbColor> for Color {
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn from(inner: RgbColor) -> Self {
 | 
					 | 
				
			||||||
        Self::Rgb(inner)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl From<u8> for Color {
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn from(inner: u8) -> Self {
 | 
					 | 
				
			||||||
        Self::Ansi256(inner.into())
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl From<(u8, u8, u8)> for Color {
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn from(inner: (u8, u8, u8)) -> Self {
 | 
					 | 
				
			||||||
        Self::Rgb(inner.into())
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// Available 4-bit ANSI color palette codes
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// The user's terminal defines the meaning of the each palette code.
 | 
					 | 
				
			||||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
 | 
					 | 
				
			||||||
#[repr(u8)]
 | 
					 | 
				
			||||||
pub enum AnsiColor {
 | 
					 | 
				
			||||||
    /// Black: #0 (foreground code `30`, background code `40`).
 | 
					 | 
				
			||||||
    Black,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Red: #1 (foreground code `31`, background code `41`).
 | 
					 | 
				
			||||||
    Red,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Green: #2 (foreground code `32`, background code `42`).
 | 
					 | 
				
			||||||
    Green,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Yellow: #3 (foreground code `33`, background code `43`).
 | 
					 | 
				
			||||||
    Yellow,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Blue: #4 (foreground code `34`, background code `44`).
 | 
					 | 
				
			||||||
    Blue,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Magenta: #5 (foreground code `35`, background code `45`).
 | 
					 | 
				
			||||||
    Magenta,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Cyan: #6 (foreground code `36`, background code `46`).
 | 
					 | 
				
			||||||
    Cyan,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// White: #7 (foreground code `37`, background code `47`).
 | 
					 | 
				
			||||||
    White,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Bright black: #0 (foreground code `90`, background code `100`).
 | 
					 | 
				
			||||||
    BrightBlack,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Bright red: #1 (foreground code `91`, background code `101`).
 | 
					 | 
				
			||||||
    BrightRed,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Bright green: #2 (foreground code `92`, background code `102`).
 | 
					 | 
				
			||||||
    BrightGreen,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Bright yellow: #3 (foreground code `93`, background code `103`).
 | 
					 | 
				
			||||||
    BrightYellow,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Bright blue: #4 (foreground code `94`, background code `104`).
 | 
					 | 
				
			||||||
    BrightBlue,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Bright magenta: #5 (foreground code `95`, background code `105`).
 | 
					 | 
				
			||||||
    BrightMagenta,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Bright cyan: #6 (foreground code `96`, background code `106`).
 | 
					 | 
				
			||||||
    BrightCyan,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Bright white: #7 (foreground code `97`, background code `107`).
 | 
					 | 
				
			||||||
    BrightWhite,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl AnsiColor {
 | 
					 | 
				
			||||||
    /// Create a [`Style`][crate::Style] with this as the foreground
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub fn on(self, background: impl Into<Color>) -> crate::Style {
 | 
					 | 
				
			||||||
        crate::Style::new()
 | 
					 | 
				
			||||||
            .fg_color(Some(self.into()))
 | 
					 | 
				
			||||||
            .bg_color(Some(background.into()))
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Create a [`Style`][crate::Style] with this as the foreground
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub const fn on_default(self) -> crate::Style {
 | 
					 | 
				
			||||||
        crate::Style::new().fg_color(Some(Color::Ansi(self)))
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Render the ANSI code for a foreground color
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub fn render_fg(self) -> impl core::fmt::Display + Copy + Clone {
 | 
					 | 
				
			||||||
        self.as_fg_str()
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn as_fg_str(&self) -> &'static str {
 | 
					 | 
				
			||||||
        match self {
 | 
					 | 
				
			||||||
            Self::Black => escape!("3", "0"),
 | 
					 | 
				
			||||||
            Self::Red => escape!("3", "1"),
 | 
					 | 
				
			||||||
            Self::Green => escape!("3", "2"),
 | 
					 | 
				
			||||||
            Self::Yellow => escape!("3", "3"),
 | 
					 | 
				
			||||||
            Self::Blue => escape!("3", "4"),
 | 
					 | 
				
			||||||
            Self::Magenta => escape!("3", "5"),
 | 
					 | 
				
			||||||
            Self::Cyan => escape!("3", "6"),
 | 
					 | 
				
			||||||
            Self::White => escape!("3", "7"),
 | 
					 | 
				
			||||||
            Self::BrightBlack => escape!("9", "0"),
 | 
					 | 
				
			||||||
            Self::BrightRed => escape!("9", "1"),
 | 
					 | 
				
			||||||
            Self::BrightGreen => escape!("9", "2"),
 | 
					 | 
				
			||||||
            Self::BrightYellow => escape!("9", "3"),
 | 
					 | 
				
			||||||
            Self::BrightBlue => escape!("9", "4"),
 | 
					 | 
				
			||||||
            Self::BrightMagenta => escape!("9", "5"),
 | 
					 | 
				
			||||||
            Self::BrightCyan => escape!("9", "6"),
 | 
					 | 
				
			||||||
            Self::BrightWhite => escape!("9", "7"),
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Render the ANSI code for a background color
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub fn render_bg(self) -> impl core::fmt::Display + Copy + Clone {
 | 
					 | 
				
			||||||
        self.as_bg_str()
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn as_bg_str(&self) -> &'static str {
 | 
					 | 
				
			||||||
        match self {
 | 
					 | 
				
			||||||
            Self::Black => escape!("4", "0"),
 | 
					 | 
				
			||||||
            Self::Red => escape!("4", "1"),
 | 
					 | 
				
			||||||
            Self::Green => escape!("4", "2"),
 | 
					 | 
				
			||||||
            Self::Yellow => escape!("4", "3"),
 | 
					 | 
				
			||||||
            Self::Blue => escape!("4", "4"),
 | 
					 | 
				
			||||||
            Self::Magenta => escape!("4", "5"),
 | 
					 | 
				
			||||||
            Self::Cyan => escape!("4", "6"),
 | 
					 | 
				
			||||||
            Self::White => escape!("4", "7"),
 | 
					 | 
				
			||||||
            Self::BrightBlack => escape!("10", "0"),
 | 
					 | 
				
			||||||
            Self::BrightRed => escape!("10", "1"),
 | 
					 | 
				
			||||||
            Self::BrightGreen => escape!("10", "2"),
 | 
					 | 
				
			||||||
            Self::BrightYellow => escape!("10", "3"),
 | 
					 | 
				
			||||||
            Self::BrightBlue => escape!("10", "4"),
 | 
					 | 
				
			||||||
            Self::BrightMagenta => escape!("10", "5"),
 | 
					 | 
				
			||||||
            Self::BrightCyan => escape!("10", "6"),
 | 
					 | 
				
			||||||
            Self::BrightWhite => escape!("10", "7"),
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn as_underline_buffer(&self) -> DisplayBuffer {
 | 
					 | 
				
			||||||
        // No per-color codes; must delegate to `Ansi256Color`
 | 
					 | 
				
			||||||
        Ansi256Color::from(*self).as_underline_buffer()
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Change the color to/from bright
 | 
					 | 
				
			||||||
    #[must_use]
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub fn bright(self, yes: bool) -> Self {
 | 
					 | 
				
			||||||
        if yes {
 | 
					 | 
				
			||||||
            match self {
 | 
					 | 
				
			||||||
                Self::Black => Self::BrightBlack,
 | 
					 | 
				
			||||||
                Self::Red => Self::BrightRed,
 | 
					 | 
				
			||||||
                Self::Green => Self::BrightGreen,
 | 
					 | 
				
			||||||
                Self::Yellow => Self::BrightYellow,
 | 
					 | 
				
			||||||
                Self::Blue => Self::BrightBlue,
 | 
					 | 
				
			||||||
                Self::Magenta => Self::BrightMagenta,
 | 
					 | 
				
			||||||
                Self::Cyan => Self::BrightCyan,
 | 
					 | 
				
			||||||
                Self::White => Self::BrightWhite,
 | 
					 | 
				
			||||||
                Self::BrightBlack => self,
 | 
					 | 
				
			||||||
                Self::BrightRed => self,
 | 
					 | 
				
			||||||
                Self::BrightGreen => self,
 | 
					 | 
				
			||||||
                Self::BrightYellow => self,
 | 
					 | 
				
			||||||
                Self::BrightBlue => self,
 | 
					 | 
				
			||||||
                Self::BrightMagenta => self,
 | 
					 | 
				
			||||||
                Self::BrightCyan => self,
 | 
					 | 
				
			||||||
                Self::BrightWhite => self,
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            match self {
 | 
					 | 
				
			||||||
                Self::Black => self,
 | 
					 | 
				
			||||||
                Self::Red => self,
 | 
					 | 
				
			||||||
                Self::Green => self,
 | 
					 | 
				
			||||||
                Self::Yellow => self,
 | 
					 | 
				
			||||||
                Self::Blue => self,
 | 
					 | 
				
			||||||
                Self::Magenta => self,
 | 
					 | 
				
			||||||
                Self::Cyan => self,
 | 
					 | 
				
			||||||
                Self::White => self,
 | 
					 | 
				
			||||||
                Self::BrightBlack => Self::Black,
 | 
					 | 
				
			||||||
                Self::BrightRed => Self::Red,
 | 
					 | 
				
			||||||
                Self::BrightGreen => Self::Green,
 | 
					 | 
				
			||||||
                Self::BrightYellow => Self::Yellow,
 | 
					 | 
				
			||||||
                Self::BrightBlue => Self::Blue,
 | 
					 | 
				
			||||||
                Self::BrightMagenta => Self::Magenta,
 | 
					 | 
				
			||||||
                Self::BrightCyan => Self::Cyan,
 | 
					 | 
				
			||||||
                Self::BrightWhite => Self::White,
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Report whether the color is bright
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub fn is_bright(self) -> bool {
 | 
					 | 
				
			||||||
        match self {
 | 
					 | 
				
			||||||
            Self::Black => false,
 | 
					 | 
				
			||||||
            Self::Red => false,
 | 
					 | 
				
			||||||
            Self::Green => false,
 | 
					 | 
				
			||||||
            Self::Yellow => false,
 | 
					 | 
				
			||||||
            Self::Blue => false,
 | 
					 | 
				
			||||||
            Self::Magenta => false,
 | 
					 | 
				
			||||||
            Self::Cyan => false,
 | 
					 | 
				
			||||||
            Self::White => false,
 | 
					 | 
				
			||||||
            Self::BrightBlack => true,
 | 
					 | 
				
			||||||
            Self::BrightRed => true,
 | 
					 | 
				
			||||||
            Self::BrightGreen => true,
 | 
					 | 
				
			||||||
            Self::BrightYellow => true,
 | 
					 | 
				
			||||||
            Self::BrightBlue => true,
 | 
					 | 
				
			||||||
            Self::BrightMagenta => true,
 | 
					 | 
				
			||||||
            Self::BrightCyan => true,
 | 
					 | 
				
			||||||
            Self::BrightWhite => true,
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// 256 (8-bit) color support
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// - `0..16` are [`AnsiColor`] palette codes
 | 
					 | 
				
			||||||
/// - `0..232` map to [`RgbColor`] color values
 | 
					 | 
				
			||||||
/// - `232..` map to [`RgbColor`] gray-scale values
 | 
					 | 
				
			||||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
 | 
					 | 
				
			||||||
#[repr(transparent)]
 | 
					 | 
				
			||||||
pub struct Ansi256Color(pub u8);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl Ansi256Color {
 | 
					 | 
				
			||||||
    /// Create a [`Style`][crate::Style] with this as the foreground
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub fn on(self, background: impl Into<Color>) -> crate::Style {
 | 
					 | 
				
			||||||
        crate::Style::new()
 | 
					 | 
				
			||||||
            .fg_color(Some(self.into()))
 | 
					 | 
				
			||||||
            .bg_color(Some(background.into()))
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Create a [`Style`][crate::Style] with this as the foreground
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub const fn on_default(self) -> crate::Style {
 | 
					 | 
				
			||||||
        crate::Style::new().fg_color(Some(Color::Ansi256(self)))
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub const fn index(self) -> u8 {
 | 
					 | 
				
			||||||
        self.0
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub const fn into_ansi(self) -> Option<AnsiColor> {
 | 
					 | 
				
			||||||
        match self.index() {
 | 
					 | 
				
			||||||
            0 => Some(AnsiColor::Black),
 | 
					 | 
				
			||||||
            1 => Some(AnsiColor::Red),
 | 
					 | 
				
			||||||
            2 => Some(AnsiColor::Green),
 | 
					 | 
				
			||||||
            3 => Some(AnsiColor::Yellow),
 | 
					 | 
				
			||||||
            4 => Some(AnsiColor::Blue),
 | 
					 | 
				
			||||||
            5 => Some(AnsiColor::Magenta),
 | 
					 | 
				
			||||||
            6 => Some(AnsiColor::Cyan),
 | 
					 | 
				
			||||||
            7 => Some(AnsiColor::White),
 | 
					 | 
				
			||||||
            8 => Some(AnsiColor::BrightBlack),
 | 
					 | 
				
			||||||
            9 => Some(AnsiColor::BrightRed),
 | 
					 | 
				
			||||||
            10 => Some(AnsiColor::BrightGreen),
 | 
					 | 
				
			||||||
            11 => Some(AnsiColor::BrightYellow),
 | 
					 | 
				
			||||||
            12 => Some(AnsiColor::BrightBlue),
 | 
					 | 
				
			||||||
            13 => Some(AnsiColor::BrightMagenta),
 | 
					 | 
				
			||||||
            14 => Some(AnsiColor::BrightCyan),
 | 
					 | 
				
			||||||
            15 => Some(AnsiColor::BrightWhite),
 | 
					 | 
				
			||||||
            _ => None,
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub const fn from_ansi(color: AnsiColor) -> Self {
 | 
					 | 
				
			||||||
        match color {
 | 
					 | 
				
			||||||
            AnsiColor::Black => Self(0),
 | 
					 | 
				
			||||||
            AnsiColor::Red => Self(1),
 | 
					 | 
				
			||||||
            AnsiColor::Green => Self(2),
 | 
					 | 
				
			||||||
            AnsiColor::Yellow => Self(3),
 | 
					 | 
				
			||||||
            AnsiColor::Blue => Self(4),
 | 
					 | 
				
			||||||
            AnsiColor::Magenta => Self(5),
 | 
					 | 
				
			||||||
            AnsiColor::Cyan => Self(6),
 | 
					 | 
				
			||||||
            AnsiColor::White => Self(7),
 | 
					 | 
				
			||||||
            AnsiColor::BrightBlack => Self(8),
 | 
					 | 
				
			||||||
            AnsiColor::BrightRed => Self(9),
 | 
					 | 
				
			||||||
            AnsiColor::BrightGreen => Self(10),
 | 
					 | 
				
			||||||
            AnsiColor::BrightYellow => Self(11),
 | 
					 | 
				
			||||||
            AnsiColor::BrightBlue => Self(12),
 | 
					 | 
				
			||||||
            AnsiColor::BrightMagenta => Self(13),
 | 
					 | 
				
			||||||
            AnsiColor::BrightCyan => Self(14),
 | 
					 | 
				
			||||||
            AnsiColor::BrightWhite => Self(15),
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Render the ANSI code for a foreground color
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub fn render_fg(self) -> impl core::fmt::Display + Copy + Clone {
 | 
					 | 
				
			||||||
        self.as_fg_buffer()
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn as_fg_buffer(&self) -> DisplayBuffer {
 | 
					 | 
				
			||||||
        DisplayBuffer::default()
 | 
					 | 
				
			||||||
            .write_str("\x1B[38;5;")
 | 
					 | 
				
			||||||
            .write_code(self.index())
 | 
					 | 
				
			||||||
            .write_str("m")
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Render the ANSI code for a background color
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub fn render_bg(self) -> impl core::fmt::Display + Copy + Clone {
 | 
					 | 
				
			||||||
        self.as_bg_buffer()
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn as_bg_buffer(&self) -> DisplayBuffer {
 | 
					 | 
				
			||||||
        DisplayBuffer::default()
 | 
					 | 
				
			||||||
            .write_str("\x1B[48;5;")
 | 
					 | 
				
			||||||
            .write_code(self.index())
 | 
					 | 
				
			||||||
            .write_str("m")
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn as_underline_buffer(&self) -> DisplayBuffer {
 | 
					 | 
				
			||||||
        DisplayBuffer::default()
 | 
					 | 
				
			||||||
            .write_str("\x1B[58;5;")
 | 
					 | 
				
			||||||
            .write_code(self.index())
 | 
					 | 
				
			||||||
            .write_str("m")
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl From<u8> for Ansi256Color {
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn from(inner: u8) -> Self {
 | 
					 | 
				
			||||||
        Self(inner)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl From<AnsiColor> for Ansi256Color {
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn from(inner: AnsiColor) -> Self {
 | 
					 | 
				
			||||||
        Self::from_ansi(inner)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// 24-bit ANSI RGB color codes
 | 
					 | 
				
			||||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
 | 
					 | 
				
			||||||
pub struct RgbColor(pub u8, pub u8, pub u8);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl RgbColor {
 | 
					 | 
				
			||||||
    /// Create a [`Style`][crate::Style] with this as the foreground
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub fn on(self, background: impl Into<Color>) -> crate::Style {
 | 
					 | 
				
			||||||
        crate::Style::new()
 | 
					 | 
				
			||||||
            .fg_color(Some(self.into()))
 | 
					 | 
				
			||||||
            .bg_color(Some(background.into()))
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Create a [`Style`][crate::Style] with this as the foreground
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub const fn on_default(self) -> crate::Style {
 | 
					 | 
				
			||||||
        crate::Style::new().fg_color(Some(Color::Rgb(self)))
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub const fn r(self) -> u8 {
 | 
					 | 
				
			||||||
        self.0
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub const fn g(self) -> u8 {
 | 
					 | 
				
			||||||
        self.1
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub const fn b(self) -> u8 {
 | 
					 | 
				
			||||||
        self.2
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Render the ANSI code for a foreground color
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub fn render_fg(self) -> impl core::fmt::Display + Copy + Clone {
 | 
					 | 
				
			||||||
        self.as_fg_buffer()
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn as_fg_buffer(&self) -> DisplayBuffer {
 | 
					 | 
				
			||||||
        DisplayBuffer::default()
 | 
					 | 
				
			||||||
            .write_str("\x1B[38;2;")
 | 
					 | 
				
			||||||
            .write_code(self.r())
 | 
					 | 
				
			||||||
            .write_str(";")
 | 
					 | 
				
			||||||
            .write_code(self.g())
 | 
					 | 
				
			||||||
            .write_str(";")
 | 
					 | 
				
			||||||
            .write_code(self.b())
 | 
					 | 
				
			||||||
            .write_str("m")
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Render the ANSI code for a background color
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub fn render_bg(self) -> impl core::fmt::Display + Copy + Clone {
 | 
					 | 
				
			||||||
        self.as_bg_buffer()
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn as_bg_buffer(&self) -> DisplayBuffer {
 | 
					 | 
				
			||||||
        DisplayBuffer::default()
 | 
					 | 
				
			||||||
            .write_str("\x1B[48;2;")
 | 
					 | 
				
			||||||
            .write_code(self.r())
 | 
					 | 
				
			||||||
            .write_str(";")
 | 
					 | 
				
			||||||
            .write_code(self.g())
 | 
					 | 
				
			||||||
            .write_str(";")
 | 
					 | 
				
			||||||
            .write_code(self.b())
 | 
					 | 
				
			||||||
            .write_str("m")
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn as_underline_buffer(&self) -> DisplayBuffer {
 | 
					 | 
				
			||||||
        DisplayBuffer::default()
 | 
					 | 
				
			||||||
            .write_str("\x1B[58;2;")
 | 
					 | 
				
			||||||
            .write_code(self.r())
 | 
					 | 
				
			||||||
            .write_str(";")
 | 
					 | 
				
			||||||
            .write_code(self.g())
 | 
					 | 
				
			||||||
            .write_str(";")
 | 
					 | 
				
			||||||
            .write_code(self.b())
 | 
					 | 
				
			||||||
            .write_str("m")
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl From<(u8, u8, u8)> for RgbColor {
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn from(inner: (u8, u8, u8)) -> Self {
 | 
					 | 
				
			||||||
        let (r, g, b) = inner;
 | 
					 | 
				
			||||||
        Self(r, g, b)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[derive(Copy, Clone, Default, Debug)]
 | 
					 | 
				
			||||||
struct DisplayBuffer {
 | 
					 | 
				
			||||||
    buffer: [u8; 19],
 | 
					 | 
				
			||||||
    len: usize,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl DisplayBuffer {
 | 
					 | 
				
			||||||
    #[must_use]
 | 
					 | 
				
			||||||
    #[inline(never)]
 | 
					 | 
				
			||||||
    fn write_str(mut self, part: &'static str) -> Self {
 | 
					 | 
				
			||||||
        for (i, b) in part.as_bytes().iter().enumerate() {
 | 
					 | 
				
			||||||
            self.buffer[self.len + i] = *b;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        self.len += part.len();
 | 
					 | 
				
			||||||
        self
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[must_use]
 | 
					 | 
				
			||||||
    #[inline(never)]
 | 
					 | 
				
			||||||
    fn write_code(mut self, code: u8) -> Self {
 | 
					 | 
				
			||||||
        let c1: u8 = (code / 100) % 10;
 | 
					 | 
				
			||||||
        let c2: u8 = (code / 10) % 10;
 | 
					 | 
				
			||||||
        let c3: u8 = code % 10;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        let mut printed = true;
 | 
					 | 
				
			||||||
        if c1 != 0 {
 | 
					 | 
				
			||||||
            printed = true;
 | 
					 | 
				
			||||||
            self.buffer[self.len] = b'0' + c1;
 | 
					 | 
				
			||||||
            self.len += 1;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        if c2 != 0 || printed {
 | 
					 | 
				
			||||||
            self.buffer[self.len] = b'0' + c2;
 | 
					 | 
				
			||||||
            self.len += 1;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        // If we received a zero value we must still print a value.
 | 
					 | 
				
			||||||
        self.buffer[self.len] = b'0' + c3;
 | 
					 | 
				
			||||||
        self.len += 1;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn as_str(&self) -> &str {
 | 
					 | 
				
			||||||
        // SAFETY: Only `&str` can be written to the buffer
 | 
					 | 
				
			||||||
        unsafe { core::str::from_utf8_unchecked(&self.buffer[0..self.len]) }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    #[cfg(feature = "std")]
 | 
					 | 
				
			||||||
    fn write_to(self, write: &mut dyn std::io::Write) -> std::io::Result<()> {
 | 
					 | 
				
			||||||
        write.write_all(self.as_str().as_bytes())
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl core::fmt::Display for DisplayBuffer {
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
 | 
					 | 
				
			||||||
        self.as_str().fmt(f)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[cfg(test)]
 | 
					 | 
				
			||||||
#[cfg(feature = "std")]
 | 
					 | 
				
			||||||
mod test {
 | 
					 | 
				
			||||||
    use super::*;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[test]
 | 
					 | 
				
			||||||
    fn max_display_buffer() {
 | 
					 | 
				
			||||||
        let c = RgbColor(255, 255, 255);
 | 
					 | 
				
			||||||
        let actual = c.render_fg().to_string();
 | 
					 | 
				
			||||||
        assert_eq!(actual, "\u{1b}[38;2;255;255;255m");
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										369
									
								
								vendor/anstyle/src/effect.rs
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										369
									
								
								vendor/anstyle/src/effect.rs
									
									
									
									
										vendored
									
									
								
							@@ -1,369 +0,0 @@
 | 
				
			|||||||
/// A set of text effects
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// # Examples
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// ```rust
 | 
					 | 
				
			||||||
/// let effects = anstyle::Effects::BOLD | anstyle::Effects::UNDERLINE;
 | 
					 | 
				
			||||||
/// ```
 | 
					 | 
				
			||||||
#[derive(Copy, Clone, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
 | 
					 | 
				
			||||||
pub struct Effects(u16);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl Effects {
 | 
					 | 
				
			||||||
    const PLAIN: Self = Effects(0);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    pub const BOLD: Self = Effects(1 << 0);
 | 
					 | 
				
			||||||
    pub const DIMMED: Self = Effects(1 << 1);
 | 
					 | 
				
			||||||
    /// Not widely supported. Sometimes treated as inverse or blink
 | 
					 | 
				
			||||||
    pub const ITALIC: Self = Effects(1 << 2);
 | 
					 | 
				
			||||||
    /// Style extensions exist for Kitty, VTE, mintty and iTerm2.
 | 
					 | 
				
			||||||
    pub const UNDERLINE: Self = Effects(1 << 3);
 | 
					 | 
				
			||||||
    pub const DOUBLE_UNDERLINE: Self = Effects(1 << 4);
 | 
					 | 
				
			||||||
    pub const CURLY_UNDERLINE: Self = Effects(1 << 5);
 | 
					 | 
				
			||||||
    pub const DOTTED_UNDERLINE: Self = Effects(1 << 6);
 | 
					 | 
				
			||||||
    pub const DASHED_UNDERLINE: Self = Effects(1 << 7);
 | 
					 | 
				
			||||||
    pub const BLINK: Self = Effects(1 << 8);
 | 
					 | 
				
			||||||
    /// Swap foreground and background colors; inconsistent emulation
 | 
					 | 
				
			||||||
    pub const INVERT: Self = Effects(1 << 9);
 | 
					 | 
				
			||||||
    pub const HIDDEN: Self = Effects(1 << 10);
 | 
					 | 
				
			||||||
    ///  Characters legible but marked as if for deletion. Not supported in Terminal.app
 | 
					 | 
				
			||||||
    pub const STRIKETHROUGH: Self = Effects(1 << 11);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// No effects enabled
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// # Examples
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// ```rust
 | 
					 | 
				
			||||||
    /// let effects = anstyle::Effects::new();
 | 
					 | 
				
			||||||
    /// ```
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub const fn new() -> Self {
 | 
					 | 
				
			||||||
        Self::PLAIN
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Check if no effects are enabled
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// # Examples
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// ```rust
 | 
					 | 
				
			||||||
    /// let effects = anstyle::Effects::new();
 | 
					 | 
				
			||||||
    /// assert!(effects.is_plain());
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// let effects = anstyle::Effects::BOLD | anstyle::Effects::UNDERLINE;
 | 
					 | 
				
			||||||
    /// assert!(!effects.is_plain());
 | 
					 | 
				
			||||||
    /// ```
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub const fn is_plain(self) -> bool {
 | 
					 | 
				
			||||||
        self.0 == Self::PLAIN.0
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Returns `true` if all of the effects in `other` are contained within `self`.
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// # Examples
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// ```rust
 | 
					 | 
				
			||||||
    /// let effects = anstyle::Effects::BOLD | anstyle::Effects::UNDERLINE;
 | 
					 | 
				
			||||||
    /// assert!(effects.contains(anstyle::Effects::BOLD));
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// let effects = anstyle::Effects::new();
 | 
					 | 
				
			||||||
    /// assert!(!effects.contains(anstyle::Effects::BOLD));
 | 
					 | 
				
			||||||
    /// ```
 | 
					 | 
				
			||||||
    #[inline(always)]
 | 
					 | 
				
			||||||
    pub const fn contains(self, other: Effects) -> bool {
 | 
					 | 
				
			||||||
        (other.0 & self.0) == other.0
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Inserts the specified effects in-place.
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// # Examples
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// ```rust
 | 
					 | 
				
			||||||
    /// let effects = anstyle::Effects::new().insert(anstyle::Effects::new());
 | 
					 | 
				
			||||||
    /// assert!(effects.is_plain());
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// let effects = anstyle::Effects::new().insert(anstyle::Effects::BOLD);
 | 
					 | 
				
			||||||
    /// assert!(effects.contains(anstyle::Effects::BOLD));
 | 
					 | 
				
			||||||
    /// ```
 | 
					 | 
				
			||||||
    #[inline(always)]
 | 
					 | 
				
			||||||
    #[must_use]
 | 
					 | 
				
			||||||
    pub const fn insert(mut self, other: Effects) -> Self {
 | 
					 | 
				
			||||||
        self.0 |= other.0;
 | 
					 | 
				
			||||||
        self
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Removes the specified effects in-place.
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// # Examples
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// ```rust
 | 
					 | 
				
			||||||
    /// let effects = (anstyle::Effects::BOLD | anstyle::Effects::UNDERLINE).remove(anstyle::Effects::BOLD);
 | 
					 | 
				
			||||||
    /// assert!(!effects.contains(anstyle::Effects::BOLD));
 | 
					 | 
				
			||||||
    /// assert!(effects.contains(anstyle::Effects::UNDERLINE));
 | 
					 | 
				
			||||||
    /// ```
 | 
					 | 
				
			||||||
    #[inline(always)]
 | 
					 | 
				
			||||||
    #[must_use]
 | 
					 | 
				
			||||||
    pub const fn remove(mut self, other: Effects) -> Self {
 | 
					 | 
				
			||||||
        self.0 &= !other.0;
 | 
					 | 
				
			||||||
        self
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Reset all effects in-place
 | 
					 | 
				
			||||||
    /// ```rust
 | 
					 | 
				
			||||||
    /// let effects = (anstyle::Effects::BOLD | anstyle::Effects::UNDERLINE).clear();
 | 
					 | 
				
			||||||
    /// assert!(!effects.contains(anstyle::Effects::BOLD));
 | 
					 | 
				
			||||||
    /// assert!(!effects.contains(anstyle::Effects::UNDERLINE));
 | 
					 | 
				
			||||||
    /// ```
 | 
					 | 
				
			||||||
    #[inline(always)]
 | 
					 | 
				
			||||||
    #[must_use]
 | 
					 | 
				
			||||||
    pub const fn clear(self) -> Self {
 | 
					 | 
				
			||||||
        Self::new()
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Enable or disable the specified effects depending on the passed value.
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// # Examples
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// ```rust
 | 
					 | 
				
			||||||
    /// let effects = anstyle::Effects::new().set(anstyle::Effects::BOLD, true);
 | 
					 | 
				
			||||||
    /// assert!(effects.contains(anstyle::Effects::BOLD));
 | 
					 | 
				
			||||||
    /// ```
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    #[must_use]
 | 
					 | 
				
			||||||
    pub const fn set(self, other: Self, enable: bool) -> Self {
 | 
					 | 
				
			||||||
        if enable {
 | 
					 | 
				
			||||||
            self.insert(other)
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            self.remove(other)
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Iterate over enabled effects
 | 
					 | 
				
			||||||
    #[inline(always)]
 | 
					 | 
				
			||||||
    pub fn iter(self) -> EffectIter {
 | 
					 | 
				
			||||||
        EffectIter {
 | 
					 | 
				
			||||||
            index: 0,
 | 
					 | 
				
			||||||
            effects: self,
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Iterate over enabled effect indices
 | 
					 | 
				
			||||||
    #[inline(always)]
 | 
					 | 
				
			||||||
    pub(crate) fn index_iter(self) -> EffectIndexIter {
 | 
					 | 
				
			||||||
        EffectIndexIter {
 | 
					 | 
				
			||||||
            index: 0,
 | 
					 | 
				
			||||||
            effects: self,
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Render the ANSI code
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub fn render(self) -> impl core::fmt::Display + Copy + Clone {
 | 
					 | 
				
			||||||
        EffectsDisplay(self)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    #[cfg(feature = "std")]
 | 
					 | 
				
			||||||
    pub(crate) fn write_to(self, write: &mut dyn std::io::Write) -> std::io::Result<()> {
 | 
					 | 
				
			||||||
        for index in self.index_iter() {
 | 
					 | 
				
			||||||
            write.write_all(METADATA[index].escape.as_bytes())?;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        Ok(())
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// # Examples
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// ```rust
 | 
					 | 
				
			||||||
/// let effects = anstyle::Effects::new();
 | 
					 | 
				
			||||||
/// assert_eq!(format!("{:?}", effects), "Effects()");
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// let effects = anstyle::Effects::BOLD | anstyle::Effects::UNDERLINE;
 | 
					 | 
				
			||||||
/// assert_eq!(format!("{:?}", effects), "Effects(BOLD | UNDERLINE)");
 | 
					 | 
				
			||||||
/// ```
 | 
					 | 
				
			||||||
impl core::fmt::Debug for Effects {
 | 
					 | 
				
			||||||
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
 | 
					 | 
				
			||||||
        write!(f, "Effects(")?;
 | 
					 | 
				
			||||||
        for (i, index) in self.index_iter().enumerate() {
 | 
					 | 
				
			||||||
            if i != 0 {
 | 
					 | 
				
			||||||
                write!(f, " | ")?;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            write!(f, "{}", METADATA[index].name)?;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        write!(f, ")")?;
 | 
					 | 
				
			||||||
        Ok(())
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// # Examples
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// ```rust
 | 
					 | 
				
			||||||
/// let effects = anstyle::Effects::BOLD | anstyle::Effects::UNDERLINE;
 | 
					 | 
				
			||||||
/// assert_eq!(format!("{:?}", effects), "Effects(BOLD | UNDERLINE)");
 | 
					 | 
				
			||||||
/// ```
 | 
					 | 
				
			||||||
impl core::ops::BitOr for Effects {
 | 
					 | 
				
			||||||
    type Output = Self;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[inline(always)]
 | 
					 | 
				
			||||||
    fn bitor(self, rhs: Self) -> Self {
 | 
					 | 
				
			||||||
        self.insert(rhs)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// # Examples
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// ```rust
 | 
					 | 
				
			||||||
/// let mut effects = anstyle::Effects::BOLD;
 | 
					 | 
				
			||||||
/// effects |= anstyle::Effects::UNDERLINE;
 | 
					 | 
				
			||||||
/// assert_eq!(format!("{:?}", effects), "Effects(BOLD | UNDERLINE)");
 | 
					 | 
				
			||||||
/// ```
 | 
					 | 
				
			||||||
impl core::ops::BitOrAssign for Effects {
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn bitor_assign(&mut self, other: Self) {
 | 
					 | 
				
			||||||
        *self = self.insert(other);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// # Examples
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// ```rust
 | 
					 | 
				
			||||||
/// let effects = (anstyle::Effects::BOLD | anstyle::Effects::UNDERLINE) - anstyle::Effects::BOLD;
 | 
					 | 
				
			||||||
/// assert_eq!(format!("{:?}", effects), "Effects(UNDERLINE)");
 | 
					 | 
				
			||||||
/// ```
 | 
					 | 
				
			||||||
impl core::ops::Sub for Effects {
 | 
					 | 
				
			||||||
    type Output = Self;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn sub(self, other: Self) -> Self {
 | 
					 | 
				
			||||||
        self.remove(other)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// # Examples
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// ```rust
 | 
					 | 
				
			||||||
/// let mut effects = anstyle::Effects::BOLD | anstyle::Effects::UNDERLINE;
 | 
					 | 
				
			||||||
/// effects -= anstyle::Effects::BOLD;
 | 
					 | 
				
			||||||
/// assert_eq!(format!("{:?}", effects), "Effects(UNDERLINE)");
 | 
					 | 
				
			||||||
/// ```
 | 
					 | 
				
			||||||
impl core::ops::SubAssign for Effects {
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn sub_assign(&mut self, other: Self) {
 | 
					 | 
				
			||||||
        *self = self.remove(other);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pub(crate) struct Metadata {
 | 
					 | 
				
			||||||
    pub(crate) name: &'static str,
 | 
					 | 
				
			||||||
    pub(crate) escape: &'static str,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pub(crate) const METADATA: [Metadata; 12] = [
 | 
					 | 
				
			||||||
    Metadata {
 | 
					 | 
				
			||||||
        name: "BOLD",
 | 
					 | 
				
			||||||
        escape: escape!("1"),
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    Metadata {
 | 
					 | 
				
			||||||
        name: "DIMMED",
 | 
					 | 
				
			||||||
        escape: escape!("2"),
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    Metadata {
 | 
					 | 
				
			||||||
        name: "ITALIC",
 | 
					 | 
				
			||||||
        escape: escape!("3"),
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    Metadata {
 | 
					 | 
				
			||||||
        name: "UNDERLINE",
 | 
					 | 
				
			||||||
        escape: escape!("4"),
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    Metadata {
 | 
					 | 
				
			||||||
        name: "DOUBLE_UNDERLINE",
 | 
					 | 
				
			||||||
        escape: escape!("21"),
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    Metadata {
 | 
					 | 
				
			||||||
        name: "CURLY_UNDERLINE",
 | 
					 | 
				
			||||||
        escape: escape!("4:3"),
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    Metadata {
 | 
					 | 
				
			||||||
        name: "DOTTED_UNDERLINE",
 | 
					 | 
				
			||||||
        escape: escape!("4:4"),
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    Metadata {
 | 
					 | 
				
			||||||
        name: "DASHED_UNDERLINE",
 | 
					 | 
				
			||||||
        escape: escape!("4:5"),
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    Metadata {
 | 
					 | 
				
			||||||
        name: "BLINK",
 | 
					 | 
				
			||||||
        escape: escape!("5"),
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    Metadata {
 | 
					 | 
				
			||||||
        name: "INVERT",
 | 
					 | 
				
			||||||
        escape: escape!("7"),
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    Metadata {
 | 
					 | 
				
			||||||
        name: "HIDDEN",
 | 
					 | 
				
			||||||
        escape: escape!("8"),
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    Metadata {
 | 
					 | 
				
			||||||
        name: "STRIKETHROUGH",
 | 
					 | 
				
			||||||
        escape: escape!("9"),
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[derive(Copy, Clone, Default, Debug)]
 | 
					 | 
				
			||||||
struct EffectsDisplay(Effects);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl core::fmt::Display for EffectsDisplay {
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
 | 
					 | 
				
			||||||
        for index in self.0.index_iter() {
 | 
					 | 
				
			||||||
            METADATA[index].escape.fmt(f)?;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        Ok(())
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[derive(Clone, Debug, PartialEq, Eq)]
 | 
					 | 
				
			||||||
pub struct EffectIter {
 | 
					 | 
				
			||||||
    index: usize,
 | 
					 | 
				
			||||||
    effects: Effects,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl Iterator for EffectIter {
 | 
					 | 
				
			||||||
    type Item = Effects;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    fn next(&mut self) -> Option<Self::Item> {
 | 
					 | 
				
			||||||
        while self.index < METADATA.len() {
 | 
					 | 
				
			||||||
            let index = self.index;
 | 
					 | 
				
			||||||
            self.index += 1;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            let effect = Effects(1 << index);
 | 
					 | 
				
			||||||
            if self.effects.contains(effect) {
 | 
					 | 
				
			||||||
                return Some(effect);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        None
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[derive(Clone, Debug, PartialEq, Eq)]
 | 
					 | 
				
			||||||
pub(crate) struct EffectIndexIter {
 | 
					 | 
				
			||||||
    index: usize,
 | 
					 | 
				
			||||||
    effects: Effects,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl Iterator for EffectIndexIter {
 | 
					 | 
				
			||||||
    type Item = usize;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    fn next(&mut self) -> Option<Self::Item> {
 | 
					 | 
				
			||||||
        while self.index < METADATA.len() {
 | 
					 | 
				
			||||||
            let index = self.index;
 | 
					 | 
				
			||||||
            self.index += 1;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            let effect = Effects(1 << index);
 | 
					 | 
				
			||||||
            if self.effects.contains(effect) {
 | 
					 | 
				
			||||||
                return Some(index);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        None
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										59
									
								
								vendor/anstyle/src/lib.rs
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										59
									
								
								vendor/anstyle/src/lib.rs
									
									
									
									
										vendored
									
									
								
							@@ -1,59 +0,0 @@
 | 
				
			|||||||
//! ANSI Text Styling
 | 
					 | 
				
			||||||
//!
 | 
					 | 
				
			||||||
//! *A portmanteau of "ansi style"*
 | 
					 | 
				
			||||||
//!
 | 
					 | 
				
			||||||
//! `anstyle` provides core types describing [ANSI styling escape
 | 
					 | 
				
			||||||
//! codes](https://en.wikipedia.org/wiki/ANSI_escape_code) for interoperability
 | 
					 | 
				
			||||||
//! between crates.
 | 
					 | 
				
			||||||
//!
 | 
					 | 
				
			||||||
//! Example use cases:
 | 
					 | 
				
			||||||
//! - An argument parser allowing callers to define the colors used in the help-output without
 | 
					 | 
				
			||||||
//!   putting the text formatting crate in the public API
 | 
					 | 
				
			||||||
//! - A style description parser that can work with any text formatting crate
 | 
					 | 
				
			||||||
//!
 | 
					 | 
				
			||||||
//! Priorities:
 | 
					 | 
				
			||||||
//! 1. API stability
 | 
					 | 
				
			||||||
//! 2. Low compile-time and binary-size overhead
 | 
					 | 
				
			||||||
//! 3. `const` friendly API for callers to statically define their stylesheet
 | 
					 | 
				
			||||||
//!
 | 
					 | 
				
			||||||
//! For integration with text styling crate, see:
 | 
					 | 
				
			||||||
//! - [anstyle-ansi-term](https://docs.rs/anstyle-ansi-term)
 | 
					 | 
				
			||||||
//! - [anstyle-crossterm](https://docs.rs/anstyle-crossterm)
 | 
					 | 
				
			||||||
//! - [anstyle-owo-colors](https://docs.rs/anstyle-owo-colors)
 | 
					 | 
				
			||||||
//! - [anstyle-termcolor](https://docs.rs/anstyle-termcolor)
 | 
					 | 
				
			||||||
//! - [anstyle-yansi](https://docs.rs/anstyle-yansi)
 | 
					 | 
				
			||||||
//!
 | 
					 | 
				
			||||||
//! User-styling parsers:
 | 
					 | 
				
			||||||
//! - [anstyle-git](https://docs.rs/anstyle-git): Parse Git style descriptions
 | 
					 | 
				
			||||||
//! - [anstyle-ls](https://docs.rs/anstyle-ls): Parse LS_COLORS style descriptions
 | 
					 | 
				
			||||||
//!
 | 
					 | 
				
			||||||
//! Convert to other formats
 | 
					 | 
				
			||||||
//! - [anstream](https://docs.rs/anstream): A simple cross platform library for writing colored text to a terminal
 | 
					 | 
				
			||||||
//! - [anstyle-roff](https://docs.rs/anstyle-roff): For converting to ROFF
 | 
					 | 
				
			||||||
//!
 | 
					 | 
				
			||||||
//! Utilities
 | 
					 | 
				
			||||||
//! - [anstyle-lossy](https://docs.rs/anstyle-lossy): Convert between `anstyle::Color` types
 | 
					 | 
				
			||||||
//! - [anstyle-parse](https://docs.rs/anstyle-parse): Parsing ANSI Style Escapes
 | 
					 | 
				
			||||||
//! - [anstyle-wincon](https://docs.rs/anstyle-wincon): Styling legacy Microsoft terminals
 | 
					 | 
				
			||||||
//!
 | 
					 | 
				
			||||||
//! # Examples
 | 
					 | 
				
			||||||
//!
 | 
					 | 
				
			||||||
//! The core type is [`Style`]:
 | 
					 | 
				
			||||||
//! ```rust
 | 
					 | 
				
			||||||
//! let style = anstyle::Style::new().bold();
 | 
					 | 
				
			||||||
//! ```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#![cfg_attr(not(feature = "std"), no_std)]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[macro_use]
 | 
					 | 
				
			||||||
mod macros;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
mod color;
 | 
					 | 
				
			||||||
mod effect;
 | 
					 | 
				
			||||||
mod reset;
 | 
					 | 
				
			||||||
mod style;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pub use color::*;
 | 
					 | 
				
			||||||
pub use effect::*;
 | 
					 | 
				
			||||||
pub use reset::*;
 | 
					 | 
				
			||||||
pub use style::*;
 | 
					 | 
				
			||||||
							
								
								
									
										5
									
								
								vendor/anstyle/src/macros.rs
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								vendor/anstyle/src/macros.rs
									
									
									
									
										vendored
									
									
								
							@@ -1,5 +0,0 @@
 | 
				
			|||||||
macro_rules! escape {
 | 
					 | 
				
			||||||
    ($($inner:expr),*) => {
 | 
					 | 
				
			||||||
        concat!("\x1B[", $($inner),*, "m")
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										22
									
								
								vendor/anstyle/src/reset.rs
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										22
									
								
								vendor/anstyle/src/reset.rs
									
									
									
									
										vendored
									
									
								
							@@ -1,22 +0,0 @@
 | 
				
			|||||||
/// Reset terminal formatting
 | 
					 | 
				
			||||||
#[derive(Copy, Clone, Default, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
 | 
					 | 
				
			||||||
pub struct Reset;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl Reset {
 | 
					 | 
				
			||||||
    /// Render the ANSI code
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub fn render(self) -> impl core::fmt::Display + Copy + Clone {
 | 
					 | 
				
			||||||
        ResetDisplay
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[derive(Copy, Clone, Default, Debug)]
 | 
					 | 
				
			||||||
struct ResetDisplay;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl core::fmt::Display for ResetDisplay {
 | 
					 | 
				
			||||||
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
 | 
					 | 
				
			||||||
        RESET.fmt(f)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pub(crate) const RESET: &str = "\x1B[0m";
 | 
					 | 
				
			||||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user