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() .unwrap()
.clone(); .clone();
let value = get_value(attr); let value = from_value(attr);
let visitor_name = Ident::from(format!("{}Visitor", value)); let visitor_name = Ident::from(format!("{}Visitor", value));
@ -118,7 +118,7 @@ pub fn unit_string(input: TokenStream) -> TokenStream {
c.into() c.into()
} }
fn get_value(attr: Attribute) -> String { fn from_value(attr: Attribute) -> String {
let group = attr.tts let group = attr.tts
.clone() .clone()
.into_iter() .into_iter()
@ -218,12 +218,19 @@ pub fn properties_derive(input: TokenStream) -> TokenStream {
let lower_variant = variant.to_lowercase(); let lower_variant = variant.to_lowercase();
let fn_name = Ident::from(format!("{}_{}", ident, lower_variant)); let fn_name = Ident::from(format!("{}_{}", ident, lower_variant));
let fn_plural = Ident::from(format!("{}_{}_vec", 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); let variant = Ident::from(variant);
if is_concrete && is_option { if is_concrete && is_option {
let single = quote! { let single = quote! {
pub fn #fn_name(&self) -> ::error::Result<#variant> { 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 #single
pub fn #fn_plural(&self) -> ::error::Result<Vec<#variant>> { 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 { } else if is_concrete && is_vec {
quote! { quote! {
pub fn #fn_name(&self) -> ::error::Result<Vec<#variant>> { 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 { } else if is_concrete {
let single = quote! { let single = quote! {
pub fn #fn_name(&self) -> ::error::Result<#variant> { 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 #single
pub fn #fn_plural(&self) -> ::error::Result<Vec<#variant>> { 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 { } else if is_option {
let single = quote! { let single = quote! {
pub fn #fn_name<T: #variant>(&self) -> ::error::Result<T> { 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 #single
pub fn #fn_plural<T: #variant>(&self) -> ::error::Result<Vec<T>> { 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 { } else if is_vec {
quote! { quote! {
pub fn #fn_name<T: #variant>(&self) -> ::error::Result<Vec<T>> { 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 { } else {
let single = quote! { let single = quote! {
pub fn #fn_name<T: #variant>(&self) -> ::error::Result<T> { 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 #single
pub fn #fn_plural<T: #variant>(&self) -> ::error::Result<Vec<T>> { 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 { pub enum Error {
#[fail(display = "Key not present")] #[fail(display = "Key not present")]
NotFound, NotFound,
#[fail(display = "Failed to deserialize data as requested type")] #[fail(display = "Failed to deserialize data as requested type")]
Deserialize, Deserialize,
#[fail(display = "Failed to serialize data")]
Serialize,
} }
pub type Result<T> = result::Result<T, Error>; 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 activity;
pub mod actor; pub mod actor;
pub mod collection; pub mod collection;
pub mod custom_props;
pub mod error; pub mod error;
pub mod link; pub mod link;
pub mod object; 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 serde_json;
use error::{Error, Result}; 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 where
I: DeserializeOwned, I: DeserializeOwned,
{ {
serde_json::from_value(item.clone()).map_err(|_| Error::Deserialize) 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 where
I: DeserializeOwned, I: DeserializeOwned,
{ {
if let &Some(ref item) = item { if let &Some(ref item) = item {
serde_json::from_value(item.clone()).map_err(|_| Error::Deserialize) from_value(item)
} else { } else {
Err(Error::NotFound) 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 where
I: DeserializeOwned, I: DeserializeOwned,
{ {
v.iter().fold(Ok(Vec::new()), |acc, item| match acc { v.iter().fold(Ok(Vec::new()), |acc, item| match acc {
Ok(mut acc) => match serde_json::from_value(item.clone()) { Ok(mut acc) => from_value(item).map(|item| {
Ok(item) => { acc.push(item);
acc.push(item); acc
Ok(acc) }),
} e => e,
Err(_) => Err(Error::Deserialize), })
}, }
Err(e) => Err(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,
}) })
} }