use lazy_regex::regex_captures; use core::str::FromStr; use std::fmt::{ Display, Formatter, Result as FmtResult }; pub use atrium_api::types::{ Collection, string::{ AtIdentifier as Authority, Datetime, Did, Nsid, RecordKey, Tid, Handle, } }; pub mod lexicons; pub struct Cid(String); impl Display for Cid { fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { write!(f, "{}", self.0) } } pub struct StrongRef { pub content: T, pub cid: Cid, } pub struct Uri { whole: String, // These fields could be useful in the future, // so I'm leaving the code for them. // authority: Authority, // collection: Option, // rkey: Option, } impl FromStr for Uri { type Err = &'static str; fn from_str(uri: &str) -> Result { if uri.len() > 8000 { return Err("Uri too long") } let Some(( whole, unchecked_authority, unchecked_collection, unchecked_rkey )) = regex_captures!( r"/^at:\/\/([\w\.\-_~:]+)(?:\/([\w\.\-_~:]+)(?:)\/([\w\.\-_~:]+))?$/i", uri, ) else { return Err("Invalid Uri"); }; // This parsing is required, but the values don't need to be used yet. // No compute cost to use them, just storage cost let _authority = Authority::from_str(unchecked_authority)?; let _collection = if unchecked_collection.is_empty() { None } else { Some(Nsid::new(unchecked_collection.to_string())?) }; let _rkey = if unchecked_rkey.is_empty() { None } else { Some(RecordKey::new(unchecked_rkey.to_string())?) }; // Ok(Uri{ whole: whole.to_string(), authority, collection, rkey }) Ok(Uri { whole: whole.to_string() }) } } impl Uri { pub fn as_str(&self) -> &str { self.whole.as_str() } }