Remove dead code and simplify listen address deserialization

- Remove unused delete_tlsa_record, find_certificate, CertInfo.pem_chain,
  ChallengeInfo.challenge_type
- Remove all #[allow(dead_code)] annotations
- Replace custom deserializers with generic OneOrMany<T> enum used
  directly in SolverConfig fields

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Roman Kivalin
2026-04-14 17:16:02 +02:00
co-authored by Claude Opus 4.6
parent b6d299300d
commit a0d275527b
5 changed files with 16 additions and 73 deletions
-4
View File
@@ -15,12 +15,9 @@ pub struct AcmeClient {
}
/// Generic challenge information for any challenge type.
#[allow(dead_code)]
pub struct ChallengeInfo {
/// The identifier being validated (domain name or IP address).
pub identifier: String,
/// The challenge type that was selected.
pub challenge_type: ChallengeType,
/// The challenge token.
pub token: String,
/// The full key authorization string.
@@ -163,7 +160,6 @@ impl AcmeClient {
challenges.push(ChallengeInfo {
identifier,
challenge_type: desired,
token,
key_authorization,
dns_value,
-4
View File
@@ -5,9 +5,6 @@ use crate::error::{Error, Result};
/// Parsed certificate information.
pub struct CertInfo {
/// The full certificate chain PEM
#[allow(dead_code)]
pub pem_chain: String,
/// DER-encoded leaf certificate
pub leaf_der: Vec<u8>,
/// Not-after (expiry) timestamp
@@ -47,7 +44,6 @@ impl CertInfo {
let spki_der = cert.public_key().raw.to_vec();
Ok(Self {
pem_chain: pem_data.to_string(),
leaf_der,
not_after,
san,
+14 -41
View File
@@ -134,7 +134,6 @@ fn default_propagation_delay() -> u64 {
/// Challenge solver configuration, tagged by type.
#[derive(Debug, Deserialize)]
#[serde(tag = "type")]
#[allow(dead_code)]
pub enum SolverConfig {
#[serde(rename = "dns-01")]
Dns01 {
@@ -149,54 +148,32 @@ pub enum SolverConfig {
/// Address(es) to listen on for standalone HTTP server.
/// Accepts a single address or a list. If multiple are given,
/// certforge tries all and succeeds if at least one binds.
#[serde(default, deserialize_with = "deserialize_listen_addrs")]
listen: Option<Vec<SocketAddr>>,
listen: Option<OneOrMany<SocketAddr>>,
/// Directory to write challenge tokens for an existing web server.
webroot: Option<PathBuf>,
},
#[serde(rename = "tls-alpn-01")]
TlsAlpn01 {
/// Address(es) to listen on for the TLS-ALPN server.
#[serde(deserialize_with = "deserialize_listen_addrs_required")]
listen: Vec<SocketAddr>,
listen: OneOrMany<SocketAddr>,
},
}
/// Deserialize `listen` as either a single SocketAddr or a list.
fn deserialize_listen_addrs<'de, D>(deserializer: D) -> std::result::Result<Option<Vec<SocketAddr>>, D::Error>
where
D: serde::Deserializer<'de>,
{
#[derive(Deserialize)]
#[serde(untagged)]
enum OneOrMany {
One(SocketAddr),
Many(Vec<SocketAddr>),
}
Option::<OneOrMany>::deserialize(deserializer).map(|opt| {
opt.map(|v| match v {
OneOrMany::One(addr) => vec![addr],
OneOrMany::Many(addrs) => addrs,
})
})
/// Serde helper: accept a single value or a list.
#[derive(Debug, Deserialize)]
#[serde(untagged)]
pub enum OneOrMany<T> {
One(T),
Many(Vec<T>),
}
fn deserialize_listen_addrs_required<'de, D>(deserializer: D) -> std::result::Result<Vec<SocketAddr>, D::Error>
where
D: serde::Deserializer<'de>,
{
#[derive(Deserialize)]
#[serde(untagged)]
enum OneOrMany {
One(SocketAddr),
Many(Vec<SocketAddr>),
impl<T: Clone> OneOrMany<T> {
pub fn to_vec(&self) -> Vec<T> {
match self {
Self::One(v) => vec![v.clone()],
Self::Many(v) => v.clone(),
}
}
OneOrMany::deserialize(deserializer).map(|v| match v {
OneOrMany::One(addr) => vec![addr],
OneOrMany::Many(addrs) => addrs,
})
}
#[derive(Debug, Deserialize)]
@@ -378,10 +355,6 @@ impl Config {
})
}
#[allow(dead_code)]
pub fn find_certificate(&self, name: &str) -> Option<&CertificateConfig> {
self.certificates.iter().find(|c| c.name == name)
}
fn validate(&self) -> Result<()> {
// ACME config
-22
View File
@@ -264,28 +264,6 @@ impl DnsUpdater {
Ok(records)
}
/// Delete a specific TLSA record.
#[allow(dead_code)]
pub async fn delete_tlsa_record(
&mut self,
zone: &Name,
name: &Name,
tlsa: &TlsaRecord,
) -> Result<()> {
let rdata = tlsa_to_rdata(tlsa);
let record = Record::from_rdata(name.clone(), 0, rdata);
let response = self
.client
.delete_by_rdata(record, zone.clone())
.await
.map_err(|e| dns_err("failed to delete TLSA record", e))?;
check_update_response("failed to delete TLSA record", &response)?;
tracing::debug!(%name, rdata = %tlsa.to_rdata_string(), "deleted TLSA record");
Ok(())
}
}
/// Convert our TlsaRecord to hickory RData.
+2 -2
View File
@@ -40,7 +40,7 @@ fn build_solvers(config: &Config, solver_names: &[&str]) -> Result<HashMap<Strin
if let Some(webroot) = webroot {
Box::new(Http01WebrootSolver::new(webroot.clone()))
} else if let Some(addrs) = listen {
Box::new(Http01StandaloneSolver::new(addrs.clone()))
Box::new(Http01StandaloneSolver::new(addrs.to_vec()))
} else {
return Err(Error::Config(format!(
"solver '{name}': HTTP-01 requires either listen or webroot"
@@ -48,7 +48,7 @@ fn build_solvers(config: &Config, solver_names: &[&str]) -> Result<HashMap<Strin
}
}
SolverConfig::TlsAlpn01 { listen } => {
Box::new(TlsAlpn01Solver::new(listen.clone()))
Box::new(TlsAlpn01Solver::new(listen.to_vec()))
}
};
solvers.insert(name.to_string(), solver);