Struct udmp_parser::UserDumpParser
source · pub struct UserDumpParser<'a> {
pub foreground_tid: Option<u32>,
/* private fields */
}
Expand description
This stores useful information fished out of of Windows minidump file: thread contexts and memory blocks.
Fields§
§foreground_tid: Option<u32>
The thread id of the foreground thread.
Implementations§
source§impl<'a> UserDumpParser<'a>
impl<'a> UserDumpParser<'a>
sourcepub fn new<S: AsRef<Path>>(path: S) -> Result<UserDumpParser<'a>>
pub fn new<S: AsRef<Path>>(path: S) -> Result<UserDumpParser<'a>>
Create an instance from a filepath. This memory maps the file and parses it.
Examples found in repository?
examples/parser.rs (line 163)
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286
fn main() -> Result<(), String> {
// If we don't have any arguments, display the help.
if env::args().len() == 1 {
help();
return Ok(());
}
// Parse the command line arguments.
let cli = parse_args()?;
// Let's try to parse the dump file specified by the user.
let dump = UserDumpParser::new(cli.dump_path).map_err(|e| e.to_string())?;
// Do we want to display modules?
if cli.show_mods || cli.show_all {
println!("Loaded modules:");
// Iterate through the module and display their base address and path.
for (base, module) in dump.modules() {
println!("{:016x}: {}", base, module.path.display());
}
}
// Do we want the memory map?
if cli.show_memmap || cli.show_all {
println!("Memory map:");
// Iterate over the memory blocks.
for block in dump.mem_blocks().values() {
// Grab the string representation about its state, type, protection.
let state = block.state_as_str();
let type_ = block.type_as_str();
let protect = block.protect_as_str();
// Print it all out.
print!(
"{:016x} {:016x} {:016x} {:11} {:11} {:22}",
block.range.start,
block.range.end,
block.len(),
type_,
state,
protect
);
// Do we have a module that exists at this address?
let module = dump.get_module(block.range.start);
// If we do, then display its name / path.
if let Some(module) = module {
print!(
" [{}; \"{}\"]",
module.file_name().unwrap(),
module.path.display()
);
}
// Do we have data with this block? If so display the first few
// bytes.
if block.data.len() >= 4 {
print!(
" {:02x} {:02x} {:02x} {:02x}...",
block.data[0], block.data[1], block.data[2], block.data[3]
);
}
println!();
}
}
// Do we want threads?
if cli.show_threads || cli.show_all {
println!("Threads:");
// Grab the foreground tid.
let foreground_tid = dump.foreground_tid;
// Iterate through all the threads.
for (tid, thread) in dump.threads() {
// If the user specified a pid..
if let Some(wanted_tid) = cli.thread {
// .. skip an threads that don't match what the user wants..
if *tid != wanted_tid {
continue;
}
// Otherwise we keep going.
}
// If the user only wants the main thread, and we haven't found it,
// skip this thread until we find it.
if cli.show_foreground_thread
&& *tid != foreground_tid.expect("no foreground thread id in dump")
{
continue;
}
// Print out the thread info.
println!("TID {}, TEB {:016x}", tid, thread.teb);
println!("Context:");
println!("{}", thread.context());
}
}
// Do we want to dump memory?
if let Some(address) = cli.address {
println!("Memory:");
// Try to find a block that contains `address`.
let block = dump.get_mem_block(address);
// If we have one..
if let Some(block) = block {
// .. and it has data, dump it..
if let Some(data) = block.data_from(address) {
println!("{:016x} -> {:016x}", address, block.end_addr());
hexdump(address, data.iter().take(0x1_00).copied());
}
// .. otherwise, inform the user..
else {
println!(
"The memory at {:016x} (from block {:016x} -> {:016x}) has no backing data",
address, block.range.start, block.range.end
);
}
}
// .. otherwise, inform he user.
else {
println!("No memory block were found for {:016x}", address);
}
}
// All right, enough for today.
Ok(())
}
sourcepub fn with_slice(
slice: &'a impl Deref<Target = [u8]>
) -> Result<UserDumpParser<'a>>
pub fn with_slice( slice: &'a impl Deref<Target = [u8]> ) -> Result<UserDumpParser<'a>>
Create an instance from something that dereference to a slice of bytes.
sourcepub fn is_arch_x64(&self) -> bool
pub fn is_arch_x64(&self) -> bool
Is the architeture X64?
sourcepub fn is_arch_x86(&self) -> bool
pub fn is_arch_x86(&self) -> bool
Is the architecture X86?
sourcepub fn modules(&self) -> &Modules<'_>
pub fn modules(&self) -> &Modules<'_>
Get a reference to the base address -> Module
map.
Examples found in repository?
examples/parser.rs (line 170)
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286
fn main() -> Result<(), String> {
// If we don't have any arguments, display the help.
if env::args().len() == 1 {
help();
return Ok(());
}
// Parse the command line arguments.
let cli = parse_args()?;
// Let's try to parse the dump file specified by the user.
let dump = UserDumpParser::new(cli.dump_path).map_err(|e| e.to_string())?;
// Do we want to display modules?
if cli.show_mods || cli.show_all {
println!("Loaded modules:");
// Iterate through the module and display their base address and path.
for (base, module) in dump.modules() {
println!("{:016x}: {}", base, module.path.display());
}
}
// Do we want the memory map?
if cli.show_memmap || cli.show_all {
println!("Memory map:");
// Iterate over the memory blocks.
for block in dump.mem_blocks().values() {
// Grab the string representation about its state, type, protection.
let state = block.state_as_str();
let type_ = block.type_as_str();
let protect = block.protect_as_str();
// Print it all out.
print!(
"{:016x} {:016x} {:016x} {:11} {:11} {:22}",
block.range.start,
block.range.end,
block.len(),
type_,
state,
protect
);
// Do we have a module that exists at this address?
let module = dump.get_module(block.range.start);
// If we do, then display its name / path.
if let Some(module) = module {
print!(
" [{}; \"{}\"]",
module.file_name().unwrap(),
module.path.display()
);
}
// Do we have data with this block? If so display the first few
// bytes.
if block.data.len() >= 4 {
print!(
" {:02x} {:02x} {:02x} {:02x}...",
block.data[0], block.data[1], block.data[2], block.data[3]
);
}
println!();
}
}
// Do we want threads?
if cli.show_threads || cli.show_all {
println!("Threads:");
// Grab the foreground tid.
let foreground_tid = dump.foreground_tid;
// Iterate through all the threads.
for (tid, thread) in dump.threads() {
// If the user specified a pid..
if let Some(wanted_tid) = cli.thread {
// .. skip an threads that don't match what the user wants..
if *tid != wanted_tid {
continue;
}
// Otherwise we keep going.
}
// If the user only wants the main thread, and we haven't found it,
// skip this thread until we find it.
if cli.show_foreground_thread
&& *tid != foreground_tid.expect("no foreground thread id in dump")
{
continue;
}
// Print out the thread info.
println!("TID {}, TEB {:016x}", tid, thread.teb);
println!("Context:");
println!("{}", thread.context());
}
}
// Do we want to dump memory?
if let Some(address) = cli.address {
println!("Memory:");
// Try to find a block that contains `address`.
let block = dump.get_mem_block(address);
// If we have one..
if let Some(block) = block {
// .. and it has data, dump it..
if let Some(data) = block.data_from(address) {
println!("{:016x} -> {:016x}", address, block.end_addr());
hexdump(address, data.iter().take(0x1_00).copied());
}
// .. otherwise, inform the user..
else {
println!(
"The memory at {:016x} (from block {:016x} -> {:016x}) has no backing data",
address, block.range.start, block.range.end
);
}
}
// .. otherwise, inform he user.
else {
println!("No memory block were found for {:016x}", address);
}
}
// All right, enough for today.
Ok(())
}
sourcepub fn get_module(&self, address: u64) -> Option<&Module<'_>>
pub fn get_module(&self, address: u64) -> Option<&Module<'_>>
Find a Module
that includes address
in its range.
Examples found in repository?
examples/parser.rs (line 198)
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286
fn main() -> Result<(), String> {
// If we don't have any arguments, display the help.
if env::args().len() == 1 {
help();
return Ok(());
}
// Parse the command line arguments.
let cli = parse_args()?;
// Let's try to parse the dump file specified by the user.
let dump = UserDumpParser::new(cli.dump_path).map_err(|e| e.to_string())?;
// Do we want to display modules?
if cli.show_mods || cli.show_all {
println!("Loaded modules:");
// Iterate through the module and display their base address and path.
for (base, module) in dump.modules() {
println!("{:016x}: {}", base, module.path.display());
}
}
// Do we want the memory map?
if cli.show_memmap || cli.show_all {
println!("Memory map:");
// Iterate over the memory blocks.
for block in dump.mem_blocks().values() {
// Grab the string representation about its state, type, protection.
let state = block.state_as_str();
let type_ = block.type_as_str();
let protect = block.protect_as_str();
// Print it all out.
print!(
"{:016x} {:016x} {:016x} {:11} {:11} {:22}",
block.range.start,
block.range.end,
block.len(),
type_,
state,
protect
);
// Do we have a module that exists at this address?
let module = dump.get_module(block.range.start);
// If we do, then display its name / path.
if let Some(module) = module {
print!(
" [{}; \"{}\"]",
module.file_name().unwrap(),
module.path.display()
);
}
// Do we have data with this block? If so display the first few
// bytes.
if block.data.len() >= 4 {
print!(
" {:02x} {:02x} {:02x} {:02x}...",
block.data[0], block.data[1], block.data[2], block.data[3]
);
}
println!();
}
}
// Do we want threads?
if cli.show_threads || cli.show_all {
println!("Threads:");
// Grab the foreground tid.
let foreground_tid = dump.foreground_tid;
// Iterate through all the threads.
for (tid, thread) in dump.threads() {
// If the user specified a pid..
if let Some(wanted_tid) = cli.thread {
// .. skip an threads that don't match what the user wants..
if *tid != wanted_tid {
continue;
}
// Otherwise we keep going.
}
// If the user only wants the main thread, and we haven't found it,
// skip this thread until we find it.
if cli.show_foreground_thread
&& *tid != foreground_tid.expect("no foreground thread id in dump")
{
continue;
}
// Print out the thread info.
println!("TID {}, TEB {:016x}", tid, thread.teb);
println!("Context:");
println!("{}", thread.context());
}
}
// Do we want to dump memory?
if let Some(address) = cli.address {
println!("Memory:");
// Try to find a block that contains `address`.
let block = dump.get_mem_block(address);
// If we have one..
if let Some(block) = block {
// .. and it has data, dump it..
if let Some(data) = block.data_from(address) {
println!("{:016x} -> {:016x}", address, block.end_addr());
hexdump(address, data.iter().take(0x1_00).copied());
}
// .. otherwise, inform the user..
else {
println!(
"The memory at {:016x} (from block {:016x} -> {:016x}) has no backing data",
address, block.range.start, block.range.end
);
}
}
// .. otherwise, inform he user.
else {
println!("No memory block were found for {:016x}", address);
}
}
// All right, enough for today.
Ok(())
}
sourcepub fn threads(&self) -> &Threads<'_>
pub fn threads(&self) -> &Threads<'_>
Get a reference to the TID -> Thread
map.
Examples found in repository?
examples/parser.rs (line 230)
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286
fn main() -> Result<(), String> {
// If we don't have any arguments, display the help.
if env::args().len() == 1 {
help();
return Ok(());
}
// Parse the command line arguments.
let cli = parse_args()?;
// Let's try to parse the dump file specified by the user.
let dump = UserDumpParser::new(cli.dump_path).map_err(|e| e.to_string())?;
// Do we want to display modules?
if cli.show_mods || cli.show_all {
println!("Loaded modules:");
// Iterate through the module and display their base address and path.
for (base, module) in dump.modules() {
println!("{:016x}: {}", base, module.path.display());
}
}
// Do we want the memory map?
if cli.show_memmap || cli.show_all {
println!("Memory map:");
// Iterate over the memory blocks.
for block in dump.mem_blocks().values() {
// Grab the string representation about its state, type, protection.
let state = block.state_as_str();
let type_ = block.type_as_str();
let protect = block.protect_as_str();
// Print it all out.
print!(
"{:016x} {:016x} {:016x} {:11} {:11} {:22}",
block.range.start,
block.range.end,
block.len(),
type_,
state,
protect
);
// Do we have a module that exists at this address?
let module = dump.get_module(block.range.start);
// If we do, then display its name / path.
if let Some(module) = module {
print!(
" [{}; \"{}\"]",
module.file_name().unwrap(),
module.path.display()
);
}
// Do we have data with this block? If so display the first few
// bytes.
if block.data.len() >= 4 {
print!(
" {:02x} {:02x} {:02x} {:02x}...",
block.data[0], block.data[1], block.data[2], block.data[3]
);
}
println!();
}
}
// Do we want threads?
if cli.show_threads || cli.show_all {
println!("Threads:");
// Grab the foreground tid.
let foreground_tid = dump.foreground_tid;
// Iterate through all the threads.
for (tid, thread) in dump.threads() {
// If the user specified a pid..
if let Some(wanted_tid) = cli.thread {
// .. skip an threads that don't match what the user wants..
if *tid != wanted_tid {
continue;
}
// Otherwise we keep going.
}
// If the user only wants the main thread, and we haven't found it,
// skip this thread until we find it.
if cli.show_foreground_thread
&& *tid != foreground_tid.expect("no foreground thread id in dump")
{
continue;
}
// Print out the thread info.
println!("TID {}, TEB {:016x}", tid, thread.teb);
println!("Context:");
println!("{}", thread.context());
}
}
// Do we want to dump memory?
if let Some(address) = cli.address {
println!("Memory:");
// Try to find a block that contains `address`.
let block = dump.get_mem_block(address);
// If we have one..
if let Some(block) = block {
// .. and it has data, dump it..
if let Some(data) = block.data_from(address) {
println!("{:016x} -> {:016x}", address, block.end_addr());
hexdump(address, data.iter().take(0x1_00).copied());
}
// .. otherwise, inform the user..
else {
println!(
"The memory at {:016x} (from block {:016x} -> {:016x}) has no backing data",
address, block.range.start, block.range.end
);
}
}
// .. otherwise, inform he user.
else {
println!("No memory block were found for {:016x}", address);
}
}
// All right, enough for today.
Ok(())
}
sourcepub fn mem_blocks(&self) -> &MemBlocks<'_>
pub fn mem_blocks(&self) -> &MemBlocks<'_>
Get a reference to the base address -> MemBlock
map.
Examples found in repository?
examples/parser.rs (line 180)
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286
fn main() -> Result<(), String> {
// If we don't have any arguments, display the help.
if env::args().len() == 1 {
help();
return Ok(());
}
// Parse the command line arguments.
let cli = parse_args()?;
// Let's try to parse the dump file specified by the user.
let dump = UserDumpParser::new(cli.dump_path).map_err(|e| e.to_string())?;
// Do we want to display modules?
if cli.show_mods || cli.show_all {
println!("Loaded modules:");
// Iterate through the module and display their base address and path.
for (base, module) in dump.modules() {
println!("{:016x}: {}", base, module.path.display());
}
}
// Do we want the memory map?
if cli.show_memmap || cli.show_all {
println!("Memory map:");
// Iterate over the memory blocks.
for block in dump.mem_blocks().values() {
// Grab the string representation about its state, type, protection.
let state = block.state_as_str();
let type_ = block.type_as_str();
let protect = block.protect_as_str();
// Print it all out.
print!(
"{:016x} {:016x} {:016x} {:11} {:11} {:22}",
block.range.start,
block.range.end,
block.len(),
type_,
state,
protect
);
// Do we have a module that exists at this address?
let module = dump.get_module(block.range.start);
// If we do, then display its name / path.
if let Some(module) = module {
print!(
" [{}; \"{}\"]",
module.file_name().unwrap(),
module.path.display()
);
}
// Do we have data with this block? If so display the first few
// bytes.
if block.data.len() >= 4 {
print!(
" {:02x} {:02x} {:02x} {:02x}...",
block.data[0], block.data[1], block.data[2], block.data[3]
);
}
println!();
}
}
// Do we want threads?
if cli.show_threads || cli.show_all {
println!("Threads:");
// Grab the foreground tid.
let foreground_tid = dump.foreground_tid;
// Iterate through all the threads.
for (tid, thread) in dump.threads() {
// If the user specified a pid..
if let Some(wanted_tid) = cli.thread {
// .. skip an threads that don't match what the user wants..
if *tid != wanted_tid {
continue;
}
// Otherwise we keep going.
}
// If the user only wants the main thread, and we haven't found it,
// skip this thread until we find it.
if cli.show_foreground_thread
&& *tid != foreground_tid.expect("no foreground thread id in dump")
{
continue;
}
// Print out the thread info.
println!("TID {}, TEB {:016x}", tid, thread.teb);
println!("Context:");
println!("{}", thread.context());
}
}
// Do we want to dump memory?
if let Some(address) = cli.address {
println!("Memory:");
// Try to find a block that contains `address`.
let block = dump.get_mem_block(address);
// If we have one..
if let Some(block) = block {
// .. and it has data, dump it..
if let Some(data) = block.data_from(address) {
println!("{:016x} -> {:016x}", address, block.end_addr());
hexdump(address, data.iter().take(0x1_00).copied());
}
// .. otherwise, inform the user..
else {
println!(
"The memory at {:016x} (from block {:016x} -> {:016x}) has no backing data",
address, block.range.start, block.range.end
);
}
}
// .. otherwise, inform he user.
else {
println!("No memory block were found for {:016x}", address);
}
}
// All right, enough for today.
Ok(())
}
sourcepub fn get_mem_block(&self, address: u64) -> Option<&MemBlock<'_>>
pub fn get_mem_block(&self, address: u64) -> Option<&MemBlock<'_>>
Find a MemBlock
that includes address
in its range.
Examples found in repository?
examples/parser.rs (line 261)
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286
fn main() -> Result<(), String> {
// If we don't have any arguments, display the help.
if env::args().len() == 1 {
help();
return Ok(());
}
// Parse the command line arguments.
let cli = parse_args()?;
// Let's try to parse the dump file specified by the user.
let dump = UserDumpParser::new(cli.dump_path).map_err(|e| e.to_string())?;
// Do we want to display modules?
if cli.show_mods || cli.show_all {
println!("Loaded modules:");
// Iterate through the module and display their base address and path.
for (base, module) in dump.modules() {
println!("{:016x}: {}", base, module.path.display());
}
}
// Do we want the memory map?
if cli.show_memmap || cli.show_all {
println!("Memory map:");
// Iterate over the memory blocks.
for block in dump.mem_blocks().values() {
// Grab the string representation about its state, type, protection.
let state = block.state_as_str();
let type_ = block.type_as_str();
let protect = block.protect_as_str();
// Print it all out.
print!(
"{:016x} {:016x} {:016x} {:11} {:11} {:22}",
block.range.start,
block.range.end,
block.len(),
type_,
state,
protect
);
// Do we have a module that exists at this address?
let module = dump.get_module(block.range.start);
// If we do, then display its name / path.
if let Some(module) = module {
print!(
" [{}; \"{}\"]",
module.file_name().unwrap(),
module.path.display()
);
}
// Do we have data with this block? If so display the first few
// bytes.
if block.data.len() >= 4 {
print!(
" {:02x} {:02x} {:02x} {:02x}...",
block.data[0], block.data[1], block.data[2], block.data[3]
);
}
println!();
}
}
// Do we want threads?
if cli.show_threads || cli.show_all {
println!("Threads:");
// Grab the foreground tid.
let foreground_tid = dump.foreground_tid;
// Iterate through all the threads.
for (tid, thread) in dump.threads() {
// If the user specified a pid..
if let Some(wanted_tid) = cli.thread {
// .. skip an threads that don't match what the user wants..
if *tid != wanted_tid {
continue;
}
// Otherwise we keep going.
}
// If the user only wants the main thread, and we haven't found it,
// skip this thread until we find it.
if cli.show_foreground_thread
&& *tid != foreground_tid.expect("no foreground thread id in dump")
{
continue;
}
// Print out the thread info.
println!("TID {}, TEB {:016x}", tid, thread.teb);
println!("Context:");
println!("{}", thread.context());
}
}
// Do we want to dump memory?
if let Some(address) = cli.address {
println!("Memory:");
// Try to find a block that contains `address`.
let block = dump.get_mem_block(address);
// If we have one..
if let Some(block) = block {
// .. and it has data, dump it..
if let Some(data) = block.data_from(address) {
println!("{:016x} -> {:016x}", address, block.end_addr());
hexdump(address, data.iter().take(0x1_00).copied());
}
// .. otherwise, inform the user..
else {
println!(
"The memory at {:016x} (from block {:016x} -> {:016x}) has no backing data",
address, block.range.start, block.range.end
);
}
}
// .. otherwise, inform he user.
else {
println!("No memory block were found for {:016x}", address);
}
}
// All right, enough for today.
Ok(())
}
pub fn with_file(_mapped_file: MappedFile<'a>) -> Result<UserDumpParser<'a>>
Trait Implementations§
Auto Trait Implementations§
impl<'a> Freeze for UserDumpParser<'a>
impl<'a> RefUnwindSafe for UserDumpParser<'a>
impl<'a> Send for UserDumpParser<'a>
impl<'a> Sync for UserDumpParser<'a>
impl<'a> Unpin for UserDumpParser<'a>
impl<'a> UnwindSafe for UserDumpParser<'a>
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
Mutably borrows from an owned value. Read more