pub mod de;
pub mod enc;
use crate::types::Constraints;
use crate::{AsnType as _, Decoder as _};
pub use self::{de::Decoder, enc::Encoder};
const SIXTEEN_K: u16 = 16384;
const THIRTY_TWO_K: u16 = 32768;
const FOURTY_EIGHT_K: u16 = 49152;
const SIXTY_FOUR_K: u32 = 65536;
const SMALL_UNSIGNED_CONSTRAINT: Constraints = constraints!(value_constraint!(0, 63));
const LARGE_UNSIGNED_CONSTRAINT: Constraints = constraints!(value_constraint!(start: 0));
#[derive(crate::AsnType, crate::Encode, crate::Decode, Debug, Clone, Copy, PartialEq)]
#[rasn(crate_root = "crate", automatic_tags)]
struct DateEncoding {
year: YearEncoding,
#[rasn(value("1..=12"))]
month: u8,
#[rasn(value("1..=31"))]
day: u8,
}
#[derive(crate::AsnType, crate::Encode, crate::Decode, Debug, Clone, Copy, PartialEq)]
#[rasn(crate_root = "crate", choice, automatic_tags)]
enum YearEncoding {
Immediate(ImmediateYear),
NearFuture(NearFutureYear),
NearPast(NearPastYear),
Remainder(i32),
}
#[derive(crate::AsnType, crate::Encode, crate::Decode, Debug, Clone, Copy, PartialEq)]
#[rasn(crate_root = "crate", delegate, value("2005..=2020"))]
struct ImmediateYear(u16);
#[derive(crate::AsnType, crate::Encode, crate::Decode, Debug, Clone, Copy, PartialEq)]
#[rasn(crate_root = "crate", delegate, value("2021..=2276"))]
struct NearFutureYear(u16);
#[derive(crate::AsnType, crate::Encode, crate::Decode, Debug, Clone, Copy, PartialEq)]
#[rasn(crate_root = "crate", delegate, value("1749..=2004"))]
struct NearPastYear(u16);
impl From<crate::types::Date> for DateEncoding {
fn from(date: crate::types::Date) -> Self {
use chrono::Datelike;
let year = date.year();
Self {
year: match year {
2005..=2020 => YearEncoding::Immediate(ImmediateYear(year as u16)),
2021..=2276 => YearEncoding::NearFuture(NearFutureYear(year as u16)),
1749..=2004 => YearEncoding::NearPast(NearPastYear(year as u16)),
_ => YearEncoding::Remainder(year),
},
month: date.month() as u8,
day: date.day() as u8,
}
}
}
impl DateEncoding {
fn into_date(self) -> Option<crate::types::Date> {
let year = match self.year {
YearEncoding::Immediate(ImmediateYear(year))
| YearEncoding::NearFuture(NearFutureYear(year))
| YearEncoding::NearPast(NearPastYear(year)) => i32::from(year),
YearEncoding::Remainder(year) => year,
};
crate::types::Date::from_ymd_opt(year, self.month.into(), self.day.into())
}
}
pub(crate) fn decode<T: crate::Decode>(
options: de::DecoderOptions,
input: &[u8],
) -> Result<T, crate::error::DecodeError> {
T::decode(&mut crate::per::de::Decoder::<0, 0>::from_octets(
input, options,
))
}
pub(crate) fn decode_with_remainder<T: crate::Decode>(
options: de::DecoderOptions,
input: &[u8],
) -> Result<(T, &[u8]), crate::error::DecodeError> {
let decoder = &mut Decoder::<0, 0>::from_octets(input, options);
let decoded_instance = T::decode(decoder)?;
let remaining_bits = decoder.input().len();
let remaining_size = remaining_bits / 8;
debug_assert!(input.len() >= remaining_size);
Ok((decoded_instance, &input[input.len() - remaining_size..]))
}
pub(crate) fn encode<T: crate::Encode>(
options: enc::EncoderOptions,
value: &T,
) -> Result<alloc::vec::Vec<u8>, crate::error::EncodeError> {
let mut enc = crate::per::enc::Encoder::<0, 0>::new(options);
value.encode(&mut enc)?;
Ok(enc.output_into_vec())
}
pub(crate) fn encode_buf<T: crate::Encode>(
options: enc::EncoderOptions,
value: &T,
buffer: &mut alloc::vec::Vec<u8>,
) -> Result<(), crate::error::EncodeError> {
let raw = core::mem::take(buffer);
let output = crate::types::BitString::from_vec(raw);
let mut enc = crate::per::enc::Encoder::<0, 0>::new_with_output(options, output);
value.encode(&mut enc)?;
*buffer = enc.output_into_vec();
Ok(())
}
pub(crate) fn decode_with_constraints<T: crate::Decode>(
options: de::DecoderOptions,
constraints: &Constraints,
input: &[u8],
) -> Result<T, crate::error::DecodeError> {
T::decode_with_constraints(
&mut crate::per::de::Decoder::<0, 0>::from_octets(input, options),
constraints,
)
}
pub(crate) fn encode_with_constraints<T: crate::Encode>(
options: enc::EncoderOptions,
constraints: &Constraints,
value: &T,
) -> Result<alloc::vec::Vec<u8>, crate::error::EncodeError> {
let mut enc = crate::per::enc::Encoder::<0, 0>::new(options);
value.encode_with_constraints(&mut enc, constraints)?;
Ok(enc.output_into_vec())
}