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
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(())
|
|
}
|