Add setters, custom properties

This commit is contained in:
asonix 2018-05-13 15:37:40 -05:00
parent 4e2b965100
commit 37eb1a081b
5 changed files with 181 additions and 25 deletions

View file

@ -52,7 +52,7 @@ pub fn unit_string(input: TokenStream) -> TokenStream {
.unwrap()
.clone();
let value = get_value(attr);
let value = from_value(attr);
let visitor_name = Ident::from(format!("{}Visitor", value));
@ -118,7 +118,7 @@ pub fn unit_string(input: TokenStream) -> TokenStream {
c.into()
}
fn get_value(attr: Attribute) -> String {
fn from_value(attr: Attribute) -> String {
let group = attr.tts
.clone()
.into_iter()
@ -218,12 +218,19 @@ pub fn properties_derive(input: TokenStream) -> TokenStream {
let lower_variant = variant.to_lowercase();
let fn_name = Ident::from(format!("{}_{}", ident, lower_variant));
let fn_plural = Ident::from(format!("{}_{}_vec", ident, lower_variant));
let set_fn_name = Ident::from(format!("set_{}_{}", ident, lower_variant));
let set_fn_plural = Ident::from(format!("set_{}_{}_vec", ident, lower_variant));
let variant = Ident::from(variant);
if is_concrete && is_option {
let single = quote! {
pub fn #fn_name(&self) -> ::error::Result<#variant> {
::properties::get_item(&self.#ident)
::properties::from_item(&self.#ident)
}
pub fn #set_fn_name(&mut self, item: #variant) -> ::error::Result<()> {
self.#ident = ::properties::to_item(item)?;
Ok(())
}
};
@ -234,20 +241,35 @@ pub fn properties_derive(input: TokenStream) -> TokenStream {
#single
pub fn #fn_plural(&self) -> ::error::Result<Vec<#variant>> {
::properties::get_item(&self.#ident)
::properties::from_item(&self.#ident)
}
pub fn #set_fn_plural(&mut self, item: Vec<#variant>) -> ::error::Result<()> {
self.#ident = ::properties::to_item(item)?;
Ok(())
}
}
}
} else if is_concrete && is_vec {
quote! {
pub fn #fn_name(&self) -> ::error::Result<Vec<#variant>> {
::properties::get_vec(&self.#ident)
::properties::from_vec(&self.#ident)
}
pub fn #set_fn_name(&mut self, item: Vec<#variant>>) -> ::error::Result<()> {
self.#ident = ::properties::to_vec(item)?;
Ok(())
}
}
} else if is_concrete {
let single = quote! {
pub fn #fn_name(&self) -> ::error::Result<#variant> {
::properties::get_value(&self.#ident)
::properties::from_value(&self.#ident)
}
pub fn #set_fn_name(&mut self, item: #variant) -> ::error::Result<()> {
self.#ident = ::properties::to_value(item)?;
Ok(())
}
};
@ -258,14 +280,24 @@ pub fn properties_derive(input: TokenStream) -> TokenStream {
#single
pub fn #fn_plural(&self) -> ::error::Result<Vec<#variant>> {
::properties::get_value(&self.#ident)
::properties::from_value(&self.#ident)
}
pub #set_fn_plural(&mut self, item: Vec<#variant>) -> ::error::Result<()> {
self.#ident = ::properties::to_value(item)?;
Ok(())
}
}
}
} else if is_option {
let single = quote! {
pub fn #fn_name<T: #variant>(&self) -> ::error::Result<T> {
::properties::get_item(&self.#ident)
::properties::from_item(&self.#ident)
}
pub fn #set_fn_name<T: #variant>(&mut self, item: T) -> ::error::Result<()> {
self.#ident = ::properties::to_item(item)?;
Ok(())
}
};
@ -276,20 +308,35 @@ pub fn properties_derive(input: TokenStream) -> TokenStream {
#single
pub fn #fn_plural<T: #variant>(&self) -> ::error::Result<Vec<T>> {
::properties::get_item(&self.#ident)
::properties::from_item(&self.#ident)
}
pub fn #set_fn_plural<T: #variant>(&mut self, item: Vec<T>) -> ::error::Result<()> {
self.#ident = ::properties::to_item(item)?;
Ok(())
}
}
}
} else if is_vec {
quote! {
pub fn #fn_name<T: #variant>(&self) -> ::error::Result<Vec<T>> {
::properties::get_vec(&self.#ident)
::properties::from_vec(&self.#ident)
}
pub fn #set_fn_name<T: #variant>(&mut self, item: Vec<T>) -> ::error::Result<()> {
self.#ident = ::properties::to_vec(item)?;
Ok(())
}
}
} else {
let single = quote! {
pub fn #fn_name<T: #variant>(&self) -> ::error::Result<T> {
::properties::get_value(&self.#ident)
::properties::from_value(&self.#ident)
}
pub fn #set_fn_name<T: #variant>(&mut self, item: T) -> ::error::Result<()> {
self.#ident = ::properties::to_value(item)?;
Ok(())
}
};
@ -300,7 +347,12 @@ pub fn properties_derive(input: TokenStream) -> TokenStream {
#single
pub fn #fn_plural<T: #variant>(&self) -> ::error::Result<Vec<T>> {
::properties::get_value(&self.#ident)
::properties::from_value(&self.#ident)
}
pub fn #set_fn_plural<T: #variant>(&mut self, item: Vec<T>) -> ::error::Result<()> {
self.#ident = ::properties::to_value(item)?;
Ok(())
}
}
}

56
src/custom_props.rs Normal file
View file

@ -0,0 +1,56 @@
/*
* This file is part of ActivityStreams.
*
* Copyright © 2018 Riley Trautman
*
* ActivityStreams is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* ActivityStreams is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with ActivityStreams. If not, see <http://www.gnu.org/licenses/>.
*/
use link::Link;
use object::Object;
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct CustomLink<C, L> {
#[serde(flatten)]
link: L,
#[serde(flatten)]
pub custom_props: C,
}
impl<C, L: Link> CustomLink<C, L> {
pub fn new(link: L, custom_props: C) -> Self {
CustomLink { link, custom_props }
}
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct CustomObject<C, O> {
#[serde(flatten)]
object: O,
#[serde(flatten)]
pub custom_props: C,
}
impl<C, O: Object> CustomObject<C, O> {
pub fn new(object: O, custom_props: C) -> Self {
CustomObject {
object,
custom_props,
}
}
}

View file

@ -23,8 +23,12 @@ use std::result;
pub enum Error {
#[fail(display = "Key not present")]
NotFound,
#[fail(display = "Failed to deserialize data as requested type")]
Deserialize,
#[fail(display = "Failed to serialize data")]
Serialize,
}
pub type Result<T> = result::Result<T, Error>;

View file

@ -38,6 +38,7 @@ pub fn context() -> serde_json::Value {
pub mod activity;
pub mod actor;
pub mod collection;
pub mod custom_props;
pub mod error;
pub mod link;
pub mod object;

View file

@ -1,38 +1,81 @@
use serde::de::DeserializeOwned;
/*
* This file is part of ActivityStreams.
*
* Copyright © 2018 Riley Trautman
*
* ActivityStreams is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* ActivityStreams is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with ActivityStreams. If not, see <http://www.gnu.org/licenses/>.
*/
use serde::{de::DeserializeOwned, ser::Serialize};
use serde_json;
use error::{Error, Result};
pub fn get_value<I>(item: &serde_json::Value) -> Result<I>
pub fn from_value<I>(item: &serde_json::Value) -> Result<I>
where
I: DeserializeOwned,
{
serde_json::from_value(item.clone()).map_err(|_| Error::Deserialize)
}
pub fn get_item<I>(item: &Option<serde_json::Value>) -> Result<I>
pub fn to_value<I>(item: I) -> Result<serde_json::Value>
where
I: Serialize,
{
serde_json::to_value(item).map_err(|_| Error::Serialize)
}
pub fn from_item<I>(item: &Option<serde_json::Value>) -> Result<I>
where
I: DeserializeOwned,
{
if let &Some(ref item) = item {
serde_json::from_value(item.clone()).map_err(|_| Error::Deserialize)
from_value(item)
} else {
Err(Error::NotFound)
}
}
pub fn get_vec<I>(v: &Vec<serde_json::Value>) -> Result<Vec<I>>
pub fn to_item<I>(item: I) -> Result<Option<serde_json::Value>>
where
I: Serialize,
{
to_value(item).map(Some)
}
pub fn from_vec<I>(v: &Vec<serde_json::Value>) -> Result<Vec<I>>
where
I: DeserializeOwned,
{
v.iter().fold(Ok(Vec::new()), |acc, item| match acc {
Ok(mut acc) => match serde_json::from_value(item.clone()) {
Ok(item) => {
acc.push(item);
Ok(acc)
}
Err(_) => Err(Error::Deserialize),
},
Err(e) => Err(e),
Ok(mut acc) => from_value(item).map(|item| {
acc.push(item);
acc
}),
e => e,
})
}
pub fn to_vec<I>(v: Vec<I>) -> Result<Vec<serde_json::Value>>
where
I: Serialize,
{
v.into_iter().fold(Ok(Vec::new()), |acc, item| match acc {
Ok(mut acc) => to_value(item).map(|item| {
acc.push(item);
acc
}),
e => e,
})
}