Document derive macros

This commit is contained in:
asonix 2018-05-13 22:57:56 -05:00
parent c72cef93d6
commit 517102fcf3
7 changed files with 63 additions and 38 deletions

View file

@ -12,5 +12,11 @@ quote = "0.5"
syn = "0.13" syn = "0.13"
proc-macro2 = "0.3" proc-macro2 = "0.3"
[dev-dependencies]
activitystreams-traits = { version = "0.1", path = "../activitystreams-traits" }
serde = "1.0"
serde_derive = "1.0"
serde_json = "1.0"
[lib] [lib]
proc-macro = true proc-macro = true

View file

@ -17,6 +17,55 @@
* along with ActivityStreams Derive. If not, see <http://www.gnu.org/licenses/>. * along with ActivityStreams Derive. If not, see <http://www.gnu.org/licenses/>.
*/ */
//! Derive macros for Activity Streams
//!
//! ## Examples
//!
//! ```rust
//! #[macro_use]
//! extern crate activitystreams_derive;
//! extern crate activitystreams_traits;
//! extern crate serde;
//! #[macro_use]
//! extern crate serde_derive;
//! extern crate serde_json;
//!
//! use activitystreams_traits::{Link, Object};
//!
//! /// Using the UnitString derive macro
//! ///
//! /// This macro implements Serialize and Deserialize for the given type, making this type
//! /// represent the string "SomeKind" in JSON.
//! #[derive(Clone, Debug, Default, UnitString)]
//! #[activitystreams(SomeKind)]
//! pub struct MyKind;
//!
//! /// Using the Properties derive macro
//! ///
//! /// This macro generates getters and setters for the associated fields.
//! #[derive(Clone, Debug, Default, Deserialize, Serialize, Properties)]
//! #[serde(rename_all = "camelCase")]
//! pub struct MyProperties {
//! /// Derive getters and setters for @context with Link and Object traits.
//! #[serde(rename = "@context")]
//! #[activitystreams(ab(Object, Link))]
//! pub context: Option<serde_json::Value>,
//!
//! /// Derive getters and setters for context with Link and Object traits.
//! pub kind: MyKind,
//!
//! /// Derive getters and setters for required_key with String type.
//! ///
//! /// In the Activity Streams spec, 'functional' means there can only be one item for this
//! /// key. This means all fields not labeled 'functional' can also be serialized/deserialized
//! /// as Vec<T>.
//! #[activitystreams(concrete(String), functional)]
//! pub required_key: serde_json::Value,
//! }
//! #
//! # fn main () {}
//! ```
extern crate proc_macro; extern crate proc_macro;
extern crate proc_macro2; extern crate proc_macro2;
extern crate syn; extern crate syn;
@ -57,10 +106,10 @@ pub fn unit_string(input: TokenStream) -> TokenStream {
let visitor_name = Ident::from(format!("{}Visitor", value)); let visitor_name = Ident::from(format!("{}Visitor", value));
let serialize = quote! { let serialize = quote! {
impl Serialize for #name { impl ::serde::ser::Serialize for #name {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where where
S: Serializer, S: ::serde::ser::Serializer,
{ {
serializer.serialize_str(#value) serializer.serialize_str(#value)
} }
@ -68,7 +117,7 @@ pub fn unit_string(input: TokenStream) -> TokenStream {
}; };
let expecting = quote! { let expecting = quote! {
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { fn expecting(&self, formatter: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
write!(formatter, "The string '{}'", #value) write!(formatter, "The string '{}'", #value)
} }
}; };
@ -76,12 +125,12 @@ pub fn unit_string(input: TokenStream) -> TokenStream {
let visit = quote! { let visit = quote! {
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E> fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where where
E: de::Error, E: ::serde::de::Error,
{ {
if v == #value { if v == #value {
Ok(#name) Ok(#name)
} else { } else {
Err(de::Error::custom("Invalid type")) Err(::serde::de::Error::custom("Invalid type"))
} }
} }
}; };
@ -89,7 +138,7 @@ pub fn unit_string(input: TokenStream) -> TokenStream {
let visitor = quote! { let visitor = quote! {
struct #visitor_name; struct #visitor_name;
impl<'de> Visitor<'de> for #visitor_name { impl<'de> ::serde::de::Visitor<'de> for #visitor_name {
type Value = #name; type Value = #name;
#expecting #expecting
@ -99,10 +148,10 @@ pub fn unit_string(input: TokenStream) -> TokenStream {
}; };
let deserialize = quote! { let deserialize = quote! {
impl<'de> Deserialize<'de> for #name { impl<'de> ::serde::de::Deserialize<'de> for #name {
fn deserialize<D>(deserializer: D) -> Result<#name, D::Error> fn deserialize<D>(deserializer: D) -> Result<#name, D::Error>
where where
D: Deserializer<'de>, D: ::serde::de::Deserializer<'de>,
{ {
deserializer.deserialize_str(#visitor_name) deserializer.deserialize_str(#visitor_name)
} }

View file

@ -17,12 +17,6 @@
* along with ActivityStreams Types. If not, see <http://www.gnu.org/licenses/>. * along with ActivityStreams Types. If not, see <http://www.gnu.org/licenses/>.
*/ */
use std::fmt;
use serde::{
de::{self, Deserialize, Deserializer, Visitor}, ser::{Serialize, Serializer},
};
#[derive(Clone, Debug, Default, UnitString)] #[derive(Clone, Debug, Default, UnitString)]
#[activitystreams(Accept)] #[activitystreams(Accept)]
pub struct AcceptType; pub struct AcceptType;

View file

@ -19,12 +19,6 @@
//! Namespace for Unit Structs that serialize to strings //! Namespace for Unit Structs that serialize to strings
use std::fmt;
use serde::{
de::{self, Deserialize, Deserializer, Visitor}, ser::{Serialize, Serializer},
};
#[derive(Clone, Debug, Default, UnitString)] #[derive(Clone, Debug, Default, UnitString)]
#[activitystreams(Application)] #[activitystreams(Application)]
pub struct ApplicationType; pub struct ApplicationType;

View file

@ -19,12 +19,6 @@
//! Namespace for Unit Structs that serialize to strings //! Namespace for Unit Structs that serialize to strings
use std::fmt;
use serde::{
de::{self, Deserialize, Deserializer, Visitor}, ser::{Serialize, Serializer},
};
#[derive(Clone, Debug, Default, UnitString)] #[derive(Clone, Debug, Default, UnitString)]
#[activitystreams(Collection)] #[activitystreams(Collection)]
pub struct CollectionType; pub struct CollectionType;

View file

@ -19,12 +19,6 @@
//! Namespace for Unit Structs that serialize to strings //! Namespace for Unit Structs that serialize to strings
use std::fmt;
use serde::{
de::{self, Deserialize, Deserializer, Visitor}, ser::{Serialize, Serializer},
};
/// A Unit Struct that represents the string "Mention" /// A Unit Struct that represents the string "Mention"
#[derive(Clone, Debug, Default, UnitString)] #[derive(Clone, Debug, Default, UnitString)]
#[activitystreams(Mention)] #[activitystreams(Mention)]

View file

@ -19,12 +19,6 @@
//! Namespace for Unit Structs that serialize to strings //! Namespace for Unit Structs that serialize to strings
use std::fmt;
use serde::{
de::{self, Deserialize, Deserializer, Visitor}, ser::{Serialize, Serializer},
};
/// A Unit Struct that represents the string "Article" /// A Unit Struct that represents the string "Article"
#[derive(Clone, Debug, Default, UnitString)] #[derive(Clone, Debug, Default, UnitString)]
#[activitystreams(Article)] #[activitystreams(Article)]