Skip to main content

json_ld/core/
indexed.rs

1use std::convert::{TryFrom, TryInto};
2use std::ops::{Deref, DerefMut};
3
4use crate::JsonLdVisit;
5use crate::object::{JsonLdObjectMut, JsonLdObjectRef};
6
7/// Indexed objects.
8///
9/// Nodes and value objects may be indexed by a string in JSON-LD.
10/// This type is a wrapper around any kind of indexable data.
11///
12/// It is a pointer type that `Deref` into the underlying value.
13#[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
14#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
15pub struct JsonLdIndexed<T> {
16	/// Index.
17	#[cfg_attr(
18		feature = "serde",
19		serde(rename = "@index", default, skip_serializing_if = "Option::is_none")
20	)]
21	index: Option<String>,
22
23	/// Value.
24	#[cfg_attr(feature = "serde", serde(flatten))]
25	value: T,
26}
27
28impl<T> JsonLdIndexed<T> {
29	/// Creates a non-indexed value, without metadata.
30	pub fn unindexed(value: T) -> Self {
31		Self::new(value, None)
32	}
33
34	/// Create a new (maybe) indexed value.
35	#[inline(always)]
36	pub fn new(value: T, index: Option<String>) -> Self {
37		JsonLdIndexed { value, index }
38	}
39
40	/// Get a reference to the inner value.
41	#[inline(always)]
42	pub fn inner(&self) -> &T {
43		&self.value
44	}
45
46	pub fn inner_mut(&mut self) -> &mut T {
47		&mut self.value
48	}
49
50	/// Drop the index and return the underlying value.
51	#[inline(always)]
52	pub fn into_inner(self) -> T {
53		self.value
54	}
55
56	/// Get the index, if any.
57	#[inline(always)]
58	pub fn index(&self) -> Option<&str> {
59		match &self.index {
60			Some(index) => Some(index.as_str()),
61			None => None,
62		}
63	}
64
65	/// Set the value index.
66	#[inline(always)]
67	pub fn set_index(&mut self, index: Option<String>) {
68		self.index = index
69	}
70
71	/// Turn this indexed value into its components: inner value and index.
72	#[inline(always)]
73	pub fn into_parts(self) -> (T, Option<String>) {
74		(self.value, self.index)
75	}
76
77	/// Cast the inner value.
78	#[inline(always)]
79	pub fn map_inner<U, F>(self, f: F) -> JsonLdIndexed<U>
80	where
81		F: FnOnce(T) -> U,
82	{
83		JsonLdIndexed::new(f(self.value), self.index)
84	}
85
86	/// Cast the inner value.
87	#[inline(always)]
88	pub fn cast<U: From<T>>(self) -> JsonLdIndexed<U> {
89		JsonLdIndexed::new(self.value.into(), self.index)
90	}
91
92	/// Try to cast the inner value.
93	#[inline(always)]
94	pub fn try_cast<U: TryFrom<T>>(self) -> Result<JsonLdIndexed<U>, JsonLdIndexed<U::Error>> {
95		match self.value.try_into() {
96			Ok(value) => Ok(JsonLdIndexed::new(value, self.index)),
97			Err(e) => Err(JsonLdIndexed::new(e, self.index)),
98		}
99	}
100}
101
102impl<T: JsonLdVisit> JsonLdVisit for JsonLdIndexed<T> {
103	fn visit_with(&self, f: &mut impl FnMut(JsonLdObjectRef)) {
104		self.value.visit_with(f);
105	}
106
107	fn visit_mut_with(&mut self, f: &mut impl FnMut(JsonLdObjectMut)) {
108		self.value.visit_mut_with(f);
109	}
110}
111
112impl<T> From<T> for JsonLdIndexed<T> {
113	#[inline(always)]
114	fn from(value: T) -> JsonLdIndexed<T> {
115		JsonLdIndexed::new(value, None)
116	}
117}
118
119impl<T> Deref for JsonLdIndexed<T> {
120	type Target = T;
121
122	#[inline(always)]
123	fn deref(&self) -> &T {
124		&self.value
125	}
126}
127
128impl<T> DerefMut for JsonLdIndexed<T> {
129	#[inline(always)]
130	fn deref_mut(&mut self) -> &mut T {
131		&mut self.value
132	}
133}
134
135impl<T> AsRef<T> for JsonLdIndexed<T> {
136	#[inline(always)]
137	fn as_ref(&self) -> &T {
138		&self.value
139	}
140}
141
142impl<T> AsMut<T> for JsonLdIndexed<T> {
143	#[inline(always)]
144	fn as_mut(&mut self) -> &mut T {
145		&mut self.value
146	}
147}