Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

const-oid: add ObjectIdentifierRef; use for db #1212

Merged
merged 1 commit into from
Sep 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 16 additions & 11 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: 1 addition & 0 deletions const-oid/oiddbgen/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ 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
2 changes: 1 addition & 1 deletion const-oid/oiddbgen/ldap-parameters-3.csv
Original file line number Diff line number Diff line change
Expand Up @@ -660,7 +660,7 @@ uddiv3ExpiresAfter,A,1.3.6.1.1.10.4.42,[RFC4403]
uddiv3MaxEntities,A,1.3.6.1.1.10.4.41,[RFC4403]
uddiv3NodeId,A,1.3.6.1.1.10.4.36,[RFC4403]
uddiv3NotificationInterval,A,1.3.6.1.1.10.4.40,[RFC4403]
uddiv3ServiceKey,A,1.3.6.1.1. 10.4.32,[RFC4403]
uddiv3ServiceKey,A,1.3.6.1.1.10.4.32,[RFC4403]
uddiv3Subscription,O,1.3.6.1.1.10.6.9,[RFC4403]
uddiv3SubscriptionFilter,A,1.3.6.1.1.10.4.39,[RFC4403]
uddiv3SubscriptionKey,A,1.3.6.1.1.10.4.38,[RFC4403]
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 (obid, spec) = next[1..].split_at(next[1..].find(',').unwrap());
let (oid, spec) = next[1..].split_at(next[1..].find(',').unwrap());

let indx = obid.find('.')?;
obid.split_at(indx).0.parse::<usize>().ok()?;
let indx = oid.find('.')?;
oid.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 obid = obid.trim().to_string();
Some((spec, name, obid))
let oid = oid.trim().to_string();
Some((spec, name, oid))
})
}
}
9 changes: 0 additions & 9 deletions const-oid/oiddbgen/src/lib.rs

This file was deleted.

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

pub use asn1::Asn1Parser;
pub use ldap::LdapParser;
pub use root::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 @@ -32,19 +40,19 @@ const NO_BASES: &[(&str, &str)] = &[("", "")];
fn main() {
let mut root = Root::default();

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

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

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

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

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

#[derive(Clone, Debug, PartialEq, Eq)]
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
pub struct Node {
obid: String,
oid: ObjectIdentifier,
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(obid: String, name: String) -> Self {
pub fn new(oid: ObjectIdentifier, 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 @@ -51,7 +32,7 @@ impl Node {
let symb = symb.to_case(Case::UpperSnake);
let symb = Ident::new(&symb, Span::call_site());

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

pub fn name(&self) -> &str {
Expand All @@ -63,11 +44,19 @@ 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! {
pub const #symb: crate::ObjectIdentifier = crate::ObjectIdentifier::new_unwrap(#obid);
#doc
pub const #symb: crate::ObjectIdentifierRef<'static> = crate::ObjectIdentifierRef::from_bytes_unchecked(#bytes);
}
}
}
13 changes: 6 additions & 7 deletions const-oid/oiddbgen/src/root.rs
Original file line number Diff line number Diff line change
@@ -1,24 +1,23 @@
use crate::{node::Node, spec::Spec};

use std::collections::BTreeMap;

use const_oid::ObjectIdentifier;
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, obid: &str) {
pub fn add(&mut self, spec: &str, name: &str, oid: &str) {
let name = name.trim().to_string();
let obid = obid.trim().to_string();
let oid = oid.trim().parse::<ObjectIdentifier>().expect("invalid OID");
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(obid, name));
.insert(Node::new(oid, name));
}

pub fn module(&self) -> TokenStream {
Expand All @@ -27,7 +26,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: 11 additions & 10 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};
use crate::{Error, ObjectIdentifier, ObjectIdentifierRef};

/// 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 [(&'a ObjectIdentifier, &'a str)]);
pub struct Database<'a>(&'a [(ObjectIdentifierRef<'a>, &'a str)]);

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

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

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

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

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

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

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

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

if lhs.buffer.eq(&self.oid.buffer) {
if lhs.eq(&self.oid) {
self.position = i + 1;
return Some(self.database.0[i].1);
}
Expand Down Expand Up @@ -140,7 +141,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