1use super::Term;
2use crate::{Id, ValidId};
3use iref::IriBuf;
4use json_ld_syntax::Keyword;
5use std::convert::TryFrom;
6use std::fmt;
7
8#[derive(Clone, PartialEq, Eq, Hash, Debug)]
12pub enum Type<I = IriBuf> {
13 Id,
17
18 Json,
22
23 None,
25
26 Vocab,
28
29 Iri(I),
31}
32
33impl<I> Type<I> {
34 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 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 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 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 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}