Atproto, types overhaul and error handling

Breaks off from Atrium-rs's types because they are implemented
inconsistently, which makes them harder to use.

This was done with reference to the atproto documentation but
specifically not the atrium-rs codebase so I wouldn't have to think
about licenses.

This adds the types and error module in atproto. It also touches
Cargo.toml for some new dependencies and some shared dependencies. It
required thiserror, so I looped that into the workspace meaning that
this commit touches db.

some things to keep in mind:
- There is no CID parsing
- None of this is tested, nor are there any tests written. We're playing
  fast and loose baby~
This commit is contained in:
Julia Lange 2025-06-16 15:29:27 -07:00
parent aadea9757b
commit ab78d1fb7b
Signed by: Julia
SSH key fingerprint: SHA256:5DJcfxa5/fKCYn57dcabJa2vN2e6eT0pBerYi5SUbto
12 changed files with 453 additions and 81 deletions

View file

@ -1,80 +1,3 @@
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<T> {
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<Nsid>,
// rkey: Option<RecordKey>,
}
impl FromStr for Uri {
type Err = &'static str;
fn from_str(uri: &str) -> Result<Self, Self::Err> {
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()
}
}
pub mod types;
pub mod error;