From 07bf2102235a876606b4781c37a6492fbb67a7e7 Mon Sep 17 00:00:00 2001 From: Daniel McCarney Date: Wed, 15 Nov 2023 17:37:57 -0500 Subject: [PATCH] lib: add try_consumable! macro, handling AlreadyUsed Options In several places we represent something that could be consumed as an `Option`. When we try to use it, we `take()` the option, match the result, and return `rustls_result::AlreadyUsed` if `take()` returned `None`. Since this pattern is becoming more common with the use of more builder patterns this commit adds a `try_consumable!` macro that can do this repetitive work for us. --- src/acceptor.rs | 8 +++----- src/cipher.rs | 22 +++++----------------- src/lib.rs | 13 +++++++++++++ 3 files changed, 21 insertions(+), 22 deletions(-) diff --git a/src/acceptor.rs b/src/acceptor.rs index 09097f53..dbfbb8ef 100644 --- a/src/acceptor.rs +++ b/src/acceptor.rs @@ -12,7 +12,8 @@ use crate::rslice::{rustls_slice_bytes, rustls_str}; use crate::server::rustls_server_config; use crate::{ ffi_panic_boundary, free_box, rustls_result, set_boxed_mut_ptr, to_box, to_boxed_mut_ptr, - try_arc_from_ptr, try_callback, try_mut_from_ptr, try_ref_from_ptr, Castable, OwnershipBox, + try_arc_from_ptr, try_callback, try_consumable, try_mut_from_ptr, try_ref_from_ptr, Castable, + OwnershipBox, }; use rustls_result::NullParameter; @@ -398,10 +399,7 @@ impl rustls_accepted { ) -> rustls_result { ffi_panic_boundary! { let accepted: &mut Option = try_mut_from_ptr!(accepted); - let accepted = match accepted.take() { - Some(a) => a, - None => return rustls_result::AlreadyUsed, - }; + let accepted = try_consumable!(accepted); let config: Arc = try_arc_from_ptr!(config); match accepted.into_connection(config) { Ok(built) => { diff --git a/src/cipher.rs b/src/cipher.rs index 721b55a4..f51c54b5 100644 --- a/src/cipher.rs +++ b/src/cipher.rs @@ -19,10 +19,10 @@ use crate::error::{map_error, rustls_result}; use crate::rslice::{rustls_slice_bytes, rustls_str}; use crate::{ ffi_panic_boundary, free_arc, to_arc_const_ptr, to_boxed_mut_ptr, try_box_from_ptr, - try_mut_from_ptr, try_ref_from_ptr, try_slice, Castable, OwnershipArc, OwnershipBox, - OwnershipRef, + try_consumable, try_mut_from_ptr, try_ref_from_ptr, try_slice, Castable, OwnershipArc, + OwnershipBox, OwnershipRef, }; -use rustls_result::{AlreadyUsed, NullParameter}; +use rustls_result::NullParameter; /// An X.509 certificate, as used in rustls. /// Corresponds to `Certificate` in the Rust API. @@ -566,13 +566,7 @@ impl rustls_allow_any_authenticated_client_builder { Err(_) => return rustls_result::CertificateRevocationListParseError, }; - let client_cert_verifier = match client_cert_verifier_builder.take() { - None => { - return AlreadyUsed; - }, - Some(x) => x, - }; - + let client_cert_verifier = try_consumable!(client_cert_verifier_builder); match client_cert_verifier.with_crls(crls_der) { Ok(v) => client_cert_verifier_builder.replace(v), Err(e) => return map_error(rustls::Error::InvalidCertRevocationList(e)), @@ -710,13 +704,7 @@ impl rustls_allow_any_anonymous_or_authenticated_client_builder { Err(_) => return rustls_result::CertificateRevocationListParseError, }; - let client_cert_verifier = match client_cert_verifier_builder.take() { - None => { - return AlreadyUsed; - }, - Some(x) => x, - }; - + let client_cert_verifier = try_consumable!(client_cert_verifier_builder); match client_cert_verifier.with_crls(crls_der) { Ok(v) => client_cert_verifier_builder.replace(v), Err(e) => return map_error(rustls::Error::InvalidCertRevocationList(e)), diff --git a/src/lib.rs b/src/lib.rs index 3f943415..5682738b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -642,6 +642,19 @@ macro_rules! try_callback { pub(crate) use try_callback; +macro_rules! try_consumable { + ( $var:ident ) => { + match $var.take() { + None => { + return $crate::rustls_result::AlreadyUsed; + } + Some(x) => x, + } + }; +} + +pub(crate) use try_consumable; + /// Returns a static string containing the rustls-ffi version as well as the /// rustls version. The string is alive for the lifetime of the program and does /// not need to be freed.