trz_gateway_common/security_configuration/
either.rs

1use std::sync::Arc;
2
3use openssl::x509::X509;
4use openssl::x509::store::X509Store;
5
6use super::TrustedStoreConfig;
7use super::certificate::CertificateConfig;
8use crate::certificate_info::X509CertificateInfo;
9
10#[derive(Clone, Debug)]
11pub enum EitherConfig<L, R> {
12    Left(L),
13    Right(R),
14}
15
16impl<L: TrustedStoreConfig, R: TrustedStoreConfig> TrustedStoreConfig for EitherConfig<L, R> {
17    type Error = EitherConfig<L::Error, R::Error>;
18
19    fn root_certificates(&self) -> Result<Arc<X509Store>, Self::Error> {
20        match self {
21            Self::Left(s) => s.root_certificates().map_err(EitherConfig::Left),
22            Self::Right(s) => s.root_certificates().map_err(EitherConfig::Right),
23        }
24    }
25}
26
27impl<L: CertificateConfig, R: CertificateConfig> CertificateConfig for EitherConfig<L, R> {
28    type Error = EitherConfig<L::Error, R::Error>;
29
30    fn intermediates(&self) -> Result<Arc<Vec<X509>>, Self::Error> {
31        match self {
32            Self::Left(s) => s.intermediates().map_err(EitherConfig::Left),
33            Self::Right(store) => store.intermediates().map_err(EitherConfig::Right),
34        }
35    }
36
37    fn certificate(&self) -> Result<Arc<X509CertificateInfo>, Self::Error> {
38        match self {
39            Self::Left(s) => s.certificate().map_err(EitherConfig::Left),
40            Self::Right(s) => s.certificate().map_err(EitherConfig::Right),
41        }
42    }
43
44    fn is_dynamic(&self) -> bool {
45        match self {
46            Self::Left(s) => s.is_dynamic(),
47            Self::Right(s) => s.is_dynamic(),
48        }
49    }
50}
51
52impl<L: std::error::Error, R: std::error::Error> std::error::Error for EitherConfig<L, R> {
53    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
54        match self {
55            Self::Left(s) => s.source(),
56            Self::Right(s) => s.source(),
57        }
58    }
59}
60
61impl<L: std::fmt::Display, R: std::fmt::Display> std::fmt::Display for EitherConfig<L, R> {
62    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
63        match self {
64            Self::Left(s) => s.fmt(f),
65            Self::Right(s) => s.fmt(f),
66        }
67    }
68}