use std::{ops::Index, slice::Iter, vec::IntoIter};
use serde::{Deserialize, Serialize};
use crate::{error, Certificate};
#[derive(Clone, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)]
pub struct CertificateChain(Vec<Certificate>);
impl TryFrom<Vec<Certificate>> for CertificateChain {
type Error = error::CertificateChain;
fn try_from(certificates: Vec<Certificate>) -> Result<Self, Self::Error> {
Self::from_certificates(certificates)
}
}
impl IntoIterator for CertificateChain {
type IntoIter = IntoIter<Self::Item>;
type Item = Certificate;
fn into_iter(self) -> Self::IntoIter {
self.0.into_iter()
}
}
impl Index<usize> for CertificateChain {
type Output = Certificate;
fn index(&self, index: usize) -> &Self::Output {
self.0.index(index)
}
}
impl CertificateChain {
pub fn from_certificates<C: Into<Vec<Certificate>>>(
certificates: C,
) -> Result<Self, error::CertificateChain> {
Ok(Self(certificates.into()))
}
pub fn unchecked_from_certificates<C: Into<Vec<Certificate>>>(certificates: C) -> Self {
Self(certificates.into())
}
#[must_use]
pub fn into_end_entity_certificate(self) -> Certificate {
self.0
.into_iter()
.next()
.expect("`CertificateChain` is invalid")
}
#[must_use]
pub fn end_entity_certificate(&self) -> &Certificate {
self.0.get(0).expect("`CertificateChain` is invalid")
}
pub fn iter(&self) -> Iter<'_, Certificate> {
self.0.iter()
}
#[must_use]
pub fn get(&self, index: usize) -> Option<&Certificate> {
self.0.get(index)
}
pub(crate) fn into_rustls(self) -> Vec<rustls::Certificate> {
self.0.into_iter().map(Certificate::into_rustls).collect()
}
pub(crate) fn from_rustls(certs: &[rustls::Certificate]) -> Self {
Self(
certs
.iter()
.cloned()
.map(Certificate::from_rustls)
.collect(),
)
}
}