use std::cmp::{Eq, PartialEq};
use std::hash::{Hash, Hasher};
use std::mem;
use doc::{Data, Document, Object, PrimaryData};
use error::Error;
use query::Query;
use sealed::Sealed;
use value::{Key, Map, Set, Value};
use view::Render;
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct Identifier {
pub id: String,
#[serde(rename = "type")]
pub kind: Key,
#[serde(default, skip_serializing_if = "Map::is_empty")]
pub meta: Map,
#[serde(skip)]
_ext: (),
}
impl Identifier {
pub fn new(kind: Key, id: String) -> Self {
Identifier {
id,
kind,
meta: Default::default(),
_ext: (),
}
}
}
impl Eq for Identifier {}
impl From<Object> for Identifier {
fn from(object: Object) -> Self {
let Object { id, kind, meta, .. } = object;
let mut ident = Identifier::new(kind, id);
ident.meta = meta;
ident
}
}
impl<'a> From<&'a Object> for Identifier {
fn from(object: &'a Object) -> Self {
object.clone().into()
}
}
impl Hash for Identifier {
fn hash<H: Hasher>(&self, state: &mut H) {
self.id.hash(state);
self.kind.hash(state);
}
}
impl PartialEq for Identifier {
fn eq(&self, rhs: &Identifier) -> bool {
self.id == rhs.id && self.kind == rhs.kind
}
}
impl PartialEq<Object> for Identifier {
fn eq(&self, rhs: &Object) -> bool {
self.id == rhs.id && self.kind == rhs.kind
}
}
impl Render<Identifier> for Identifier {
fn render(mut self, _: Option<&Query>) -> Result<Document<Identifier>, Error> {
let meta = mem::replace(&mut self.meta, Default::default());
Ok(Document::Ok {
meta,
data: Data::Member(Box::new(Some(self))),
included: Default::default(),
jsonapi: Default::default(),
links: Default::default(),
})
}
}
impl Render<Identifier> for Vec<Identifier> {
fn render(self, _: Option<&Query>) -> Result<Document<Identifier>, Error> {
Ok(Document::Ok {
data: Data::Collection(self),
included: Default::default(),
jsonapi: Default::default(),
links: Default::default(),
meta: Default::default(),
})
}
}
impl PrimaryData for Identifier {
fn flatten(self, incl: &Set<Object>) -> Value {
incl.into_iter()
.find(|item| self == **item)
.map(|item| item.clone().flatten(incl))
.unwrap_or_else(|| self.id.clone().into())
}
}
impl Sealed for Identifier {}