use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Order {
pub status: OrderStatus,
#[serde(skip_serializing_if = "Option::is_none")]
pub expires: Option<DateTime<Utc>>,
pub identifiers: Vec<Identifier>,
pub authorizations: Vec<String>,
pub finalize: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub certificate: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub enum OrderStatus {
Pending,
Ready,
Processing,
Valid,
Invalid,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Identifier {
#[serde(rename = "type")]
pub id_type: String,
pub value: String,
}
impl Identifier {
pub fn dns(domain: impl Into<String>) -> Self {
Self {
id_type: "dns".to_string(),
value: domain.into(),
}
}
}
#[derive(Debug, Clone, Serialize)]
pub struct OrderCreate {
pub identifiers: Vec<Identifier>,
#[serde(rename = "notBefore", skip_serializing_if = "Option::is_none")]
pub not_before: Option<DateTime<Utc>>,
#[serde(rename = "notAfter", skip_serializing_if = "Option::is_none")]
pub not_after: Option<DateTime<Utc>>,
}
impl OrderCreate {
pub fn new(domains: Vec<String>) -> Self {
Self {
identifiers: domains.into_iter().map(Identifier::dns).collect(),
not_before: None,
not_after: None,
}
}
pub fn with_not_before(mut self, timestamp: DateTime<Utc>) -> Self {
self.not_before = Some(timestamp);
self
}
pub fn with_not_after(mut self, timestamp: DateTime<Utc>) -> Self {
self.not_after = Some(timestamp);
self
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_identifier_dns() {
let identifier = Identifier::dns("example.com");
assert_eq!(identifier.id_type, "dns");
assert_eq!(identifier.value, "example.com");
}
#[test]
fn test_order_create() {
let order = OrderCreate::new(vec![
"example.com".to_string(),
"www.example.com".to_string(),
]);
assert_eq!(order.identifiers.len(), 2);
assert_eq!(order.identifiers[0].value, "example.com");
assert_eq!(order.identifiers[1].value, "www.example.com");
}
#[test]
fn test_order_status_serialization() {
let status = OrderStatus::Valid;
let json = serde_json::to_string(&status).unwrap();
assert_eq!(json, "\"valid\"");
}
}