mirror of
https://git.asonix.dog/asonix/activitystreams.git
synced 2024-11-25 21:31:00 +00:00
Derive AsRef, AsMut, etc, begin defining primitives
This commit is contained in:
parent
bc4f29988d
commit
d738c5e8fa
14 changed files with 814 additions and 145 deletions
|
@ -70,6 +70,121 @@ use syn::{Attribute, Data, DeriveInput, Fields, Ident, Type};
|
||||||
|
|
||||||
use std::iter::FromIterator;
|
use std::iter::FromIterator;
|
||||||
|
|
||||||
|
#[proc_macro_derive(PropRefs, attributes(activitystreams))]
|
||||||
|
pub fn ref_derive(input: TokenStream) -> TokenStream {
|
||||||
|
let input: DeriveInput = syn::parse(input).unwrap();
|
||||||
|
|
||||||
|
let name = input.ident;
|
||||||
|
|
||||||
|
let data = match input.data {
|
||||||
|
Data::Struct(s) => s,
|
||||||
|
_ => panic!("Can only derive for structs"),
|
||||||
|
};
|
||||||
|
|
||||||
|
let fields = match data.fields {
|
||||||
|
Fields::Named(fields) => fields,
|
||||||
|
_ => panic!("Can only derive for named fields"),
|
||||||
|
};
|
||||||
|
|
||||||
|
let impls = fields
|
||||||
|
.named
|
||||||
|
.iter()
|
||||||
|
.filter_map(|field| {
|
||||||
|
let our_attr = field.attrs.iter().find(|attribute| {
|
||||||
|
attribute
|
||||||
|
.path
|
||||||
|
.segments
|
||||||
|
.last()
|
||||||
|
.map(|segment| {
|
||||||
|
segment.ident == Ident::new("activitystreams", segment.ident.span())
|
||||||
|
})
|
||||||
|
.unwrap_or(false)
|
||||||
|
});
|
||||||
|
|
||||||
|
our_attr.map(move |our_attr| {
|
||||||
|
(
|
||||||
|
field.ident.clone().unwrap(),
|
||||||
|
field.ty.clone(),
|
||||||
|
our_attr.clone(),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.flat_map(move |(ident, ty, attr)| {
|
||||||
|
let object = object(attr);
|
||||||
|
let name = name.clone();
|
||||||
|
let ext_trait = Ident::new(&format!("{}Ext", object), name.span());
|
||||||
|
|
||||||
|
let activity_impls = quote! {
|
||||||
|
impl #object for #name {}
|
||||||
|
|
||||||
|
impl #ext_trait for #name {
|
||||||
|
fn props(&self) -> &#ty {
|
||||||
|
self.as_ref()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn props_mut(&mut self) -> &mut #ty {
|
||||||
|
self.as_mut()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let ref_impls = quote! {
|
||||||
|
impl AsRef<#ty> for #name {
|
||||||
|
fn as_ref(&self) -> &#ty {
|
||||||
|
&self.#ident
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AsMut<#ty> for #name {
|
||||||
|
fn as_mut(&mut self) -> &mut #ty {
|
||||||
|
&mut self.#ident
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if object == "None" {
|
||||||
|
ref_impls
|
||||||
|
} else {
|
||||||
|
quote! {
|
||||||
|
#ref_impls
|
||||||
|
#activity_impls
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let tokens = proc_macro2::TokenStream::from_iter(impls);
|
||||||
|
|
||||||
|
let full = quote! {
|
||||||
|
#tokens
|
||||||
|
};
|
||||||
|
|
||||||
|
full.into()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn object(attr: Attribute) -> Ident {
|
||||||
|
let group = attr
|
||||||
|
.tokens
|
||||||
|
.clone()
|
||||||
|
.into_iter()
|
||||||
|
.filter_map(|token_tree| match token_tree {
|
||||||
|
TokenTree::Group(group) => Some(group),
|
||||||
|
_ => None,
|
||||||
|
})
|
||||||
|
.next()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
group
|
||||||
|
.stream()
|
||||||
|
.clone()
|
||||||
|
.into_iter()
|
||||||
|
.filter_map(|token_tree| match token_tree {
|
||||||
|
TokenTree::Ident(ident) => Some(ident),
|
||||||
|
_ => None,
|
||||||
|
})
|
||||||
|
.next()
|
||||||
|
.unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
#[proc_macro_derive(UnitString, attributes(activitystreams))]
|
#[proc_macro_derive(UnitString, attributes(activitystreams))]
|
||||||
pub fn unit_string(input: TokenStream) -> TokenStream {
|
pub fn unit_string(input: TokenStream) -> TokenStream {
|
||||||
let input: DeriveInput = syn::parse(input).unwrap();
|
let input: DeriveInput = syn::parse(input).unwrap();
|
||||||
|
|
|
@ -10,6 +10,7 @@ keywords = ["activitystreams", "activitypub"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
thiserror = "1.0.11"
|
||||||
activitystreams-derive = { version = "0.2", path = "../activitystreams-derive" }
|
activitystreams-derive = { version = "0.2", path = "../activitystreams-derive" }
|
||||||
activitystreams-traits = { version = "0.2", path = "../activitystreams-traits" }
|
activitystreams-traits = { version = "0.2", path = "../activitystreams-traits" }
|
||||||
chrono = { version = "0.4", features = ["serde"] }
|
chrono = { version = "0.4", features = ["serde"] }
|
||||||
|
|
|
@ -61,5 +61,6 @@ pub mod collection;
|
||||||
mod custom_props;
|
mod custom_props;
|
||||||
pub mod link;
|
pub mod link;
|
||||||
pub mod object;
|
pub mod object;
|
||||||
|
pub mod primitives;
|
||||||
|
|
||||||
pub use self::custom_props::{CustomLink, CustomObject};
|
pub use self::custom_props::{CustomLink, CustomObject};
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
|
|
||||||
//! Namespace for Object types
|
//! Namespace for Object types
|
||||||
|
|
||||||
use activitystreams_derive::Properties;
|
use activitystreams_derive::{PropRefs, Properties};
|
||||||
use activitystreams_traits::Object;
|
use activitystreams_traits::Object;
|
||||||
use serde_derive::{Deserialize, Serialize};
|
use serde_derive::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ pub trait ObjectExt: Object {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Represents any kind of multi-paragraph written work.
|
/// Represents any kind of multi-paragraph written work.
|
||||||
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
|
#[derive(Clone, Debug, Default, Deserialize, PropRefs, Serialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct Article {
|
pub struct Article {
|
||||||
#[serde(rename = "type")]
|
#[serde(rename = "type")]
|
||||||
|
@ -47,22 +47,12 @@ pub struct Article {
|
||||||
|
|
||||||
/// Adds all valid object properties to this struct
|
/// Adds all valid object properties to this struct
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
|
#[activitystreams(Object)]
|
||||||
pub object_props: ObjectProperties,
|
pub object_props: ObjectProperties,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Object for Article {}
|
|
||||||
impl ObjectExt for Article {
|
|
||||||
fn props(&self) -> &ObjectProperties {
|
|
||||||
&self.object_props
|
|
||||||
}
|
|
||||||
|
|
||||||
fn props_mut(&mut self) -> &mut ObjectProperties {
|
|
||||||
&mut self.object_props
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Represents an audio document of any kind.
|
/// Represents an audio document of any kind.
|
||||||
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
|
#[derive(Clone, Debug, Default, Deserialize, PropRefs, Serialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct Audio {
|
pub struct Audio {
|
||||||
#[serde(rename = "type")]
|
#[serde(rename = "type")]
|
||||||
|
@ -72,22 +62,12 @@ pub struct Audio {
|
||||||
|
|
||||||
/// Adds all valid object properties to this struct
|
/// Adds all valid object properties to this struct
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
|
#[activitystreams(Object)]
|
||||||
pub object_props: ObjectProperties,
|
pub object_props: ObjectProperties,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Object for Audio {}
|
|
||||||
impl ObjectExt for Audio {
|
|
||||||
fn props(&self) -> &ObjectProperties {
|
|
||||||
&self.object_props
|
|
||||||
}
|
|
||||||
|
|
||||||
fn props_mut(&mut self) -> &mut ObjectProperties {
|
|
||||||
&mut self.object_props
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Represents a document of any kind.
|
/// Represents a document of any kind.
|
||||||
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
|
#[derive(Clone, Debug, Default, Deserialize, PropRefs, Serialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct Document {
|
pub struct Document {
|
||||||
#[serde(rename = "type")]
|
#[serde(rename = "type")]
|
||||||
|
@ -97,22 +77,12 @@ pub struct Document {
|
||||||
|
|
||||||
/// Adds all valid object properties to this struct
|
/// Adds all valid object properties to this struct
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
|
#[activitystreams(Object)]
|
||||||
pub object_props: ObjectProperties,
|
pub object_props: ObjectProperties,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Object for Document {}
|
|
||||||
impl ObjectExt for Document {
|
|
||||||
fn props(&self) -> &ObjectProperties {
|
|
||||||
&self.object_props
|
|
||||||
}
|
|
||||||
|
|
||||||
fn props_mut(&mut self) -> &mut ObjectProperties {
|
|
||||||
&mut self.object_props
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Represents any kind of event.
|
/// Represents any kind of event.
|
||||||
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
|
#[derive(Clone, Debug, Default, Deserialize, PropRefs, Serialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct Event {
|
pub struct Event {
|
||||||
#[serde(rename = "type")]
|
#[serde(rename = "type")]
|
||||||
|
@ -122,22 +92,12 @@ pub struct Event {
|
||||||
|
|
||||||
/// Adds all valid object properties to this struct
|
/// Adds all valid object properties to this struct
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
|
#[activitystreams(Object)]
|
||||||
pub object_props: ObjectProperties,
|
pub object_props: ObjectProperties,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Object for Event {}
|
|
||||||
impl ObjectExt for Event {
|
|
||||||
fn props(&self) -> &ObjectProperties {
|
|
||||||
&self.object_props
|
|
||||||
}
|
|
||||||
|
|
||||||
fn props_mut(&mut self) -> &mut ObjectProperties {
|
|
||||||
&mut self.object_props
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// An image document of any kind
|
/// An image document of any kind
|
||||||
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
|
#[derive(Clone, Debug, Default, Deserialize, PropRefs, Serialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct Image {
|
pub struct Image {
|
||||||
#[serde(rename = "type")]
|
#[serde(rename = "type")]
|
||||||
|
@ -147,22 +107,12 @@ pub struct Image {
|
||||||
|
|
||||||
/// Adds all valid object properties to this struct
|
/// Adds all valid object properties to this struct
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
|
#[activitystreams(Object)]
|
||||||
pub object_props: ObjectProperties,
|
pub object_props: ObjectProperties,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Object for Image {}
|
|
||||||
impl ObjectExt for Image {
|
|
||||||
fn props(&self) -> &ObjectProperties {
|
|
||||||
&self.object_props
|
|
||||||
}
|
|
||||||
|
|
||||||
fn props_mut(&mut self) -> &mut ObjectProperties {
|
|
||||||
&mut self.object_props
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Represents a short written work typically less than a single paragraph in length.
|
/// Represents a short written work typically less than a single paragraph in length.
|
||||||
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
|
#[derive(Clone, Debug, Default, Deserialize, PropRefs, Serialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct Note {
|
pub struct Note {
|
||||||
#[serde(rename = "type")]
|
#[serde(rename = "type")]
|
||||||
|
@ -172,22 +122,12 @@ pub struct Note {
|
||||||
|
|
||||||
/// Adds all valid object properties to this struct
|
/// Adds all valid object properties to this struct
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
|
#[activitystreams(Object)]
|
||||||
pub object_props: ObjectProperties,
|
pub object_props: ObjectProperties,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Object for Note {}
|
|
||||||
impl ObjectExt for Note {
|
|
||||||
fn props(&self) -> &ObjectProperties {
|
|
||||||
&self.object_props
|
|
||||||
}
|
|
||||||
|
|
||||||
fn props_mut(&mut self) -> &mut ObjectProperties {
|
|
||||||
&mut self.object_props
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Represents a Web Page.
|
/// Represents a Web Page.
|
||||||
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
|
#[derive(Clone, Debug, Default, Deserialize, PropRefs, Serialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct Page {
|
pub struct Page {
|
||||||
#[serde(rename = "type")]
|
#[serde(rename = "type")]
|
||||||
|
@ -197,20 +137,10 @@ pub struct Page {
|
||||||
|
|
||||||
/// Adds all valid object properties to this struct
|
/// Adds all valid object properties to this struct
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
|
#[activitystreams(Object)]
|
||||||
pub object_props: ObjectProperties,
|
pub object_props: ObjectProperties,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Object for Page {}
|
|
||||||
impl ObjectExt for Page {
|
|
||||||
fn props(&self) -> &ObjectProperties {
|
|
||||||
&self.object_props
|
|
||||||
}
|
|
||||||
|
|
||||||
fn props_mut(&mut self) -> &mut ObjectProperties {
|
|
||||||
&mut self.object_props
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Represents a logical or physical location.
|
/// Represents a logical or physical location.
|
||||||
///
|
///
|
||||||
/// The Place object is used to represent both physical and logical locations. While numerous
|
/// The Place object is used to represent both physical and logical locations. While numerous
|
||||||
|
@ -229,7 +159,7 @@ impl ObjectExt for Page {
|
||||||
/// While publishers are not required to use these specific properties and MAY make use of other
|
/// While publishers are not required to use these specific properties and MAY make use of other
|
||||||
/// mechanisms for describing locations, consuming implementations that support the Place object
|
/// mechanisms for describing locations, consuming implementations that support the Place object
|
||||||
/// MUST support the use of these properties.
|
/// MUST support the use of these properties.
|
||||||
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
|
#[derive(Clone, Debug, Default, Deserialize, PropRefs, Serialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct Place {
|
pub struct Place {
|
||||||
#[serde(rename = "type")]
|
#[serde(rename = "type")]
|
||||||
|
@ -239,29 +169,20 @@ pub struct Place {
|
||||||
|
|
||||||
/// Adds all valid object properties to this struct
|
/// Adds all valid object properties to this struct
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
|
#[activitystreams(Object)]
|
||||||
pub object_props: ObjectProperties,
|
pub object_props: ObjectProperties,
|
||||||
|
|
||||||
/// Adds all valid place properties to this struct
|
/// Adds all valid place properties to this struct
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
|
#[activitystreams(None)]
|
||||||
pub place: PlaceProperties,
|
pub place: PlaceProperties,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Object for Place {}
|
|
||||||
impl ObjectExt for Place {
|
|
||||||
fn props(&self) -> &ObjectProperties {
|
|
||||||
&self.object_props
|
|
||||||
}
|
|
||||||
|
|
||||||
fn props_mut(&mut self) -> &mut ObjectProperties {
|
|
||||||
&mut self.object_props
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A Profile is a content object that describes another `Object`, typically used to describe
|
/// A Profile is a content object that describes another `Object`, typically used to describe
|
||||||
/// `Actor` Type objects.
|
/// `Actor` Type objects.
|
||||||
///
|
///
|
||||||
/// The `describes` property is used to reference the object being described by the profile.
|
/// The `describes` property is used to reference the object being described by the profile.
|
||||||
#[derive(Clone, Debug, Default, Deserialize, Serialize, Properties)]
|
#[derive(Clone, Debug, Default, Deserialize, Serialize, PropRefs, Properties)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct Profile {
|
pub struct Profile {
|
||||||
#[serde(rename = "type")]
|
#[serde(rename = "type")]
|
||||||
|
@ -271,24 +192,15 @@ pub struct Profile {
|
||||||
|
|
||||||
/// Adds all valid object properties to this struct
|
/// Adds all valid object properties to this struct
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
|
#[activitystreams(Object)]
|
||||||
pub object_props: ObjectProperties,
|
pub object_props: ObjectProperties,
|
||||||
|
|
||||||
/// Adds all valid profile properties to this struct
|
/// Adds all valid profile properties to this struct
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
|
#[activitystreams(None)]
|
||||||
pub profile: ProfileProperties,
|
pub profile: ProfileProperties,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Object for Profile {}
|
|
||||||
impl ObjectExt for Profile {
|
|
||||||
fn props(&self) -> &ObjectProperties {
|
|
||||||
&self.object_props
|
|
||||||
}
|
|
||||||
|
|
||||||
fn props_mut(&mut self) -> &mut ObjectProperties {
|
|
||||||
&mut self.object_props
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Describes a relationship between two individuals.
|
/// Describes a relationship between two individuals.
|
||||||
///
|
///
|
||||||
/// The subject and object properties are used to identify the connected individuals.
|
/// The subject and object properties are used to identify the connected individuals.
|
||||||
|
@ -303,7 +215,7 @@ impl ObjectExt for Profile {
|
||||||
/// individuals that are directly connected within a person's social graph. Suppose we have a user,
|
/// individuals that are directly connected within a person's social graph. Suppose we have a user,
|
||||||
/// Sally, with direct relationships to users Joe and Jane. Sally follows Joe's updates while Sally
|
/// Sally, with direct relationships to users Joe and Jane. Sally follows Joe's updates while Sally
|
||||||
/// and Jane have a mutual relationship.
|
/// and Jane have a mutual relationship.
|
||||||
#[derive(Clone, Debug, Default, Deserialize, Serialize, Properties)]
|
#[derive(Clone, Debug, Default, Deserialize, Serialize, Properties, PropRefs)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct Relationship {
|
pub struct Relationship {
|
||||||
#[serde(rename = "type")]
|
#[serde(rename = "type")]
|
||||||
|
@ -313,29 +225,20 @@ pub struct Relationship {
|
||||||
|
|
||||||
/// Adds all valid object properties to this struct
|
/// Adds all valid object properties to this struct
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
|
#[activitystreams(Object)]
|
||||||
pub object_props: ObjectProperties,
|
pub object_props: ObjectProperties,
|
||||||
|
|
||||||
/// Adds all valid relationship properties to this struct
|
/// Adds all valid relationship properties to this struct
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
|
#[activitystreams(None)]
|
||||||
pub relationship: RelationshipProperties,
|
pub relationship: RelationshipProperties,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Object for Relationship {}
|
|
||||||
impl ObjectExt for Relationship {
|
|
||||||
fn props(&self) -> &ObjectProperties {
|
|
||||||
&self.object_props
|
|
||||||
}
|
|
||||||
|
|
||||||
fn props_mut(&mut self) -> &mut ObjectProperties {
|
|
||||||
&mut self.object_props
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A Tombstone represents a content object that has been deleted.
|
/// A Tombstone represents a content object that has been deleted.
|
||||||
///
|
///
|
||||||
/// It can be used in Collections to signify that there used to be an object at this position, but
|
/// It can be used in Collections to signify that there used to be an object at this position, but
|
||||||
/// it has been deleted.
|
/// it has been deleted.
|
||||||
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
|
#[derive(Clone, Debug, Default, Deserialize, PropRefs, Serialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct Tombstone {
|
pub struct Tombstone {
|
||||||
#[serde(rename = "type")]
|
#[serde(rename = "type")]
|
||||||
|
@ -345,26 +248,17 @@ pub struct Tombstone {
|
||||||
|
|
||||||
/// Adds all valid object properties to this struct
|
/// Adds all valid object properties to this struct
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
|
#[activitystreams(Object)]
|
||||||
pub object_props: ObjectProperties,
|
pub object_props: ObjectProperties,
|
||||||
|
|
||||||
/// Adds all valid tombstone properties to this struct
|
/// Adds all valid tombstone properties to this struct
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
|
#[activitystreams(None)]
|
||||||
pub tombstone_props: TombstoneProperties,
|
pub tombstone_props: TombstoneProperties,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Object for Tombstone {}
|
|
||||||
impl ObjectExt for Tombstone {
|
|
||||||
fn props(&self) -> &ObjectProperties {
|
|
||||||
&self.object_props
|
|
||||||
}
|
|
||||||
|
|
||||||
fn props_mut(&mut self) -> &mut ObjectProperties {
|
|
||||||
&mut self.object_props
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Represents a video document of any kind.
|
/// Represents a video document of any kind.
|
||||||
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
|
#[derive(Clone, Debug, Default, Deserialize, PropRefs, Serialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct Video {
|
pub struct Video {
|
||||||
#[serde(rename = "type")]
|
#[serde(rename = "type")]
|
||||||
|
@ -374,16 +268,6 @@ pub struct Video {
|
||||||
|
|
||||||
/// Adds all valid object properties to this struct
|
/// Adds all valid object properties to this struct
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
|
#[activitystreams(Object)]
|
||||||
pub object_props: ObjectProperties,
|
pub object_props: ObjectProperties,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Object for Video {}
|
|
||||||
impl ObjectExt for Video {
|
|
||||||
fn props(&self) -> &ObjectProperties {
|
|
||||||
&self.object_props
|
|
||||||
}
|
|
||||||
|
|
||||||
fn props_mut(&mut self) -> &mut ObjectProperties {
|
|
||||||
&mut self.object_props
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
81
activitystreams-types/src/primitives/mime_media_type.rs
Normal file
81
activitystreams-types/src/primitives/mime_media_type.rs
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct MimeMediaType(mime::Mime);
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, thiserror::Error)]
|
||||||
|
#[error("Error parsing MIME")]
|
||||||
|
pub struct MimeMediaTypeError;
|
||||||
|
|
||||||
|
impl From<mime::Mime> for MimeMediaType {
|
||||||
|
fn from(m: mime::Mime) -> Self {
|
||||||
|
MimeMediaType(m)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<MimeMediaType> for mime::Mime {
|
||||||
|
fn from(m: MimeMediaType) -> Self {
|
||||||
|
m.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AsRef<mime::Mime> for MimeMediaType {
|
||||||
|
fn as_ref(&self) -> &mime::Mime {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AsMut<mime::Mime> for MimeMediaType {
|
||||||
|
fn as_mut(&mut self) -> &mut mime::Mime {
|
||||||
|
&mut self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::convert::TryFrom<String> for MimeMediaType {
|
||||||
|
type Error = MimeMediaTypeError;
|
||||||
|
|
||||||
|
fn try_from(s: String) -> Result<Self, Self::Error> {
|
||||||
|
s.parse()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::convert::TryFrom<&str> for MimeMediaType {
|
||||||
|
type Error = MimeMediaTypeError;
|
||||||
|
|
||||||
|
fn try_from(s: &str) -> Result<Self, Self::Error> {
|
||||||
|
s.parse()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::convert::TryFrom<&mut str> for MimeMediaType {
|
||||||
|
type Error = MimeMediaTypeError;
|
||||||
|
|
||||||
|
fn try_from(s: &mut str) -> Result<Self, Self::Error> {
|
||||||
|
s.parse()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::str::FromStr for MimeMediaType {
|
||||||
|
type Err = MimeMediaTypeError;
|
||||||
|
|
||||||
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
|
Ok(MimeMediaType(s.parse().map_err(|_| MimeMediaTypeError)?))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl serde::ser::Serialize for MimeMediaType {
|
||||||
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
|
where
|
||||||
|
S: serde::ser::Serializer,
|
||||||
|
{
|
||||||
|
serializer.serialize_str(&self.0.to_string())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'de> serde::de::Deserialize<'de> for MimeMediaType {
|
||||||
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
|
where
|
||||||
|
D: serde::de::Deserializer<'de>,
|
||||||
|
{
|
||||||
|
let s = String::deserialize(deserializer)?;
|
||||||
|
s.parse().map_err(serde::de::Error::custom)
|
||||||
|
}
|
||||||
|
}
|
21
activitystreams-types/src/primitives/mod.rs
Normal file
21
activitystreams-types/src/primitives/mod.rs
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
mod mime_media_type;
|
||||||
|
mod rdf_lang_string;
|
||||||
|
mod xsd_any_uri;
|
||||||
|
mod xsd_datetime;
|
||||||
|
mod xsd_duration;
|
||||||
|
mod xsd_float;
|
||||||
|
mod xsd_non_negative_float;
|
||||||
|
mod xsd_non_negative_integer;
|
||||||
|
mod xsd_string;
|
||||||
|
|
||||||
|
pub use self::{
|
||||||
|
mime_media_type::{MimeMediaType, MimeMediaTypeError},
|
||||||
|
rdf_lang_string::RDFLangString,
|
||||||
|
xsd_any_uri::{XsdAnyURI, XsdAnyURIError},
|
||||||
|
xsd_datetime::{XsdDateTime, XsdDateTimeError},
|
||||||
|
xsd_duration::{XsdDuration, XsdDurationError},
|
||||||
|
xsd_float::{XsdFloat, XsdFloatError},
|
||||||
|
xsd_non_negative_float::{XsdNonNegativeFloat, XsdNonNegativeFloatError},
|
||||||
|
xsd_non_negative_integer::{XsdNonNegativeInteger, XsdNonNegativeIntegerError},
|
||||||
|
xsd_string::XsdString,
|
||||||
|
};
|
14
activitystreams-types/src/primitives/rdf_lang_string.rs
Normal file
14
activitystreams-types/src/primitives/rdf_lang_string.rs
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
#[derive(Clone, Debug, serde_derive::Deserialize, serde_derive::Serialize)]
|
||||||
|
pub struct RDFLangString {
|
||||||
|
#[serde(rename = "@value")]
|
||||||
|
pub value: String,
|
||||||
|
|
||||||
|
#[serde(rename = "@language")]
|
||||||
|
pub language: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Display for RDFLangString {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
|
write!(f, "{}:{}", self.language, self.value)
|
||||||
|
}
|
||||||
|
}
|
45
activitystreams-types/src/primitives/xsd_any_uri.rs
Normal file
45
activitystreams-types/src/primitives/xsd_any_uri.rs
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
#[derive(Clone, Debug, serde_derive::Deserialize, serde_derive::Serialize)]
|
||||||
|
#[serde(transparent)]
|
||||||
|
pub struct XsdAnyURI(String);
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, thiserror::Error)]
|
||||||
|
#[error("Could not parse XsdAnyURI")]
|
||||||
|
pub struct XsdAnyURIError;
|
||||||
|
|
||||||
|
impl std::convert::TryFrom<String> for XsdAnyURI {
|
||||||
|
type Error = XsdAnyURIError;
|
||||||
|
|
||||||
|
fn try_from(s: String) -> Result<Self, Self::Error> {
|
||||||
|
Ok(XsdAnyURI(s))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::convert::TryFrom<&str> for XsdAnyURI {
|
||||||
|
type Error = XsdAnyURIError;
|
||||||
|
|
||||||
|
fn try_from(s: &str) -> Result<Self, Self::Error> {
|
||||||
|
Ok(XsdAnyURI(s.to_owned()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::convert::TryFrom<&mut str> for XsdAnyURI {
|
||||||
|
type Error = XsdAnyURIError;
|
||||||
|
|
||||||
|
fn try_from(s: &mut str) -> Result<Self, Self::Error> {
|
||||||
|
Ok(XsdAnyURI(s.to_owned()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::str::FromStr for XsdAnyURI {
|
||||||
|
type Err = XsdAnyURIError;
|
||||||
|
|
||||||
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
|
Ok(XsdAnyURI(s.to_owned()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Display for XsdAnyURI {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
|
std::fmt::Display::fmt(&self.0, f)
|
||||||
|
}
|
||||||
|
}
|
92
activitystreams-types/src/primitives/xsd_datetime.rs
Normal file
92
activitystreams-types/src/primitives/xsd_datetime.rs
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct XsdDateTime(chrono::DateTime<chrono::Utc>);
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, thiserror::Error)]
|
||||||
|
#[error("Error parsing DateTime")]
|
||||||
|
pub struct XsdDateTimeError;
|
||||||
|
|
||||||
|
impl From<chrono::DateTime<chrono::Utc>> for XsdDateTime {
|
||||||
|
fn from(d: chrono::DateTime<chrono::Utc>) -> Self {
|
||||||
|
XsdDateTime(d)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<XsdDateTime> for chrono::DateTime<chrono::Utc> {
|
||||||
|
fn from(d: XsdDateTime) -> Self {
|
||||||
|
d.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AsRef<chrono::DateTime<chrono::Utc>> for XsdDateTime {
|
||||||
|
fn as_ref(&self) -> &chrono::DateTime<chrono::Utc> {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AsMut<chrono::DateTime<chrono::Utc>> for XsdDateTime {
|
||||||
|
fn as_mut(&mut self) -> &mut chrono::DateTime<chrono::Utc> {
|
||||||
|
&mut self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::convert::TryFrom<String> for XsdDateTime {
|
||||||
|
type Error = XsdDateTimeError;
|
||||||
|
|
||||||
|
fn try_from(s: String) -> Result<Self, Self::Error> {
|
||||||
|
s.parse()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::convert::TryFrom<&str> for XsdDateTime {
|
||||||
|
type Error = XsdDateTimeError;
|
||||||
|
|
||||||
|
fn try_from(s: &str) -> Result<Self, Self::Error> {
|
||||||
|
s.parse()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::convert::TryFrom<&mut str> for XsdDateTime {
|
||||||
|
type Error = XsdDateTimeError;
|
||||||
|
|
||||||
|
fn try_from(s: &mut str) -> Result<Self, Self::Error> {
|
||||||
|
s.parse()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::str::FromStr for XsdDateTime {
|
||||||
|
type Err = XsdDateTimeError;
|
||||||
|
|
||||||
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
|
Ok(XsdDateTime(
|
||||||
|
chrono::DateTime::parse_from_rfc3339(s)
|
||||||
|
.map_err(|_| XsdDateTimeError)?
|
||||||
|
.into(),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Display for XsdDateTime {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
|
let s = self.0.to_rfc3339();
|
||||||
|
std::fmt::Display::fmt(&s, f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl serde::ser::Serialize for XsdDateTime {
|
||||||
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
|
where
|
||||||
|
S: serde::ser::Serializer,
|
||||||
|
{
|
||||||
|
serializer.serialize_str(&self.to_string())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'de> serde::de::Deserialize<'de> for XsdDateTime {
|
||||||
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
|
where
|
||||||
|
D: serde::de::Deserializer<'de>,
|
||||||
|
{
|
||||||
|
let s = String::deserialize(deserializer)?;
|
||||||
|
s.parse().map_err(serde::de::Error::custom)
|
||||||
|
}
|
||||||
|
}
|
174
activitystreams-types/src/primitives/xsd_duration.rs
Normal file
174
activitystreams-types/src/primitives/xsd_duration.rs
Normal file
|
@ -0,0 +1,174 @@
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct XsdDuration(chrono::Duration);
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, thiserror::Error)]
|
||||||
|
#[error("Error parsing Duration")]
|
||||||
|
pub struct XsdDurationError;
|
||||||
|
|
||||||
|
impl From<chrono::Duration> for XsdDuration {
|
||||||
|
fn from(d: chrono::Duration) -> Self {
|
||||||
|
XsdDuration(d)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<XsdDuration> for chrono::Duration {
|
||||||
|
fn from(d: XsdDuration) -> Self {
|
||||||
|
d.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AsRef<chrono::Duration> for XsdDuration {
|
||||||
|
fn as_ref(&self) -> &chrono::Duration {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AsMut<chrono::Duration> for XsdDuration {
|
||||||
|
fn as_mut(&mut self) -> &mut chrono::Duration {
|
||||||
|
&mut self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::convert::TryFrom<String> for XsdDuration {
|
||||||
|
type Error = XsdDurationError;
|
||||||
|
|
||||||
|
fn try_from(s: String) -> Result<Self, Self::Error> {
|
||||||
|
s.parse()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::convert::TryFrom<&str> for XsdDuration {
|
||||||
|
type Error = XsdDurationError;
|
||||||
|
|
||||||
|
fn try_from(s: &str) -> Result<Self, Self::Error> {
|
||||||
|
s.parse()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::convert::TryFrom<&mut str> for XsdDuration {
|
||||||
|
type Error = XsdDurationError;
|
||||||
|
|
||||||
|
fn try_from(s: &mut str) -> Result<Self, Self::Error> {
|
||||||
|
s.parse()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::str::FromStr for XsdDuration {
|
||||||
|
type Err = XsdDurationError;
|
||||||
|
|
||||||
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
|
if s.find('P') != Some(0) {
|
||||||
|
return Err(XsdDurationError);
|
||||||
|
}
|
||||||
|
|
||||||
|
let s = s.trim_start_matches('P');
|
||||||
|
|
||||||
|
let negative = Some(0) == s.find('-');
|
||||||
|
let s = s.trim_start_matches('-');
|
||||||
|
|
||||||
|
let (large, small) = if let Some(index) = s.find('T') {
|
||||||
|
let (l, s) = s.split_at(index);
|
||||||
|
(l, s.trim_start_matches('T'))
|
||||||
|
} else {
|
||||||
|
(s, "")
|
||||||
|
};
|
||||||
|
|
||||||
|
let (years, large) = parse_next(large, 'Y')?;
|
||||||
|
let (months, large) = parse_next(large, 'M')?;
|
||||||
|
let (days, _) = parse_next(large, 'D')?;
|
||||||
|
|
||||||
|
let (hours, small) = parse_next(small, 'H')?;
|
||||||
|
let (minutes, small) = parse_next(small, 'M')?;
|
||||||
|
let (seconds, _) = parse_next(small, 'S')?;
|
||||||
|
|
||||||
|
let mut duration = chrono::Duration::days(365 * years);
|
||||||
|
duration = duration + chrono::Duration::days(31 * months);
|
||||||
|
duration = duration + chrono::Duration::days(days);
|
||||||
|
duration = duration + chrono::Duration::hours(hours);
|
||||||
|
duration = duration + chrono::Duration::minutes(minutes);
|
||||||
|
duration = duration + chrono::Duration::seconds(seconds);
|
||||||
|
|
||||||
|
duration = if negative { duration * -1 } else { duration };
|
||||||
|
|
||||||
|
Ok(XsdDuration(duration))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_next(s: &str, c: char) -> Result<(i64, &str), XsdDurationError> {
|
||||||
|
let res = if let Some(index) = s.find(c) {
|
||||||
|
let (beginning, end) = s.split_at(index);
|
||||||
|
let i = beginning.parse().map_err(|_| XsdDurationError)?;
|
||||||
|
(i, end.trim_start_matches(c))
|
||||||
|
} else {
|
||||||
|
(0, s)
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(res)
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Display for XsdDuration {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
|
let (s, mut duration) = if chrono::Duration::seconds(0) > self.0 {
|
||||||
|
(format!("P-"), self.0 * -1)
|
||||||
|
} else {
|
||||||
|
(format!("P"), self.0)
|
||||||
|
};
|
||||||
|
|
||||||
|
let s = if duration.num_days() > 0 {
|
||||||
|
format!("{}{}D", s, duration.num_days())
|
||||||
|
} else {
|
||||||
|
s
|
||||||
|
};
|
||||||
|
|
||||||
|
duration = duration - chrono::Duration::days(duration.num_days());
|
||||||
|
|
||||||
|
let s = if duration.num_seconds() > 0 {
|
||||||
|
format!("{}T", s)
|
||||||
|
} else {
|
||||||
|
s
|
||||||
|
};
|
||||||
|
|
||||||
|
let s = if duration.num_hours() > 0 {
|
||||||
|
format!("{}{}H", s, duration.num_hours())
|
||||||
|
} else {
|
||||||
|
s
|
||||||
|
};
|
||||||
|
|
||||||
|
duration = duration - chrono::Duration::hours(duration.num_hours());
|
||||||
|
|
||||||
|
let s = if duration.num_minutes() > 0 {
|
||||||
|
format!("{}{}M", s, duration.num_minutes())
|
||||||
|
} else {
|
||||||
|
s
|
||||||
|
};
|
||||||
|
|
||||||
|
duration = duration - chrono::Duration::minutes(duration.num_minutes());
|
||||||
|
|
||||||
|
let s = if duration.num_seconds() > 0 {
|
||||||
|
format!("{}{}S", s, duration.num_seconds())
|
||||||
|
} else {
|
||||||
|
s
|
||||||
|
};
|
||||||
|
|
||||||
|
std::fmt::Display::fmt(&s, f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl serde::ser::Serialize for XsdDuration {
|
||||||
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
|
where
|
||||||
|
S: serde::ser::Serializer,
|
||||||
|
{
|
||||||
|
serializer.serialize_str(&self.to_string())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'de> serde::de::Deserialize<'de> for XsdDuration {
|
||||||
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
|
where
|
||||||
|
D: serde::de::Deserializer<'de>,
|
||||||
|
{
|
||||||
|
let s = String::deserialize(deserializer)?;
|
||||||
|
s.parse().map_err(serde::de::Error::custom)
|
||||||
|
}
|
||||||
|
}
|
69
activitystreams-types/src/primitives/xsd_float.rs
Normal file
69
activitystreams-types/src/primitives/xsd_float.rs
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
#[derive(Clone, Debug, serde_derive::Deserialize, serde_derive::Serialize)]
|
||||||
|
#[serde(transparent)]
|
||||||
|
pub struct XsdFloat(f64);
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, thiserror::Error)]
|
||||||
|
#[error("Error parsing Float")]
|
||||||
|
pub struct XsdFloatError;
|
||||||
|
|
||||||
|
impl AsRef<f64> for XsdFloat {
|
||||||
|
fn as_ref(&self) -> &f64 {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AsMut<f64> for XsdFloat {
|
||||||
|
fn as_mut(&mut self) -> &mut f64 {
|
||||||
|
&mut self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<f64> for XsdFloat {
|
||||||
|
fn from(f: f64) -> Self {
|
||||||
|
XsdFloat(f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<XsdFloat> for f64 {
|
||||||
|
fn from(f: XsdFloat) -> Self {
|
||||||
|
f.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::convert::TryFrom<String> for XsdFloat {
|
||||||
|
type Error = XsdFloatError;
|
||||||
|
|
||||||
|
fn try_from(s: String) -> Result<Self, Self::Error> {
|
||||||
|
s.parse()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::convert::TryFrom<&str> for XsdFloat {
|
||||||
|
type Error = XsdFloatError;
|
||||||
|
|
||||||
|
fn try_from(s: &str) -> Result<Self, Self::Error> {
|
||||||
|
s.parse()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::convert::TryFrom<&mut str> for XsdFloat {
|
||||||
|
type Error = XsdFloatError;
|
||||||
|
|
||||||
|
fn try_from(s: &mut str) -> Result<Self, Self::Error> {
|
||||||
|
s.parse()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::str::FromStr for XsdFloat {
|
||||||
|
type Err = XsdFloatError;
|
||||||
|
|
||||||
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
|
Ok(XsdFloat(s.parse().map_err(|_| XsdFloatError)?))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Display for XsdFloat {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
|
std::fmt::Display::fmt(&self.0, f)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,73 @@
|
||||||
|
#[derive(Clone, Debug, serde_derive::Deserialize, serde_derive::Serialize)]
|
||||||
|
#[serde(transparent)]
|
||||||
|
pub struct XsdNonNegativeFloat(f64);
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, thiserror::Error)]
|
||||||
|
#[error("Error parsing NonNegativeFloat")]
|
||||||
|
pub struct XsdNonNegativeFloatError;
|
||||||
|
|
||||||
|
impl AsRef<f64> for XsdNonNegativeFloat {
|
||||||
|
fn as_ref(&self) -> &f64 {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<XsdNonNegativeFloat> for f64 {
|
||||||
|
fn from(f: XsdNonNegativeFloat) -> Self {
|
||||||
|
f.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::convert::TryFrom<f64> for XsdNonNegativeFloat {
|
||||||
|
type Error = XsdNonNegativeFloatError;
|
||||||
|
|
||||||
|
fn try_from(f: f64) -> Result<Self, Self::Error> {
|
||||||
|
if f < 0.0 {
|
||||||
|
return Err(XsdNonNegativeFloatError);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(XsdNonNegativeFloat(f))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::convert::TryFrom<String> for XsdNonNegativeFloat {
|
||||||
|
type Error = XsdNonNegativeFloatError;
|
||||||
|
|
||||||
|
fn try_from(s: String) -> Result<Self, Self::Error> {
|
||||||
|
s.parse()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::convert::TryFrom<&str> for XsdNonNegativeFloat {
|
||||||
|
type Error = XsdNonNegativeFloatError;
|
||||||
|
|
||||||
|
fn try_from(s: &str) -> Result<Self, Self::Error> {
|
||||||
|
s.parse()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::convert::TryFrom<&mut str> for XsdNonNegativeFloat {
|
||||||
|
type Error = XsdNonNegativeFloatError;
|
||||||
|
|
||||||
|
fn try_from(s: &mut str) -> Result<Self, Self::Error> {
|
||||||
|
s.parse()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::str::FromStr for XsdNonNegativeFloat {
|
||||||
|
type Err = XsdNonNegativeFloatError;
|
||||||
|
|
||||||
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
|
let f = s.parse().map_err(|_| XsdNonNegativeFloatError)?;
|
||||||
|
if f < 0.0 {
|
||||||
|
return Err(XsdNonNegativeFloatError);
|
||||||
|
}
|
||||||
|
Ok(XsdNonNegativeFloat(f))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Display for XsdNonNegativeFloat {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
|
std::fmt::Display::fmt(&self.0, f)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,66 @@
|
||||||
|
#[derive(Clone, Debug, serde_derive::Deserialize, serde_derive::Serialize)]
|
||||||
|
#[serde(transparent)]
|
||||||
|
pub struct XsdNonNegativeInteger(u64);
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, thiserror::Error)]
|
||||||
|
#[error("Error parsing NonNegativeInteger")]
|
||||||
|
pub struct XsdNonNegativeIntegerError;
|
||||||
|
|
||||||
|
impl AsRef<u64> for XsdNonNegativeInteger {
|
||||||
|
fn as_ref(&self) -> &u64 {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<XsdNonNegativeInteger> for u64 {
|
||||||
|
fn from(i: XsdNonNegativeInteger) -> Self {
|
||||||
|
i.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::convert::TryFrom<u64> for XsdNonNegativeInteger {
|
||||||
|
type Error = XsdNonNegativeIntegerError;
|
||||||
|
|
||||||
|
fn try_from(f: u64) -> Result<Self, Self::Error> {
|
||||||
|
Ok(XsdNonNegativeInteger(f))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::convert::TryFrom<String> for XsdNonNegativeInteger {
|
||||||
|
type Error = XsdNonNegativeIntegerError;
|
||||||
|
|
||||||
|
fn try_from(s: String) -> Result<Self, Self::Error> {
|
||||||
|
s.parse()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::convert::TryFrom<&str> for XsdNonNegativeInteger {
|
||||||
|
type Error = XsdNonNegativeIntegerError;
|
||||||
|
|
||||||
|
fn try_from(s: &str) -> Result<Self, Self::Error> {
|
||||||
|
s.parse()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::convert::TryFrom<&mut str> for XsdNonNegativeInteger {
|
||||||
|
type Error = XsdNonNegativeIntegerError;
|
||||||
|
|
||||||
|
fn try_from(s: &mut str) -> Result<Self, Self::Error> {
|
||||||
|
s.parse()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::str::FromStr for XsdNonNegativeInteger {
|
||||||
|
type Err = XsdNonNegativeIntegerError;
|
||||||
|
|
||||||
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
|
let f = s.parse().map_err(|_| XsdNonNegativeIntegerError)?;
|
||||||
|
Ok(XsdNonNegativeInteger(f))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Display for XsdNonNegativeInteger {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
|
std::fmt::Display::fmt(&self.0, f)
|
||||||
|
}
|
||||||
|
}
|
33
activitystreams-types/src/primitives/xsd_string.rs
Normal file
33
activitystreams-types/src/primitives/xsd_string.rs
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
#[derive(Clone, Debug, serde_derive::Deserialize, serde_derive::Serialize)]
|
||||||
|
#[serde(transparent)]
|
||||||
|
pub struct XsdString(String);
|
||||||
|
|
||||||
|
impl From<String> for XsdString {
|
||||||
|
fn from(s: String) -> Self {
|
||||||
|
XsdString(s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&str> for XsdString {
|
||||||
|
fn from(s: &str) -> Self {
|
||||||
|
XsdString(s.to_owned())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&mut str> for XsdString {
|
||||||
|
fn from(s: &mut str) -> Self {
|
||||||
|
XsdString(s.to_owned())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<XsdString> for String {
|
||||||
|
fn from(s: XsdString) -> Self {
|
||||||
|
s.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Display for XsdString {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
|
std::fmt::Display::fmt(&self.0, f)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue