use std::collections::{BTreeMap, HashMap};
use std::cmp::{Eq, Ord, Ordering, PartialEq};
use std::fmt;
use std::hash::{Hash, Hasher};
use serde::{Serialize, Serializer};
use serde_json::Value;
use crate::config;
use crate::metadata::Metadata;
pub enum AuthorKey {
Avatar,
Bio,
Email,
Name,
Nick,
Unknown,
}
impl Serialize for AuthorKey {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_str(&self.to_string())
}
}
impl PartialEq for AuthorKey {
fn eq(&self, other: &Self) -> bool {
self.to_string() == other.to_string()
}
}
impl Eq for AuthorKey {}
impl PartialOrd for AuthorKey {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl Ord for AuthorKey {
fn cmp(&self, other: &Self) -> Ordering {
self.to_string().cmp(&other.to_string())
}
}
impl fmt::Display for AuthorKey {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Self::Avatar => write!(f, "avatar"),
Self::Bio => write!(f, "bio"),
Self::Email => write!(f, "email"),
Self::Name => write!(f, "name"),
Self::Nick => write!(f, "nick"),
_ => write!(f, "unknown"),
}
}
}
impl From<&String> for AuthorKey {
fn from(s: &String) -> Self {
match s.to_ascii_lowercase().as_ref() {
"avatar" => Self::Avatar,
"bio" => Self::Bio,
"email" => Self::Email,
"name" => Self::Name,
"nick" => Self::Nick,
_ => Self::Unknown,
}
}
}
impl Hash for AuthorKey {
fn hash<H: Hasher>(&self, state: &mut H) {
self.to_string().hash(state);
}
}
pub struct Author {
_map: HashMap<AuthorKey, String>,
}
impl Serialize for Author {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let map: BTreeMap<_, _> = self._map.iter().collect();
map.serialize(serializer)
}
}
impl Default for Author {
fn default() -> Self {
let map: HashMap<AuthorKey, String> = HashMap::new();
Author { _map: map }
}
}
impl From<&config::Author> for Author {
fn from(a: &config::Author) -> Self {
let mut author = Self::default();
author.add(
AuthorKey::Avatar,
a.avatar.clone().map_or("".to_string(), |s| s),
);
author.add(AuthorKey::Bio, a.bio.clone().map_or("".to_string(), |s| s));
author.add(
AuthorKey::Email,
a.email.clone().map_or("".to_string(), |s| s),
);
author.add(AuthorKey::Name, a.name.to_string());
author.add(
AuthorKey::Nick,
a.nick.clone().map_or("".to_string(), |s| s),
);
author
}
}
impl Metadata<AuthorKey> for Author {
fn new() -> Self {
Self::default()
}
fn add(&mut self, key: AuthorKey, value: String) -> Option<String> {
self._map.insert(key, value)
}
fn get(&self, key: AuthorKey) -> Option<String> {
self._map.get(&key).map(|v| v.to_owned())
}
fn has(&self, key: AuthorKey) -> bool {
self._map.get(&key).is_some()
}
fn to_json(&self) -> Value {
json!(self._map)
}
}
impl Author {
pub fn new(name: &str) -> Self {
let mut author = Self::default();
author.add(AuthorKey::Name, name.to_string());
author
}
}