You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

49 lines
1.6 KiB
Rust

use json_ld::{
syntax::{Parse, Value},
Expand, RemoteDocument,
};
use rdf_types::{IndexVocabulary, IriVocabulary};
use crate::ap::loader::CachedLoader;
use crate::core::*;
use crate::state::AppState;
/// Main API for handling ActivityPub ingress, called by [`crate::job::inbox::InboxWorker`].
pub async fn process_document(state: &AppState, raw: &str) -> Result<()> {
let mut vocab: IndexVocabulary = IndexVocabulary::new();
let document = Value::parse_str(raw, |span| span)
.map_err(|e| Error::MalformedApub(format!("Could not parse document: {e}")))?;
let rd = RemoteDocument::new(
None,
Some("application/activity+json".parse().unwrap()),
document,
);
let mut loader = CachedLoader::new(state.clone());
let rd = rd.expand_with(&mut vocab, &mut loader).await.unwrap();
// this loop will usually only run once (one object per request)
for object in rd.into_value() {
let id = object
.id()
.and_then(|i| i.as_iri())
.and_then(|index| vocab.iri(index))
.ok_or(Error::MalformedApub(String::from(
"Document does not have an id",
)))?;
let mut typ = None;
for t in object.types() {
typ = Some(t);
}
let typ = typ.ok_or(Error::MalformedApub(String::from(
"Document does not have a type",
)))?;
// just for testing some stuff
let typ = typ.as_iri().and_then(|index| vocab.iri(index)).unwrap();
debug!("Object id=\"{id}\" type=\"{typ}\"");
}
Ok(())
}