json_ld_core/
ty.rs

1use super::Term;
2use crate::{Id, ValidId};
3use iref::IriBuf;
4use json_ld_syntax::Keyword;
5use std::convert::TryFrom;
6use std::fmt;
7
8/// Object type.
9///
10/// This is the value of a `@type` entry.
11#[derive(Clone, PartialEq, Eq, Hash, Debug)]
12pub enum Type<I = IriBuf> {
13	/// `@id`.
14	///
15	/// The value must be interpreted as an IRI.
16	Id,
17
18	/// `@json`.
19	///
20	/// The value is an arbitrary JSON value.
21	Json,
22
23	/// `@none`
24	None,
25
26	/// `@vocab`
27	Vocab,
28
29	/// IRI type.
30	Iri(I),
31}
32
33impl<I> Type<I> {
34	/// Turns this type into an IRI if possible.
35	pub fn into_iri(self) -> Result<I, Type<I>> {
36		match self {
37			Type::Iri(id) => Ok(id),
38			typ => Err(typ),
39		}
40	}
41
42	/// Maps the IRI of this type.
43	pub fn map<U>(self, f: impl FnOnce(I) -> U) -> Type<U> {
44		match self {
45			Type::Id => Type::Id,
46			Type::Json => Type::Json,
47			Type::None => Type::None,
48			Type::Vocab => Type::Vocab,
49			Type::Iri(t) => Type::Iri(f(t)),
50		}
51	}
52}
53
54impl<'a, I: Clone> Type<&'a I> {
55	/// Clones the referenced IRI.
56	pub fn cloned(self) -> Type<I> {
57		match self {
58			Type::Id => Type::Id,
59			Type::Json => Type::Json,
60			Type::None => Type::None,
61			Type::Vocab => Type::Vocab,
62			Type::Iri(t) => Type::Iri(t.clone()),
63		}
64	}
65}
66
67impl<I> Type<I> {
68	/// Returns a reference to the type IRI if any.
69	pub fn as_iri(&self) -> Option<&I> {
70		match self {
71			Type::Iri(id) => Some(id),
72			_ => None,
73		}
74	}
75}
76
77impl<I: AsRef<str>> Type<I> {
78	/// Returns a JSON-LD string representation of the type.
79	pub fn as_str(&self) -> &str {
80		match self {
81			Type::Id => "@id",
82			Type::Json => "@json",
83			Type::None => "@none",
84			Type::Vocab => "@vocab",
85			Type::Iri(id) => id.as_ref(),
86		}
87	}
88}
89
90impl<'a, I> From<&'a Type<I>> for Type<&'a I> {
91	fn from(t: &'a Type<I>) -> Type<&'a I> {
92		match t {
93			Type::Id => Type::Id,
94			Type::Json => Type::Json,
95			Type::None => Type::None,
96			Type::Vocab => Type::Vocab,
97			Type::Iri(id) => Type::Iri(id),
98		}
99	}
100}
101
102impl<I, B> From<Type<I>> for Term<I, B> {
103	fn from(t: Type<I>) -> Term<I, B> {
104		match t {
105			Type::Id => Term::Keyword(Keyword::Id),
106			Type::Json => Term::Keyword(Keyword::Json),
107			Type::None => Term::Keyword(Keyword::None),
108			Type::Vocab => Term::Keyword(Keyword::Vocab),
109			Type::Iri(id) => Term::Id(Id::Valid(ValidId::Iri(id))),
110		}
111	}
112}
113
114impl<I, B> TryFrom<Term<I, B>> for Type<I> {
115	type Error = Term<I, B>;
116
117	fn try_from(term: Term<I, B>) -> Result<Type<I>, Term<I, B>> {
118		match term {
119			Term::Keyword(Keyword::Id) => Ok(Type::Id),
120			Term::Keyword(Keyword::Json) => Ok(Type::Json),
121			Term::Keyword(Keyword::None) => Ok(Type::None),
122			Term::Keyword(Keyword::Vocab) => Ok(Type::Vocab),
123			Term::Id(Id::Valid(ValidId::Iri(id))) => Ok(Type::Iri(id)),
124			term => Err(term),
125		}
126	}
127}
128
129impl<I: fmt::Display> fmt::Display for Type<I> {
130	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
131		match self {
132			Type::Id => write!(f, "@id"),
133			Type::Json => write!(f, "@json"),
134			Type::None => write!(f, "@none"),
135			Type::Vocab => write!(f, "@vocab"),
136			Type::Iri(id) => id.fmt(f),
137		}
138	}
139}