use std::convert::TryFrom;
use std::fmt;
use json::JsonValue;
use crate::util;
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
pub enum Keyword {
Base,
Container,
Context,
Direction,
Graph,
Id,
Import,
Included,
Index,
Json,
Language,
List,
Nest,
None,
Prefix,
Propagate,
Protected,
Reverse,
Set,
Type,
Value,
Version,
Vocab
}
impl Keyword {
pub fn into_str(self) -> &'static str {
use Keyword::*;
match self {
Base => "@base",
Container => "@container",
Context => "@context",
Direction => "@direction",
Graph => "@graph",
Id => "@id",
Import => "@import",
Included => "@included",
Index => "@index",
Json => "@json",
Language => "@language",
List => "@list",
Nest => "@nest",
None => "@none",
Prefix => "@prefix",
Propagate => "@propagate",
Protected => "@protected",
Reverse => "@reverse",
Set => "@set",
Type => "@type",
Value => "@value",
Version => "@version",
Vocab => "@vocab"
}
}
}
impl<'a> TryFrom<&'a str> for Keyword {
type Error = &'a str;
fn try_from(str: &'a str) -> Result<Keyword, &'a str> {
use Keyword::*;
match str {
"@base" => Ok(Base),
"@container" => Ok(Container),
"@context" => Ok(Context),
"@direction" => Ok(Direction),
"@graph" => Ok(Graph),
"@id" => Ok(Id),
"@import" => Ok(Import),
"@included" => Ok(Included),
"@index" => Ok(Index),
"@json" => Ok(Json),
"@language" => Ok(Language),
"@list" => Ok(List),
"@nest" => Ok(Nest),
"@none" => Ok(None),
"@prefix" => Ok(Prefix),
"@propagate" => Ok(Propagate),
"@protected" => Ok(Protected),
"@reverse" => Ok(Reverse),
"@set" => Ok(Set),
"@type" => Ok(Type),
"@value" => Ok(Value),
"@version" => Ok(Version),
"@vocab" => Ok(Vocab),
_ => Err(str)
}
}
}
impl From<Keyword> for &'static str {
fn from(k: Keyword) -> &'static str {
k.into_str()
}
}
impl fmt::Display for Keyword {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.into_str().fmt(f)
}
}
impl util::AsJson for Keyword {
fn as_json(&self) -> JsonValue {
self.into_str().into()
}
}
pub fn is_keyword(str: &str) -> bool {
Keyword::try_from(str).is_ok()
}
fn is_alpha(c: char) -> bool {
let c = c as u32;
(c >= 0x41 && c <= 0x5a) || (c >= 0x61 && c <= 0x7a)
}
pub fn is_keyword_like(str: &str) -> bool {
if str.len() > 1 {
for (i, c) in str.chars().enumerate() {
if (i == 0 && c != '@') || (i > 0 && !is_alpha(c)) {
return false
}
}
true
} else {
false
}
}