summaryrefslogtreecommitdiff
path: root/src/asn1_types/enumerated.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/asn1_types/enumerated.rs')
-rw-r--r--src/asn1_types/enumerated.rs72
1 files changed, 72 insertions, 0 deletions
diff --git a/src/asn1_types/enumerated.rs b/src/asn1_types/enumerated.rs
new file mode 100644
index 0000000..5f843a8
--- /dev/null
+++ b/src/asn1_types/enumerated.rs
@@ -0,0 +1,72 @@
+use crate::ber::bytes_to_u64;
+use crate::*;
+use core::convert::TryFrom;
+
+/// ASN.1 `ENUMERATED` type
+///
+/// # Limitations
+///
+/// Supported values are limited to 0 .. 2^32
+#[derive(Debug, PartialEq, Eq)]
+pub struct Enumerated(pub u32);
+
+impl Enumerated {
+ pub const fn new(value: u32) -> Self {
+ Enumerated(value)
+ }
+}
+
+impl<'a> TryFrom<Any<'a>> for Enumerated {
+ type Error = Error;
+
+ fn try_from(any: Any<'a>) -> Result<Enumerated> {
+ TryFrom::try_from(&any)
+ }
+}
+
+impl<'a, 'b> TryFrom<&'b Any<'a>> for Enumerated {
+ type Error = Error;
+
+ fn try_from(any: &'b Any<'a>) -> Result<Enumerated> {
+ any.tag().assert_eq(Self::TAG)?;
+ any.header.assert_primitive()?;
+ let res_u64 = bytes_to_u64(any.data)?;
+ if res_u64 > (<u32>::MAX as u64) {
+ return Err(Error::IntegerTooLarge);
+ }
+ let value = res_u64 as u32;
+ Ok(Enumerated(value))
+ }
+}
+
+impl CheckDerConstraints for Enumerated {
+ fn check_constraints(any: &Any) -> Result<()> {
+ any.header.length.assert_definite()?;
+ Ok(())
+ }
+}
+
+impl DerAutoDerive for Enumerated {}
+
+impl Tagged for Enumerated {
+ const TAG: Tag = Tag::Enumerated;
+}
+
+#[cfg(feature = "std")]
+impl ToDer for Enumerated {
+ fn to_der_len(&self) -> Result<usize> {
+ Integer::from(self.0).to_der_len()
+ }
+
+ fn write_der_header(&self, writer: &mut dyn std::io::Write) -> SerializeResult<usize> {
+ let i = Integer::from(self.0);
+ let len = i.data.len();
+ let header = Header::new(Class::Universal, false, Self::TAG, Length::Definite(len));
+ header.write_der_header(writer).map_err(Into::into)
+ }
+
+ fn write_der_content(&self, writer: &mut dyn std::io::Write) -> SerializeResult<usize> {
+ let int = Integer::from(self.0);
+ int.write_der_content(writer).map_err(Into::into)
+ }
+}