1use super::Term;
2use crate::{Id, ValidId};
3use iri_rs::IriBuf;
4use jsonld_syntax::Keyword;
5use std::{convert::TryFrom, fmt};
6
7#[derive(Clone, PartialEq, Eq, Hash, Debug)]
11pub enum Type<I = IriBuf> {
12 Id,
16
17 Json,
21
22 None,
24
25 Vocab,
27
28 Iri(I),
30}
31
32impl<I> Type<I> {
33 pub fn into_iri(self) -> Result<I, Type<I>> {
39 match self {
40 Type::Iri(id) => Ok(id),
41 typ => Err(typ),
42 }
43 }
44
45 pub fn map<U>(self, f: impl FnOnce(I) -> U) -> Type<U> {
47 match self {
48 Type::Id => Type::Id,
49 Type::Json => Type::Json,
50 Type::None => Type::None,
51 Type::Vocab => Type::Vocab,
52 Type::Iri(t) => Type::Iri(f(t)),
53 }
54 }
55}
56
57impl<I: Clone> Type<&I> {
58 #[must_use]
60 pub fn cloned(self) -> Type<I> {
61 match self {
62 Type::Id => Type::Id,
63 Type::Json => Type::Json,
64 Type::None => Type::None,
65 Type::Vocab => Type::Vocab,
66 Type::Iri(t) => Type::Iri(t.clone()),
67 }
68 }
69}
70
71impl<I> Type<I> {
72 pub fn as_iri(&self) -> Option<&I> {
74 match self {
75 Type::Iri(id) => Some(id),
76 _ => None,
77 }
78 }
79}
80
81impl<I: AsRef<str>> Type<I> {
82 pub fn as_str(&self) -> &str {
84 match self {
85 Type::Id => "@id",
86 Type::Json => "@json",
87 Type::None => "@none",
88 Type::Vocab => "@vocab",
89 Type::Iri(id) => id.as_ref(),
90 }
91 }
92}
93
94impl<'a, I> From<&'a Type<I>> for Type<&'a I> {
95 fn from(t: &'a Type<I>) -> Type<&'a I> {
96 match t {
97 Type::Id => Type::Id,
98 Type::Json => Type::Json,
99 Type::None => Type::None,
100 Type::Vocab => Type::Vocab,
101 Type::Iri(id) => Type::Iri(id),
102 }
103 }
104}
105
106impl<I, B> From<Type<I>> for Term<I, B> {
107 fn from(t: Type<I>) -> Term<I, B> {
108 match t {
109 Type::Id => Term::Keyword(Keyword::Id),
110 Type::Json => Term::Keyword(Keyword::Json),
111 Type::None => Term::Keyword(Keyword::None),
112 Type::Vocab => Term::Keyword(Keyword::Vocab),
113 Type::Iri(id) => Term::Id(Id::Valid(ValidId::Iri(id))),
114 }
115 }
116}
117
118impl<I, B> TryFrom<Term<I, B>> for Type<I> {
119 type Error = Term<I, B>;
120
121 fn try_from(term: Term<I, B>) -> Result<Type<I>, Term<I, B>> {
122 match term {
123 Term::Keyword(Keyword::Id) => Ok(Type::Id),
124 Term::Keyword(Keyword::Json) => Ok(Type::Json),
125 Term::Keyword(Keyword::None) => Ok(Type::None),
126 Term::Keyword(Keyword::Vocab) => Ok(Type::Vocab),
127 Term::Id(Id::Valid(ValidId::Iri(id))) => Ok(Type::Iri(id)),
128 term => Err(term),
129 }
130 }
131}
132
133impl<I: fmt::Display> fmt::Display for Type<I> {
134 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
135 match self {
136 Type::Id => write!(f, "@id"),
137 Type::Json => write!(f, "@json"),
138 Type::None => write!(f, "@none"),
139 Type::Vocab => write!(f, "@vocab"),
140 Type::Iri(id) => id.fmt(f),
141 }
142 }
143}