rdfx 0.23.1

RDF 1.2 data-structures, traits and utilities: terms (incl. triple terms), triples, quads, interpretations, graphs, datasets, unstar/restar reification helpers.
Documentation
/// Generates UUID blank node identifiers based on the [`uuid`](https://crates.io/crates/uuid) crate.
///
/// This is an enum type with different UUID versions supported
/// by the `uuid` library, so you can choose which kind of UUID
/// better fits your application.
/// Version 1 is not supported.
///
/// You need to enable the `uuid-generator` feature to
/// use this type.
/// You also need to enable the features of each version you need
/// in the `uuid` crate.
pub enum Uuid {
    /// UUIDv3.
    ///
    /// You must provide a vocabulary UUID and a name.
    /// See [uuid::Uuid::new_v3] for more information.
    #[cfg(feature = "uuid-generator-v3")]
    V3(uuid::Uuid, String),

    /// UUIDv4.
    ///
    /// See [uuid::Uuid::new_v4] for more information.
    #[cfg(feature = "uuid-generator-v4")]
    V4,

    /// UUIDv5.
    ///
    /// You must provide a vocabulary UUID and a name.
    /// See [uuid::Uuid::new_v5] for more information.
    #[cfg(feature = "uuid-generator-v5")]
    V5(uuid::Uuid, String),
}

#[cfg(any(feature = "uuid-generator-v3", feature = "uuid-generator-v4", feature = "uuid-generator-v5"))]
impl Uuid {
    pub fn next_uuid(&self) -> uuid::Uuid {
        match self {
            #[cfg(feature = "uuid-generator-v3")]
            Self::V3(vocabulary, name) => uuid::Uuid::new_v3(vocabulary, name.as_bytes()),
            #[cfg(feature = "uuid-generator-v4")]
            Self::V4 => uuid::Uuid::new_v4(),
            #[cfg(feature = "uuid-generator-v5")]
            Self::V5(vocabulary, name) => uuid::Uuid::new_v5(vocabulary, name.as_bytes()),
        }
    }
}

#[cfg(any(feature = "uuid-generator-v3", feature = "uuid-generator-v4", feature = "uuid-generator-v5"))]
impl crate::Generator for Uuid {
    fn next_term(&mut self) -> crate::Term {
        let mut buffer: Vec<u8> = vec![0; uuid::fmt::Urn::LENGTH];
        let uuid = self.next_uuid();
        let len = uuid.urn().encode_lower(buffer.as_mut()).len();
        buffer.truncate(len);
        let s = unsafe { String::from_utf8_unchecked(buffer) };
        // Safety: the `uuid` crate's URN encoder produces only ASCII output in
        // the RFC 8141 form `urn:uuid:<8-4-4-4-12 hex>`; this is unconditionally
        // a valid IRI per RFC 3987, so `IriBuf::parse_unchecked` is sound.
        crate::Term::Iri(iri_rs::IriBuf::parse_unchecked(s))
    }
}

#[cfg(any(feature = "uuid-generator-v3", feature = "uuid-generator-v4", feature = "uuid-generator-v5"))]
#[cfg(test)]
#[allow(clippy::unwrap_used, clippy::panic, clippy::expect_used)]
mod tests {
    use super::*;
    use crate::Generator;

    #[cfg(feature = "uuid-generator-v3")]
    #[test]
    fn uuidv3_iri() {
        let mut uuid_gen = Uuid::V3(uuid::Uuid::parse_str("936DA01F9ABD4d9d80C702AF85C822A8").unwrap(), "test".to_string());
        for _ in 0..100 {
            let term = uuid_gen.next_term();
            assert!(term.as_iri().is_some())
        }
    }

    #[cfg(feature = "uuid-generator-v4")]
    #[test]
    fn uuidv4_iri() {
        let mut uuid_gen = Uuid::V4;
        for _ in 0..100 {
            let term = uuid_gen.next_term();
            assert!(term.as_iri().is_some())
        }
    }

    #[cfg(feature = "uuid-generator-v5")]
    #[test]
    fn uuidv5_iri() {
        let mut uuid_gen = Uuid::V5(uuid::Uuid::parse_str("936DA01F9ABD4d9d80C702AF85C822A8").unwrap(), "test".to_string());
        for _ in 0..100 {
            let term = uuid_gen.next_term();
            assert!(term.as_iri().is_some())
        }
    }
}