use serde::Serialize;
use super::pagination::Page;
#[doc(hidden)]
pub fn field_to_json<T: Serialize>(val: &T) -> serde_json::Value {
serde_json::to_value(val).unwrap_or(serde_json::Value::Null)
}
#[doc(hidden)]
pub fn build_resource(fields: Vec<(&str, serde_json::Value)>) -> serde_json::Value {
let map: serde_json::Map<String, serde_json::Value> = fields
.into_iter()
.map(|(k, v)| (k.to_string(), v))
.collect();
serde_json::Value::Object(map)
}
#[doc(hidden)]
pub type ResourceValue = serde_json::Value;
#[derive(Debug, Clone)]
pub struct Resource<T: Serialize>(pub T);
impl<T: Serialize> Resource<T> {
pub fn new(data: T) -> Self {
Self(data)
}
pub fn to_json(&self) -> serde_json::Value {
serde_json::to_value(&self.0).unwrap_or(serde_json::Value::Null)
}
}
impl<T: Serialize> Serialize for Resource<T> {
fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
self.0.serialize(s)
}
}
impl<T: Serialize> From<T> for Resource<T> {
fn from(val: T) -> Self {
Self(val)
}
}
#[derive(Debug, Clone, Serialize)]
pub struct ResourceCollection<T: Serialize> {
pub data: Vec<T>,
pub total: usize,
}
impl<T: Serialize> ResourceCollection<T> {
pub fn new(data: Vec<T>) -> Self {
let total = data.len();
Self { data, total }
}
pub fn from_page(page: &Page<T>) -> Self
where
T: Clone,
{
Self {
data: page.data.clone(),
total: page.meta.total as usize,
}
}
pub fn map<U: Serialize>(self, f: impl Fn(T) -> U) -> ResourceCollection<U> {
let total = self.total;
ResourceCollection {
data: self.data.into_iter().map(f).collect(),
total,
}
}
pub fn to_json(&self) -> serde_json::Value {
serde_json::to_value(self).unwrap_or(serde_json::Value::Null)
}
}
impl<T: Serialize> From<Vec<T>> for ResourceCollection<T> {
fn from(data: Vec<T>) -> Self {
Self::new(data)
}
}
#[derive(Debug, Clone, Serialize)]
pub struct PageResource<T: Serialize> {
pub data: Vec<T>,
pub meta: crate::orm::pagination::PageMeta,
pub links: crate::orm::pagination::PageLinks,
}
impl<T: Serialize + Clone> PageResource<T> {
pub fn from_page(page: &Page<T>) -> Self {
Self {
data: page.data.clone(),
meta: page.meta.clone(),
links: page.links.clone(),
}
}
}
impl<T: Serialize + Clone> From<Page<T>> for PageResource<T> {
fn from(page: Page<T>) -> Self {
Self {
data: page.data,
meta: page.meta,
links: page.links,
}
}
}