1use proc_macro2::TokenStream;
4use quote::quote;
5use std::{fmt, str::FromStr};
6
7#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
10pub(crate) enum Asn1Type {
11 BitString,
13
14 Ia5String,
16
17 GeneralizedTime,
19
20 OctetString,
22
23 PrintableString,
25
26 TeletexString,
28
29 VideotexString,
31
32 UtcTime,
34
35 Utf8String,
37}
38
39impl Asn1Type {
40 pub fn tag(self) -> TokenStream {
42 match self {
43 Asn1Type::BitString => quote!(::der::Tag::BitString),
44 Asn1Type::Ia5String => quote!(::der::Tag::Ia5String),
45 Asn1Type::GeneralizedTime => quote!(::der::Tag::GeneralizedTime),
46 Asn1Type::OctetString => quote!(::der::Tag::OctetString),
47 Asn1Type::PrintableString => quote!(::der::Tag::PrintableString),
48 Asn1Type::TeletexString => quote!(::der::Tag::TeletexString),
49 Asn1Type::VideotexString => quote!(::der::Tag::VideotexString),
50 Asn1Type::UtcTime => quote!(::der::Tag::UtcTime),
51 Asn1Type::Utf8String => quote!(::der::Tag::Utf8String),
52 }
53 }
54
55 pub fn decoder(self) -> TokenStream {
57 match self {
58 Asn1Type::BitString => quote!(::der::asn1::BitStringRef::decode(reader)?),
59 Asn1Type::Ia5String => quote!(::der::asn1::Ia5StringRef::decode(reader)?),
60 Asn1Type::GeneralizedTime => quote!(::der::asn1::GeneralizedTime::decode(reader)?),
61 Asn1Type::OctetString => quote!(::der::asn1::OctetStringRef::decode(reader)?),
62 Asn1Type::PrintableString => quote!(::der::asn1::PrintableStringRef::decode(reader)?),
63 Asn1Type::TeletexString => quote!(::der::asn1::TeletexStringRef::decode(reader)?),
64 Asn1Type::VideotexString => quote!(::der::asn1::VideotexStringRef::decode(reader)?),
65 Asn1Type::UtcTime => quote!(::der::asn1::UtcTime::decode(reader)?),
66 Asn1Type::Utf8String => quote!(::der::asn1::Utf8StringRef::decode(reader)?),
67 }
68 }
69
70 pub fn encoder(self, binding: &TokenStream) -> TokenStream {
72 let type_path = self.type_path();
73
74 match self {
75 Asn1Type::Ia5String
76 | Asn1Type::OctetString
77 | Asn1Type::PrintableString
78 | Asn1Type::TeletexString
79 | Asn1Type::VideotexString
80 | Asn1Type::Utf8String => quote!(#type_path::new(#binding)?),
81 _ => quote!(#type_path::try_from(#binding)?),
82 }
83 }
84
85 pub fn type_path(self) -> TokenStream {
88 match self {
89 Asn1Type::BitString => quote!(::der::asn1::BitStringRef),
90 Asn1Type::Ia5String => quote!(::der::asn1::Ia5StringRef),
91 Asn1Type::GeneralizedTime => quote!(::der::asn1::GeneralizedTime),
92 Asn1Type::OctetString => quote!(::der::asn1::OctetStringRef),
93 Asn1Type::PrintableString => quote!(::der::asn1::PrintableStringRef),
94 Asn1Type::TeletexString => quote!(::der::asn1::TeletexStringRef),
95 Asn1Type::VideotexString => quote!(::der::asn1::VideotexStringRef),
96 Asn1Type::UtcTime => quote!(::der::asn1::UtcTime),
97 Asn1Type::Utf8String => quote!(::der::asn1::Utf8StringRef),
98 }
99 }
100}
101
102impl FromStr for Asn1Type {
103 type Err = ParseError;
104
105 fn from_str(s: &str) -> Result<Self, ParseError> {
106 match s {
107 "BIT STRING" => Ok(Self::BitString),
108 "IA5String" => Ok(Self::Ia5String),
109 "GeneralizedTime" => Ok(Self::GeneralizedTime),
110 "OCTET STRING" => Ok(Self::OctetString),
111 "PrintableString" => Ok(Self::PrintableString),
112 "TeletexString" => Ok(Self::TeletexString),
113 "VideotexString" => Ok(Self::VideotexString),
114 "UTCTime" => Ok(Self::UtcTime),
115 "UTF8String" => Ok(Self::Utf8String),
116 _ => Err(ParseError),
117 }
118 }
119}
120
121impl fmt::Display for Asn1Type {
122 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
123 f.write_str(match self {
124 Asn1Type::BitString => "BIT STRING",
125 Asn1Type::Ia5String => "IA5String",
126 Asn1Type::GeneralizedTime => "GeneralizedTime",
127 Asn1Type::OctetString => "OCTET STRING",
128 Asn1Type::PrintableString => "PrintableString",
129 Asn1Type::TeletexString => "TeletexString",
130 Asn1Type::VideotexString => "VideotexString",
131 Asn1Type::UtcTime => "UTCTime",
132 Asn1Type::Utf8String => "UTF8String",
133 })
134 }
135}
136
137#[derive(Debug)]
139pub(crate) struct ParseError;