#[repr(C, packed(1))]pub struct DebugId { /* private fields */ }
Expand description
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:
- 36 character hyphenated hex representation of the UUID field
- 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
use std::str::FromStr;
use debugid::DebugId;
let id = DebugId::from_str("dfb8e43a-f242-3d73-a453-aeb6a777ef75-a")?;
assert_eq!("dfb8e43a-f242-3d73-a453-aeb6a777ef75-a".to_string(), id.to_string());
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.
Implementations§
§impl DebugId
impl DebugId
pub fn from_parts(uuid: Uuid, appendix: u32) -> DebugId
pub fn from_parts(uuid: Uuid, appendix: u32) -> DebugId
Constructs a DebugId
from its uuid
and appendix
parts.
pub fn from_guid_age(
guid: &[u8],
age: u32
) -> Result<DebugId, ParseDebugIdError>
pub fn from_guid_age( guid: &[u8], age: u32 ) -> Result<DebugId, ParseDebugIdError>
Constructs a DebugId
from a Microsoft little-endian GUID and age.
pub fn from_pdb20(timestamp: u32, age: u32) -> DebugId
pub fn from_pdb20(timestamp: u32, age: u32) -> DebugId
Constructs a DebugId
from a PDB 2.0 timestamp and age.
pub fn from_breakpad(string: &str) -> Result<DebugId, ParseDebugIdError>
pub fn from_breakpad(string: &str) -> Result<DebugId, ParseDebugIdError>
Parses a breakpad identifier from a string.
pub fn uuid(&self) -> Uuid
pub fn uuid(&self) -> Uuid
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:
pub fn appendix(&self) -> u32
pub fn appendix(&self) -> u32
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 breakpad(&self) -> BreakpadFormat<'_>
pub fn breakpad(&self) -> BreakpadFormat<'_>
Returns a wrapper which when formatted via fmt::Display
will format a
a breakpad identifier.
Trait Implementations§
§impl<'de> Deserialize<'de> for DebugId
impl<'de> Deserialize<'de> for DebugId
§fn deserialize<D>(
deserializer: D
) -> Result<DebugId, <D as Deserializer<'de>>::Error>where
D: Deserializer<'de>,
fn deserialize<D>( deserializer: D ) -> Result<DebugId, <D as Deserializer<'de>>::Error>where D: Deserializer<'de>,
§impl FromStr for DebugId
impl FromStr for DebugId
§type Err = ParseDebugIdError
type Err = ParseDebugIdError
§impl Ord for DebugId
impl Ord for DebugId
§impl PartialOrd<DebugId> for DebugId
impl PartialOrd<DebugId> for DebugId
§fn partial_cmp(&self, other: &DebugId) -> Option<Ordering>
fn partial_cmp(&self, other: &DebugId) -> Option<Ordering>
1.0.0 · source§fn le(&self, other: &Rhs) -> bool
fn le(&self, other: &Rhs) -> bool
self
and other
) and is used by the <=
operator. Read more§impl Serialize for DebugId
impl Serialize for DebugId
§fn serialize<S>(
&self,
serializer: S
) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error>where
S: Serializer,
fn serialize<S>( &self, serializer: S ) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error>where S: Serializer,
impl Copy for DebugId
impl Eq for DebugId
impl StructuralEq for DebugId
impl StructuralPartialEq for DebugId
Auto Trait Implementations§
impl RefUnwindSafe for DebugId
impl Send for DebugId
impl Sync for DebugId
impl Unpin for DebugId
impl UnwindSafe for DebugId
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<T> Conv for T
impl<T> Conv for T
source§impl<Q, K> Equivalent<K> for Qwhere
Q: Eq + ?Sized,
K: Borrow<Q> + ?Sized,
impl<Q, K> Equivalent<K> for Qwhere Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,
source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key
and return true
if they are equal.§impl<I, T> ExtractContext<I, ()> for T
impl<I, T> ExtractContext<I, ()> for T
§fn extract_context(self, _original_input: I)
fn extract_context(self, _original_input: I)
§impl<T> FmtForward for T
impl<T> FmtForward for T
§fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
fn fmt_binary(self) -> FmtBinary<Self>where Self: Binary,
self
to use its Binary
implementation when Debug
-formatted.§fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
fn fmt_display(self) -> FmtDisplay<Self>where Self: Display,
self
to use its Display
implementation when
Debug
-formatted.§fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
fn fmt_lower_exp(self) -> FmtLowerExp<Self>where Self: LowerExp,
self
to use its LowerExp
implementation when
Debug
-formatted.§fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
fn fmt_lower_hex(self) -> FmtLowerHex<Self>where Self: LowerHex,
self
to use its LowerHex
implementation when
Debug
-formatted.§fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
fn fmt_octal(self) -> FmtOctal<Self>where Self: Octal,
self
to use its Octal
implementation when Debug
-formatted.§fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
fn fmt_pointer(self) -> FmtPointer<Self>where Self: Pointer,
self
to use its Pointer
implementation when
Debug
-formatted.§fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
fn fmt_upper_exp(self) -> FmtUpperExp<Self>where Self: UpperExp,
self
to use its UpperExp
implementation when
Debug
-formatted.§fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
fn fmt_upper_hex(self) -> FmtUpperHex<Self>where Self: UpperHex,
self
to use its UpperHex
implementation when
Debug
-formatted.§fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
fn fmt_list(self) -> FmtList<Self>where &'a Self: for<'a> IntoIterator,
§impl<T> Indentable for Twhere
T: Display,
impl<T> Indentable for Twhere T: Display,
source§impl<T> Instrument for T
impl<T> Instrument for T
source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere T: ?Sized,
§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere Self: Sized,
§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere R: 'a,
self
and passes that borrow into the pipe function. Read more§fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere R: 'a,
self
and passes that borrow into the pipe function. Read more§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> Rwhere
Self: Borrow<B>,
B: 'a + ?Sized,
R: 'a,
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> Rwhere Self: Borrow<B>, B: 'a + ?Sized, R: 'a,
§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R
) -> Rwhere
Self: BorrowMut<B>,
B: 'a + ?Sized,
R: 'a,
fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R ) -> Rwhere Self: BorrowMut<B>, B: 'a + ?Sized, R: 'a,
§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> Rwhere
Self: AsRef<U>,
U: 'a + ?Sized,
R: 'a,
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> Rwhere Self: AsRef<U>, U: 'a + ?Sized, R: 'a,
self
, then passes self.as_ref()
into the pipe function.§fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> Rwhere
Self: AsMut<U>,
U: 'a + ?Sized,
R: 'a,
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> Rwhere Self: AsMut<U>, U: 'a + ?Sized, R: 'a,
self
, then passes self.as_mut()
into the pipe
function.§impl<I> RecreateContext<I> for I
impl<I> RecreateContext<I> for I
§fn recreate_context(_original_input: I, tail: I) -> I
fn recreate_context(_original_input: I, tail: I) -> I
§impl<T> Tap for T
impl<T> Tap for T
§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Selfwhere
Self: Borrow<B>,
B: ?Sized,
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Selfwhere Self: Borrow<B>, B: ?Sized,
Borrow<B>
of a value. Read more§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere
Self: BorrowMut<B>,
B: ?Sized,
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere Self: BorrowMut<B>, B: ?Sized,
BorrowMut<B>
of a value. Read more§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Selfwhere
Self: AsRef<R>,
R: ?Sized,
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Selfwhere Self: AsRef<R>, R: ?Sized,
AsRef<R>
view of a value. Read more§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere
Self: AsMut<R>,
R: ?Sized,
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere Self: AsMut<R>, R: ?Sized,
AsMut<R>
view of a value. Read more§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Selfwhere
Self: Deref<Target = T>,
T: ?Sized,
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Selfwhere Self: Deref<Target = T>, T: ?Sized,
Deref::Target
of a value. Read more§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere
Self: DerefMut<Target = T> + Deref,
T: ?Sized,
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere Self: DerefMut<Target = T> + Deref, T: ?Sized,
Deref::Target
of a value. Read more§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
.tap()
only in debug builds, and is erased in release builds.§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
.tap_mut()
only in debug builds, and is erased in release
builds.§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Selfwhere
Self: Borrow<B>,
B: ?Sized,
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Selfwhere Self: Borrow<B>, B: ?Sized,
.tap_borrow()
only in debug builds, and is erased in release
builds.§fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere
Self: BorrowMut<B>,
B: ?Sized,
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere Self: BorrowMut<B>, B: ?Sized,
.tap_borrow_mut()
only in debug builds, and is erased in release
builds.§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Selfwhere
Self: AsRef<R>,
R: ?Sized,
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Selfwhere Self: AsRef<R>, R: ?Sized,
.tap_ref()
only in debug builds, and is erased in release
builds.§fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere
Self: AsMut<R>,
R: ?Sized,
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere Self: AsMut<R>, R: ?Sized,
.tap_ref_mut()
only in debug builds, and is erased in release
builds.