pub use crate::{
Decode, Encode, constraints, permitted_alphabet_constraint, size_constraint, value_constraint,
};
#[macro_use]
#[cfg(test)]
pub mod test;
#[macro_export]
macro_rules! value_constraint {
($($args:tt)*) => {
$crate::bounded_constraint!(Value, $($args)*)
};
}
#[macro_export]
macro_rules! size_constraint {
($($args:tt)*) => {
$crate::bounded_constraint!(Size, $($args)*)
};
}
#[macro_export]
macro_rules! constraints {
($($constraint:expr),+ $(,)?) => {
$crate::types::constraints::Constraints::new(&[$($constraint),+])
};
}
#[macro_export]
macro_rules! permitted_alphabet_constraint {
( $alphabet:expr) => {
$crate::types::constraints::Constraint::PermittedAlphabet(
$crate::types::constraints::Extensible::new(
$crate::types::constraints::PermittedAlphabet::new($alphabet),
),
)
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! bounded_constraint {
($constraint_type:ident, $single:expr, extensible) => {
$crate::types::constraints::Constraint::$constraint_type(
$crate::types::constraints::Extensible::new(
$crate::types::constraints::$constraint_type::new(
$crate::types::constraints::Bounded::Single($single),
),
)
.set_extensible(true),
)
};
($constraint_type:ident, $start:expr, $end:expr, extensible) => {
$crate::types::constraints::Constraint::$constraint_type(
$crate::types::constraints::Extensible::new(
$crate::types::constraints::$constraint_type::new(
$crate::types::constraints::Bounded::const_new($start, $end),
),
)
.set_extensible(true),
)
};
($constraint_type:ident, start: $start:expr, extensible) => {
$crate::types::constraints::Constraint::$constraint_type(
$crate::types::constraints::Extensible::new(
$crate::types::constraints::$constraint_type::new(
$crate::types::constraints::Bounded::start_from($start),
),
)
.set_extensible(true),
)
};
($constraint_type:ident, end: $end:expr, extensible) => {
$crate::types::constraints::Constraint::$constraint_type(
$crate::types::constraints::Extensible::new(
$crate::types::constraints::$constraint_type::new(
$crate::types::constraints::Bounded::up_to($end),
),
)
.set_extensible(true),
)
};
($constraint_type:ident, $start:expr, $end:expr) => {
$crate::types::constraints::Constraint::$constraint_type(
$crate::types::constraints::Extensible::new(
$crate::types::constraints::$constraint_type::new(
$crate::types::constraints::Bounded::const_new($start, $end),
),
),
)
};
($constraint_type:ident, start: $start:expr) => {
$crate::types::constraints::Constraint::$constraint_type(
$crate::types::constraints::Extensible::new(
$crate::types::constraints::$constraint_type::new(
$crate::types::constraints::Bounded::start_from($start),
),
),
)
};
($constraint_type:ident, end: $end:expr) => {
$crate::types::constraints::Constraint::$constraint_type(
$crate::types::constraints::Extensible::new(
$crate::types::constraints::$constraint_type::new(
$crate::types::constraints::Bounded::up_to($end),
),
),
)
};
($constraint_type:ident, $single:expr) => {
$crate::types::constraints::Constraint::$constraint_type(
$crate::types::constraints::Extensible::new(
$crate::types::constraints::$constraint_type::new(
$crate::types::constraints::Bounded::Single($single),
),
),
)
};
}
#[macro_export]
macro_rules! oid {
($s:literal) => {{
const OID: &'static $crate::types::Oid = const {
const BYTE_STRING: &'static [u8] = const {
let s: &'static str = $s;
let bytes = s.as_bytes();
core::assert!(!bytes.is_empty(), "OID string literals cannot be empty");
core::assert!(bytes.is_ascii(), "OID string literals must be ASCII");
core::assert!(
bytes[bytes.len() - 1] != b'.',
"OID string literals cannot end with a period"
);
match bytes {
[b'.', rest @ ..] => rest,
bytes => bytes,
}
};
const COMPONENT_LEN: usize = const {
let mut component_count = 1;
let mut index = 0;
while index < BYTE_STRING.len() {
let byte = BYTE_STRING[index];
core::assert!(
core::matches!(byte, b'0'..=b'9' | b'.'),
"OID string literals can only contain ASCII digits and periods"
);
if byte == b'.' {
if index + 1 < BYTE_STRING.len() {
core::assert!(
BYTE_STRING[index + 1] != b'.',
"OID string literals cannot contain two or more consecutive periods"
);
}
component_count += 1;
}
index += 1;
}
component_count
};
const COMPONENTS: [u32; COMPONENT_LEN] = const {
let mut bytes_index = 0;
let mut components = [0u32; COMPONENT_LEN];
let mut index = 0;
while bytes_index < BYTE_STRING.len() {
let byte = BYTE_STRING[bytes_index];
match byte {
b'0'..=b'9' => {
components[index] = components[index] * 10 + ((byte - b'0') as u32)
}
b'.' => index += 1,
_ => core::unreachable!(),
}
bytes_index += 1;
}
core::assert!(components[0] <= 2, "the first OID arc must be <= 2");
components
};
$crate::types::Oid::new(&COMPONENTS).unwrap()
};
OID
}};
}