use crate::error::Result;
use crate::order::Challenge;
use crate::types::{ChallengeType, Identifier};
use async_trait::async_trait;
pub mod dns01;
pub mod dns_cache;
pub mod http01;
pub mod tls_alpn01;
pub use dns_cache::{CachingDnsResolver, DnsCache};
pub use dns01::{Dns01Solver, DnsProvider, MockDnsProvider};
pub use http01::Http01Solver;
pub use tls_alpn01::TlsAlpn01Solver;
#[async_trait]
pub trait ChallengeSolver: Send + Sync {
fn challenge_type(&self) -> ChallengeType;
async fn prepare(
&mut self,
challenge: &Challenge,
identifier: &Identifier,
key_authorization: &str,
) -> Result<()>;
async fn present(&self) -> Result<()>;
async fn verify(&self) -> Result<bool>;
async fn cleanup(&mut self) -> Result<()>;
}
pub struct ChallengeSolverRegistry {
solvers: std::collections::HashMap<ChallengeType, Box<dyn ChallengeSolver>>,
}
impl ChallengeSolverRegistry {
pub fn new() -> Self {
Self {
solvers: std::collections::HashMap::new(),
}
}
pub fn register<S: ChallengeSolver + 'static>(&mut self, solver: S) {
self.solvers
.insert(solver.challenge_type(), Box::new(solver));
}
pub fn get(&self, challenge_type: ChallengeType) -> Option<&dyn ChallengeSolver> {
self.solvers.get(&challenge_type).map(|s| s.as_ref())
}
pub fn get_mut(
&mut self,
challenge_type: ChallengeType,
) -> Option<&mut (dyn ChallengeSolver + '_)> {
if let Some(solver) = self.solvers.get_mut(&challenge_type) {
Some(solver.as_mut())
} else {
None
}
}
pub fn supported_types(&self) -> Vec<ChallengeType> {
self.solvers.keys().copied().collect()
}
}
impl Default for ChallengeSolverRegistry {
fn default() -> Self {
Self::new()
}
}