pub enum InMemoryPrivateKey {
EcdsaP256(InMemoryEcdsaKey<NistP256>),
Ed25519(InMemoryEd25519Key),
Rsa(InMemoryRsaKey),
}Expand description
Holds a private key in memory.
Variants§
EcdsaP256(InMemoryEcdsaKey<NistP256>)
ECDSA private key using Nist P256 curve.
Ed25519(InMemoryEd25519Key)
ED25519 private key.
Rsa(InMemoryRsaKey)
RSA private key.
Implementations§
source§impl InMemoryPrivateKey
impl InMemoryPrivateKey
sourcepub fn from_pkcs1_der(
data: impl AsRef<[u8]>
) -> Result<Self, AppleCodesignError>
pub fn from_pkcs1_der(
data: impl AsRef<[u8]>
) -> Result<Self, AppleCodesignError>
Construct an instance by parsing PKCS#1 DER data.
Examples found in repository?
src/cli.rs (line 610)
566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668
fn collect_certificates_from_args(
args: &ArgMatches,
scan_smartcard: bool,
) -> Result<(Vec<Box<dyn PrivateKey>>, Vec<CapturedX509Certificate>), AppleCodesignError> {
let mut keys: Vec<Box<dyn PrivateKey>> = vec![];
let mut certs = vec![];
if let Some(p12_path) = args.get_one::<String>("p12_path") {
let p12_data = std::fs::read(p12_path)?;
let p12_password = if let Some(password) = args.get_one::<String>("p12_password") {
password.to_string()
} else if let Some(path) = args.get_one::<String>("p12_password_file") {
std::fs::read_to_string(path)?
.lines()
.next()
.expect("should get a single line")
.to_string()
} else {
dialoguer::Password::new()
.with_prompt("Please enter password for p12 file")
.interact()?
};
let (cert, key) = parse_pfx_data(&p12_data, &p12_password)?;
keys.push(Box::new(key));
certs.push(cert);
}
if let Some(values) = args.get_many::<String>("pem_source") {
for pem_source in values {
warn!("reading PEM data from {}", pem_source);
let pem_data = std::fs::read(pem_source)?;
for pem in pem::parse_many(pem_data).map_err(AppleCodesignError::CertificatePem)? {
match pem.tag.as_str() {
"CERTIFICATE" => {
certs.push(CapturedX509Certificate::from_der(pem.contents)?);
}
"PRIVATE KEY" => {
keys.push(Box::new(InMemoryPrivateKey::from_pkcs8_der(&pem.contents)?));
}
"RSA PRIVATE KEY" => {
keys.push(Box::new(InMemoryPrivateKey::from_pkcs1_der(&pem.contents)?));
}
tag => warn!("(unhandled PEM tag {}; ignoring)", tag),
}
}
}
}
if let Some(values) = args.get_many::<String>("der_source") {
for der_source in values {
warn!("reading DER file {}", der_source);
let der_data = std::fs::read(der_source)?;
certs.push(CapturedX509Certificate::from_der(der_data)?);
}
}
find_certificates_in_keychain(args, &mut keys, &mut certs)?;
if scan_smartcard {
if let Some(slot) = args.get_one::<String>("smartcard_slot") {
let pin_env_var = args.get_one::<String>("smartcard_pin_env");
handle_smartcard_sign_slot(slot, pin_env_var.map(|x| &**x), &mut keys, &mut certs)?;
}
}
let remote_signing_url = if args.get_flag("remote_signer") {
args.get_one::<String>("remote_signing_url")
} else {
None
};
if let Some(remote_signing_url) = remote_signing_url {
let initiator = get_remote_signing_initiator(args)?;
let client = UnjoinedSigningClient::new_initiator(
remote_signing_url,
initiator,
Some(print_session_join),
)?;
// As part of the handshake we obtained the public certificates from the signer.
// So make them the canonical set.
if !certs.is_empty() {
warn!(
"ignoring {} local certificates and using remote signer's certificate(s)",
certs.len()
);
}
certs = vec![client.signing_certificate().clone()];
certs.extend(client.certificate_chain().iter().cloned());
// The client implements Sign, so we just use it as the private key.
keys = vec![Box::new(client)];
}
Ok((keys, certs))
}sourcepub fn from_pkcs8_der(
data: impl AsRef<[u8]>
) -> Result<Self, AppleCodesignError>
pub fn from_pkcs8_der(
data: impl AsRef<[u8]>
) -> Result<Self, AppleCodesignError>
Construct an instance by parsing PKCS#8 DER data.
Examples found in repository?
src/cli.rs (line 607)
566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668
fn collect_certificates_from_args(
args: &ArgMatches,
scan_smartcard: bool,
) -> Result<(Vec<Box<dyn PrivateKey>>, Vec<CapturedX509Certificate>), AppleCodesignError> {
let mut keys: Vec<Box<dyn PrivateKey>> = vec![];
let mut certs = vec![];
if let Some(p12_path) = args.get_one::<String>("p12_path") {
let p12_data = std::fs::read(p12_path)?;
let p12_password = if let Some(password) = args.get_one::<String>("p12_password") {
password.to_string()
} else if let Some(path) = args.get_one::<String>("p12_password_file") {
std::fs::read_to_string(path)?
.lines()
.next()
.expect("should get a single line")
.to_string()
} else {
dialoguer::Password::new()
.with_prompt("Please enter password for p12 file")
.interact()?
};
let (cert, key) = parse_pfx_data(&p12_data, &p12_password)?;
keys.push(Box::new(key));
certs.push(cert);
}
if let Some(values) = args.get_many::<String>("pem_source") {
for pem_source in values {
warn!("reading PEM data from {}", pem_source);
let pem_data = std::fs::read(pem_source)?;
for pem in pem::parse_many(pem_data).map_err(AppleCodesignError::CertificatePem)? {
match pem.tag.as_str() {
"CERTIFICATE" => {
certs.push(CapturedX509Certificate::from_der(pem.contents)?);
}
"PRIVATE KEY" => {
keys.push(Box::new(InMemoryPrivateKey::from_pkcs8_der(&pem.contents)?));
}
"RSA PRIVATE KEY" => {
keys.push(Box::new(InMemoryPrivateKey::from_pkcs1_der(&pem.contents)?));
}
tag => warn!("(unhandled PEM tag {}; ignoring)", tag),
}
}
}
}
if let Some(values) = args.get_many::<String>("der_source") {
for der_source in values {
warn!("reading DER file {}", der_source);
let der_data = std::fs::read(der_source)?;
certs.push(CapturedX509Certificate::from_der(der_data)?);
}
}
find_certificates_in_keychain(args, &mut keys, &mut certs)?;
if scan_smartcard {
if let Some(slot) = args.get_one::<String>("smartcard_slot") {
let pin_env_var = args.get_one::<String>("smartcard_pin_env");
handle_smartcard_sign_slot(slot, pin_env_var.map(|x| &**x), &mut keys, &mut certs)?;
}
}
let remote_signing_url = if args.get_flag("remote_signer") {
args.get_one::<String>("remote_signing_url")
} else {
None
};
if let Some(remote_signing_url) = remote_signing_url {
let initiator = get_remote_signing_initiator(args)?;
let client = UnjoinedSigningClient::new_initiator(
remote_signing_url,
initiator,
Some(print_session_join),
)?;
// As part of the handshake we obtained the public certificates from the signer.
// So make them the canonical set.
if !certs.is_empty() {
warn!(
"ignoring {} local certificates and using remote signer's certificate(s)",
certs.len()
);
}
certs = vec![client.signing_certificate().clone()];
certs.extend(client.certificate_chain().iter().cloned());
// The client implements Sign, so we just use it as the private key.
keys = vec![Box::new(client)];
}
Ok((keys, certs))
}More examples
src/cryptography.rs (line 568)
487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588
pub fn parse_pfx_data(
data: &[u8],
password: &str,
) -> Result<(CapturedX509Certificate, InMemoryPrivateKey), AppleCodesignError> {
let pfx = p12::PFX::parse(data).map_err(|e| {
AppleCodesignError::PfxParseError(format!("data does not appear to be PFX: {e:?}"))
})?;
if !pfx.verify_mac(password) {
return Err(AppleCodesignError::PfxBadPassword);
}
// Apple's certificate export format consists of regular data content info
// with inner ContentInfo components holding the key and certificate.
let data = match pfx.auth_safe {
p12::ContentInfo::Data(data) => data,
_ => {
return Err(AppleCodesignError::PfxParseError(
"unexpected PFX content info".to_string(),
));
}
};
let content_infos = yasna::parse_der(&data, |reader| {
reader.collect_sequence_of(p12::ContentInfo::parse)
})
.map_err(|e| {
AppleCodesignError::PfxParseError(format!("failed parsing inner ContentInfo: {e:?}"))
})?;
let bmp_password = bmp_string(password);
let mut certificate = None;
let mut signing_key = None;
for content in content_infos {
let bags_data = match content {
p12::ContentInfo::Data(inner) => inner,
p12::ContentInfo::EncryptedData(encrypted) => {
encrypted.data(&bmp_password).ok_or_else(|| {
AppleCodesignError::PfxParseError(
"failed decrypting inner EncryptedData".to_string(),
)
})?
}
p12::ContentInfo::OtherContext(_) => {
return Err(AppleCodesignError::PfxParseError(
"unexpected OtherContent content in inner PFX data".to_string(),
));
}
};
let bags = yasna::parse_ber(&bags_data, |reader| {
reader.collect_sequence_of(p12::SafeBag::parse)
})
.map_err(|e| {
AppleCodesignError::PfxParseError(format!(
"failed parsing SafeBag within inner Data: {e:?}"
))
})?;
for bag in bags {
match bag.bag {
p12::SafeBagKind::CertBag(cert_bag) => match cert_bag {
p12::CertBag::X509(cert_data) => {
certificate = Some(CapturedX509Certificate::from_der(cert_data)?);
}
p12::CertBag::SDSI(_) => {
return Err(AppleCodesignError::PfxParseError(
"unexpected SDSI certificate data".to_string(),
));
}
},
p12::SafeBagKind::Pkcs8ShroudedKeyBag(key_bag) => {
let decrypted = key_bag.decrypt(&bmp_password).ok_or_else(|| {
AppleCodesignError::PfxParseError(
"error decrypting PKCS8 shrouded key bag; is the password correct?"
.to_string(),
)
})?;
signing_key = Some(InMemoryPrivateKey::from_pkcs8_der(decrypted)?);
}
p12::SafeBagKind::OtherBagKind(_) => {
return Err(AppleCodesignError::PfxParseError(
"unexpected bag type in inner PFX content".to_string(),
));
}
}
}
}
match (certificate, signing_key) {
(Some(certificate), Some(signing_key)) => Ok((certificate, signing_key)),
(None, Some(_)) => Err(AppleCodesignError::PfxParseError(
"failed to find x509 certificate in PFX data".to_string(),
)),
(_, None) => Err(AppleCodesignError::PfxParseError(
"failed to find signing key in PFX data".to_string(),
)),
}
}Trait Implementations§
source§impl Clone for InMemoryPrivateKey
impl Clone for InMemoryPrivateKey
source§fn clone(&self) -> InMemoryPrivateKey
fn clone(&self) -> InMemoryPrivateKey
Returns a copy of the value. Read more
1.0.0 · source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
Performs copy-assignment from
source. Read moresource§impl Debug for InMemoryPrivateKey
impl Debug for InMemoryPrivateKey
source§impl EncodePrivateKey for InMemoryPrivateKey
impl EncodePrivateKey for InMemoryPrivateKey
source§fn to_pkcs8_der(&self) -> Result<SecretDocument>
fn to_pkcs8_der(&self) -> Result<SecretDocument>
Serialize a
SecretDocument containing a PKCS#8-encoded private key.source§fn to_pkcs8_pem(
&self,
line_ending: LineEnding
) -> Result<Zeroizing<String>, Error>
fn to_pkcs8_pem(
&self,
line_ending: LineEnding
) -> Result<Zeroizing<String>, Error>
Serialize this private key as PEM-encoded PKCS#8 with the given [
LineEnding].source§impl PrivateKey for InMemoryPrivateKey
impl PrivateKey for InMemoryPrivateKey
fn as_key_info_signer(&self) -> &dyn KeyInfoSigner
fn to_public_key_peer_decrypt(
&self
) -> Result<Box<dyn PublicKeyPeerDecrypt>, AppleCodesignError>
source§impl Sign for InMemoryPrivateKey
impl Sign for InMemoryPrivateKey
source§fn sign(
&self,
message: &[u8]
) -> Result<(Vec<u8>, SignatureAlgorithm), X509CertificateError>
fn sign(
&self,
message: &[u8]
) -> Result<(Vec<u8>, SignatureAlgorithm), X509CertificateError>
👎Deprecated since 0.13.0: use the signature::Signer trait instead
Create a cyrptographic signature over a message. Read more
source§fn key_algorithm(&self) -> Option<KeyAlgorithm>
fn key_algorithm(&self) -> Option<KeyAlgorithm>
Obtain the algorithm of the private key. Read more
source§fn public_key_data(&self) -> Bytes
fn public_key_data(&self) -> Bytes
Obtain the raw bytes constituting the public key of the signing certificate. Read more
source§fn signature_algorithm(
&self
) -> Result<SignatureAlgorithm, X509CertificateError>
fn signature_algorithm(
&self
) -> Result<SignatureAlgorithm, X509CertificateError>
Obtain the SignatureAlgorithm that this signer will use. Read more
source§fn rsa_primes(&self) -> Result<Option<(Vec<u8>, Vec<u8>)>, X509CertificateError>
fn rsa_primes(&self) -> Result<Option<(Vec<u8>, Vec<u8>)>, X509CertificateError>
Obtain RSA key primes p and q, if available.
source§impl Signer<Signature> for InMemoryPrivateKey
impl Signer<Signature> for InMemoryPrivateKey
source§impl TryFrom<InMemoryPrivateKey> for InMemorySigningKeyPair
impl TryFrom<InMemoryPrivateKey> for InMemorySigningKeyPair
§type Error = AppleCodesignError
type Error = AppleCodesignError
The type returned in the event of a conversion error.
source§impl<'a> TryFrom<PrivateKeyInfo<'a>> for InMemoryPrivateKey
impl<'a> TryFrom<PrivateKeyInfo<'a>> for InMemoryPrivateKey
impl KeyInfoSigner for InMemoryPrivateKey
Auto Trait Implementations§
impl RefUnwindSafe for InMemoryPrivateKey
impl Send for InMemoryPrivateKey
impl Sync for InMemoryPrivateKey
impl Unpin for InMemoryPrivateKey
impl UnwindSafe for InMemoryPrivateKey
Blanket Implementations§
§impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
§impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
§impl<T> Conv for T
impl<T> Conv for T
§impl<T> EncodeEcPrivateKey for Twhere
T: EncodePrivateKey,
impl<T> EncodeEcPrivateKey for Twhere
T: EncodePrivateKey,
§fn to_sec1_der(&self) -> Result<SecretDocument, Error>
fn to_sec1_der(&self) -> Result<SecretDocument, Error>
Serialize a
SecretDocument containing a SEC1-encoded private key.source§impl<T> EncodeRsaPrivateKey for Twhere
T: EncodePrivateKey,
impl<T> EncodeRsaPrivateKey for Twhere
T: EncodePrivateKey,
source§fn to_pkcs1_der(&self) -> Result<SecretDocument, Error>
fn to_pkcs1_der(&self) -> Result<SecretDocument, Error>
Serialize a
SecretDocument containing a PKCS#1-encoded private key.source§fn to_pkcs1_pem(
&self,
line_ending: LineEnding
) -> Result<Zeroizing<String>, Error>
fn to_pkcs1_pem(
&self,
line_ending: LineEnding
) -> Result<Zeroizing<String>, Error>
Serialize this private key as PEM-encoded PKCS#1 with the given [
LineEnding].§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,
Causes
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,
Causes
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,
Causes
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,
Causes
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,
Causes
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,
Causes
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,
Causes
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,
Causes
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,
Formats each item in a sequence. Read more
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,
Pipes by value. This is generally the method you want to use. Read more
§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,
Borrows
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,
Mutably borrows
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,
Borrows
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,
Mutably borrows
self, then passes self.as_mut() into the pipe
function.§impl<T> Pointable for T
impl<T> Pointable for T
source§impl<T, S> SignerMut<S> for Twhere
T: Signer<S>,
S: Signature,
impl<T, S> SignerMut<S> for Twhere
T: Signer<S>,
S: Signature,
§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,
Immutable access to the
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,
Mutable access to the
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,
Immutable access to the
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,
Mutable access to the
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,
Immutable access to the
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,
Mutable access to the
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
Calls
.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
Calls
.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,
Calls
.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,
Calls
.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,
Calls
.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,
Calls
.tap_ref_mut() only in debug builds, and is erased in release
builds.