From eda88c162c5712360ce282fdd2841de62948d566 Mon Sep 17 00:00:00 2001 From: asonix Date: Tue, 10 Mar 2020 14:55:15 -0500 Subject: [PATCH] Dates, Docs, Derives, tests --- Cargo.toml | 5 +- README.md | 2 +- activitystreams-derive/src/lib.rs | 179 +++++++++++++++--- activitystreams-traits/src/lib.rs | 3 +- activitystreams-types/src/activity/delete.rs | 2 +- activitystreams-types/src/activity/dislike.rs | 2 +- activitystreams-types/src/activity/flag.rs | 2 +- activitystreams-types/src/activity/follow.rs | 2 +- activitystreams-types/src/activity/ignore.rs | 2 +- activitystreams-types/src/activity/invite.rs | 2 +- activitystreams-types/src/activity/join.rs | 2 +- activitystreams-types/src/activity/kind.rs | 2 +- activitystreams-types/src/activity/leave.rs | 2 +- activitystreams-types/src/activity/like.rs | 2 +- activitystreams-types/src/activity/listen.rs | 2 +- activitystreams-types/src/activity/mod.rs | 2 +- activitystreams-types/src/activity/offer.rs | 2 +- .../src/activity/properties.rs | 20 +- .../src/activity/question.rs | 2 +- activitystreams-types/src/activity/read.rs | 2 +- activitystreams-types/src/activity/reject.rs | 2 +- activitystreams-types/src/activity/remove.rs | 2 +- .../src/activity/tentative_accept.rs | 2 +- .../src/activity/tentative_reject.rs | 2 +- activitystreams-types/src/activity/travel.rs | 2 +- activitystreams-types/src/activity/undo.rs | 2 +- activitystreams-types/src/activity/update.rs | 2 +- activitystreams-types/src/activity/view.rs | 2 +- activitystreams-types/src/actor/kind.rs | 2 +- activitystreams-types/src/actor/mod.rs | 2 +- activitystreams-types/src/collection/kind.rs | 2 +- activitystreams-types/src/collection/mod.rs | 2 +- .../src/collection/properties.rs | 23 ++- activitystreams-types/src/lib.rs | 4 +- activitystreams-types/src/link/kind.rs | 2 +- activitystreams-types/src/link/mod.rs | 2 +- activitystreams-types/src/link/properties.rs | 11 +- activitystreams-types/src/object/kind.rs | 2 +- activitystreams-types/src/object/mod.rs | 2 +- .../src/object/properties.rs | 18 +- .../src/primitives/length.rs | 21 ++ .../src/primitives/mime_media_type.rs | 27 +++ activitystreams-types/src/primitives/mod.rs | 55 ++++++ .../src/primitives/rdf_lang_string.rs | 32 +++- .../src/primitives/xsd_any_uri.rs | 53 ++++++ .../src/primitives/xsd_datetime.rs | 55 ++++-- .../src/primitives/xsd_duration.rs | 44 +++++ .../src/primitives/xsd_float.rs | 33 ++++ .../src/primitives/xsd_non_negative_float.rs | 35 ++++ .../primitives/xsd_non_negative_integer.rs | 24 +++ .../src/primitives/xsd_string.rs | 31 +++ src/lib.rs | 129 +++++++++---- 52 files changed, 713 insertions(+), 153 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 699d3ca..6b8b9e3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "activitystreams" description = "Activity Streams in Rust" -version = "0.3.0" +version = "0.4.0" license = "GPL-3.0" authors = ["asonix "] repository = "https://git.asonix.dog/Aardwolf/activitystreams" @@ -12,12 +12,13 @@ edition = "2018" [dependencies] activitystreams-traits = { version = "0.3.0", path = "activitystreams-traits" } activitystreams-types = { version = "0.4.0", path = "activitystreams-types" } +activitystreams-derive = { version = "0.3.0", path = "activitystreams-derive" } [dev-dependencies] anyhow = "1.0" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" -activitystreams-derive = { version = "0.3.0", path = "activitystreams-derive" } +typetag = "0.1.4" [profile.dev.package.activitystreams-derive] opt-level = 3 diff --git a/README.md b/README.md index 6b5d49e..8d252c9 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ For basic use, add the following to your Cargo.toml ```toml # Cargo.toml -activitystreams = "0.3" +activitystreams = "0.4" ``` And then use it in your project diff --git a/activitystreams-derive/src/lib.rs b/activitystreams-derive/src/lib.rs index 9904c5c..1c53879 100644 --- a/activitystreams-derive/src/lib.rs +++ b/activitystreams-derive/src/lib.rs @@ -35,7 +35,7 @@ //! /// //! /// This macro implements Serialize and Deserialize for the given type, making this type //! /// represent the string "SomeKind" in JSON. -//! #[derive(Clone, Debug, Default, UnitString)] +//! #[derive(Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd, UnitString)] //! #[activitystreams(SomeKind)] //! pub struct MyKind; //! @@ -46,7 +46,7 @@ //! My { //! context { //! types [ -//! Value, +//! String, //! ], //! rename("@context"), //! }, @@ -64,23 +64,28 @@ //! ], //! functional, //! required, +//! alias [ +//! "someKey", +//! "existingKey", +//! "woooKey", +//! ], //! }, //! } //! } -//! # -//! # fn main () -> Result<(), Box { -//! let s = r#"{ -//! "@context": "http://www.w3c.org/ns#activitystreams", -//! "type": "SomeKind", -//! "required_key": { -//! "key": "value" -//! } -//! }"# //! -//! let m: MyProperties = serde_json::from_str(s)?; -//! println!("{:?}", m.get_kind()); -//! # Ok(()) -//! # } +//! fn main () -> Result<(), Box> { +//! let s = r#"{ +//! "@context": "http://www.w3c.org/ns#activitystreams", +//! "type": "SomeKind", +//! "woooKey": { +//! "key": "value" +//! } +//! }"#; +//! +//! let m: MyProperties = serde_json::from_str(s)?; +//! assert_eq!(&MyKind, m.get_kind()); +//! Ok(()) +//! } //! ``` extern crate proc_macro; @@ -230,7 +235,7 @@ pub fn unit_string(input: TokenStream) -> TokenStream { .clone(); let visitor_name = from_value(attr); - let value = format!("\"{}\"", visitor_name); + let value = format!("{}", visitor_name); let serialize = quote! { impl ::serde::ser::Serialize for #name { @@ -318,17 +323,26 @@ fn from_value(attr: Attribute) -> Ident { .unwrap() } +fn to_doc(s: &String) -> proc_macro2::TokenStream { + format!("/// {}", s).parse().unwrap() +} + +fn many_docs(v: &Vec) -> proc_macro2::TokenStream { + v.iter() + .map(|d| { + let d = to_doc(d); + quote! { + #d + } + }) + .collect() +} + #[proc_macro] pub fn properties(tokens: TokenStream) -> TokenStream { let Properties { name, docs, fields } = parse_macro_input!(tokens as Properties); - let docs: proc_macro2::TokenStream = docs - .into_iter() - .map(|doc| { - let idents: proc_macro2::TokenStream = format!("/// {}", doc).parse().unwrap(); - quote! { #idents } - }) - .collect(); + let docs: proc_macro2::TokenStream = many_docs(&docs); let name = Ident::new(&format!("{}Properties", name), name.span()); @@ -338,10 +352,7 @@ pub fn properties(tokens: TokenStream) -> TokenStream { } let fname = field.name.clone(); - let fdocs: proc_macro2::TokenStream = field.description.docs.iter().map(|doc| { - let idents: proc_macro2::TokenStream = format!("/// {}", doc).parse().unwrap(); - quote! { #idents } - }).collect(); + let fdocs: proc_macro2::TokenStream = many_docs(&field.description.docs); let (ty, deps) = if field.description.types.len() == 1 { let ty = Ident::new(&field.description.types.first().unwrap().to_token_stream().to_string(), fname.span()); @@ -349,7 +360,13 @@ pub fn properties(tokens: TokenStream) -> TokenStream { (ty, None) } else { let enum_ty = Ident::new(&camelize(&format!("{}_{}_enum", name, fname)), fname.span()); + let doc_lines = many_docs(&vec![ + format!("Variations for the `{}` field from `{}", fname, name), + String::new(), + format!("`{}` isn't functional, meaning it can be represented as either a single `{}` or a vector of `{}`.", fname, ty, ty), + ]); let deps = quote! { + #doc_lines #[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] #[serde(rename_all = "camelCase")] #[serde(untagged)] @@ -413,7 +430,18 @@ pub fn properties(tokens: TokenStream) -> TokenStream { }) .collect(); + let term_doc_lines = many_docs(&vec![ + format!("Terminating variations for the `{}` field from `{}`", fname, name), + String::new(), + format!("Since {} can be one of multiple types, this enum represents all possibilities of {}", fname, fname), + ]); + let doc_lines = many_docs(&vec![ + format!("Non-Terminating variations for the `{}` field from `{}`", fname, name), + String::new(), + format!("`{}` isn't functional, meaning it can be represented as either a single `{}` or a vector of `{}`", fname, term_ty, term_ty), + ]); quote! { + #term_doc_lines #[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] #[serde(rename_all = "camelCase")] #[serde(untagged)] @@ -421,6 +449,7 @@ pub fn properties(tokens: TokenStream) -> TokenStream { #v_tokens } + #doc_lines #[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] #[serde(rename_all = "camelCase")] #[serde(untagged)] @@ -465,7 +494,15 @@ pub fn properties(tokens: TokenStream) -> TokenStream { }) .collect(); + let doc_lines = many_docs(&vec![ + format!("Variations for the `{}` field from `{}`", fname, name), + String::new(), + format!("`{}` isn't functional, meaning it can only be represented as a single `{}`", fname, ty), + String::new(), + format!("This enum's variants representa ll valid types to construct a `{}`", fname), + ]); quote! { + #doc_lines #[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] #[serde(rename_all = "camelCase")] #[serde(untagged)] @@ -528,7 +565,9 @@ pub fn properties(tokens: TokenStream) -> TokenStream { if field.description.required { if field.description.functional { + let doc_line = to_doc(&format!("Set `{}` with a type that can be cnoverted into a `{}`", fname, v_ty.to_token_stream())); let set = quote! { + #doc_line pub fn #set_ident(&mut self, item: T) -> Result<&mut Self, >::Error> where T: std::convert::TryInto<#v_ty>, @@ -539,7 +578,9 @@ pub fn properties(tokens: TokenStream) -> TokenStream { } }; + let doc_line = to_doc(&format!("Get the `{}` as `{}`", fname, v_ty.to_token_stream())); let get = quote! { + #doc_line pub fn #get_ident(&self) -> &#v_ty { &self.#fname } @@ -550,7 +591,9 @@ pub fn properties(tokens: TokenStream) -> TokenStream { #set } } else { + let doc_line = to_doc(&format!("Set `{}` with a type that can be converted into a `{}`", fname, v_ty.to_token_stream())); let set = quote! { + #doc_line pub fn #set_ident(&mut self, item: T) -> Result<&mut Self, >::Error> where T: std::convert::TryInto<#v_ty>, @@ -561,7 +604,11 @@ pub fn properties(tokens: TokenStream) -> TokenStream { } }; + let doc_line = to_doc(&format!("Get the `{}` as `{}`", fname, v_ty.to_token_stream())); let get = quote! { + #doc_line + /// + /// This returns `None` when there is more than one item pub fn #get_ident(&self) -> Option<&#v_ty> { match self.#fname { #enum_ty::Term(ref term) => Some(term), @@ -570,7 +617,9 @@ pub fn properties(tokens: TokenStream) -> TokenStream { } }; + let doc_line = to_doc(&format!("Set the `{}` with a vector of types that can be converted into `{}`s", fname, v_ty.to_token_stream())); let set_many = quote! { + #doc_line pub fn #set_many_ident(&mut self, item: Vec) -> Result<&mut Self, >::Error> where T: std::convert::TryInto<#v_ty>, @@ -581,7 +630,12 @@ pub fn properties(tokens: TokenStream) -> TokenStream { } }; + let doc_line = to_doc(&format!("Get the `{}` as a slice of `{}`", fname, v_ty.to_token_stream())); let get_many = quote! { + #doc_line + /// + /// This returns `None` if + /// - There is only one element pub fn #get_many_ident(&self) -> Option<&[#v_ty]> { match self.#fname { #enum_ty::Array(ref array) => Some(array), @@ -599,7 +653,9 @@ pub fn properties(tokens: TokenStream) -> TokenStream { } } else { if field.description.functional { + let doc_line = to_doc(&format!("Set the `{}` with a type that can be converted into `{}`", fname, v_ty.to_token_stream())); let set = quote! { + #doc_line pub fn #set_ident(&mut self, item: T) -> Result<&mut Self, >::Error> where T: std::convert::TryInto<#v_ty>, @@ -610,7 +666,11 @@ pub fn properties(tokens: TokenStream) -> TokenStream { } }; + let doc_line = to_doc(&format!("Get `{}` as a `{}`", fname, v_ty.to_token_stream())); let get = quote! { + #doc_line + /// + /// This returns `None` if there is no value present pub fn #get_ident(&self) -> Option<&#v_ty> { self.#fname.as_ref() } @@ -621,7 +681,9 @@ pub fn properties(tokens: TokenStream) -> TokenStream { #set } } else { + let doc_line = to_doc(&format!("Set the `{}` with a type that can be converted into `{}`", fname, v_ty.to_token_stream())); let set = quote! { + #doc_line pub fn #set_ident(&mut self, item: T) -> Result<&mut Self, >::Error> where T: std::convert::TryInto<#v_ty>, @@ -632,7 +694,13 @@ pub fn properties(tokens: TokenStream) -> TokenStream { } }; + let doc_line = to_doc(&format!("Get `{}` as a `{}`", fname, v_ty.to_token_stream())); let get = quote! { + #doc_line + /// + /// This returns `None` if + /// - There is no value present + /// - There is more than one value present pub fn #get_ident(&self) -> Option<&#v_ty> { match self.#fname { Some(#enum_ty::Term(ref term)) => Some(term), @@ -641,7 +709,9 @@ pub fn properties(tokens: TokenStream) -> TokenStream { } }; + let doc_line = to_doc(&format!("Set the `{}` with a vector of types that can be converted into `{}`s", fname, v_ty.to_token_stream())); let set_many = quote! { + #doc_line pub fn #set_many_ident(&mut self, item: Vec) -> Result<&mut Self, >::Error> where T: std::convert::TryInto<#v_ty>, @@ -652,7 +722,13 @@ pub fn properties(tokens: TokenStream) -> TokenStream { } }; + let doc_line = to_doc(&format!("Get `{}` as a slice of `{}`s", fname, v_ty.to_token_stream())); let get_many = quote! { + #doc_line + /// + /// This returns `None` if + /// - There is no value present + /// - There is only one value present pub fn #get_many_ident(&self) -> Option<&[#v_ty]> { match self.#fname { Some(#enum_ty::Array(ref a)) => Some(a), @@ -681,7 +757,9 @@ pub fn properties(tokens: TokenStream) -> TokenStream { Ident::new(&format!("get_{}_{}", fname, snakize(&v_ty.to_token_stream().to_string())), fname.span()); if field.description.required { + let doc_line = to_doc(&format!("Set the `{}` with a type that can be converted into `{}`", fname, v_ty.to_token_stream())); let set = quote! { + #doc_line pub fn #set_ident(&mut self, item: T) -> Result<&mut Self, >::Error> where T: std::convert::TryInto<#v_ty>, @@ -693,7 +771,12 @@ pub fn properties(tokens: TokenStream) -> TokenStream { } }; + let doc_line = to_doc(&format!("Get `{}` as a slice of `{}`s", fname, v_ty.to_token_stream())); let get = quote! { + #doc_line + /// + /// This returns `None` if + /// - The requested type is not the stored type pub fn #get_ident(&self) -> Option<&#v_ty> { match self.#fname { #ty::#v_ty(ref term) => Some(term), @@ -707,7 +790,9 @@ pub fn properties(tokens: TokenStream) -> TokenStream { #set } } else { + let doc_line = to_doc(&format!("Set `{}` with a value that can be converted into `{}`", fname, v_ty.to_token_stream())); let set = quote! { + #doc_line pub fn #set_ident(&mut self, item: T) -> Result<&mut Self, >::Error> where T: std::convert::TryInto<#v_ty>, @@ -719,7 +804,13 @@ pub fn properties(tokens: TokenStream) -> TokenStream { } }; + let doc_line = to_doc(&format!("Get `{}` as a `{}`", fname, v_ty.to_token_stream())); let get = quote! { + #doc_line + /// + /// This returns `None` if + /// - There is no value present + /// - The requested type is not the stored type pub fn #get_ident(&self) -> Option<&#v_ty> { match self.#fname { Some(#ty::#v_ty(ref term)) => Some(term), @@ -757,7 +848,9 @@ pub fn properties(tokens: TokenStream) -> TokenStream { Ident::new(&format!("get_many_{}_{}s", fname, snakize(&v_ty.to_token_stream().to_string())), fname.span()); if field.description.required { + let doc_line = to_doc(&format!("Set `{}` with a value that can be converted into `{}`", fname, v_ty.to_token_stream())); let set = quote! { + #doc_line pub fn #set_ident(&mut self, item: T) -> Result<&mut Self, >::Error> where T: std::convert::TryInto<#v_ty>, @@ -770,7 +863,13 @@ pub fn properties(tokens: TokenStream) -> TokenStream { } }; + let doc_line = to_doc(&format!("Get the `{}` as a `{}`", fname, v_ty.to_token_stream())); let get = quote! { + #doc_line + /// + /// This returns `None` if + /// - There is more than one value present + /// - The requested type is not the stored type pub fn #get_ident(&self) -> Option<&#v_ty> { match self.#fname { #ty::Term(#term_ty::#v_ty(ref term)) => Some(term), @@ -779,7 +878,9 @@ pub fn properties(tokens: TokenStream) -> TokenStream { } }; + let doc_line = to_doc(&format!("Set `{}` from a vec of items that can be converted into `{}`s", fname, v_ty.to_token_stream())); let set_many = quote! { + #doc_line pub fn #set_many_ident(&mut self, item: Vec) -> Result<&mut Self, >::Error> where T: std::convert::TryInto<#v_ty>, @@ -791,7 +892,12 @@ pub fn properties(tokens: TokenStream) -> TokenStream { } }; + let doc_line = to_doc(&format!("Get `{}` as a slice of `{}`s", fname, term_ty.to_token_stream())); let get_many = quote! { + #doc_line + /// + /// This returns `None` if + /// - There is only one value present pub fn #get_many_ident(&self) -> Option<&[#term_ty]> { match self.#fname { #ty::Array(ref array) => Some(array), @@ -807,7 +913,9 @@ pub fn properties(tokens: TokenStream) -> TokenStream { #set_many } } else { + let doc_line = to_doc(&format!("Set `{}` from a value that can be converted into `{}`", fname, v_ty.to_token_stream())); let set = quote! { + #doc_line pub fn #set_ident(&mut self, item: T) -> Result<&mut Self, >::Error> where T: std::convert::TryInto<#v_ty>, @@ -820,7 +928,14 @@ pub fn properties(tokens: TokenStream) -> TokenStream { } }; + let doc_line = to_doc(&format!("Get `{}` as a `{}`", fname, v_ty.to_token_stream())); let get = quote! { + #doc_line + /// + /// This returns `None` if + /// - There is no value present + /// - There is more than one value present + /// - The requested type is not stored type pub fn #get_ident(&self) -> Option<&#v_ty> { match self.#fname { Some(#ty::Term(#term_ty::#v_ty(ref term))) => Some(term), @@ -829,7 +944,9 @@ pub fn properties(tokens: TokenStream) -> TokenStream { } }; + let doc_line = to_doc(&format!("Set `{}` from a vec of items that can be converted into `{}`s", fname, v_ty.to_token_stream())); let set_many = quote! { + #doc_line pub fn #set_many_ident(&mut self, item: Vec) -> Result<&mut Self, >::Error> where T: std::convert::TryInto<#v_ty>, @@ -841,7 +958,13 @@ pub fn properties(tokens: TokenStream) -> TokenStream { } }; + let doc_line = to_doc(&format!("Get `{}` as a slice of `{}`s", fname, term_ty.to_token_stream())); let get_many = quote! { + #doc_line + /// + /// This returns `None` if + /// - There is no value present + /// - There is only one value present pub fn #get_many_ident(&self) -> Option<&[#term_ty]> { match self.#fname { Some(#ty::Array(ref array)) => Some(array), @@ -864,7 +987,9 @@ pub fn properties(tokens: TokenStream) -> TokenStream { let delete_ident = Ident::new(&format!("delete_{}", fname), fname.span()); + let doc_line = to_doc(&format!("Set the `{}` field to `None`", fname)); quote! { + #doc_line pub fn #delete_ident(&mut self) -> &mut Self { self.#fname = None; self diff --git a/activitystreams-traits/src/lib.rs b/activitystreams-traits/src/lib.rs index 289350f..04a6249 100644 --- a/activitystreams-traits/src/lib.rs +++ b/activitystreams-traits/src/lib.rs @@ -27,12 +27,13 @@ //! ```rust //! use activitystreams_traits::{Object, Actor}; //! use serde::{Deserialize, Serialize}; +//! use std::any::Any; //! //! #[derive(Clone, Debug, Default, Deserialize, Serialize)] //! #[serde(rename_all = "camelCase")] //! pub struct Persona { //! #[serde(rename = "@context")] -//! context: serde_json::Value, +//! context: String, //! //! #[serde(rename = "type")] //! kind: String, diff --git a/activitystreams-types/src/activity/delete.rs b/activitystreams-types/src/activity/delete.rs index 4e9a41d..9ee630b 100644 --- a/activitystreams-types/src/activity/delete.rs +++ b/activitystreams-types/src/activity/delete.rs @@ -1,7 +1,7 @@ /* * This file is part of ActivityStreams Types. * - * Copyright © 2018 Riley Trautman + * Copyright © 2020 Riley Trautman * * ActivityStreams Types is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/activitystreams-types/src/activity/dislike.rs b/activitystreams-types/src/activity/dislike.rs index 51c54d4..019c726 100644 --- a/activitystreams-types/src/activity/dislike.rs +++ b/activitystreams-types/src/activity/dislike.rs @@ -1,7 +1,7 @@ /* * This file is part of ActivityStreams Types. * - * Copyright © 2018 Riley Trautman + * Copyright © 2020 Riley Trautman * * ActivityStreams Types is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/activitystreams-types/src/activity/flag.rs b/activitystreams-types/src/activity/flag.rs index cb8ba58..40062ba 100644 --- a/activitystreams-types/src/activity/flag.rs +++ b/activitystreams-types/src/activity/flag.rs @@ -1,7 +1,7 @@ /* * This file is part of ActivityStreams Types. * - * Copyright © 2018 Riley Trautman + * Copyright © 2020 Riley Trautman * * ActivityStreams Types is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/activitystreams-types/src/activity/follow.rs b/activitystreams-types/src/activity/follow.rs index b2316cd..ae0504b 100644 --- a/activitystreams-types/src/activity/follow.rs +++ b/activitystreams-types/src/activity/follow.rs @@ -1,7 +1,7 @@ /* * This file is part of ActivityStreams Types. * - * Copyright © 2018 Riley Trautman + * Copyright © 2020 Riley Trautman * * ActivityStreams Types is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/activitystreams-types/src/activity/ignore.rs b/activitystreams-types/src/activity/ignore.rs index fbbd20d..6488d5e 100644 --- a/activitystreams-types/src/activity/ignore.rs +++ b/activitystreams-types/src/activity/ignore.rs @@ -1,7 +1,7 @@ /* * This file is part of ActivityStreams Types. * - * Copyright © 2018 Riley Trautman + * Copyright © 2020 Riley Trautman * * ActivityStreams Types is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/activitystreams-types/src/activity/invite.rs b/activitystreams-types/src/activity/invite.rs index c309e82..a37a9b8 100644 --- a/activitystreams-types/src/activity/invite.rs +++ b/activitystreams-types/src/activity/invite.rs @@ -1,7 +1,7 @@ /* * This file is part of ActivityStreams Types. * - * Copyright © 2018 Riley Trautman + * Copyright © 2020 Riley Trautman * * ActivityStreams Types is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/activitystreams-types/src/activity/join.rs b/activitystreams-types/src/activity/join.rs index 384e45f..53a2a82 100644 --- a/activitystreams-types/src/activity/join.rs +++ b/activitystreams-types/src/activity/join.rs @@ -1,7 +1,7 @@ /* * This file is part of ActivityStreams Types. * - * Copyright © 2018 Riley Trautman + * Copyright © 2020 Riley Trautman * * ActivityStreams Types is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/activitystreams-types/src/activity/kind.rs b/activitystreams-types/src/activity/kind.rs index c167161..659985a 100644 --- a/activitystreams-types/src/activity/kind.rs +++ b/activitystreams-types/src/activity/kind.rs @@ -1,7 +1,7 @@ /* * This file is part of ActivityStreams Types. * - * Copyright © 2018 Riley Trautman + * Copyright © 2020 Riley Trautman * * ActivityStreams Types is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/activitystreams-types/src/activity/leave.rs b/activitystreams-types/src/activity/leave.rs index 52fc668..582ad6e 100644 --- a/activitystreams-types/src/activity/leave.rs +++ b/activitystreams-types/src/activity/leave.rs @@ -1,7 +1,7 @@ /* * This file is part of ActivityStreams Types. * - * Copyright © 2018 Riley Trautman + * Copyright © 2020 Riley Trautman * * ActivityStreams Types is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/activitystreams-types/src/activity/like.rs b/activitystreams-types/src/activity/like.rs index db19fb9..33728d8 100644 --- a/activitystreams-types/src/activity/like.rs +++ b/activitystreams-types/src/activity/like.rs @@ -1,7 +1,7 @@ /* * This file is part of ActivityStreams Types. * - * Copyright © 2018 Riley Trautman + * Copyright © 2020 Riley Trautman * * ActivityStreams Types is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/activitystreams-types/src/activity/listen.rs b/activitystreams-types/src/activity/listen.rs index 3b571a5..67aaed6 100644 --- a/activitystreams-types/src/activity/listen.rs +++ b/activitystreams-types/src/activity/listen.rs @@ -1,7 +1,7 @@ /* * This file is part of ActivityStreams Types. * - * Copyright © 2018 Riley Trautman + * Copyright © 2020 Riley Trautman * * ActivityStreams Types is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/activitystreams-types/src/activity/mod.rs b/activitystreams-types/src/activity/mod.rs index 116f1b5..a16e1b8 100644 --- a/activitystreams-types/src/activity/mod.rs +++ b/activitystreams-types/src/activity/mod.rs @@ -1,7 +1,7 @@ /* * This file is part of ActivityStreams Types. * - * Copyright © 2018 Riley Trautman + * Copyright © 2020 Riley Trautman * * ActivityStreams Types is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/activitystreams-types/src/activity/offer.rs b/activitystreams-types/src/activity/offer.rs index 05b268a..d523d70 100644 --- a/activitystreams-types/src/activity/offer.rs +++ b/activitystreams-types/src/activity/offer.rs @@ -1,7 +1,7 @@ /* * This file is part of ActivityStreams Types. * - * Copyright © 2018 Riley Trautman + * Copyright © 2020 Riley Trautman * * ActivityStreams Types is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/activitystreams-types/src/activity/properties.rs b/activitystreams-types/src/activity/properties.rs index d24775d..abe8eb6 100644 --- a/activitystreams-types/src/activity/properties.rs +++ b/activitystreams-types/src/activity/properties.rs @@ -1,6 +1,6 @@ /* This file is part of ActivityStreams Types. * - * Copyright © 2018 Riley Trautman + * Copyright © 2020 Riley Trautman * * ActivityStreams Types is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,14 +21,21 @@ //! To use these properties in your own types, you can flatten them into your struct with serde: //! //! ```rust +//! use activitystreams_derive::PropRefs; //! use activitystreams_traits::{Activity, Object}; //! use activitystreams_types::{ -//! activity::properties::ActivityProperties, -//! object::properties::ObjectProperties, +//! activity::{ +//! properties::ActivityProperties, +//! ActivityExt, +//! }, +//! object::{ +//! properties::ObjectProperties, +//! ObjectExt, +//! }, //! }; //! use serde::{Deserialize, Serialize}; //! -//! #[derive(Debug, Serialize, Deserialize)] +//! #[derive(Clone, Debug, Serialize, Deserialize, PropRefs)] //! #[serde(rename_all = "camelCase")] //! pub struct MyActivity { //! #[serde(rename = "type")] @@ -40,14 +47,13 @@ //! pub my_property: String, //! //! #[serde(flatten)] +//! #[activitystreams(Object)] //! pub object_properties: ObjectProperties, //! //! #[serde(flatten)] +//! #[activitystreams(Activity)] //! pub activity_properties: ActivityProperties, //! } -//! -//! impl Object for MyActivity {} -//! impl Activity for MyActivity {} //! # //! # fn main() {} //! ``` diff --git a/activitystreams-types/src/activity/question.rs b/activitystreams-types/src/activity/question.rs index d411ba2..9d35977 100644 --- a/activitystreams-types/src/activity/question.rs +++ b/activitystreams-types/src/activity/question.rs @@ -1,7 +1,7 @@ /* * This file is part of ActivityStreams Types. * - * Copyright © 2018 Riley Trautman + * Copyright © 2020 Riley Trautman * * ActivityStreams Types is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/activitystreams-types/src/activity/read.rs b/activitystreams-types/src/activity/read.rs index 56bc05e..ef86fee 100644 --- a/activitystreams-types/src/activity/read.rs +++ b/activitystreams-types/src/activity/read.rs @@ -1,7 +1,7 @@ /* * This file is part of ActivityStreams Types. * - * Copyright © 2018 Riley Trautman + * Copyright © 2020 Riley Trautman * * ActivityStreams Types is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/activitystreams-types/src/activity/reject.rs b/activitystreams-types/src/activity/reject.rs index 993d4f4..3a88844 100644 --- a/activitystreams-types/src/activity/reject.rs +++ b/activitystreams-types/src/activity/reject.rs @@ -1,7 +1,7 @@ /* * This file is part of ActivityStreams Types. * - * Copyright © 2018 Riley Trautman + * Copyright © 2020 Riley Trautman * * ActivityStreams Types is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/activitystreams-types/src/activity/remove.rs b/activitystreams-types/src/activity/remove.rs index d425e0c..c540bf1 100644 --- a/activitystreams-types/src/activity/remove.rs +++ b/activitystreams-types/src/activity/remove.rs @@ -1,7 +1,7 @@ /* * This file is part of ActivityStreams Types. * - * Copyright © 2018 Riley Trautman + * Copyright © 2020 Riley Trautman * * ActivityStreams Types is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/activitystreams-types/src/activity/tentative_accept.rs b/activitystreams-types/src/activity/tentative_accept.rs index a72f66b..b07c682 100644 --- a/activitystreams-types/src/activity/tentative_accept.rs +++ b/activitystreams-types/src/activity/tentative_accept.rs @@ -1,7 +1,7 @@ /* * This file is part of ActivityStreams Types. * - * Copyright © 2018 Riley Trautman + * Copyright © 2020 Riley Trautman * * ActivityStreams Types is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/activitystreams-types/src/activity/tentative_reject.rs b/activitystreams-types/src/activity/tentative_reject.rs index f34fe2e..79c91f2 100644 --- a/activitystreams-types/src/activity/tentative_reject.rs +++ b/activitystreams-types/src/activity/tentative_reject.rs @@ -1,7 +1,7 @@ /* * This file is part of ActivityStreams Types. * - * Copyright © 2018 Riley Trautman + * Copyright © 2020 Riley Trautman * * ActivityStreams Types is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/activitystreams-types/src/activity/travel.rs b/activitystreams-types/src/activity/travel.rs index 32025c5..f1af6b1 100644 --- a/activitystreams-types/src/activity/travel.rs +++ b/activitystreams-types/src/activity/travel.rs @@ -1,7 +1,7 @@ /* * This file is part of ActivityStreams Types. * - * Copyright © 2018 Riley Trautman + * Copyright © 2020 Riley Trautman * * ActivityStreams Types is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/activitystreams-types/src/activity/undo.rs b/activitystreams-types/src/activity/undo.rs index 315ece6..fa03f02 100644 --- a/activitystreams-types/src/activity/undo.rs +++ b/activitystreams-types/src/activity/undo.rs @@ -1,7 +1,7 @@ /* * This file is part of ActivityStreams Types. * - * Copyright © 2018 Riley Trautman + * Copyright © 2020 Riley Trautman * * ActivityStreams Types is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/activitystreams-types/src/activity/update.rs b/activitystreams-types/src/activity/update.rs index 0b09263..22bd69d 100644 --- a/activitystreams-types/src/activity/update.rs +++ b/activitystreams-types/src/activity/update.rs @@ -1,7 +1,7 @@ /* * This file is part of ActivityStreams Types. * - * Copyright © 2018 Riley Trautman + * Copyright © 2020 Riley Trautman * * ActivityStreams Types is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/activitystreams-types/src/activity/view.rs b/activitystreams-types/src/activity/view.rs index 1395e19..75523e2 100644 --- a/activitystreams-types/src/activity/view.rs +++ b/activitystreams-types/src/activity/view.rs @@ -1,7 +1,7 @@ /* * This file is part of ActivityStreams Types. * - * Copyright © 2018 Riley Trautman + * Copyright © 2020 Riley Trautman * * ActivityStreams Types is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/activitystreams-types/src/actor/kind.rs b/activitystreams-types/src/actor/kind.rs index 92b6634..5caaf34 100644 --- a/activitystreams-types/src/actor/kind.rs +++ b/activitystreams-types/src/actor/kind.rs @@ -1,7 +1,7 @@ /* * This file is part of ActivityStreams Types. * - * Copyright © 2018 Riley Trautman + * Copyright © 2020 Riley Trautman * * ActivityStreams Types is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/activitystreams-types/src/actor/mod.rs b/activitystreams-types/src/actor/mod.rs index 27b96b7..6cb2a5b 100644 --- a/activitystreams-types/src/actor/mod.rs +++ b/activitystreams-types/src/actor/mod.rs @@ -1,7 +1,7 @@ /* * This file is part of ActivityStreams Types. * - * Copyright © 2018 Riley Trautman + * Copyright © 2020 Riley Trautman * * ActivityStreams Types is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/activitystreams-types/src/collection/kind.rs b/activitystreams-types/src/collection/kind.rs index 42118ec..033bcc7 100644 --- a/activitystreams-types/src/collection/kind.rs +++ b/activitystreams-types/src/collection/kind.rs @@ -1,7 +1,7 @@ /* * This file is part of ActivityStreams Types. * - * Copyright © 2018 Riley Trautman + * Copyright © 2020 Riley Trautman * * ActivityStreams Types is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/activitystreams-types/src/collection/mod.rs b/activitystreams-types/src/collection/mod.rs index 9b2dec8..0e99ffd 100644 --- a/activitystreams-types/src/collection/mod.rs +++ b/activitystreams-types/src/collection/mod.rs @@ -1,7 +1,7 @@ /* * This file is part of ActivityStreams Types. * - * Copyright © 2018 Riley Trautman + * Copyright © 2020 Riley Trautman * * ActivityStreams Types is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/activitystreams-types/src/collection/properties.rs b/activitystreams-types/src/collection/properties.rs index e0569ad..1a41b96 100644 --- a/activitystreams-types/src/collection/properties.rs +++ b/activitystreams-types/src/collection/properties.rs @@ -1,7 +1,7 @@ /* * This file is part of ActivityStreams Types. * - * Copyright © 2018 Riley Trautman + * Copyright © 2020 Riley Trautman * * ActivityStreams Types is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -22,31 +22,38 @@ //! To use these properties in your own types, you can flatten them into your struct with serde: //! //! ```rust +//! use activitystreams_derive::PropRefs; //! use activitystreams_traits::{Collection, Object}; //! use activitystreams_types::{ -//! collection::properties::CollectionProperties, -//! object::properties::ObjectProperties, +//! collection::{ +//! properties::CollectionProperties, +//! CollectionExt, +//! }, +//! object::{ +//! properties::ObjectProperties, +//! ObjectExt, +//! }, //! }; //! use serde::{Deserialize, Serialize}; +//! use std::any::Any; //! -//! #[derive(Debug, Serialize, Deserialize)] +//! #[derive(Clone, Debug, Serialize, Deserialize, PropRefs)] //! #[serde(rename_all = "camelCase")] //! pub struct MyCollection { //! #[serde(rename = "type")] //! pub kind: String, //! -//! docs("Define a require property for the MyCollection type"), +//! /// Define a require property for the MyCollection type //! pub my_property: String, //! //! #[serde(flatten)] +//! #[activitystreams(Object)] //! pub object_properties: ObjectProperties, //! //! #[serde(flatten)] +//! #[activitystreams(Collection)] //! pub collection_properties: CollectionProperties, //! } -//! -//! impl Object for MyCollection {} -//! impl Collection for MyCollection {} //! # //! # fn main() {} //! ``` diff --git a/activitystreams-types/src/lib.rs b/activitystreams-types/src/lib.rs index 36411fb..0d5232d 100644 --- a/activitystreams-types/src/lib.rs +++ b/activitystreams-types/src/lib.rs @@ -1,7 +1,7 @@ /* * This file is part of ActivityStreams Types. * - * Copyright © 2018 Riley Trautman + * Copyright © 2020 Riley Trautman * * ActivityStreams Types is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -28,7 +28,7 @@ //! fn run() -> Result<(), anyhow::Error> { //! /// A Mention is the only predefined Link type in the Activity Streams spec //! let mut mention = Mention::default(); -//! mention.link_props.set_context_xdg_any_uri(context())?; +//! mention.as_mut().set_context_xsd_any_uri(context())?; //! //! let mention_string = serde_json::to_string(&mention)?; //! diff --git a/activitystreams-types/src/link/kind.rs b/activitystreams-types/src/link/kind.rs index adbcc6b..ff64cb1 100644 --- a/activitystreams-types/src/link/kind.rs +++ b/activitystreams-types/src/link/kind.rs @@ -1,7 +1,7 @@ /* * This file is part of ActivityStreams Types. * - * Copyright © 2018 Riley Trautman + * Copyright © 2020 Riley Trautman * * ActivityStreams Types is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/activitystreams-types/src/link/mod.rs b/activitystreams-types/src/link/mod.rs index 5e22ca6..5646f11 100644 --- a/activitystreams-types/src/link/mod.rs +++ b/activitystreams-types/src/link/mod.rs @@ -1,7 +1,7 @@ /* * This file is part of ActivityStreams Types. * - * Copyright © 2018 Riley Trautman + * Copyright © 2020 Riley Trautman * * ActivityStreams Types is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/activitystreams-types/src/link/properties.rs b/activitystreams-types/src/link/properties.rs index 1e6e557..e564108 100644 --- a/activitystreams-types/src/link/properties.rs +++ b/activitystreams-types/src/link/properties.rs @@ -1,7 +1,7 @@ /* * This file is part of ActivityStreams Types. * - * Copyright © 2018 Riley Trautman + * Copyright © 2020 Riley Trautman * * ActivityStreams Types is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -22,11 +22,13 @@ //! To use these properties in your own types, you can flatten them into your struct with serde: //! //! ```rust +//! use activitystreams_derive::PropRefs; //! use activitystreams_traits::Link; -//! use activitystreams_types::link::properties::LinkProperties; +//! use activitystreams_types::link::{properties::LinkProperties, LinkExt}; //! use serde::{Deserialize, Serialize}; +//! use std::any::Any; //! -//! #[derive(Clone, Debug, Serialize, Deserialize)] +//! #[derive(Clone, Debug, Serialize, Deserialize, PropRefs)] //! #[serde(rename_all = "camelCase")] //! pub struct MyLink { //! #[serde(rename = "type")] @@ -36,10 +38,9 @@ //! pub my_property: String, //! //! #[serde(flatten)] +//! #[activitystreams(Link)] //! pub link_properties: LinkProperties, //! } -//! -//! impl Link for MyLink {} //! # //! # fn main() {} //! ``` diff --git a/activitystreams-types/src/object/kind.rs b/activitystreams-types/src/object/kind.rs index 42ccc03..868ec3d 100644 --- a/activitystreams-types/src/object/kind.rs +++ b/activitystreams-types/src/object/kind.rs @@ -1,7 +1,7 @@ /* * This file is part of ActivityStreams Types. * - * Copyright © 2018 Riley Trautman + * Copyright © 2020 Riley Trautman * * ActivityStreams Types is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/activitystreams-types/src/object/mod.rs b/activitystreams-types/src/object/mod.rs index 68b07fa..770f72a 100644 --- a/activitystreams-types/src/object/mod.rs +++ b/activitystreams-types/src/object/mod.rs @@ -1,7 +1,7 @@ /* * This file is part of ActivityStreams Types. * - * Copyright © 2018 Riley Trautman + * Copyright © 2020 Riley Trautman * * ActivityStreams Types is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/activitystreams-types/src/object/properties.rs b/activitystreams-types/src/object/properties.rs index 8ba8465..e924e3e 100644 --- a/activitystreams-types/src/object/properties.rs +++ b/activitystreams-types/src/object/properties.rs @@ -1,7 +1,7 @@ /* * This file is part of ActivityStreams Types. * - * Copyright © 2018 Riley Trautman + * Copyright © 2020 Riley Trautman * * ActivityStreams Types is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -22,12 +22,13 @@ //! To use these properties in your own types, you can flatten them into your struct with serde: //! //! ```rust +//! use activitystreams_derive::PropRefs; //! use activitystreams_traits::Object; -//! use activitystreams_types::object::properties::ObjectProperties; +//! use activitystreams_types::object::{properties::ObjectProperties, ObjectExt}; //! use serde::{Deserialize, Serialize}; //! use std::any::Any; //! -//! #[derive(Clone, Debug, Serialize, Deserialize)] +//! #[derive(Clone, Debug, Serialize, Deserialize, PropRefs)] //! #[serde(rename_all = "camelCase")] //! pub struct MyObject { //! #[serde(rename = "type")] @@ -37,18 +38,9 @@ //! pub my_property: String, //! //! #[serde(flatten)] +//! #[activitystreams(Object)] //! pub object_properties: ObjectProperties, //! } -//! -//! impl Object for MyObject { -//! fn as_any(&self) -> &dyn Any { -//! self -//! } -//! -//! fn as_any_mut(&mut self) -> &mut dyn Any { -//! self -//! } -//! } //! # //! # fn main() {} //! ``` diff --git a/activitystreams-types/src/primitives/length.rs b/activitystreams-types/src/primitives/length.rs index 8530792..674403a 100644 --- a/activitystreams-types/src/primitives/length.rs +++ b/activitystreams-types/src/primitives/length.rs @@ -1,3 +1,23 @@ +/* + * This file is part of ActivityStreams Types. + * + * Copyright © 2020 Riley Trautman + * + * ActivityStreams Types 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 Types 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 Types. If not, see . + */ + +/// A list of units of length that represent valid units for certain ActivityStreams objects #[derive( Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, serde::Deserialize, serde::Serialize, )] @@ -21,6 +41,7 @@ pub enum Length { #[derive(Clone, Debug, thiserror::Error)] #[error("Could not parse units")] +/// The error type produced when a Length cannot be parsed pub struct LengthError; impl Length { diff --git a/activitystreams-types/src/primitives/mime_media_type.rs b/activitystreams-types/src/primitives/mime_media_type.rs index cdd74df..05c8110 100644 --- a/activitystreams-types/src/primitives/mime_media_type.rs +++ b/activitystreams-types/src/primitives/mime_media_type.rs @@ -1,8 +1,35 @@ +/* + * This file is part of ActivityStreams Types. + * + * Copyright © 2020 Riley Trautman + * + * ActivityStreams Types 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 Types 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 Types. If not, see . + */ + +/// A MIME Media Type consists of a top-level type and a subtype, which is further structured into +/// trees. +/// +/// Optionally, media types can define companion data, known as parameters. +/// +/// See [`RFC 2045`](https://tools.ietf.org/html/rfc2045) and +/// [`RFC 2046`](https://tools.ietf.org/html/rfc2046) for more information. #[derive(Clone, Debug)] pub struct MimeMediaType(mime::Mime); #[derive(Clone, Debug, thiserror::Error)] #[error("Error parsing MIME")] +/// The error type produced when a MimeMediaType cannot be parsed pub struct MimeMediaTypeError; impl From for MimeMediaType { diff --git a/activitystreams-types/src/primitives/mod.rs b/activitystreams-types/src/primitives/mod.rs index f504281..80ec07a 100644 --- a/activitystreams-types/src/primitives/mod.rs +++ b/activitystreams-types/src/primitives/mod.rs @@ -1,3 +1,58 @@ +/* + * This file is part of ActivityStreams Types. + * + * Copyright © 2020 Riley Trautman + * + * ActivityStreams Types 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 Types 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 Types. If not, see . + */ + +//! Types defined as 'primitives' are used as building-blocks for ActivityStreams objects. +//! +//! For example, an `Object` may have a `summary` field, which is defined as a range of +//! `xsd:string` and `rdf:langString`. As code, this is represented as an enum that either +//! contains an `XsdString` or an `RdfLangString`. +//! +//! ```rust +//! use activitystreams_types::primitives::{RdfLangString, XsdString}; +//! +//! /// Define a terminating enum for the Summary field in Object Properties +//! /// +//! /// In this case, terminating means it does not contain child elements. +//! pub enum ObjectPropertiesSummaryTermEnum { +//! XsdString(XsdString), +//! RdfLangString(RdfLangString), +//! } +//! +//! /// Since summary isn't functional, we can either have a single string, or multiple strings. +//! pub enum ObjectPropertiesSummaryEnum { +//! Term(ObjectPropertiesSummaryTermEnum), +//! Array(Vec), +//! } +//! +//! /// Define an excerpt from the ObjectProperties struct +//! pub struct ObjectProperties { +//! // ... +//! +//! /// Since summary isn't a required field, it's stored as an option +//! summary: Option, +//! +//! // ... +//! } +//! # +//! # fn main() {} +//! ``` + mod length; mod mime_media_type; mod rdf_lang_string; diff --git a/activitystreams-types/src/primitives/rdf_lang_string.rs b/activitystreams-types/src/primitives/rdf_lang_string.rs index 5771697..096c82d 100644 --- a/activitystreams-types/src/primitives/rdf_lang_string.rs +++ b/activitystreams-types/src/primitives/rdf_lang_string.rs @@ -1,10 +1,38 @@ +/* + * This file is part of ActivityStreams Types. + * + * Copyright © 2020 Riley Trautman + * + * ActivityStreams Types 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 Types 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 Types. If not, see . + */ + +use crate::primitives::XsdString; + +/// The rdf.langString type extends xs.string, and represents a language tagged string in RDF. #[derive(Clone, Debug, Default, serde::Deserialize, serde::Serialize)] pub struct RdfLangString { + /// The content of the langstring + /// + /// Represented in json as "@value" #[serde(rename = "@value")] - pub value: String, + pub value: XsdString, + /// The language identifier + /// + /// Represented in json as "@language" #[serde(rename = "@language")] - pub language: String, + pub language: XsdString, } impl std::fmt::Display for RdfLangString { diff --git a/activitystreams-types/src/primitives/xsd_any_uri.rs b/activitystreams-types/src/primitives/xsd_any_uri.rs index 5f1d7ef..55ef44e 100644 --- a/activitystreams-types/src/primitives/xsd_any_uri.rs +++ b/activitystreams-types/src/primitives/xsd_any_uri.rs @@ -1,6 +1,59 @@ +/* + * This file is part of ActivityStreams Types. + * + * Copyright © 2020 Riley Trautman + * + * ActivityStreams Types 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 Types 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 Types. If not, see . + */ + +/// The type xsd:anyURI represents a Uniform Resource Identifier (URI) reference. +/// +/// URIs are used to identify resources, and they may be absolute or relative. Absolute URIs +/// provide the entire context for locating the resources, such as http://datypic.com/prod.html. +/// Relative URIs are specified as the difference from a base URI, such as ../prod.html. It is also +/// possible to specify a fragment identifier, using the # character, such as ../prod.html#shirt. +/// +/// The three previous examples happen to be HTTP URLs (Uniform Resource Locators), but URIs also +/// encompass URLs of other schemes (e.g., FTP, gopher, telnet), as well as URNs (Uniform Resource +/// Names). URIs are not required to be dereferencable; that is, it is not necessary for there to +/// be a web page at http://datypic.com/prod.html in order for this to be a valid URI. +/// +/// URIs require that some characters be escaped with their hexadecimal Unicode code point preceded +/// by the % character. This includes non-ASCII characters and some ASCII characters, namely +/// control characters, spaces, and the following characters (unless they are used as deliimiters +/// in the URI): <>#%{}|\^`. For example, ../édition.html must be represented instead as +/// ../%C3%A9dition.html, with the é escaped as %C3%A9. However, the anyURI type will accept these +/// characters either escaped or unescaped. With the exception of the characters % and #, it will +/// assume that unescaped characters are intended to be escaped when used in an actual URI, +/// although the schema processor will do nothing to alter them. It is valid for an anyURI value to +/// contain a space, but this practice is strongly discouraged. Spaces should instead be escaped +/// using %20. +/// +/// The schema processor is not required to parse the contents of an xsd:anyURI value to determine +/// whether it is valid according to any particular URI scheme. Since the bare minimum rules for +/// valid URI references are fairly generic, the schema processor will accept most character +/// strings, including an empty value. The only values that are not accepted are ones that make +/// inappropriate use of reserved characters, such as ones that contain multiple # characters or +/// have % characters that are not followed by two hexadecimal digits. +/// +/// Note that when relative URI references such as "../prod" are used as values of xsd:anyURI, no +/// attempt is made to determine or keep track of the base URI to which they may be applied. For +/// more information on URIs, see RFC 2396, Uniform Resource Identifiers (URI): Generic Syntax. #[derive(Clone, Debug)] pub struct XsdAnyUri(url::Url); +/// The error type produced when an XsdAnyUri cannot be parsed #[derive(Clone, Debug, thiserror::Error)] #[error("Could not parse XsdAnyUri")] pub struct XsdAnyUriError; diff --git a/activitystreams-types/src/primitives/xsd_datetime.rs b/activitystreams-types/src/primitives/xsd_datetime.rs index c89bf75..ce1c475 100644 --- a/activitystreams-types/src/primitives/xsd_datetime.rs +++ b/activitystreams-types/src/primitives/xsd_datetime.rs @@ -1,30 +1,63 @@ -#[derive(Clone, Debug)] -pub struct XsdDateTime(chrono::DateTime); +/* + * This file is part of ActivityStreams Types. + * + * Copyright © 2020 Riley Trautman + * + * ActivityStreams Types 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 Types 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 Types. If not, see . + */ +/// The type xsd:dateTime represents a specific date and time in the format +/// CCYY-MM-DDThh:mm:ss.sss, which is a concatenation of the date and time forms, separated by a +/// literal letter "T". +/// +/// All of the same rules that apply to the date and time types are applicable +/// to xsd:dateTime as well. +/// +/// An optional time zone expression may be added at the end of the value. The letter Z is used to +/// indicate Coordinated Universal Time (UTC). All other time zones are represented by their +/// difference from Coordinated Universal Time in the format +hh:mm, or -hh:mm. These values may +/// range from -14:00 to 14:00. For example, US Eastern Standard Time, which is five hours behind +/// UTC, is represented as -05:00. If no time zone value is present, it is considered unknown; it +/// is not assumed to be UTC. +#[derive(Clone, Debug)] +pub struct XsdDateTime(chrono::DateTime); + +/// The error type produced when an XsdDateTime cannot be parsed #[derive(Clone, Debug, thiserror::Error)] #[error("Error parsing DateTime")] pub struct XsdDateTimeError; -impl From> for XsdDateTime { - fn from(d: chrono::DateTime) -> Self { +impl From> for XsdDateTime { + fn from(d: chrono::DateTime) -> Self { XsdDateTime(d) } } -impl From for chrono::DateTime { +impl From for chrono::DateTime { fn from(d: XsdDateTime) -> Self { d.0 } } -impl AsRef> for XsdDateTime { - fn as_ref(&self) -> &chrono::DateTime { +impl AsRef> for XsdDateTime { + fn as_ref(&self) -> &chrono::DateTime { &self.0 } } -impl AsMut> for XsdDateTime { - fn as_mut(&mut self) -> &mut chrono::DateTime { +impl AsMut> for XsdDateTime { + fn as_mut(&mut self) -> &mut chrono::DateTime { &mut self.0 } } @@ -58,9 +91,7 @@ impl std::str::FromStr for XsdDateTime { fn from_str(s: &str) -> Result { Ok(XsdDateTime( - chrono::DateTime::parse_from_rfc3339(s) - .map_err(|_| XsdDateTimeError)? - .into(), + chrono::DateTime::parse_from_rfc3339(s).map_err(|_| XsdDateTimeError)?, )) } } diff --git a/activitystreams-types/src/primitives/xsd_duration.rs b/activitystreams-types/src/primitives/xsd_duration.rs index 0d4cba3..82b2e75 100644 --- a/activitystreams-types/src/primitives/xsd_duration.rs +++ b/activitystreams-types/src/primitives/xsd_duration.rs @@ -1,6 +1,50 @@ +/* + * This file is part of ActivityStreams Types. + * + * Copyright © 2020 Riley Trautman + * + * ActivityStreams Types 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 Types 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 Types. If not, see . + */ + +/// The type xsd:duration represents a duration of time expressed as a number of years, months, +/// days, hours, minutes, and seconds. +/// +/// The format of xsd:duration is PnYnMnDTnHnMnS, where P is a literal value that starts the +/// expression, nY is the number of years followed by a literal Y, nM is the number of months +/// followed by a literal M, nD is the number of days followed by a literal D, T is a literal value +/// that separates the date and time, nH is the number of hours followed by a literal H, nM is the +/// number of minutes followed by a literal M, and nS is the number of seconds followed by a +/// literal S. The following rules apply to xsd:duration values: +/// +/// - Any of these numbers and corresponding designators may be absent if they are equal to 0, but +/// at least one number and designator must appear. +/// - The numbers may be any unsigned integer, with the exception of the number of seconds, which +/// may be an unsigned decimal number. +/// - If a decimal point appears in the number of seconds, there must be at least one digit after +/// the decimal point. +/// - A minus sign may appear before the P to specify a negative duration. +/// - If no time items (hour, minute, second) are present, the letter T must not appear. +/// +/// ### Note +/// +/// This implementation converts Months to Days by multiplying by 31, and converts Years to days by +/// multiplying by 365. If this is an issue for your application, look into specifying days +/// directly. #[derive(Clone, Debug)] pub struct XsdDuration(chrono::Duration); +/// The error type produced when an XsdDuration cannot be parsed #[derive(Clone, Debug, thiserror::Error)] #[error("Error parsing Duration")] pub struct XsdDurationError; diff --git a/activitystreams-types/src/primitives/xsd_float.rs b/activitystreams-types/src/primitives/xsd_float.rs index 786b0af..b11df11 100644 --- a/activitystreams-types/src/primitives/xsd_float.rs +++ b/activitystreams-types/src/primitives/xsd_float.rs @@ -1,7 +1,40 @@ +/* + * This file is part of ActivityStreams Types. + * + * Copyright © 2020 Riley Trautman + * + * ActivityStreams Types 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 Types 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 Types. If not, see . + */ + +/// The type xsd:float represents an IEEE single-precision 32-bit floating-point number. +/// +/// TODO: handle exponents, infinity, not-a-number +/// +/// The format of xsd:float values is a mantissa (a number which conforms to the type decimal) +/// followed, optionally, by the character "E" or "e" followed by an exponent. The exponent must be +/// an integer. For example, 3E2 represents 3 times 10 to the 2nd power, or 300. The exponent must +/// be an integer. +/// +/// In addition, the following values are valid: INF (infinity), -INF (negative infinity), and NaN +/// (Not a Number). INF is considered to be greater than all other values, while -INF is less than +/// all other values. The value NaN cannot be compared to any other values, although it equals +/// itself. #[derive(Clone, Debug, Default, serde::Deserialize, serde::Serialize)] #[serde(transparent)] pub struct XsdFloat(f64); +/// The error type produced when an XsdFloat cannot be parsed #[derive(Clone, Debug, thiserror::Error)] #[error("Error parsing Float")] pub struct XsdFloatError; diff --git a/activitystreams-types/src/primitives/xsd_non_negative_float.rs b/activitystreams-types/src/primitives/xsd_non_negative_float.rs index b1bd56e..30d75c9 100644 --- a/activitystreams-types/src/primitives/xsd_non_negative_float.rs +++ b/activitystreams-types/src/primitives/xsd_non_negative_float.rs @@ -1,7 +1,42 @@ +/* + * This file is part of ActivityStreams Types. + * + * Copyright © 2020 Riley Trautman + * + * ActivityStreams Types 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 Types 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 Types. If not, see . + */ + +/// The type xsd:float represents an IEEE single-precision 32-bit floating-point number. +/// +/// TODO: handle exponents, infinity, not-a-number +/// +/// The format of xsd:float values is a mantissa (a number which conforms to the type decimal) +/// followed, optionally, by the character "E" or "e" followed by an exponent. The exponent must be +/// an integer. For example, 3E2 represents 3 times 10 to the 2nd power, or 300. The exponent must +/// be an integer. +/// +/// In addition, the following values are valid: INF (infinity), -INF (negative infinity), and NaN +/// (Not a Number). INF is considered to be greater than all other values, while -INF is less than +/// all other values. The value NaN cannot be compared to any other values, although it equals +/// itself. +/// +/// This type also validates that a float is at least 0.0 #[derive(Clone, Debug, Default, serde::Deserialize, serde::Serialize)] #[serde(transparent)] pub struct XsdNonNegativeFloat(f64); +/// The error type produced when an XsdNonNegativeFloat cannot be parsed #[derive(Clone, Debug, thiserror::Error)] #[error("Error parsing NonNegativeFloat")] pub struct XsdNonNegativeFloatError; diff --git a/activitystreams-types/src/primitives/xsd_non_negative_integer.rs b/activitystreams-types/src/primitives/xsd_non_negative_integer.rs index 34cfad0..c2334cb 100644 --- a/activitystreams-types/src/primitives/xsd_non_negative_integer.rs +++ b/activitystreams-types/src/primitives/xsd_non_negative_integer.rs @@ -1,7 +1,31 @@ +/* + * This file is part of ActivityStreams Types. + * + * Copyright © 2020 Riley Trautman + * + * ActivityStreams Types 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 Types 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 Types. If not, see . + */ + +/// The type xsd:nonNegativeInteger represents an arbitrarily large non-negative integer. +/// +/// An xsd:nonNegativeInteger is a sequence of digits, optionally preceded by a + sign. Leading +/// zeros are permitted, but decimal points are not. #[derive(Clone, Debug, Default, serde::Deserialize, serde::Serialize)] #[serde(transparent)] pub struct XsdNonNegativeInteger(u64); +/// The error type produced when an XsdNonNegativeInteger cannot be parsed #[derive(Clone, Debug, thiserror::Error)] #[error("Error parsing NonNegativeInteger")] pub struct XsdNonNegativeIntegerError; diff --git a/activitystreams-types/src/primitives/xsd_string.rs b/activitystreams-types/src/primitives/xsd_string.rs index 16cc16a..43ecd60 100644 --- a/activitystreams-types/src/primitives/xsd_string.rs +++ b/activitystreams-types/src/primitives/xsd_string.rs @@ -1,3 +1,34 @@ +/* + * This file is part of ActivityStreams Types. + * + * Copyright © 2020 Riley Trautman + * + * ActivityStreams Types 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 Types 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 Types. If not, see . + */ + +/// A string type that conforms to the xsd:string specification. +/// +/// TODO: Escape `<` and `&` when converting +/// +/// The type xsd:string represents a character string that may contain any Unicode character +/// allowed by XML. Certain characters, namely the "less than" symbol (<) and the ampersand (&), +/// must be escaped (using the entities < and &, respectively) when used in strings in XML +/// instances. +/// +/// The xsd:string type has a whiteSpace facet of preserve, which means that all whitespace +/// characters (spaces, tabs, carriage returns, and line feeds) are preserved by the processor. +/// This is in contrast to two types derived from it: normalizedString, and token. #[derive(Clone, Debug, Default, serde::Deserialize, serde::Serialize)] #[serde(transparent)] pub struct XsdString(String); diff --git a/src/lib.rs b/src/lib.rs index 6fbea61..0036826 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -26,32 +26,60 @@ //! ### Basic //! //! ```rust -//! use activitystreams::{context, Object, Actor, object::Profile}; -//! use serde_derive::{Deserialize, Serialize}; +//! use activitystreams::{ +//! context, +//! object::{ +//! properties::{ +//! ObjectProperties, +//! ProfileProperties +//! }, +//! Profile, +//! }, +//! primitives::XsdAnyUri, +//! Actor, +//! Object, +//! }; +//! use serde::{Deserialize, Serialize}; +//! use std::any::Any; //! //! #[derive(Clone, Debug, Default, Deserialize, Serialize)] //! #[serde(rename_all = "camelCase")] //! pub struct Persona { //! #[serde(rename = "@context")] -//! context: serde_json::Value, +//! context: XsdAnyUri, //! //! #[serde(rename = "type")] //! kind: String, //! } //! -//! impl Object for Persona {} +//! #[typetag::serde] +//! impl Object for Persona { +//! fn as_any(&self) -> &(dyn Any + 'static) { +//! self +//! } +//! +//! fn as_any_mut(&mut self) -> &mut (dyn Any + 'static) { +//! self +//! } +//! +//! fn duplicate(&self) -> Box { +//! Box::new(self.clone()) +//! } +//! } //! impl Actor for Persona {} //! -//! fn run() -> Result<(), anyhow::Error> { +//! fn main() -> Result<(), anyhow::Error> { //! let mut profile = Profile::default(); //! -//! profile.profile.set_describes_object(Persona { -//! context: serde_json::to_value(context())?, +//! let pprops: &mut ProfileProperties = profile.as_mut(); //! +//! pprops.set_describes_object_box(Persona { +//! context: context(), //! kind: "Persona".to_owned(), //! })?; //! -//! profile.object_props.set_context_object(context())?; +//! let oprops: &mut ObjectProperties = profile.as_mut(); +//! oprops.set_context_xsd_any_uri(context())?; //! //! let profile_string = serde_json::to_string(&profile)?; //! @@ -59,67 +87,82 @@ //! //! Ok(()) //! } -//! # -//! # fn main() { -//! # run().unwrap(); -//! # } //! ``` //! //! ### Advanced //! //! ```rust -//! use activitystreams_derive::{Properties, UnitString}; -//! use activitystreams_traits::{Link, Object}; -//! use activitystreams_types::{CustomLink, link::Mention}; -//! use serde_derive::{Deserialize, Serialize}; +//! use activitystreams::{ +//! properties, +//! link::{ +//! properties::LinkProperties, +//! Mention, +//! }, +//! Link, +//! LinkExt, +//! PropRefs, +//! UnitString, +//! }; +//! use serde::{Deserialize, Serialize}; //! //! /// Using the UnitString derive macro //! /// //! /// This macro implements Serialize and Deserialize for the given type, making this type -//! /// represent the string "SomeKind" in JSON. +//! /// represent the string "MyLink" in JSON. //! #[derive(Clone, Debug, Default, UnitString)] -//! #[activitystreams(SomeKind)] +//! #[activitystreams(MyLink)] //! pub struct MyKind; //! +//! properties! { +//! My { +//! docs [ "Defining our own properties struct called MyProperties" ], +//! +//! required_key { +//! docs [ +//! "Our own required key field", +//! "", +//! "'types' defines the range of values that can be stored in required_key", +//! "", +//! "'functional' means there is at most one value for required_key", +//! "'required' means there is at least one value for required_key", +//! ], +//! types [ String ], +//! functional, +//! required, +//! }, +//! } +//! } +//! //! /// Using the Properties derive macro //! /// //! /// This macro generates getters and setters for the associated fields. -//! #[derive(Clone, Debug, Default, Deserialize, Serialize, Properties)] +//! #[derive(Clone, Debug, Default, Deserialize, Serialize, PropRefs)] //! #[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, -//! -//! /// Use the UnitString MyKind to enforce the type of the object by "SomeKind" +//! pub struct My { +//! /// Use the UnitString MyKind to enforce the type of the object by "MyLink" //! 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. -//! #[activitystreams(concrete(String), functional)] -//! pub required_key: serde_json::Value, +//! /// Derive AsRef/AsMut for My -> MyProperties +//! #[activitystreams(None)] +//! pub my_properties: MyProperties, +//! +//! /// Derive AsRef/AsMut/Link/LinkExt for My -> MyProperties +//! #[activitystreams(Link)] +//! pub link_properties: LinkProperties, //! } //! -//! fn run() -> Result<(), anyhow::Error> { -//! let mut props = MyProperties::default(); +//! fn main() -> Result<(), anyhow::Error> { +//! let mut my_link = My::default(); //! -//! props.set_required_key_string("Hey".to_owned())?; -//! -//! let my_link = CustomLink::new(Mention::default(), props); +//! let lprops: &mut MyProperties = my_link.as_mut(); +//! lprops.set_required_key("Hey")?; //! //! let my_link_string = serde_json::to_string(&my_link)?; //! -//! let my_link: CustomLink = serde_json::from_str(&my_link_string)?; +//! let my_link: My = serde_json::from_str(&my_link_string)?; //! //! Ok(()) //! } -//! # fn main() { -//! # run().unwrap(); -//! # } //! ``` pub mod activity; @@ -136,3 +179,5 @@ pub use self::{ object::{Object, ObjectExt}, }; pub use activitystreams_types::{context, primitives}; + +pub use activitystreams_derive::{properties, PropRefs, UnitString};