upub/utils/uriproxy/lib.rs
alemi e63433b77b
fix: context is now under /objects/{id}/context
just like /objects/{id}/replies, makes easier composing urls, and also
more correct: context is not something we serve, but instead some
reference associated to objects
2024-06-06 16:41:39 +02:00

52 lines
1.4 KiB
Rust

use base64::Engine;
#[derive(Clone, Copy)]
pub enum UriClass {
Actor,
Object,
Activity,
}
impl AsRef<str> for UriClass {
fn as_ref(&self) -> &str {
match self {
Self::Actor => "actors",
Self::Object => "objects",
Self::Activity => "activities",
}
}
}
/// unpack uri in id if valid, otherwise compose full uri with "{base}/{entity}/{id}"
pub fn uri(base: &str, entity: UriClass, id: &str) -> String {
if id.starts_with("https://") || id.starts_with("http://") {
return id.to_string();
}
if id.starts_with('+') { // ready-to-use base64-encoded id
if let Ok(bytes) = base64::prelude::BASE64_URL_SAFE_NO_PAD.decode(id.replacen('+', "", 1)) {
if let Ok(uri) = std::str::from_utf8(&bytes) {
return uri.to_string();
}
}
}
format!("{}/{}/{}", base, entity.as_ref(), id)
}
/// decompose local id constructed by uri() fn
pub fn decompose_id(full_id: &str) -> String {
full_id // https://example.org/actors/test/followers/page?offset=42
.replace("https://", "")
.replace("http://", "")
.split('/') // ['example.org', 'actors', 'test', 'followers', 'page?offset=42' ]
.nth(2) // 'test'
.unwrap_or("")
.to_string()
}
/// encode with base64 remote url and prefix it with +
pub fn compact_id(uri: &str) -> String {
let encoded = base64::prelude::BASE64_URL_SAFE_NO_PAD.encode(uri.as_bytes());
format!("+{encoded}")
}