This commit is contained in:
asonix 2020-04-25 20:25:02 -05:00
parent 170cae32b8
commit a662004ce1
10 changed files with 131 additions and 136 deletions

View file

@ -1,7 +1,7 @@
[package] [package]
name = "activitystreams" name = "activitystreams"
description = "Activity Streams in Rust" description = "Activity Streams in Rust"
version = "0.5.0" version = "0.6.0"
license = "GPL-3.0" license = "GPL-3.0"
authors = ["asonix <asonix@asonix.dog>"] authors = ["asonix <asonix@asonix.dog>"]
repository = "https://git.asonix.dog/Aardwolf/activitystreams" repository = "https://git.asonix.dog/Aardwolf/activitystreams"
@ -17,7 +17,7 @@ primitives = ["chrono", "mime", "serde", "thiserror", "url"]
types = ["derive", "kinds", "primitives"] types = ["derive", "kinds", "primitives"]
[dependencies] [dependencies]
activitystreams-derive = { version = "0.5.0", path = "activitystreams-derive", optional = true} activitystreams-derive = { version = "0.6.0", path = "activitystreams-derive", optional = true}
chrono = { version = "0.4", optional = true } chrono = { version = "0.4", optional = true }
mime = { version = "0.3", optional = true } mime = { version = "0.3", optional = true }
serde = { version = "1.0", features = ["derive"], optional = true } serde = { version = "1.0", features = ["derive"], optional = true }

View file

@ -9,7 +9,7 @@ __A set of Traits and Types that make up the ActivityStreams and ActivityPub spe
First, add ActivityStreams to your dependencies First, add ActivityStreams to your dependencies
```toml ```toml
activitystreams = "0.5.0" activitystreams = "0.6.0"
``` ```
### Types ### Types
@ -177,7 +177,7 @@ There are a number of features that can be disabled in this crate. By default, e
enabled. enabled.
```toml ```toml
activitystreams = { version = "0.5.0", default-features = "false", features = ["derive"] } activitystreams = { version = "0.6.0", default-features = "false", features = ["derive"] }
``` ```
| feature | what you get | | feature | what you get |

View file

@ -1,7 +1,7 @@
[package] [package]
name = "activitystreams-derive" name = "activitystreams-derive"
description = "Derive macros for activitystreams" description = "Derive macros for activitystreams"
version = "0.5.0" version = "0.6.0"
license = "GPL-3.0" license = "GPL-3.0"
authors = ["asonix <asonix.dev@gmail.com>"] authors = ["asonix <asonix.dev@gmail.com>"]
repository = "https://git.asonix.dog/Aardwolf/activitystreams" repository = "https://git.asonix.dog/Aardwolf/activitystreams"

View file

@ -10,7 +10,7 @@ Add the required crates to your `Cargo.toml`
```toml ```toml
# Cargo.toml # Cargo.toml
activitystreams = "0.5.0" activitystreams = "0.6.0"
serde = { version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }
``` ```

View file

@ -303,7 +303,7 @@ pub fn ref_derive(input: TokenStream) -> TokenStream {
/// where /// where
/// T: Object + serde::ser::Serialize; /// T: Object + serde::ser::Serialize;
/// ///
/// pub fn to_concrete<T>(self) -> Result<T, std::io::Error> /// pub fn into_concrete<T>(self) -> Result<T, std::io::Error>
/// where /// where
/// T: Object + serde::de::DeserializeOwned; /// T: Object + serde::de::DeserializeOwned;
/// ///
@ -344,7 +344,7 @@ pub fn wrapper_type(_: TokenStream, input: TokenStream) -> TokenStream {
/// ///
/// Before this method is called, the type should be verified via the `kind` or /// Before this method is called, the type should be verified via the `kind` or
/// `is_kind` methods /// `is_kind` methods
pub fn to_concrete<T>(self) -> Result<T, std::io::Error> pub fn into_concrete<T>(self) -> Result<T, std::io::Error>
where where
T: #trait_name + serde::de::DeserializeOwned, T: #trait_name + serde::de::DeserializeOwned,
{ {
@ -360,7 +360,7 @@ pub fn wrapper_type(_: TokenStream, input: TokenStream) -> TokenStream {
/// apub::Image, /// apub::Image,
/// }; /// };
/// if my_wrapper_type.is_kind(ImageType) { /// if my_wrapper_type.is_kind(ImageType) {
/// let image = my_wrapper_type.to_concrete::<Image>()?; /// let image = my_wrapper_type.into_concrete::<Image>()?;
/// ... /// ...
/// } /// }
/// ``` /// ```
@ -374,7 +374,7 @@ pub fn wrapper_type(_: TokenStream, input: TokenStream) -> TokenStream {
/// ```ignore /// ```ignore
/// match my_wrapper_type.kind() { /// match my_wrapper_type.kind() {
/// Some("Image") => { /// Some("Image") => {
/// let image = my_wrapper_type.to_concrete::<Image>()?; /// let image = my_wrapper_type.into_concrete::<Image>()?;
/// ... /// ...
/// } /// }
/// _ => ..., /// _ => ...,
@ -500,7 +500,6 @@ pub fn unit_string(input: TokenStream) -> TokenStream {
fn from_value(attr: Attribute) -> Ident { fn from_value(attr: Attribute) -> Ident {
let group = attr let group = attr
.tokens .tokens
.clone()
.into_iter() .into_iter()
.filter_map(|token_tree| match token_tree { .filter_map(|token_tree| match token_tree {
TokenTree::Group(group) => Some(group), TokenTree::Group(group) => Some(group),
@ -511,7 +510,6 @@ fn from_value(attr: Attribute) -> Ident {
group group
.stream() .stream()
.clone()
.into_iter() .into_iter()
.filter_map(|token_tree| match token_tree { .filter_map(|token_tree| match token_tree {
TokenTree::Ident(ident) => Some(ident), TokenTree::Ident(ident) => Some(ident),
@ -521,11 +519,11 @@ fn from_value(attr: Attribute) -> Ident {
.unwrap() .unwrap()
} }
fn to_doc(s: &String) -> proc_macro2::TokenStream { fn to_doc(s: &str) -> proc_macro2::TokenStream {
format!("/// {}", s).parse().unwrap() format!("/// {}", s).parse().unwrap()
} }
fn many_docs(v: &Vec<String>) -> proc_macro2::TokenStream { fn many_docs(v: &[String]) -> proc_macro2::TokenStream {
v.iter() v.iter()
.map(|d| { .map(|d| {
let d = to_doc(d); let d = to_doc(d);
@ -572,9 +570,7 @@ fn many_docs(v: &Vec<String>) -> proc_macro2::TokenStream {
/// } /// }
/// } /// }
/// ///
/// fn main() { /// let _ = HelloProperties::default();
/// let _ = HelloProperties::default();
/// }
/// ``` /// ```
#[proc_macro] #[proc_macro]
pub fn properties(tokens: TokenStream) -> TokenStream { pub fn properties(tokens: TokenStream) -> TokenStream {
@ -598,7 +594,7 @@ pub fn properties(tokens: TokenStream) -> TokenStream {
(ty, None) (ty, None)
} else { } else {
let enum_ty = Ident::new(&camelize(&format!("{}_{}_enum", name, fname)), fname.span()); let enum_ty = Ident::new(&camelize(&format!("{}_{}_enum", name, fname)), fname.span());
let doc_lines = many_docs(&vec![ let doc_lines = many_docs(&[
format!("Variations for the `{}` field from `{}", fname, name), format!("Variations for the `{}` field from `{}", fname, name),
String::new(), String::new(),
format!("`{}` isn't functional, meaning it can be represented as either a single `{}` or a vector of `{}`.", fname, ty, ty), format!("`{}` isn't functional, meaning it can be represented as either a single `{}` or a vector of `{}`.", fname, ty, ty),
@ -668,12 +664,12 @@ pub fn properties(tokens: TokenStream) -> TokenStream {
}) })
.collect(); .collect();
let term_doc_lines = many_docs(&vec![ let term_doc_lines = many_docs(&[
format!("Terminating variations for the `{}` field from `{}`", fname, name), format!("Terminating variations for the `{}` field from `{}`", fname, name),
String::new(), String::new(),
format!("Since {} can be one of multiple types, this enum represents all possibilities of {}", fname, fname), format!("Since {} can be one of multiple types, this enum represents all possibilities of {}", fname, fname),
]); ]);
let doc_lines = many_docs(&vec![ let doc_lines = many_docs(&[
format!("Non-Terminating variations for the `{}` field from `{}`", fname, name), format!("Non-Terminating variations for the `{}` field from `{}`", fname, name),
String::new(), String::new(),
format!("`{}` isn't functional, meaning it can be represented as either a single `{}` or a vector of `{}`", fname, term_ty, term_ty), format!("`{}` isn't functional, meaning it can be represented as either a single `{}` or a vector of `{}`", fname, term_ty, term_ty),
@ -732,7 +728,7 @@ pub fn properties(tokens: TokenStream) -> TokenStream {
}) })
.collect(); .collect();
let doc_lines = many_docs(&vec![ let doc_lines = many_docs(&[
format!("Variations for the `{}` field from `{}`", fname, name), format!("Variations for the `{}` field from `{}`", fname, name),
String::new(), String::new(),
format!("`{}` isn't functional, meaning it can only be represented as a single `{}`", fname, ty), format!("`{}` isn't functional, meaning it can only be represented as a single `{}`", fname, ty),
@ -889,98 +885,96 @@ pub fn properties(tokens: TokenStream) -> TokenStream {
#set_many #set_many
} }
} }
} 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<T>(&mut self, item: T) -> Result<&mut Self, <T as std::convert::TryInto<#v_ty>>::Error>
where
T: std::convert::TryInto<#v_ty>,
{
use std::convert::TryInto;
self.#fname = Some(item.try_into()?);
Ok(self)
}
};
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()
}
};
quote!{
#get
#set
}
} else { } 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 doc_line = to_doc(&format!("Set the `{}` with a type that can be converted into `{}`", fname, v_ty.to_token_stream())); let set = quote! {
let set = quote! { #doc_line
#doc_line pub fn #set_ident<T>(&mut self, item: T) -> Result<&mut Self, <T as std::convert::TryInto<#v_ty>>::Error>
pub fn #set_ident<T>(&mut self, item: T) -> Result<&mut Self, <T as std::convert::TryInto<#v_ty>>::Error> where
where T: std::convert::TryInto<#v_ty>,
T: std::convert::TryInto<#v_ty>, {
{ use std::convert::TryInto;
use std::convert::TryInto; self.#fname = Some(#enum_ty::Term(item.try_into()?));
self.#fname = Some(item.try_into()?); Ok(self)
Ok(self)
}
};
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()
}
};
quote!{
#get
#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<T>(&mut self, item: T) -> Result<&mut Self, <T as std::convert::TryInto<#v_ty>>::Error>
where
T: std::convert::TryInto<#v_ty>,
{
use std::convert::TryInto;
self.#fname = Some(#enum_ty::Term(item.try_into()?));
Ok(self)
}
};
let doc_line = to_doc(&format!("Get `{}` as a `{}`", fname, v_ty.to_token_stream())); let doc_line = to_doc(&format!("Get `{}` as a `{}`", fname, v_ty.to_token_stream()));
let get = quote! { let get = quote! {
#doc_line #doc_line
/// ///
/// This returns `None` if /// This returns `None` if
/// - There is no value present /// - There is no value present
/// - There is more than one value present /// - There is more than one value present
pub fn #get_ident(&self) -> Option<&#v_ty> { pub fn #get_ident(&self) -> Option<&#v_ty> {
match self.#fname { match self.#fname {
Some(#enum_ty::Term(ref term)) => Some(term), Some(#enum_ty::Term(ref term)) => Some(term),
_ => None, _ => None,
}
} }
};
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<T>(&mut self, item: Vec<T>) -> Result<&mut Self, <T as std::convert::TryInto<#v_ty>>::Error>
where
T: std::convert::TryInto<#v_ty>,
{
let item: Vec<#v_ty> = item.into_iter().map(std::convert::TryInto::try_into).collect::<Result<Vec<_>, _>>()?;
self.#fname = Some(#enum_ty::Array(item));
Ok(self)
}
};
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),
_ => None,
}
}
};
quote! {
#get
#set
#get_many
#set_many
} }
};
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<T>(&mut self, item: Vec<T>) -> Result<&mut Self, <T as std::convert::TryInto<#v_ty>>::Error>
where
T: std::convert::TryInto<#v_ty>,
{
let item: Vec<#v_ty> = item.into_iter().map(std::convert::TryInto::try_into).collect::<Result<Vec<_>, _>>()?;
self.#fname = Some(#enum_ty::Array(item));
Ok(self)
}
};
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),
_ => None,
}
}
};
quote! {
#get
#set
#get_many
#set_many
} }
} }
} else if field.description.functional { } else if field.description.functional {
@ -1365,7 +1359,7 @@ impl Parse for Description {
} }
} }
fn parse_kw<T: Peek + Copy, U: Parse>(input: &ParseStream, t: T) -> Result<bool> { fn parse_kw<T: Peek + Copy, U: Parse>(input: ParseStream, t: T) -> Result<bool> {
let lookahead = input.lookahead1(); let lookahead = input.lookahead1();
if lookahead.peek(t) { if lookahead.peek(t) {
input.parse::<U>()?; input.parse::<U>()?;
@ -1377,7 +1371,7 @@ fn parse_kw<T: Peek + Copy, U: Parse>(input: &ParseStream, t: T) -> Result<bool>
Ok(false) Ok(false)
} }
fn parse_string_array<T: Peek + Copy, U: Parse>(input: &ParseStream, t: T) -> Result<Vec<String>> { fn parse_string_array<T: Peek + Copy, U: Parse>(input: ParseStream, t: T) -> Result<Vec<String>> {
let lookahead = input.lookahead1(); let lookahead = input.lookahead1();
if lookahead.peek(t) { if lookahead.peek(t) {
input.parse::<U>()?; input.parse::<U>()?;
@ -1393,7 +1387,7 @@ fn parse_string_array<T: Peek + Copy, U: Parse>(input: &ParseStream, t: T) -> Re
} }
fn parse_string_group<T: Peek + Copy, U: Parse>( fn parse_string_group<T: Peek + Copy, U: Parse>(
input: &ParseStream, input: ParseStream,
t: T, t: T,
) -> Result<Option<String>> { ) -> Result<Option<String>> {
let lookahead = input.lookahead1(); let lookahead = input.lookahead1();
@ -1410,7 +1404,7 @@ fn parse_string_group<T: Peek + Copy, U: Parse>(
Ok(None) Ok(None)
} }
fn optional_comma(input: &ParseStream) -> Result<()> { fn optional_comma(input: ParseStream) -> Result<()> {
let lookahead = input.lookahead1(); let lookahead = input.lookahead1();
if lookahead.peek(Token![,]) { if lookahead.peek(Token![,]) {
input.parse::<Token![,]>()?; input.parse::<Token![,]>()?;

View file

@ -56,7 +56,7 @@ fn main() -> Result<(), Error> {
let v: Vec<Ext<Page, ApObjectProperties>> = cprops let v: Vec<Ext<Page, ApObjectProperties>> = cprops
.get_many_items_base_boxes() .get_many_items_base_boxes()
.unwrap() .unwrap()
.map(|base_box| base_box.clone().to_concrete()) .map(|base_box| base_box.clone().into_concrete())
.collect::<Result<Vec<_>, std::io::Error>>()?; .collect::<Result<Vec<_>, std::io::Error>>()?;
let cprops: &mut CollectionProperties = collection.as_mut(); let cprops: &mut CollectionProperties = collection.as_mut();

View file

@ -90,22 +90,20 @@
//! impl<T> Extension<T> for PublicKeyExtension where T: Actor {} //! impl<T> Extension<T> for PublicKeyExtension where T: Actor {}
//! //!
//! // Now that these types are defined, we can put them to use! //! // Now that these types are defined, we can put them to use!
//! fn main() { //! let person = Person::new();
//! let person = Person::new();
//! //!
//! // let's just create a dummy key for this example //! // let's just create a dummy key for this example
//! let public_key = PublicKey { //! let public_key = PublicKey {
//! id: "My ID".to_owned(), //! id: "My ID".to_owned(),
//! owner: "Owner ID".to_owned(), //! owner: "Owner ID".to_owned(),
//! public_key_pem: "My Public Key".to_owned(), //! public_key_pem: "My Public Key".to_owned(),
//! }; //! };
//! //!
//! // We're doing it! The person is being extended with a public key //! // We're doing it! The person is being extended with a public key
//! // //! //
//! // Note that calling `extend` on person here is possible because the Extensible trait is in //! // Note that calling `extend` on person here is possible because the Extensible trait is in
//! // scope //! // scope
//! let person_with_key = person.extend(public_key.to_ext()); //! let person_with_key = person.extend(public_key.to_ext());
//! }
//! ``` //! ```
use crate::{ use crate::{

View file

@ -64,7 +64,7 @@ impl AnyImage {
serde_json::from_value(serde_json::to_value(t)?) serde_json::from_value(serde_json::to_value(t)?)
} }
pub fn to_concrete<T>(self) -> Result<T, serde_json::Error> pub fn into_concrete<T>(self) -> Result<T, serde_json::Error>
where where
T: Object + serde::de::DeserializeOwned, T: Object + serde::de::DeserializeOwned,
{ {

View file

@ -165,9 +165,9 @@ fn parse_next(s: &str, c: char) -> Result<(i64, &str), XsdDurationError> {
impl std::fmt::Display for XsdDuration { impl std::fmt::Display for XsdDuration {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
let (s, mut duration) = if chrono::Duration::seconds(0) > self.0 { let (s, mut duration) = if chrono::Duration::seconds(0) > self.0 {
(format!("P-"), self.0 * -1) ("P-".to_string(), self.0 * -1)
} else { } else {
(format!("P"), self.0) ("P".to_string(), self.0)
}; };
let s = if duration.num_days() > 0 { let s = if duration.num_days() > 0 {

View file

@ -45,11 +45,6 @@
pub struct XsdString(String); pub struct XsdString(String);
impl XsdString { impl XsdString {
/// Get an XsdString from an &str
pub fn from_str(s: &str) -> Self {
s.into()
}
/// Get an XsdString from a String /// Get an XsdString from a String
pub fn from_string(s: String) -> Self { pub fn from_string(s: String) -> Self {
s.into() s.into()
@ -61,11 +56,19 @@ impl XsdString {
} }
/// Consume the XsdString and get a String /// Consume the XsdString and get a String
pub fn to_string(self) -> String { pub fn into_string(self) -> String {
self.into() self.into()
} }
} }
impl std::str::FromStr for XsdString {
type Err = std::convert::Infallible;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(s.into())
}
}
impl From<String> for XsdString { impl From<String> for XsdString {
fn from(s: String) -> Self { fn from(s: String) -> Self {
XsdString(s) XsdString(s)