Skip to main content

jsonld_core/flattening/
environment.rs

1use crate::{Id, ValidId, ValidVocabularyId, VocabularyId};
2use rdfx::{
3    LocalGenerator,
4    vocabulary::{Vocabulary, VocabularyMut},
5};
6use std::{collections::HashMap, hash::Hash};
7
8/// Vocabulary and blank node generator used while flattening.
9pub struct Environment<'n, N: Vocabulary, G> {
10    vocabulary: &'n mut N,
11    generator: G,
12    map: HashMap<N::BlankId, ValidVocabularyId<N>>,
13}
14
15impl<'n, N: Vocabulary, G> Environment<'n, N, G> {
16    /// Creates a new `Environment`.
17    pub fn new(vocabulary: &'n mut N, generator: G) -> Self {
18        Self {
19            vocabulary,
20            generator,
21            map: HashMap::default(),
22        }
23    }
24}
25
26impl<V: Vocabulary, G: LocalGenerator> Environment<'_, V, G>
27where
28    V: VocabularyMut,
29    V::Iri: Clone,
30    V::BlankId: Clone + Hash + Eq,
31{
32    /// Returns the identifier this blank node was relabelled to, generating
33    /// one on first sight.
34    ///
35    /// # Errors
36    ///
37    /// Returns an error when the generator runs out of identifiers.
38    pub fn assign(&mut self, blank_id: V::BlankId) -> Result<ValidId<V::Iri, V::BlankId>, crate::id::GeneratedIdError> {
39        use std::collections::hash_map::Entry;
40        match self.map.entry(blank_id) {
41            Entry::Occupied(entry) => Ok(entry.get().clone()),
42            Entry::Vacant(entry) => {
43                let id = crate::id::generator_next_id(self.vocabulary, &mut self.generator)?;
44                entry.insert(id.clone());
45                Ok(id)
46            }
47        }
48    }
49
50    /// Returns the identifier of a node, generating a blank one when the node
51    /// is anonymous.
52    ///
53    /// # Errors
54    ///
55    /// Returns an error when the generator runs out of identifiers.
56    pub fn assign_node_id(&mut self, r: Option<&VocabularyId<V>>) -> Result<Id<V::Iri, V::BlankId>, crate::id::GeneratedIdError> {
57        match r {
58            Some(Id::Valid(ValidId::Blank(id))) => Ok(self.assign(id.clone())?.into()),
59            Some(r) => Ok(r.clone()),
60            None => Ok(self.next_id()?.into()),
61        }
62    }
63
64    /// Generates a fresh blank node identifier.
65    ///
66    /// # Errors
67    ///
68    /// Returns an error when the generator runs out of identifiers.
69    pub fn next_id(&mut self) -> Result<ValidId<V::Iri, V::BlankId>, crate::id::GeneratedIdError> {
70        crate::id::generator_next_id(self.vocabulary, &mut self.generator)
71    }
72}