picky_asn1_x509/
validity.rs1use picky_asn1::date::{GeneralizedTime, UTCTime};
2use picky_asn1::tag::TagPeeker;
3use picky_asn1::wrapper::{GeneralizedTimeAsn1, UtcTimeAsn1};
4use picky_asn1::Asn1Type;
5use serde::{de, ser, Deserialize, Serialize};
6use std::fmt;
7
8#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
9pub struct Validity {
10 pub not_before: Time,
11 pub not_after: Time,
12}
13
14#[derive(Debug, PartialEq, Eq, Clone)]
15pub enum Time {
16 Utc(UtcTimeAsn1),
17 Generalized(GeneralizedTimeAsn1),
18}
19
20impl From<UtcTimeAsn1> for Time {
21 fn from(time: UtcTimeAsn1) -> Self {
22 Self::Utc(time)
23 }
24}
25
26impl From<UTCTime> for Time {
27 fn from(time: UTCTime) -> Self {
28 Self::Utc(time.into())
29 }
30}
31
32impl From<GeneralizedTimeAsn1> for Time {
33 fn from(time: GeneralizedTimeAsn1) -> Self {
34 Self::Generalized(time)
35 }
36}
37
38impl From<GeneralizedTime> for Time {
39 fn from(time: GeneralizedTime) -> Self {
40 Self::Generalized(time.into())
41 }
42}
43
44impl ser::Serialize for Time {
45 fn serialize<S>(&self, serializer: S) -> Result<<S as ser::Serializer>::Ok, <S as ser::Serializer>::Error>
46 where
47 S: ser::Serializer,
48 {
49 match &self {
50 Time::Utc(time) => time.serialize(serializer),
51 Time::Generalized(time) => time.serialize(serializer),
52 }
53 }
54}
55
56impl<'de> de::Deserialize<'de> for Time {
57 fn deserialize<D>(deserializer: D) -> Result<Self, <D as de::Deserializer<'de>>::Error>
58 where
59 D: de::Deserializer<'de>,
60 {
61 struct Visitor;
62
63 impl<'de> de::Visitor<'de> for Visitor {
64 type Value = Time;
65
66 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
67 formatter.write_str("a valid DER-encoded Time")
68 }
69
70 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
71 where
72 A: de::SeqAccess<'de>,
73 {
74 let tag_peeker: TagPeeker = seq_next_element!(seq, Time, "choice tag");
75 match tag_peeker.next_tag {
76 UtcTimeAsn1::TAG => Ok(Time::Utc(seq_next_element!(seq, Time, "UTCTime"))),
77 GeneralizedTimeAsn1::TAG => Ok(Time::Generalized(seq_next_element!(seq, Time, "GeneralizedTime"))),
78 _ => Err(serde_invalid_value!(
79 Time,
80 "invalid variant",
81 "either UTCTime or GeneralizedTime"
82 )),
83 }
84 }
85 }
86
87 deserializer.deserialize_enum("Time", &["UTC", "Generalized"], Visitor)
88 }
89}