Vendor things
This commit is contained in:
parent
5deceec006
commit
977e3c17e5
19434 changed files with 10682014 additions and 0 deletions
1
third-party/vendor/debugid/.cargo-checksum.json
vendored
Normal file
1
third-party/vendor/debugid/.cargo-checksum.json
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"files":{"CHANGELOG.md":"2cf828df6f9e9544eb35466de3646b03262f9d03938da9f9c6ef2c2e68e7c8d4","Cargo.toml":"e866dbd4e8fcfae5766ad977779cda62cfc25eb1324487f16571f5ba6f1fb9d2","LICENSE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","Makefile":"acc4e8dc69b0fae078515c01c3f4353afe18f54a616ec7e6e20ddc893cd97e59","README.md":"2381579ffc25b9eddd07c4a470b1a695876701ee8004174c8f657d3831e4f00d","clippy.toml":"444ea54130c23cdd2b5a5d4976c00e63175cfd67501d14888158a1ea841b48d4","scripts/bump-version.sh":"81aad8c6d661a75c064d351c1722a0fc19d9f00883a4832a11a7ace936b7858a","src/lib.rs":"d39adde21fef7b00210b90c20d94320fc8fad94af7f073022c36b6c3635eb961","tests/test_codeid.rs":"e90ef3d209ecb79b2f3d5568b62645a3341565168a7ba4a81770eea7b93a9d71","tests/test_debugid.rs":"98d93057ea1bfed142797589e24f72f58741e7e037f5423b927a5d1c5b98b4e2","tests/test_serde.rs":"37ca5066022e9771e464184dba94adbad2a223d80d15513c6662d8ffca8536ee"},"package":"bef552e6f588e446098f6ba40d89ac146c8c7b64aade83c051ee00bb5d2bc18d"}
|
||||
80
third-party/vendor/debugid/CHANGELOG.md
vendored
Normal file
80
third-party/vendor/debugid/CHANGELOG.md
vendored
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
# Changelog
|
||||
|
||||
## 0.8.0
|
||||
|
||||
- Bump Minimal Supported Rust Version to 1.46 due to dependencies.
|
||||
- Update `uuid` dependency to `1.0`.
|
||||
|
||||
## 0.7.3
|
||||
|
||||
- Bump Minimal Supported Rust Version to 1.36 due to dependencies.
|
||||
- Add support for PDB 2.0 format.
|
||||
|
||||
## 0.7.2
|
||||
|
||||
- Implement stricter and more consistent validation in `FromStr for DebugId`.
|
||||
- `DebugId::from_breakpad` now properly validates the identifier.
|
||||
- Remove internal dependencies on `regex` and `lazy_static`.
|
||||
|
||||
## 0.7.1
|
||||
|
||||
- Remove deprecated implementation of `Error::description` on errors.
|
||||
|
||||
## 0.7.0
|
||||
|
||||
- Update `uuid` to `0.8.1`.
|
||||
|
||||
## 0.6.0
|
||||
|
||||
_yanked_
|
||||
|
||||
## 0.5.3
|
||||
|
||||
- Only allow ASCII hex charactes in code identifiers.
|
||||
- Implement `AsRef<str>` for `CodeId`.
|
||||
|
||||
## 0.5.2
|
||||
|
||||
- Implement conversion traits for `CodeId`.
|
||||
- Always coerce code identifiers to lower case.
|
||||
|
||||
## 0.6.0 (yanked)
|
||||
|
||||
- Change `CodeId` to be a binary buffer instead of formatted string.
|
||||
|
||||
## 0.5.1
|
||||
|
||||
- Implement `Display` and `std::error::Error` for `ParseCodeIdError`.
|
||||
|
||||
## 0.5.0
|
||||
|
||||
- Add `CodeId`, an identifier for code files.
|
||||
- Add `DebugId::nil` to create an empty id. This is the default.
|
||||
- Add `DebugId::is_nil` to check whether a debug ID is empty.
|
||||
- **Breaking Change:** The serde feature is now only called `"serde"`.
|
||||
|
||||
## 0.4.0
|
||||
|
||||
- **Breaking Change**: Require Rust 1.31.0 (Edition 2018) or newer
|
||||
- Make parsing from string future-proof
|
||||
|
||||
## 0.3.1
|
||||
|
||||
Add a conversion from Microsoft GUIDs.
|
||||
|
||||
## 0.3.0
|
||||
|
||||
Update to `uuid:0.7.0`.
|
||||
|
||||
## 0.2.0
|
||||
|
||||
Renamed `DebugIdParseError` to `ParseDebugIdError`, according to Rust naming
|
||||
guidelines.
|
||||
|
||||
## 0.1.1
|
||||
|
||||
Improved implementation of the `serde` traits.
|
||||
|
||||
## 0.1.0
|
||||
|
||||
Initial release.
|
||||
38
third-party/vendor/debugid/Cargo.toml
vendored
Normal file
38
third-party/vendor/debugid/Cargo.toml
vendored
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
|
||||
#
|
||||
# When uploading crates to the registry Cargo will automatically
|
||||
# "normalize" Cargo.toml files for maximal compatibility
|
||||
# with all versions of Cargo and also rewrite `path` dependencies
|
||||
# to registry (e.g., crates.io) dependencies.
|
||||
#
|
||||
# If you are reading this file be aware that the original Cargo.toml
|
||||
# will likely look very different (and much more reasonable).
|
||||
# See Cargo.toml.orig for the original contents.
|
||||
|
||||
[package]
|
||||
edition = "2018"
|
||||
name = "debugid"
|
||||
version = "0.8.0"
|
||||
authors = ["Sentry <hello@sentry.io>"]
|
||||
description = "Common reusable types for implementing the sentry.io protocol."
|
||||
homepage = "https://sentry.io/"
|
||||
documentation = "https://docs.rs/debugid"
|
||||
readme = "README.md"
|
||||
keywords = [
|
||||
"sentry",
|
||||
"debugid",
|
||||
"breakpad",
|
||||
"crashpad",
|
||||
]
|
||||
license = "Apache-2.0"
|
||||
repository = "https://github.com/getsentry/rust-debugid"
|
||||
|
||||
[dependencies.serde]
|
||||
version = "1.0.85"
|
||||
optional = true
|
||||
|
||||
[dependencies.uuid]
|
||||
version = "1.0.0"
|
||||
|
||||
[dev-dependencies.serde_json]
|
||||
version = "1.0.37"
|
||||
201
third-party/vendor/debugid/LICENSE
vendored
Normal file
201
third-party/vendor/debugid/LICENSE
vendored
Normal file
|
|
@ -0,0 +1,201 @@
|
|||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [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.
|
||||
32
third-party/vendor/debugid/Makefile
vendored
Normal file
32
third-party/vendor/debugid/Makefile
vendored
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
all: style lint test
|
||||
.PHONY: all
|
||||
|
||||
check: style lint
|
||||
.PHONY: check
|
||||
|
||||
build:
|
||||
@cargo build
|
||||
.PHONY: build
|
||||
|
||||
doc:
|
||||
@cargo doc
|
||||
.PHONY: doc
|
||||
|
||||
test:
|
||||
@cargo test
|
||||
.PHONY: test
|
||||
|
||||
style:
|
||||
@rustup component add rustfmt --toolchain stable 2> /dev/null
|
||||
cargo +stable fmt -- --check
|
||||
.PHONY: style
|
||||
|
||||
format:
|
||||
@rustup component add rustfmt --toolchain stable 2> /dev/null
|
||||
@cargo +stable fmt
|
||||
.PHONY: format
|
||||
|
||||
lint:
|
||||
@rustup component add clippy --toolchain stable 2> /dev/null
|
||||
@cargo +stable clippy --tests -- -D clippy::all
|
||||
.PHONY: lint
|
||||
13
third-party/vendor/debugid/README.md
vendored
Normal file
13
third-party/vendor/debugid/README.md
vendored
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
# Rust Debug ID
|
||||
|
||||
<a href="https://travis-ci.org/getsentry/rust-debugid"><img src="https://travis-ci.org/getsentry/rust-debugid.svg?branch=master" alt=""></a>
|
||||
<a href="https://crates.io/crates/debugid"><img src="https://img.shields.io/crates/v/debugid.svg" alt=""></a>
|
||||
|
||||
This crate implements a type that is a thin wrapper around uuids that
|
||||
can hold a "debug id". This is a concept that originally comes from
|
||||
breakpad and is also used by Sentry to identify a debug information
|
||||
file.
|
||||
|
||||
## License
|
||||
|
||||
Symbolic is licensed under the Apache 2 license.
|
||||
1
third-party/vendor/debugid/clippy.toml
vendored
Normal file
1
third-party/vendor/debugid/clippy.toml
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
msrv = "1.46"
|
||||
17
third-party/vendor/debugid/scripts/bump-version.sh
vendored
Executable file
17
third-party/vendor/debugid/scripts/bump-version.sh
vendored
Executable file
|
|
@ -0,0 +1,17 @@
|
|||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
if [ "$(uname -s)" != "Linux" ]; then
|
||||
echo "Please use the GitHub Action."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
cd $SCRIPT_DIR/..
|
||||
|
||||
OLD_VERSION="${1}"
|
||||
NEW_VERSION="${2}"
|
||||
|
||||
echo "Bumping version: ${NEW_VERSION}"
|
||||
|
||||
find . -name Cargo.toml -type f -exec sed -i '' -e "s/^version.*/version = \"$NEW_VERSION\"/" {} \;
|
||||
543
third-party/vendor/debugid/src/lib.rs
vendored
Normal file
543
third-party/vendor/debugid/src/lib.rs
vendored
Normal file
|
|
@ -0,0 +1,543 @@
|
|||
//! This crate provides types for identifiers of object files, such as executables, dynamic
|
||||
//! libraries or debug companion files. The concept originates in Google Breakpad and defines two
|
||||
//! types:
|
||||
//!
|
||||
//! - [`CodeId`]: Identifies the file containing source code, i.e. the actual library or
|
||||
//! executable. The identifier is platform dependent and implementation defined. Thus, there is
|
||||
//! no canonical representation.
|
||||
//! - [`DebugId`]: Identifies a debug information file, which may or may not use information from
|
||||
//! the Code ID. The contents are also implementation defined, but as opposed to `CodeId`, the
|
||||
//! structure is streamlined across platforms. It is also guaranteed to be 32 bytes in size.
|
||||
//!
|
||||
//! [`CodeId`]: struct.CodeId.html
|
||||
//! [`DebugId`]: struct.DebugId.html
|
||||
|
||||
#![warn(missing_docs)]
|
||||
|
||||
use std::error;
|
||||
use std::fmt;
|
||||
use std::fmt::Write;
|
||||
use std::str;
|
||||
|
||||
use uuid::{Bytes, Uuid};
|
||||
|
||||
/// Indicates an error parsing a [`DebugId`](struct.DebugId.html).
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub struct ParseDebugIdError;
|
||||
|
||||
impl error::Error for ParseDebugIdError {}
|
||||
|
||||
impl fmt::Display for ParseDebugIdError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "invalid debug identifier")
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
struct ParseOptions {
|
||||
allow_hyphens: bool,
|
||||
require_appendix: bool,
|
||||
allow_tail: bool,
|
||||
}
|
||||
|
||||
/// Unique identifier for debug information files and their debug information.
|
||||
///
|
||||
/// This type is analogous to [`CodeId`], except that it identifies a debug file instead of the
|
||||
/// actual library or executable. One some platforms, a `DebugId` is an alias for a `CodeId` but the
|
||||
/// exact rules around this are complex. On Windows, the identifiers are completely different and
|
||||
/// refer to separate files.
|
||||
///
|
||||
/// The string representation must be between 33 and 40 characters long and consist of:
|
||||
///
|
||||
/// 1. 36 character hyphenated hex representation of the UUID field
|
||||
/// 2. 1-16 character lowercase hex representation of the u32 appendix
|
||||
///
|
||||
/// The debug identifier is compatible to Google Breakpad. Use [`DebugId::breakpad`] to get a
|
||||
/// breakpad string representation of this debug identifier.
|
||||
///
|
||||
/// There is one exception to this: for the old PDB 2.0 format the debug identifier consists
|
||||
/// of only a 32-bit integer + age resulting in a string representation of between 9 and 16
|
||||
/// hex characters.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// # extern crate debugid;
|
||||
/// use std::str::FromStr;
|
||||
/// use debugid::DebugId;
|
||||
///
|
||||
/// # fn foo() -> Result<(), ::debugid::ParseDebugIdError> {
|
||||
/// let id = DebugId::from_str("dfb8e43a-f242-3d73-a453-aeb6a777ef75-a")?;
|
||||
/// assert_eq!("dfb8e43a-f242-3d73-a453-aeb6a777ef75-a".to_string(), id.to_string());
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
///
|
||||
/// # fn main() { foo().unwrap() }
|
||||
/// ```
|
||||
///
|
||||
/// # In-memory representation
|
||||
///
|
||||
/// The in-memory representation takes up 32 bytes and can be directly written to storage
|
||||
/// and mapped back into an object reference.
|
||||
///
|
||||
/// ```
|
||||
/// use std::str::FromStr;
|
||||
/// use debugid::DebugId;
|
||||
///
|
||||
/// let debug_id = DebugId::from_str("dfb8e43a-f242-3d73-a453-aeb6a777ef75-a").unwrap();
|
||||
///
|
||||
/// let slice = &[debug_id];
|
||||
/// let ptr = slice.as_ptr() as *const u8;
|
||||
/// let len = std::mem::size_of_val(slice);
|
||||
/// let buf: &[u8] = unsafe { std::slice::from_raw_parts(ptr, len) };
|
||||
///
|
||||
/// let mut new_buf: Vec<u8> = Vec::new();
|
||||
/// std::io::copy(&mut std::io::Cursor::new(buf), &mut new_buf).unwrap();
|
||||
///
|
||||
/// let ptr = new_buf.as_ptr() as *const DebugId;
|
||||
/// let new_debug_id = unsafe { &*ptr };
|
||||
///
|
||||
/// assert_eq!(*new_debug_id, debug_id);
|
||||
/// ```
|
||||
///
|
||||
/// As long the bytes were written using the same major version of this crate you will be
|
||||
/// able to read it again like this.
|
||||
///
|
||||
/// [`CodeId`]: struct.CodeId.html
|
||||
/// [`DebugId::breakpad`]: struct.DebugId.html#method.breakpad
|
||||
// This needs to be backwards compatible also in its exact in-memory byte-layout since this
|
||||
// struct is directly mapped from disk in e.g. Symbolic SymCache formats. The first version
|
||||
// of this struct was defined as:
|
||||
//
|
||||
// ```rust
|
||||
// struct DebugId {
|
||||
// uuid: Uuid,
|
||||
// appendix: u32,
|
||||
// _padding: [u8; 12],
|
||||
// }
|
||||
// ```
|
||||
//
|
||||
// For this reason the current `typ` byte represents the type of `DebugId` stored in the
|
||||
// `Bytes`:
|
||||
//
|
||||
// - `0u8`: The `bytes` field contains a UUID.
|
||||
// - `1u8`: The first 4 bytes of the `bytes` field contain a big-endian u32, the remaining
|
||||
// bytes are 0.
|
||||
#[repr(C, packed)]
|
||||
#[derive(Default, Eq, PartialEq, Ord, PartialOrd, Hash, Clone, Copy)]
|
||||
pub struct DebugId {
|
||||
bytes: Bytes,
|
||||
appendix: u32,
|
||||
_padding: [u8; 11],
|
||||
typ: u8,
|
||||
}
|
||||
|
||||
impl DebugId {
|
||||
/// Constructs an empty debug identifier, containing only zeros.
|
||||
pub fn nil() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
/// Constructs a `DebugId` from its `uuid`.
|
||||
pub fn from_uuid(uuid: Uuid) -> Self {
|
||||
Self::from_parts(uuid, 0)
|
||||
}
|
||||
|
||||
/// Constructs a `DebugId` from its `uuid` and `appendix` parts.
|
||||
pub fn from_parts(uuid: Uuid, appendix: u32) -> Self {
|
||||
DebugId {
|
||||
bytes: *uuid.as_bytes(),
|
||||
appendix,
|
||||
typ: 0,
|
||||
_padding: [0; 11],
|
||||
}
|
||||
}
|
||||
|
||||
/// Constructs a `DebugId` from a Microsoft little-endian GUID and age.
|
||||
pub fn from_guid_age(guid: &[u8], age: u32) -> Result<Self, ParseDebugIdError> {
|
||||
if guid.len() != 16 {
|
||||
return Err(ParseDebugIdError);
|
||||
}
|
||||
|
||||
let uuid = Uuid::from_bytes([
|
||||
guid[3], guid[2], guid[1], guid[0], guid[5], guid[4], guid[7], guid[6], guid[8],
|
||||
guid[9], guid[10], guid[11], guid[12], guid[13], guid[14], guid[15],
|
||||
]);
|
||||
|
||||
Ok(DebugId::from_parts(uuid, age))
|
||||
}
|
||||
|
||||
/// Constructs a `DebugId` from a PDB 2.0 timestamp and age.
|
||||
pub fn from_pdb20(timestamp: u32, age: u32) -> Self {
|
||||
// The big-endian byte-order here has to match the one used to read this number in
|
||||
// the DebugId::timestamp method.
|
||||
DebugId {
|
||||
bytes: [
|
||||
(timestamp >> 24) as u8,
|
||||
(timestamp >> 16) as u8,
|
||||
(timestamp >> 8) as u8,
|
||||
timestamp as u8,
|
||||
0u8,
|
||||
0u8,
|
||||
0u8,
|
||||
0u8,
|
||||
0u8,
|
||||
0u8,
|
||||
0u8,
|
||||
0u8,
|
||||
0u8,
|
||||
0u8,
|
||||
0u8,
|
||||
0u8,
|
||||
],
|
||||
appendix: age,
|
||||
_padding: [0u8; 11],
|
||||
typ: 1u8,
|
||||
}
|
||||
}
|
||||
|
||||
/// Parses a breakpad identifier from a string.
|
||||
pub fn from_breakpad(string: &str) -> Result<Self, ParseDebugIdError> {
|
||||
let options = ParseOptions {
|
||||
allow_hyphens: false,
|
||||
require_appendix: true,
|
||||
allow_tail: false,
|
||||
};
|
||||
Self::parse_str(string, options).ok_or(ParseDebugIdError)
|
||||
}
|
||||
|
||||
/// Returns the UUID part of the code module's debug_identifier.
|
||||
///
|
||||
/// If this is a debug identifier for the PDB 2.0 format an invalid UUID is returned
|
||||
/// where only the first 4 bytes are filled in and the remainder of the bytes are 0.
|
||||
/// This means the UUID has variant [`uuid::Variant::NCS`] and an unknown version,
|
||||
/// [`Uuid::get_version`] will return `None`, which is not a valid UUID.
|
||||
///
|
||||
/// This may seem odd however does seem reasonable:
|
||||
///
|
||||
/// - Every [`DebugId`] can be represented as [`Uuid`] and will still mostly look
|
||||
/// reasonable e.g. in comparisons etc.
|
||||
/// - The PDB 2.0 format is very old and very unlikely to appear practically.
|
||||
pub fn uuid(&self) -> Uuid {
|
||||
Uuid::from_bytes(self.bytes)
|
||||
}
|
||||
|
||||
/// Returns the appendix part of the code module's debug identifier.
|
||||
///
|
||||
/// On Windows, this is an incrementing counter to identify the build.
|
||||
/// On all other platforms, this value will always be zero.
|
||||
pub fn appendix(&self) -> u32 {
|
||||
self.appendix
|
||||
}
|
||||
|
||||
/// Returns whether this identifier is nil, i.e. it consists only of zeros.
|
||||
pub fn is_nil(&self) -> bool {
|
||||
self.bytes == [0u8; 16] && self.appendix == 0
|
||||
}
|
||||
|
||||
/// Returns whether this identifier is from the PDB 2.0 format.
|
||||
pub fn is_pdb20(&self) -> bool {
|
||||
self.typ == 1
|
||||
}
|
||||
|
||||
/// Returns a wrapper which when formatted via `fmt::Display` will format a
|
||||
/// a breakpad identifier.
|
||||
pub fn breakpad(&self) -> BreakpadFormat<'_> {
|
||||
BreakpadFormat { inner: self }
|
||||
}
|
||||
|
||||
fn parse_str(string: &str, options: ParseOptions) -> Option<Self> {
|
||||
let is_hyphenated = string.get(8..9) == Some("-");
|
||||
if is_hyphenated && !options.allow_hyphens || !string.is_ascii() {
|
||||
return None;
|
||||
}
|
||||
|
||||
// Can the PDB 2.0 format match? This can never be true for a valid UUID.
|
||||
let min_len = if is_hyphenated { 10 } else { 9 };
|
||||
let max_len = if is_hyphenated { 17 } else { 16 };
|
||||
if min_len <= string.len() && string.len() <= max_len {
|
||||
let timestamp_str = string.get(..8)?;
|
||||
let timestamp = u32::from_str_radix(timestamp_str, 16).ok()?;
|
||||
let appendix_str = match is_hyphenated {
|
||||
true => string.get(9..)?,
|
||||
false => string.get(8..)?,
|
||||
};
|
||||
let appendix = u32::from_str_radix(appendix_str, 16).ok()?;
|
||||
return Some(Self::from_pdb20(timestamp, appendix));
|
||||
}
|
||||
|
||||
let uuid_len = if is_hyphenated { 36 } else { 32 };
|
||||
let uuid = string.get(..uuid_len)?.parse().ok()?;
|
||||
if !options.require_appendix && string.len() == uuid_len {
|
||||
return Some(Self::from_parts(uuid, 0));
|
||||
}
|
||||
|
||||
let mut appendix_str = &string[uuid_len..];
|
||||
if is_hyphenated ^ appendix_str.starts_with('-') {
|
||||
return None; // Require a hyphen if and only if we're hyphenated.
|
||||
} else if is_hyphenated {
|
||||
appendix_str = &appendix_str[1..]; // Skip the hyphen for parsing.
|
||||
}
|
||||
|
||||
if options.allow_tail && appendix_str.len() > 8 {
|
||||
appendix_str = &appendix_str[..8];
|
||||
}
|
||||
|
||||
// Parse the appendix, which fails on empty strings.
|
||||
let appendix = u32::from_str_radix(appendix_str, 16).ok()?;
|
||||
Some(Self::from_parts(uuid, appendix))
|
||||
}
|
||||
|
||||
/// Returns the PDB 2.0 timestamp.
|
||||
///
|
||||
/// Only valid if you know this is a PDB 2.0 debug identifier.
|
||||
fn timestamp(&self) -> u32 {
|
||||
u32::from_be_bytes([self.bytes[0], self.bytes[1], self.bytes[2], self.bytes[3]])
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for DebugId {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
let uuid = self.uuid();
|
||||
f.debug_struct("DebugId")
|
||||
.field("uuid", &uuid.hyphenated().to_string())
|
||||
.field("appendix", &self.appendix())
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for DebugId {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self.is_pdb20() {
|
||||
true => {
|
||||
let timestamp = self.timestamp();
|
||||
write!(f, "{:08X}", timestamp)?;
|
||||
}
|
||||
false => {
|
||||
let uuid = self.uuid();
|
||||
uuid.fmt(f)?;
|
||||
}
|
||||
}
|
||||
if self.appendix > 0 {
|
||||
write!(f, "-{:x}", { self.appendix })?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl str::FromStr for DebugId {
|
||||
type Err = ParseDebugIdError;
|
||||
|
||||
fn from_str(string: &str) -> Result<Self, ParseDebugIdError> {
|
||||
let options = ParseOptions {
|
||||
allow_hyphens: true,
|
||||
require_appendix: false,
|
||||
allow_tail: true,
|
||||
};
|
||||
Self::parse_str(string, options).ok_or(ParseDebugIdError)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Uuid> for DebugId {
|
||||
fn from(uuid: Uuid) -> Self {
|
||||
DebugId::from_uuid(uuid)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<(Uuid, u32)> for DebugId {
|
||||
fn from(tuple: (Uuid, u32)) -> Self {
|
||||
let (uuid, appendix) = tuple;
|
||||
DebugId::from_parts(uuid, appendix)
|
||||
}
|
||||
}
|
||||
|
||||
/// Wrapper around [`DebugId`] for Breakpad formatting.
|
||||
///
|
||||
/// **Example:**
|
||||
///
|
||||
/// ```
|
||||
/// # extern crate debugid;
|
||||
/// use std::str::FromStr;
|
||||
/// use debugid::DebugId;
|
||||
///
|
||||
/// # fn foo() -> Result<(), debugid::ParseDebugIdError> {
|
||||
/// let id = DebugId::from_breakpad("DFB8E43AF2423D73A453AEB6A777EF75a")?;
|
||||
/// assert_eq!("DFB8E43AF2423D73A453AEB6A777EF75a".to_string(), id.breakpad().to_string());
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
///
|
||||
/// # fn main() { foo().unwrap() }
|
||||
/// ```
|
||||
///
|
||||
/// [`DebugId`]: struct.DebugId.html
|
||||
#[derive(Debug)]
|
||||
pub struct BreakpadFormat<'a> {
|
||||
inner: &'a DebugId,
|
||||
}
|
||||
|
||||
impl<'a> fmt::Display for BreakpadFormat<'a> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self.inner.is_pdb20() {
|
||||
true => {
|
||||
let timestamp = self.inner.timestamp();
|
||||
write!(f, "{:08X}{:x}", timestamp, self.inner.appendix())
|
||||
}
|
||||
false => {
|
||||
let uuid = self.inner.uuid();
|
||||
write!(f, "{:X}{:x}", uuid.simple(), self.inner.appendix())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Indicates an error parsing a [`CodeId`](struct.CodeId.html).
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub struct ParseCodeIdError;
|
||||
|
||||
impl error::Error for ParseCodeIdError {}
|
||||
|
||||
impl fmt::Display for ParseCodeIdError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "invalid code identifier")
|
||||
}
|
||||
}
|
||||
|
||||
/// Unique platform-dependent identifier of code files.
|
||||
///
|
||||
/// This identifier assumes a string representation that depends on the platform and compiler used.
|
||||
/// The representation only retains hex characters and canonically stores lower case.
|
||||
///
|
||||
/// There are the following known formats:
|
||||
///
|
||||
/// - **MachO UUID**: The unique identifier of a Mach binary, specified in the `LC_UUID` load
|
||||
/// command header.
|
||||
/// - **GNU Build ID**: Contents of the `.gnu.build-id` note or section contents formatted as
|
||||
/// lowercase hex string.
|
||||
/// - **PE Timestamp**: Timestamp and size of image values from a Windows PE header. The size of
|
||||
/// image value is truncated, so the length of the `CodeId` might not be a multiple of 2.
|
||||
#[derive(Clone, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
|
||||
pub struct CodeId {
|
||||
inner: String,
|
||||
}
|
||||
|
||||
impl CodeId {
|
||||
/// Constructs an empty code identifier.
|
||||
pub fn nil() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
/// Constructs a `CodeId` from its string representation.
|
||||
pub fn new(mut string: String) -> Self {
|
||||
string.retain(|c| c.is_ascii_hexdigit());
|
||||
string.make_ascii_lowercase();
|
||||
CodeId { inner: string }
|
||||
}
|
||||
|
||||
/// Constructs a `CodeId` from a binary slice.
|
||||
pub fn from_binary(slice: &[u8]) -> Self {
|
||||
let mut string = String::with_capacity(slice.len() * 2);
|
||||
|
||||
for byte in slice {
|
||||
write!(&mut string, "{:02x}", byte).expect("");
|
||||
}
|
||||
|
||||
Self::new(string)
|
||||
}
|
||||
|
||||
/// Returns whether this identifier is nil, i.e. it is empty.
|
||||
pub fn is_nil(&self) -> bool {
|
||||
self.inner.is_empty()
|
||||
}
|
||||
|
||||
/// Returns the string representation of this code identifier.
|
||||
pub fn as_str(&self) -> &str {
|
||||
self.inner.as_str()
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for CodeId {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.write_str(&self.inner)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for CodeId {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "CodeId({})", self)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<String> for CodeId {
|
||||
fn from(string: String) -> Self {
|
||||
Self::new(string)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&'_ str> for CodeId {
|
||||
fn from(string: &str) -> Self {
|
||||
Self::new(string.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<str> for CodeId {
|
||||
fn as_ref(&self) -> &str {
|
||||
self.as_str()
|
||||
}
|
||||
}
|
||||
|
||||
impl str::FromStr for CodeId {
|
||||
type Err = ParseCodeIdError;
|
||||
|
||||
fn from_str(string: &str) -> Result<Self, ParseCodeIdError> {
|
||||
Ok(Self::new(string.into()))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
mod serde_support {
|
||||
use serde::de::{self, Deserialize, Deserializer, Unexpected, Visitor};
|
||||
use serde::ser::{Serialize, Serializer};
|
||||
|
||||
use super::*;
|
||||
|
||||
impl Serialize for CodeId {
|
||||
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
||||
serializer.serialize_str(self.as_str())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for CodeId {
|
||||
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
|
||||
let string = String::deserialize(deserializer)?;
|
||||
Ok(CodeId::new(string))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for DebugId {
|
||||
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
|
||||
struct V;
|
||||
|
||||
impl<'de> Visitor<'de> for V {
|
||||
type Value = DebugId;
|
||||
|
||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
formatter.write_str("DebugId")
|
||||
}
|
||||
|
||||
fn visit_str<E: de::Error>(self, value: &str) -> Result<DebugId, E> {
|
||||
value
|
||||
.parse()
|
||||
.map_err(|_| de::Error::invalid_value(Unexpected::Str(value), &self))
|
||||
}
|
||||
}
|
||||
|
||||
deserializer.deserialize_str(V)
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for DebugId {
|
||||
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
||||
serializer.serialize_str(&self.to_string())
|
||||
}
|
||||
}
|
||||
}
|
||||
27
third-party/vendor/debugid/tests/test_codeid.rs
vendored
Normal file
27
third-party/vendor/debugid/tests/test_codeid.rs
vendored
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
use debugid::CodeId;
|
||||
|
||||
#[test]
|
||||
fn test_new() {
|
||||
let id = CodeId::new("dfb8e43af2423d73a453aeb6a777ef75".into());
|
||||
assert_eq!(id.as_str(), "dfb8e43af2423d73a453aeb6a777ef75");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_pe() {
|
||||
// Code identifiers of PE files might have an odd length and contain upper case characters.
|
||||
let id = CodeId::new("5CCC38584b08000".into());
|
||||
assert_eq!(id.as_str(), "5ccc38584b08000");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_from_binary() {
|
||||
let binary = b"\xdf\xb8\xe4\x3a\xf2\x42\x3d\x73\xa4\x53\xae\xb6\xa7\x77\xef\x75";
|
||||
let id = CodeId::from_binary(&binary[..]);
|
||||
assert_eq!(id.as_str(), "dfb8e43af2423d73a453aeb6a777ef75");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_is_nil() {
|
||||
let id = CodeId::nil();
|
||||
assert!(id.is_nil());
|
||||
}
|
||||
388
third-party/vendor/debugid/tests/test_debugid.rs
vendored
Normal file
388
third-party/vendor/debugid/tests/test_debugid.rs
vendored
Normal file
|
|
@ -0,0 +1,388 @@
|
|||
use std::mem::{align_of, size_of};
|
||||
use std::str::FromStr;
|
||||
|
||||
use debugid::DebugId;
|
||||
use uuid::Uuid;
|
||||
|
||||
#[test]
|
||||
fn test_is_nil() {
|
||||
assert!(DebugId::default().is_nil());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_zero() {
|
||||
assert_eq!(
|
||||
DebugId::from_str("dfb8e43a-f242-3d73-a453-aeb6a777ef75").unwrap(),
|
||||
DebugId::from_parts(
|
||||
Uuid::parse_str("dfb8e43a-f242-3d73-a453-aeb6a777ef75").unwrap(),
|
||||
0,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_short() {
|
||||
assert_eq!(
|
||||
DebugId::from_str("dfb8e43a-f242-3d73-a453-aeb6a777ef75-a").unwrap(),
|
||||
DebugId::from_parts(
|
||||
Uuid::parse_str("dfb8e43a-f242-3d73-a453-aeb6a777ef75").unwrap(),
|
||||
0xa,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_long() {
|
||||
assert_eq!(
|
||||
DebugId::from_str("dfb8e43a-f242-3d73-a453-aeb6a777ef75-feedface").unwrap(),
|
||||
DebugId::from_parts(
|
||||
Uuid::parse_str("dfb8e43a-f242-3d73-a453-aeb6a777ef75").unwrap(),
|
||||
0xfeed_face,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_compact() {
|
||||
assert_eq!(
|
||||
DebugId::from_str("dfb8e43af2423d73a453aeb6a777ef75feedface").unwrap(),
|
||||
DebugId::from_parts(
|
||||
Uuid::parse_str("dfb8e43a-f242-3d73-a453-aeb6a777ef75").unwrap(),
|
||||
0xfeed_face,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_upper() {
|
||||
assert_eq!(
|
||||
DebugId::from_str("DFB8E43A-F242-3D73-A453-AEB6A777EF75-FEEDFACE").unwrap(),
|
||||
DebugId::from_parts(
|
||||
Uuid::parse_str("dfb8e43a-f242-3d73-a453-aeb6a777ef75").unwrap(),
|
||||
0xfeed_face,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_ignores_tail() {
|
||||
assert_eq!(
|
||||
DebugId::from_str("dfb8e43a-f242-3d73-a453-aeb6a777ef75-feedface-1-2-3").unwrap(),
|
||||
DebugId::from_parts(
|
||||
Uuid::parse_str("dfb8e43a-f242-3d73-a453-aeb6a777ef75").unwrap(),
|
||||
0xfeed_face,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_to_string_zero() {
|
||||
let id = DebugId::from_parts(
|
||||
Uuid::parse_str("dfb8e43a-f242-3d73-a453-aeb6a777ef75").unwrap(),
|
||||
0,
|
||||
);
|
||||
|
||||
assert_eq!(id.to_string(), "dfb8e43a-f242-3d73-a453-aeb6a777ef75");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_to_string_short() {
|
||||
let id = DebugId::from_parts(
|
||||
Uuid::parse_str("dfb8e43a-f242-3d73-a453-aeb6a777ef75").unwrap(),
|
||||
10,
|
||||
);
|
||||
|
||||
assert_eq!(id.to_string(), "dfb8e43a-f242-3d73-a453-aeb6a777ef75-a");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_to_string_long() {
|
||||
let id = DebugId::from_parts(
|
||||
Uuid::parse_str("dfb8e43a-f242-3d73-a453-aeb6a777ef75").unwrap(),
|
||||
0xfeed_face,
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
id.to_string(),
|
||||
"dfb8e43a-f242-3d73-a453-aeb6a777ef75-feedface"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_error_short() {
|
||||
assert!(DebugId::from_str("dfb8e43a-f242-3d73-a453-aeb6a777ef7").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_error_trailing_dash() {
|
||||
assert!(DebugId::from_str("dfb8e43a-f242-3d73-a453-aeb6a777ef75-").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_error_unicode() {
|
||||
assert!(DebugId::from_str("아이쿱 조합원 앱카드").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_from_guid_age() {
|
||||
let guid = [
|
||||
0x98, 0xd1, 0xef, 0xe8, 0x6e, 0xf8, 0xfe, 0x45, 0x9d, 0xdb, 0xe1, 0x13, 0x82, 0xb5, 0xd1,
|
||||
0xc9,
|
||||
];
|
||||
|
||||
assert_eq!(
|
||||
DebugId::from_guid_age(&guid[..], 1).unwrap(),
|
||||
DebugId::from_str("e8efd198-f86e-45fe-9ddb-e11382b5d1c9-1").unwrap()
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_breakpad_zero() {
|
||||
assert_eq!(
|
||||
DebugId::from_breakpad("DFB8E43AF2423D73A453AEB6A777EF750").unwrap(),
|
||||
DebugId::from_parts(
|
||||
Uuid::parse_str("DFB8E43AF2423D73A453AEB6A777EF75").unwrap(),
|
||||
0,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_breakpad_short() {
|
||||
assert_eq!(
|
||||
DebugId::from_breakpad("DFB8E43AF2423D73A453AEB6A777EF75a").unwrap(),
|
||||
DebugId::from_parts(
|
||||
Uuid::parse_str("DFB8E43AF2423D73A453AEB6A777EF75").unwrap(),
|
||||
10,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_breakpad_long() {
|
||||
assert_eq!(
|
||||
DebugId::from_breakpad("DFB8E43AF2423D73A453AEB6A777EF75feedface").unwrap(),
|
||||
DebugId::from_parts(
|
||||
Uuid::parse_str("DFB8E43AF2423D73A453AEB6A777EF75").unwrap(),
|
||||
0xfeed_face,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_breakpad_error_tail() {
|
||||
assert!(DebugId::from_breakpad("DFB8E43AF2423D73A453AEB6A777EF75feedface123").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_breakpad_error_missing_age() {
|
||||
assert!(DebugId::from_breakpad("DFB8E43AF2423D73A453AEB6A777EF75").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_breakpad_error_short() {
|
||||
assert!(DebugId::from_breakpad("DFB8E43AF2423D73A453AEB6A777EF7").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_breakpad_error_dashes() {
|
||||
assert!(DebugId::from_breakpad("e8efd198-f86e-45fe-9ddb-e11382b5d1c9-1").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_to_string_breakpad_zero() {
|
||||
let id = DebugId::from_parts(
|
||||
Uuid::parse_str("DFB8E43AF2423D73A453AEB6A777EF75").unwrap(),
|
||||
0,
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
id.breakpad().to_string(),
|
||||
"DFB8E43AF2423D73A453AEB6A777EF750"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_to_string_breakpad_short() {
|
||||
let id = DebugId::from_parts(
|
||||
Uuid::parse_str("DFB8E43AF2423D73A453AEB6A777EF75").unwrap(),
|
||||
10,
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
id.breakpad().to_string(),
|
||||
"DFB8E43AF2423D73A453AEB6A777EF75a"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_to_string_breakpad_long() {
|
||||
let id = DebugId::from_parts(
|
||||
Uuid::parse_str("DFB8E43AF2423D73A453AEB6A777EF75").unwrap(),
|
||||
0xfeed_face,
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
id.breakpad().to_string(),
|
||||
"DFB8E43AF2423D73A453AEB6A777EF75feedface"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_debug_id_debug() {
|
||||
let id = DebugId::from_parts(
|
||||
Uuid::parse_str("DFB8E43AF2423D73A453AEB6A777EF75").unwrap(),
|
||||
10,
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
format!("{:?}", id),
|
||||
"DebugId { uuid: \"dfb8e43a-f242-3d73-a453-aeb6a777ef75\", appendix: 10 }"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "with_serde")]
|
||||
fn test_serde_serialize() {
|
||||
let id = DebugId::from_parts(
|
||||
Uuid::parse_str("DFB8E43AF2423D73A453AEB6A777EF75").unwrap(),
|
||||
10,
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
serde_json::to_string(&id).expect("could not serialize"),
|
||||
"\"dfb8e43a-f242-3d73-a453-aeb6a777ef75-a\""
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "with_serde")]
|
||||
fn test_serde_deserialize() {
|
||||
let id: DebugId = serde_json::from_str("\"dfb8e43a-f242-3d73-a453-aeb6a777ef75-a\"")
|
||||
.expect("could not deserialize");
|
||||
|
||||
assert_eq!(
|
||||
id,
|
||||
DebugId::from_parts(
|
||||
Uuid::parse_str("DFB8E43AF2423D73A453AEB6A777EF75").unwrap(),
|
||||
10,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_pdb20() {
|
||||
let timestamp: u32 = 0x418e89c3;
|
||||
let age: u32 = 1;
|
||||
let debug_id = DebugId::from_pdb20(timestamp, age);
|
||||
|
||||
assert!(debug_id.is_pdb20());
|
||||
assert_eq!(
|
||||
debug_id.uuid(),
|
||||
Uuid::parse_str("418e89c3-0000-0000-0000-000000000000").unwrap()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_pdb20_format() {
|
||||
let timestamp: u32 = 0x418e89c3;
|
||||
let age: u32 = 1;
|
||||
let debug_id = DebugId::from_pdb20(timestamp, age);
|
||||
|
||||
assert_eq!(debug_id.to_string(), "418E89C3-1".to_string());
|
||||
assert_eq!(debug_id.breakpad().to_string(), "418E89C31");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_pdb20_parse() {
|
||||
let timestamp: u32 = 0x418e89c3;
|
||||
let age: u32 = 1;
|
||||
let debug_id = DebugId::from_pdb20(timestamp, age);
|
||||
|
||||
let s = "418E89C3-1";
|
||||
let parsed = DebugId::from_str(s).unwrap();
|
||||
assert_eq!(parsed, debug_id);
|
||||
|
||||
let s = "418E89C31";
|
||||
let parsed = DebugId::from_str(s).unwrap();
|
||||
assert_eq!(parsed, debug_id);
|
||||
|
||||
let s = "418E89C31";
|
||||
let parsed = DebugId::from_breakpad(s).unwrap();
|
||||
assert_eq!(parsed, debug_id);
|
||||
|
||||
let s = "418E89C3-1";
|
||||
assert!(DebugId::from_breakpad(s).is_err());
|
||||
}
|
||||
|
||||
/// The version of `DebugId` up to 0.7.2.
|
||||
#[repr(C, packed)]
|
||||
struct OldDebugId {
|
||||
uuid: Uuid,
|
||||
appendix: u32,
|
||||
_padding: [u8; 12],
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mem() {
|
||||
// The size of this struct needs to be exactly aligned and can not change for backwards
|
||||
// compatibility.
|
||||
assert_eq!(size_of::<OldDebugId>(), 32);
|
||||
assert_eq!(size_of::<OldDebugId>(), size_of::<DebugId>());
|
||||
assert_eq!(align_of::<DebugId>(), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_to_from_raw() {
|
||||
let debug_id = DebugId::from_str("dfb8e43a-f242-3d73-a453-aeb6a777ef75-a").unwrap();
|
||||
|
||||
// Create &[u8] from DebugId.
|
||||
let slice = &[debug_id];
|
||||
let ptr = slice.as_ptr() as *const u8;
|
||||
let len = std::mem::size_of_val(slice);
|
||||
let buf: &[u8] = unsafe { std::slice::from_raw_parts(ptr, len) };
|
||||
|
||||
// Copy bytes to new location.
|
||||
let mut new_buf: Vec<u8> = Vec::new();
|
||||
std::io::copy(&mut std::io::Cursor::new(buf), &mut new_buf).unwrap();
|
||||
|
||||
// Create DebugId from &[u8].
|
||||
let ptr = new_buf.as_ptr() as *const DebugId;
|
||||
let new_debug_id = unsafe { &*ptr };
|
||||
|
||||
assert_eq!(*new_debug_id, debug_id);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_from_old_raw() {
|
||||
// Ensures we can still read previous in-memory representations into the new format.
|
||||
let debug_id = DebugId::from_str("dfb8e43a-f242-3d73-a453-aeb6a777ef75-a").unwrap();
|
||||
let old_debug_id = OldDebugId {
|
||||
uuid: debug_id.uuid(),
|
||||
appendix: debug_id.appendix(),
|
||||
_padding: [0; 12],
|
||||
};
|
||||
|
||||
// Create &[u8] from OldDebugId.
|
||||
let slice = &[old_debug_id];
|
||||
let ptr = slice.as_ptr() as *const u8;
|
||||
let len = std::mem::size_of_val(slice);
|
||||
let buf: &[u8] = unsafe { std::slice::from_raw_parts(ptr, len) };
|
||||
|
||||
// Copy bytes to new location.
|
||||
let mut new_buf: Vec<u8> = Vec::new();
|
||||
std::io::copy(&mut std::io::Cursor::new(buf), &mut new_buf).unwrap();
|
||||
|
||||
// Create DebugId from &[u8].
|
||||
let ptr = new_buf.as_ptr() as *const DebugId;
|
||||
let new_debug_id = unsafe { &*ptr };
|
||||
|
||||
assert_eq!(*new_debug_id, debug_id);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_default() {
|
||||
let debug_id = DebugId::default();
|
||||
assert_eq!(debug_id.uuid(), Uuid::nil());
|
||||
assert_eq!(debug_id.appendix(), 0);
|
||||
}
|
||||
44
third-party/vendor/debugid/tests/test_serde.rs
vendored
Normal file
44
third-party/vendor/debugid/tests/test_serde.rs
vendored
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
#![cfg(feature = "serde")]
|
||||
|
||||
use debugid::{CodeId, DebugId};
|
||||
use uuid::Uuid;
|
||||
|
||||
#[test]
|
||||
fn test_deserialize_debugid() {
|
||||
assert_eq!(
|
||||
DebugId::from_parts(
|
||||
Uuid::parse_str("dfb8e43a-f242-3d73-a453-aeb6a777ef75").unwrap(),
|
||||
0,
|
||||
),
|
||||
serde_json::from_str("\"dfb8e43a-f242-3d73-a453-aeb6a777ef75\"").unwrap(),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_serialize_debugid() {
|
||||
let id = DebugId::from_parts(
|
||||
Uuid::parse_str("dfb8e43a-f242-3d73-a453-aeb6a777ef75").unwrap(),
|
||||
0,
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
"\"dfb8e43a-f242-3d73-a453-aeb6a777ef75\"",
|
||||
serde_json::to_string(&id).unwrap(),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_deserialize_codeid() {
|
||||
assert_eq!(
|
||||
CodeId::new("dfb8e43af2423d73a453aeb6a777ef75".into()),
|
||||
serde_json::from_str("\"dfb8e43af2423d73a453aeb6a777ef75\"").unwrap(),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_serialize_codeid() {
|
||||
assert_eq!(
|
||||
"\"dfb8e43af2423d73a453aeb6a777ef75\"",
|
||||
serde_json::to_string(&CodeId::new("dfb8e43af2423d73a453aeb6a777ef75".into())).unwrap(),
|
||||
);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue