From 01260e3fffe76e8190448e13d47a4105948eb702 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 11 Mar 2022 15:50:58 -0700 Subject: [PATCH] const-oid: add `ObjectIdentifier::parent` Adds a method for getting the parent of a given OID in the hierarchy. This also changes the `ObjectIdentifier::from_arcs` method to take `Arc`s by value rather than reference. --- const-oid/src/lib.rs | 15 +++++++++++++-- const-oid/tests/lib.rs | 22 +++++++++++++++------- 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/const-oid/src/lib.rs b/const-oid/src/lib.rs index 14bf22e0b..76730abb0 100644 --- a/const-oid/src/lib.rs +++ b/const-oid/src/lib.rs @@ -105,10 +105,10 @@ impl ObjectIdentifier { } /// Parse an OID from a slice of [`Arc`] values (i.e. integers). - pub fn from_arcs<'a>(arcs: impl IntoIterator) -> Result { + pub fn from_arcs(arcs: impl IntoIterator) -> Result { let mut encoder = Encoder::new(); - for &arc in arcs { + for arc in arcs { encoder = encoder.arc(arc)?; } @@ -158,6 +158,17 @@ impl ObjectIdentifier { Arcs::new(self) } + /// Get the length of this [`ObjectIdentifier`] in arcs. + pub fn len(&self) -> usize { + self.arcs().count() + } + + /// Get the parent OID of this one (if applicable). + pub fn parent(&self) -> Option { + let num_arcs = self.len().checked_sub(1)?; + Self::from_arcs(self.arcs().take(num_arcs)).ok() + } + /// Push an additional arc onto this OID, returning the child OID. pub const fn push_arc(self, arc: Arc) -> Result { // TODO(tarcieri): use `?` when stable in `const fn` diff --git a/const-oid/tests/lib.rs b/const-oid/tests/lib.rs index 607634f18..18453729e 100644 --- a/const-oid/tests/lib.rs +++ b/const-oid/tests/lib.rs @@ -115,24 +115,24 @@ fn display() { #[test] fn try_from_u32_slice() { - let oid1 = ObjectIdentifier::from_arcs(&[1, 2, 840, 10045, 2, 1]).unwrap(); + let oid1 = ObjectIdentifier::from_arcs([1, 2, 840, 10045, 2, 1]).unwrap(); assert_eq!(oid1.arc(0).unwrap(), 1); assert_eq!(oid1.arc(1).unwrap(), 2); assert_eq!(EXAMPLE_OID_1, oid1); - let oid2 = ObjectIdentifier::from_arcs(&[2, 16, 840, 1, 101, 3, 4, 1, 42]).unwrap(); + let oid2 = ObjectIdentifier::from_arcs([2, 16, 840, 1, 101, 3, 4, 1, 42]).unwrap(); assert_eq!(oid2.arc(0).unwrap(), 2); assert_eq!(oid2.arc(1).unwrap(), 16); assert_eq!(EXAMPLE_OID_2, oid2); // Too short - assert!(ObjectIdentifier::from_arcs(&[1, 2]).is_err()); + assert!(ObjectIdentifier::from_arcs([1, 2]).is_err()); // Invalid first arc - assert!(ObjectIdentifier::from_arcs(&[3, 2, 840, 10045, 3, 1, 7]).is_err()); + assert!(ObjectIdentifier::from_arcs([3, 2, 840, 10045, 3, 1, 7]).is_err()); // Invalid second arc - assert!(ObjectIdentifier::from_arcs(&[1, 40, 840, 10045, 3, 1, 7]).is_err()); + assert!(ObjectIdentifier::from_arcs([1, 40, 840, 10045, 3, 1, 7]).is_err()); } #[test] @@ -167,11 +167,19 @@ fn parse_invalid_second_arc() { ); } +#[test] +fn parent() { + let oid = ObjectIdentifier::new("1.2.3.4").unwrap(); + let parent = oid.parent().unwrap(); + assert_eq!(parent, ObjectIdentifier::new("1.2.3").unwrap()); + assert_eq!(parent.parent(), None); +} + #[test] fn push_arc() { - let oid = ObjectIdentifier::new_unwrap("1.2.3"); + let oid = ObjectIdentifier::new("1.2.3").unwrap(); assert_eq!( oid.push_arc(4).unwrap(), - ObjectIdentifier::new_unwrap("1.2.3.4") + ObjectIdentifier::new("1.2.3.4").unwrap() ); }