Skip to content

Commit

Permalink
Revert "const-oid: add ObjectIdentifierRef; use for db (#1212)"
Browse files Browse the repository at this point in the history
This reverts commit 2f6303b.

Per #1293 to keep the ergonomics of the v0.9 release we need derived
`Eq`/`PartialEq` impls which allow the constants to be used in `match`
expressions.

That's not really possible with the generic backing storage approach
that the v0.10 prereleases have been trying, and also precludes
comparing OIDs with different backing storages.

While an `ObjectIdentifierRef` is still worth experimenting with, it's
clear it isn't ready for prime time yet, so this begins the process of
backing out some changes so the database isn't yet dependent on its
existence.
  • Loading branch information
tarcieri committed Jan 4, 2024
1 parent 734b7b1 commit 5739075
Show file tree
Hide file tree
Showing 10 changed files with 3,815 additions and 7,155 deletions.
21 changes: 8 additions & 13 deletions const-oid/oiddbgen/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion const-oid/oiddbgen/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ edition = "2021"

[dependencies]
convert_case = "0.5.0"
const-oid = { path = ".." }
proc-macro2 = "1.0.36"
quote = "1.0.15"
regex = "1.5.5"
Expand Down
10 changes: 5 additions & 5 deletions const-oid/oiddbgen/src/ldap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,19 @@ impl<'a> LdapParser<'a> {
self.0.lines().filter_map(|line| {
let (name, next) = line.split_at(line.find(',').unwrap());
let (.., next) = next[1..].split_at(next[1..].find(',').unwrap());
let (oid, spec) = next[1..].split_at(next[1..].find(',').unwrap());
let (obid, spec) = next[1..].split_at(next[1..].find(',').unwrap());

let indx = oid.find('.')?;
oid.split_at(indx).0.parse::<usize>().ok()?;
let indx = obid.find('.')?;
obid.split_at(indx).0.parse::<usize>().ok()?;

if !spec.trim().starts_with(",[RFC") {
return None;
}

let spec = spec[2..][..spec.len() - 3].to_ascii_lowercase();
let name = name.trim().to_string();
let oid = oid.trim().to_string();
Some((spec, name, oid))
let obid = obid.trim().to_string();
Some((spec, name, obid))
})
}
}
9 changes: 9 additions & 0 deletions const-oid/oiddbgen/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
mod asn1;
mod ldap;
mod node;
mod root;
mod spec;

pub use asn1::Asn1Parser;
pub use ldap::LdapParser;
pub use root::Root;
22 changes: 7 additions & 15 deletions const-oid/oiddbgen/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,4 @@
mod asn1;
mod ldap;
mod node;
mod root;
mod spec;

pub use asn1::Asn1Parser;
pub use ldap::LdapParser;
pub use root::Root;
use oiddbgen::{Asn1Parser, LdapParser, Root};

// Update this database by downloading the CSV file here:
// https://www.iana.org/assignments/ldap-parameters/ldap-parameters.xhtml#ldap-parameters-3
Expand Down Expand Up @@ -41,19 +33,19 @@ const NO_BASES: &[(&str, &str)] = &[("", "")];
fn main() {
let mut root = Root::default();

for (spec, name, oid) in LdapParser::new(LDAP).iter() {
root.add(&spec, &name, &oid);
for (spec, name, obid) in LdapParser::new(LDAP).iter() {
root.add(&spec, &name, &obid);
}

for (spec, body) in RFCS {
for (name, oid) in Asn1Parser::new(body, BASES).iter() {
root.add(spec, &name, &oid);
for (name, obid) in Asn1Parser::new(body, BASES).iter() {
root.add(spec, &name, &obid);
}
}

for (spec, body) in MDS {
for (name, oid) in Asn1Parser::new(body, NO_BASES).iter() {
root.add(spec, &name, &oid);
for (name, obid) in Asn1Parser::new(body, NO_BASES).iter() {
root.add(spec, &name, &obid);
}
}

Expand Down
41 changes: 26 additions & 15 deletions const-oid/oiddbgen/src/node.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,36 @@
use const_oid::ObjectIdentifier;
use std::cmp::Ordering;

use convert_case::{Case, Casing};
use proc_macro2::{Ident, Span, TokenStream};
use quote::quote;

#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Node {
oid: ObjectIdentifier,
obid: String,
name: String,
symb: Ident,
}

impl Ord for Node {
fn cmp(&self, other: &Self) -> Ordering {
match self.obid.cmp(&other.obid) {
Ordering::Equal => match self.name.len().cmp(&other.name.len()) {
Ordering::Equal => self.name.cmp(&other.name),
o => o,
},
o => o,
}
}
}

impl PartialOrd for Node {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
Some(self.cmp(other))
}
}

impl Node {
pub fn new(oid: ObjectIdentifier, name: String) -> Self {
pub fn new(obid: String, name: String) -> Self {
// Raise the first letter in the beginning or after a hyphen.
// This produces more natural UpperSnake conversions below.
let mut upper = true;
Expand All @@ -32,7 +51,7 @@ impl Node {
let symb = symb.to_case(Case::UpperSnake);
let symb = Ident::new(&symb, Span::call_site());

Self { oid, name, symb }
Self { obid, name, symb }
}

pub fn name(&self) -> &str {
Expand All @@ -44,19 +63,11 @@ impl Node {
}

pub fn definition(&self) -> TokenStream {
let obid = self.obid.replace(' ', ""); // Fix a typo.
let symb = &self.symb;
let oid = self.oid.to_string();
let doc = format!("#[doc=\"{}: {}\"]", &self.oid, &self.name)
.parse::<TokenStream>()
.expect("malformed doc comment");

let bytes = format!("&{:?}", oid.as_bytes())
.parse::<TokenStream>()
.expect("malformed byte slice literal");

quote! {
#doc
pub const #symb: crate::ObjectIdentifierRef<'static> = crate::ObjectIdentifierRef::from_bytes_unchecked(#bytes);
pub const #symb: crate::ObjectIdentifier = crate::ObjectIdentifier::new_unwrap(#obid);
}
}
}
13 changes: 7 additions & 6 deletions const-oid/oiddbgen/src/root.rs
Original file line number Diff line number Diff line change
@@ -1,23 +1,24 @@
use crate::{node::Node, spec::Spec};
use const_oid::ObjectIdentifier;

use std::collections::BTreeMap;

use proc_macro2::{Ident, Span, TokenStream};
use quote::quote;
use std::collections::BTreeMap;

#[derive(Clone, Debug, Default)]
pub struct Root(BTreeMap<Ident, Spec>);

impl Root {
pub fn add(&mut self, spec: &str, name: &str, oid: &str) {
pub fn add(&mut self, spec: &str, name: &str, obid: &str) {
let name = name.trim().to_string();
let oid = oid.trim().parse::<ObjectIdentifier>().expect("invalid OID");
let obid = obid.trim().to_string();
let spec = spec.trim().to_ascii_lowercase();
let spec = Ident::new(&spec, Span::call_site());

self.0
.entry(spec)
.or_insert_with(Spec::default)
.insert(Node::new(oid, name));
.insert(Node::new(obid, name));
}

pub fn module(&self) -> TokenStream {
Expand All @@ -26,7 +27,7 @@ impl Root {

for (spec, s) in &self.0 {
mods.extend(s.module(spec));
recs.extend(s.records(quote! { #spec }));
recs.extend(s.records(quote! { &#spec }));
}

quote! {
Expand Down
21 changes: 10 additions & 11 deletions const-oid/src/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ mod gen;

pub use gen::*;

use crate::{Error, ObjectIdentifier, ObjectIdentifierRef};
use crate::{Error, ObjectIdentifier};

/// A const implementation of case-insensitive ASCII equals.
const fn eq_case(lhs: &[u8], rhs: &[u8]) -> bool {
Expand All @@ -37,7 +37,7 @@ const fn eq_case(lhs: &[u8], rhs: &[u8]) -> bool {

/// A query interface for OIDs/Names.
#[derive(Copy, Clone)]
pub struct Database<'a>(&'a [(ObjectIdentifierRef<'a>, &'a str)]);
pub struct Database<'a>(&'a [(&'a ObjectIdentifier, &'a str)]);

impl<'a> Database<'a> {
/// Looks up a name for an OID.
Expand All @@ -52,14 +52,13 @@ impl<'a> Database<'a> {
}

/// Finds a named oid by its associated OID.
pub fn by_oid<B>(&self, oid: &ObjectIdentifier<B>) -> Option<&'a str>
where
B: AsRef<[u8]>,
{
pub const fn by_oid(&self, oid: &ObjectIdentifier) -> Option<&'a str> {
let mut i = 0;

while i < self.0.len() {
if oid == &self.0[i].0 {
let lhs = self.0[i].0;

if lhs.buffer.eq(&oid.buffer) {
return Some(self.0[i].1);
}

Expand All @@ -70,7 +69,7 @@ impl<'a> Database<'a> {
}

/// Finds a named oid by its associated name.
pub const fn by_name(&self, name: &str) -> Option<ObjectIdentifierRef<'a>> {
pub const fn by_name(&self, name: &str) -> Option<&'a ObjectIdentifier> {
let mut i = 0;

while i < self.0.len() {
Expand All @@ -86,7 +85,7 @@ impl<'a> Database<'a> {
}

/// Return the list of matched name for the OID.
pub fn find_names_for_oid(&self, oid: ObjectIdentifier) -> Names<'a> {
pub const fn find_names_for_oid(&self, oid: ObjectIdentifier) -> Names<'a> {
Names {
database: *self,
oid,
Expand All @@ -111,7 +110,7 @@ impl<'a> Iterator for Names<'a> {
while i < self.database.0.len() {
let lhs = self.database.0[i].0;

if lhs.eq(&self.oid) {
if lhs.buffer.eq(&self.oid.buffer) {
self.position = i + 1;
return Some(self.database.0[i].1);
}
Expand Down Expand Up @@ -141,7 +140,7 @@ mod tests {
#[test]
fn by_name() {
let cn = super::DB.by_name("CN").expect("cn not found");
assert_eq!(CN, cn);
assert_eq!(&CN, cn);

assert_eq!(None, super::DB.by_name("purplePeopleEater"));
}
Expand Down
Loading

0 comments on commit 5739075

Please sign in to comment.