use core::fmt; use rand::{rngs::OsRng, Rng}; //TODO: gen- Check URN are valid // https://www.rfc-editor.org/rfc/rfc2141#section-2.1 pub struct Urn { /// Namespace Identifier nid: String, /// Namespace Specific string. This is the unique part of the identifier nss: String, } impl Urn { /// awake specific function for generating a URN in the form of: /// `urn:NID:1234-5678` /// Where 1234-5678 is a randomly generated eight digit ID broken in two. pub fn new_random>(nid: S) -> Self { let first = random_base58(4); let second = random_base58(4); Self { nid: nid.into(), nss: format!("{first}-{second}"), } } } impl fmt::Display for Urn { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let Urn { nid, nss } = self; write!(f, "urn:{nid}:{nss}") } } const BASE58: &'static [u8] = b"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; const USER_ID_LENGTH: usize = 6; const SESSION_ID_LENGTH: usize = 12; /// Random Base58 string, `count` characters long, using OsRng which is assumed /// to be secure /// > assumed that system always provides high-quality cryptographically secure random data fn random_base58(count: usize) -> String { let mut rng = OsRng::default(); std::iter::from_fn(|| Some(BASE58[rng.gen_range(0..BASE58.len())] as char)) .take(count) .collect() }