Skip to main content

jsonld_expansion/
slice.rs

1//! Expansion of a document given as JSON text.
2use crate::{Context, Expand, ExpandedDocument, Loader, Options, WarningHandler, error::Error};
3use rdfx::vocabulary::VocabularyMut;
4use std::hash::Hash;
5
6/// Error of [`expand_slice`].
7#[derive(Debug, thiserror::Error)]
8pub enum SliceExpansionError<E> {
9    /// The bytes are not one well-formed JSON text (RFC 8259).
10    #[error("invalid JSON: {0}")]
11    Syntax(#[from] jstrict::parse::Error),
12    /// The JSON text is not a document the Expansion algorithm accepts.
13    #[error(transparent)]
14    Expansion(Error<E>),
15}
16
17/// Expands the JSON-LD document whose JSON text is `bytes`.
18///
19/// The text is parsed with `jstrict`'s non-recursive parser, expanded
20/// exactly as [`Expand::expand_full`] expands the parsed value, and the
21/// parsed tree is dropped before this returns, so no JSON tree outlives the
22/// call. `context` is the initial active context: an empty one built with
23/// `Context::new(base_url)` for a document that carries its own `@context`,
24/// or an active context the caller processed once and reuses across
25/// documents. Parsing, expansion and the drop of the parsed tree are all
26/// bounded by memory, not by the caller's native stack.
27///
28/// # Errors
29///
30/// [`SliceExpansionError::Syntax`] when `bytes` is not JSON, and
31/// [`SliceExpansionError::Expansion`] for every failure `expand_full` reports.
32pub async fn expand_slice<N, L, W>(
33    bytes: &[u8],
34    vocabulary: &mut N,
35    context: Context<N::Iri, N::BlankId>,
36    base_url: Option<&N::Iri>,
37    loader: &L,
38    options: Options,
39    warnings: W,
40) -> Result<ExpandedDocument<N::Iri, N::BlankId>, SliceExpansionError<L::Error>>
41where
42    N: VocabularyMut,
43    N::Iri: Clone + Eq + Hash,
44    N::BlankId: Clone + Eq + Hash,
45    L: Loader,
46    W: WarningHandler<N>,
47{
48    let document = jstrict::parse::parse_slice_value(bytes)?;
49    document
50        .expand_full(vocabulary, context, base_url, loader, options, warnings)
51        .await
52        .map_err(SliceExpansionError::Expansion)
53}