Skip to content

Commit 9ac5281

Browse files
authored
Use FlagSet to provide an ergonomic experience with flag types (#412)
This provides a consistent, ergonomic experience when using flag types. It also removes custom code, replacing it with well tested code. Signed-off-by: Nathaniel McCallum <nathaniel@profian.com>
1 parent fdf97d6 commit 9ac5281

8 files changed

Lines changed: 166 additions & 225 deletions

File tree

Cargo.lock

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

der/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ rust-version = "1.57"
1818
[dependencies]
1919
const-oid = { version = "0.8", optional = true, path = "../const-oid" }
2020
der_derive = { version = "=0.6.0-pre.1", optional = true, path = "derive" }
21+
flagset = { version = "0.4.3", optional = true }
2122
pem-rfc7468 = { version = "=0.4.0-pre.0", optional = true, path = "../pem-rfc7468" }
2223
time = { version = "0.3", optional = true, default-features = false }
2324

der/src/asn1/bit_string.rs

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,74 @@ impl<'a> ExactSizeIterator for BitStringIter<'a> {
225225

226226
impl<'a> FusedIterator for BitStringIter<'a> {}
227227

228+
#[cfg(feature = "flagset")]
229+
impl<T: flagset::Flags> FixedTag for flagset::FlagSet<T> {
230+
const TAG: Tag = BitString::TAG;
231+
}
232+
233+
#[cfg(feature = "flagset")]
234+
impl<'a, T> DecodeValue<'a> for flagset::FlagSet<T>
235+
where
236+
T: flagset::Flags,
237+
T::Type: From<bool>,
238+
T::Type: core::ops::Shl<usize, Output = T::Type>,
239+
{
240+
fn decode_value(decoder: &mut Decoder<'a>, header: Header) -> Result<Self> {
241+
let position = decoder.position();
242+
243+
let bits = BitString::decode_value(decoder, header)?;
244+
245+
let mut flags = T::none().bits();
246+
if bits.bit_len() > core::mem::size_of_val(&flags) * 8 {
247+
return Err(Error::new(ErrorKind::Overlength, position));
248+
}
249+
250+
for (i, bit) in bits.bits().enumerate() {
251+
flags |= T::Type::from(bit) << i;
252+
}
253+
254+
Ok(Self::new_truncated(flags))
255+
}
256+
}
257+
258+
#[cfg(feature = "flagset")]
259+
#[inline(always)]
260+
fn encode<T>(set: &flagset::FlagSet<T>) -> (usize, [u8; 16])
261+
where
262+
T: flagset::Flags,
263+
u128: From<T::Type>,
264+
{
265+
let bits: u128 = set.bits().into();
266+
let mut swap = 0u128;
267+
268+
for i in 0..128 {
269+
let on = bits & (1 << i);
270+
swap |= on >> i << (128 - i - 1);
271+
}
272+
273+
(bits.leading_zeros() as usize, swap.to_be_bytes())
274+
}
275+
276+
#[cfg(feature = "flagset")]
277+
impl<T: flagset::Flags> EncodeValue for flagset::FlagSet<T>
278+
where
279+
T::Type: From<bool>,
280+
T::Type: core::ops::Shl<usize, Output = T::Type>,
281+
u128: From<T::Type>,
282+
{
283+
fn value_len(&self) -> Result<Length> {
284+
let (lead, buff) = encode(self);
285+
let buff = &buff[..buff.len() - lead / 8];
286+
BitString::new((lead % 8) as u8, buff)?.value_len()
287+
}
288+
289+
fn encode_value(&self, encoder: &mut Encoder<'_>) -> Result<()> {
290+
let (lead, buff) = encode(self);
291+
let buff = &buff[..buff.len() - lead / 8];
292+
BitString::new((lead % 8) as u8, buff)?.encode_value(encoder)
293+
}
294+
}
295+
228296
#[cfg(test)]
229297
mod tests {
230298
use super::{BitString, Result, Tag};

x509/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ edition = "2021"
1515
rust-version = "1.56"
1616

1717
[dependencies]
18-
der = { version = "=0.6.0-pre.1", features = ["derive", "alloc"], path = "../der" }
18+
der = { version = "=0.6.0-pre.1", features = ["derive", "alloc", "flagset"], path = "../der" }
19+
flagset = { version = "0.4.3" }
1920
spki = { version = "=0.6.0-pre.0", path = "../spki" }
2021
x501 = { version = "=0.1.0-pre.0", path = "../x501" }
2122

x509/src/extensions_utils.rs

Lines changed: 0 additions & 148 deletions
This file was deleted.

x509/src/lib.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,11 @@ extern crate alloc;
1515
extern crate std;
1616

1717
mod certificate;
18-
pub mod extensions_utils;
1918
mod general_name;
2019
pub mod pkix_extensions;
2120
pub mod pkix_oids;
2221
pub mod trust_anchor_format;
2322

24-
pub use crate::{
25-
certificate::*, extensions_utils::*, general_name::*, pkix_extensions::*, pkix_oids::*,
26-
};
23+
pub use crate::{certificate::*, general_name::*, pkix_extensions::*, pkix_oids::*};
2724
pub use der::{self, asn1::ObjectIdentifier};
2825
pub use spki::{self, AlgorithmIdentifier, SubjectPublicKeyInfo};

0 commit comments

Comments
 (0)