1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
use iref::Iri;

use crate::{
	vocabulary::{BlankIdVocabulary, BlankIdVocabularyMut, IriVocabulary, IriVocabularyMut},
	BlankId, Id,
};

use super::{
	BlankIdInterpretation, BlankIdInterpretationMut, IriInterpretation, IriInterpretationMut,
	ReverseBlankIdInterpretation, ReverseBlankIdInterpretationMut, ReverseIriInterpretation,
	ReverseIriInterpretationMut,
};

/// Node identifier interpretation.
pub trait IdInterpretation<I, B>: IriInterpretation<I> + BlankIdInterpretation<B> {
	/// Returns the interpretation of the given node identifier, if any.
	fn id_interpretation(&self, id: &Id<I, B>) -> Option<Self::Resource> {
		match id {
			Id::Iri(i) => self.iri_interpretation(i),
			Id::Blank(b) => self.blank_id_interpretation(b),
		}
	}

	fn lexical_id_interpretation(
		&self,
		vocabulary: &(impl IriVocabulary<Iri = I> + BlankIdVocabulary<BlankId = B>),
		id: Id<&Iri, &BlankId>,
	) -> Option<Self::Resource> {
		match id {
			Id::Iri(i) => self.lexical_iri_interpretation(vocabulary, i),
			Id::Blank(b) => self.lexical_blank_id_interpretation(vocabulary, b),
		}
	}
}

impl<I, B, T: IriInterpretation<I> + BlankIdInterpretation<B>> IdInterpretation<I, B> for T {}

/// Node identifier interpretation.
pub trait IdInterpretationMut<I, B>: IriInterpretationMut<I> + BlankIdInterpretationMut<B> {
	/// Interprets the given identifier.
	fn interpret_id(&mut self, id: Id<I, B>) -> Self::Resource {
		match id {
			Id::Iri(i) => self.interpret_iri(i),
			Id::Blank(b) => self.interpret_blank_id(b),
		}
	}

	fn interpret_lexical_id(
		&mut self,
		vocabulary: &mut (impl IriVocabularyMut<Iri = I> + BlankIdVocabularyMut<BlankId = B>),
		id: Id<&Iri, &BlankId>,
	) -> Self::Resource {
		match id {
			Id::Iri(i) => self.interpret_lexical_iri(vocabulary, i),
			Id::Blank(b) => self.interpret_lexical_blank_id(vocabulary, b),
		}
	}

	fn interpret_owned_lexical_id(
		&mut self,
		vocabulary: &mut (impl IriVocabularyMut<Iri = I> + BlankIdVocabularyMut<BlankId = B>),
		id: Id,
	) -> Self::Resource {
		match id {
			Id::Iri(i) => self.interpret_owned_lexical_iri(vocabulary, i),
			Id::Blank(b) => self.interpret_owned_lexical_blank_id(vocabulary, b),
		}
	}
}

impl<I, B, T: IriInterpretationMut<I> + BlankIdInterpretationMut<B>> IdInterpretationMut<I, B>
	for T
{
}

/// Reverse node identifier interpretation.
///
/// Used to retrieve the node identifiers of a given resource.
pub trait ReverseIdInterpretation: ReverseIriInterpretation + ReverseBlankIdInterpretation {
	fn ids_of<'a>(&'a self, id: &'a Self::Resource) -> IdsOf<'a, Self> {
		IdsOf {
			iris: self.iris_of(id),
			blanks: self.blank_ids_of(id),
		}
	}
}

impl<I: ?Sized + ReverseIriInterpretation + ReverseBlankIdInterpretation> ReverseIdInterpretation
	for I
{
}

pub struct IdsOf<'a, I: 'a + ?Sized + ReverseIdInterpretation> {
	iris: I::Iris<'a>,
	blanks: I::BlankIds<'a>,
}

impl<'a, I: 'a + ?Sized + ReverseIdInterpretation> Clone for IdsOf<'a, I> {
	fn clone(&self) -> Self {
		Self {
			iris: self.iris.clone(),
			blanks: self.blanks.clone(),
		}
	}
}

impl<'a, I: 'a + ?Sized + ReverseIdInterpretation> Copy for IdsOf<'a, I>
where
	I::Iris<'a>: Copy,
	I::BlankIds<'a>: Copy,
{
}

impl<'a, I: 'a + ?Sized + ReverseIdInterpretation> Iterator for IdsOf<'a, I> {
	type Item = Id<&'a I::Iri, &'a I::BlankId>;

	fn next(&mut self) -> Option<Self::Item> {
		self.iris
			.next()
			.map(Id::Iri)
			.or_else(|| self.blanks.next().map(Id::Blank))
	}
}

pub trait ReverseIdInterpretationMut:
	ReverseIriInterpretationMut + ReverseBlankIdInterpretationMut
{
	fn assign_id(&mut self, r: &Self::Resource, id: Id<Self::Iri, Self::BlankId>) -> bool {
		match id {
			Id::Iri(i) => self.assign_iri(r, i),
			Id::Blank(b) => self.assign_blank_id(r, b),
		}
	}
}

impl<I: ?Sized + ReverseIriInterpretationMut + ReverseBlankIdInterpretationMut>
	ReverseIdInterpretationMut for I
{
}