Add new_none_type methods for creating as constructs with no 'type'

General cleaning
This commit is contained in:
asonix 2020-08-09 18:32:15 -05:00
parent 9becb15580
commit 9a9fd47cb3
8 changed files with 316 additions and 35 deletions

View file

@ -1,4 +1,9 @@
# Unreleased
- Clean up unneeded `.into()` calls
- Remove redundant `into_iter` method on OneOrMany.
- Add `new_none_type` constructors to create activitystreams constructs without setting the `type`
field
- Don't serialize a collection's `items` field if it's `None`
- Rename plural methods
- `src/actor.rs`: set_streams -> set_stream, add_streams -> add_stream
- `src/collections.rs`: set_items -> set_item, add_items -> add_item

View file

@ -1977,6 +1977,30 @@ impl<Kind> Activity<Kind> {
}
}
/// Create a new activity with `None` for it's `kind` property
///
/// This means that no `type` field will be present in serialized JSON
///
/// ```rust
/// # fn main() -> Result<(), anyhow::Error> {
/// use activitystreams::activity::Activity;
///
/// let activity = Activity::<()>::new_none_type();
///
/// let s = serde_json::to_string(&activity)?;
///
/// assert_eq!(s, "{}");
/// # Ok(())
/// # }
/// ```
pub fn new_none_type() -> Self {
Activity {
result: None,
instrument: None,
inner: Object::new_none_type(),
}
}
fn extending(mut inner: Object<Kind>) -> Result<Self, serde_json::Error> {
let result = inner.remove("result")?;
let instrument = inner.remove("instrument")?;
@ -2024,6 +2048,34 @@ impl<Kind> ActorAndObject<Kind> {
}
}
/// Create a new ActorAndObject with `None` for it's `kind` property
///
/// This means that no `type` field will be present in serialized JSON
///
/// ```rust
/// # fn main() -> Result<(), anyhow::Error> {
/// use activitystreams::activity::ActorAndObject;
///
/// let activity = ActorAndObject::<()>::new_none_type(vec![], vec![]);
///
/// let s = serde_json::to_string(&activity)?;
///
/// assert_eq!(s, r#"{"actor":[],"object":[]}"#);
/// # Ok(())
/// # }
/// ```
pub fn new_none_type<T, U>(actor: T, object: U) -> Self
where
T: Into<OneOrMany<AnyBase>>,
U: Into<OneOrMany<AnyBase>>,
{
ActorAndObject {
actor: actor.into(),
object: object.into(),
inner: Activity::new_none_type(),
}
}
/// Deconstruct the ActorAndObject into its parts
///
/// ```rust
@ -2295,6 +2347,36 @@ impl<Kind> ActorAndObjectOptOriginAndTarget<Kind> {
}
}
/// Create a new ActorAndObjectOptOriginAndTarget with `None` for it's `kind` property
///
/// This means that no `type` field will be present in serialized JSON
///
/// ```rust
/// # fn main() -> Result<(), anyhow::Error> {
/// use activitystreams::activity::ActorAndObjectOptOriginAndTarget;
///
/// let activity = ActorAndObjectOptOriginAndTarget::<()>::new_none_type(vec![], vec![]);
///
/// let s = serde_json::to_string(&activity)?;
///
/// assert_eq!(s, r#"{"actor":[],"object":[]}"#);
/// # Ok(())
/// # }
/// ```
pub fn new_none_type<T, U>(actor: T, object: U) -> Self
where
T: Into<OneOrMany<AnyBase>>,
U: Into<OneOrMany<AnyBase>>,
{
ActorAndObjectOptOriginAndTarget {
actor: actor.into(),
object: object.into(),
origin: None,
target: None,
inner: Activity::new_none_type(),
}
}
/// Deconstruct the ActorAndObjectOptOriginAndTarget into its parts
///
/// ```rust
@ -2383,6 +2465,35 @@ impl<Kind> ActorAndObjectOptTarget<Kind> {
}
}
/// Create a new ActorAndObjectOptTarget with `None` for it's `kind` property
///
/// This means that no `type` field will be present in serialized JSON
///
/// ```rust
/// # fn main() -> Result<(), anyhow::Error> {
/// use activitystreams::activity::ActorAndObjectOptTarget;
///
/// let activity = ActorAndObjectOptTarget::<()>::new_none_type(vec![], vec![]);
///
/// let s = serde_json::to_string(&activity)?;
///
/// assert_eq!(s, r#"{"actor":[],"object":[]}"#);
/// # Ok(())
/// # }
/// ```
pub fn new_none_type<T, U>(actor: T, object: U) -> Self
where
T: Into<OneOrMany<AnyBase>>,
U: Into<OneOrMany<AnyBase>>,
{
ActorAndObjectOptTarget {
actor: actor.into(),
object: object.into(),
target: None,
inner: Activity::new_none_type(),
}
}
/// Deconstruct the ActorAndObjectOptTarget into its parts
///
/// ```rust

View file

@ -141,7 +141,7 @@ pub trait ApActorExt<Inner>: AsApActor<Inner> {
/// # }
/// ```
fn set_inbox(&mut self, inbox: Url) -> &mut Self {
self.ap_actor_mut().inbox = inbox.into();
self.ap_actor_mut().inbox = inbox;
self
}
@ -223,7 +223,7 @@ pub trait ApActorExt<Inner>: AsApActor<Inner> {
/// # }
/// ```
fn set_outbox(&mut self, outbox: Url) -> &mut Self {
self.ap_actor_mut().outbox = Some(outbox.into());
self.ap_actor_mut().outbox = Some(outbox);
self
}
@ -344,7 +344,7 @@ pub trait ApActorExt<Inner>: AsApActor<Inner> {
/// # }
/// ```
fn set_following(&mut self, following: Url) -> &mut Self {
self.ap_actor_mut().following = Some(following.into());
self.ap_actor_mut().following = Some(following);
self
}
@ -465,7 +465,7 @@ pub trait ApActorExt<Inner>: AsApActor<Inner> {
/// # }
/// ```
fn set_followers(&mut self, followers: Url) -> &mut Self {
self.ap_actor_mut().followers = Some(followers.into());
self.ap_actor_mut().followers = Some(followers);
self
}
@ -586,7 +586,7 @@ pub trait ApActorExt<Inner>: AsApActor<Inner> {
/// # }
/// ```
fn set_liked(&mut self, liked: Url) -> &mut Self {
self.ap_actor_mut().liked = Some(liked.into());
self.ap_actor_mut().liked = Some(liked);
self
}
@ -773,7 +773,7 @@ pub trait ApActorExt<Inner>: AsApActor<Inner> {
v.add(stream);
v
}
None => vec![stream.into()].into(),
None => vec![stream].into(),
};
self.ap_actor_mut().streams = Some(v);
self
@ -829,10 +829,7 @@ pub trait ApActorExt<Inner>: AsApActor<Inner> {
where
Inner: 'a,
{
self.ap_actor_ref()
.preferred_username
.as_ref()
.map(|pu| pu.as_str())
self.ap_actor_ref().preferred_username.as_deref()
}
/// Set the preferred_username for the current actor
@ -1005,7 +1002,7 @@ pub trait ApActorExt<Inner>: AsApActor<Inner> {
/// # }
/// ```
fn set_endpoints(&mut self, endpoints: Endpoints<Url>) -> &mut Self {
self.ap_actor_mut().endpoints = Some(endpoints.map(|u| u.into()));
self.ap_actor_mut().endpoints = Some(endpoints);
self
}
@ -1254,6 +1251,26 @@ impl<Kind> Actor<Kind> {
{
Actor(Object::new())
}
/// Create a new actor with `None` for it's `kind` property
///
/// This means that no `type` field will be present in serialized JSON
///
/// ```rust
/// # fn main() -> Result<(), anyhow::Error> {
/// use activitystreams::actor::Actor;
///
/// let actor = Actor::<()>::new_none_type();
///
/// let s = serde_json::to_string(&actor)?;
///
/// assert_eq!(s, "{}");
/// # Ok(())
/// # }
/// ```
pub fn new_none_type() -> Self {
Actor(Object::new_none_type())
}
}
impl<Inner> ApActor<Inner> {
@ -1275,7 +1292,7 @@ impl<Inner> ApActor<Inner> {
Inner: markers::Actor,
{
ApActor {
inbox: inbox.into(),
inbox,
outbox: None,
following: None,
followers: None,

View file

@ -345,7 +345,7 @@ pub trait BaseExt<Kind>: AsBase<Kind> {
/// # }
/// ```
fn set_id(&mut self, id: Url) -> &mut Self {
self.base_mut().id = Some(id.into());
self.base_mut().id = Some(id);
self
}
@ -955,6 +955,34 @@ impl<Kind> Base<Kind> {
}
}
/// Create a new base with `None` for it's `kind` property
///
/// This means that no `type` field will be present in serialized JSON
///
/// ```rust
/// # fn main() -> Result<(), anyhow::Error> {
/// use activitystreams::base::Base;
///
/// let base = Base::<()>::new_none_type();
///
/// let s = serde_json::to_string(&base)?;
///
/// assert_eq!(s, "{}");
/// # Ok(())
/// # }
/// ```
pub fn new_none_type() -> Self {
Base {
context: None,
id: None,
kind: None,
name: None,
media_type: None,
preview: None,
unparsed: Default::default(),
}
}
/// Extend the Base into any other ActivityStreams type provided in this crate
///
/// ```rust

View file

@ -843,6 +843,7 @@ pub struct Collection<Kind> {
///
/// - Range: Object | Link | Ordered List of [ Object | Link ]
/// - Functional: false
#[serde(skip_serializing_if = "Option::is_none")]
items: Option<OneOrMany<AnyBase>>,
/// A non-negative integer specifying the total number of objects contained by the logical view
@ -956,6 +957,33 @@ impl<Kind> Collection<Kind> {
}
}
/// Create a new collection with `None` for it's `kind` property
///
/// This means that no `type` field will be present in serialized JSON
///
/// ```rust
/// # fn main() -> Result<(), anyhow::Error> {
/// use activitystreams::collection::Collection;
///
/// let collection = Collection::<()>::new_none_type();
///
/// let s = serde_json::to_string(&collection)?;
///
/// assert_eq!(s, "{}");
/// # Ok(())
/// # }
/// ```
pub fn new_none_type() -> Self {
Collection {
items: None,
total_items: None,
current: None,
first: None,
last: None,
inner: Object::new_none_type(),
}
}
fn extending(mut inner: Object<Kind>) -> Result<Self, serde_json::Error> {
let items = inner.remove("items")?;
let total_items = inner.remove("totalItems")?;
@ -1014,6 +1042,31 @@ impl<Kind> CollectionPage<Kind> {
}
}
/// Create a new collection page with `None` for it's `kind` property
///
/// This means that no `type` field will be present in serialized JSON
///
/// ```rust
/// # fn main() -> Result<(), anyhow::Error> {
/// use activitystreams::collection::CollectionPage;
///
/// let collection_page = CollectionPage::<()>::new_none_type();
///
/// let s = serde_json::to_string(&collection_page)?;
///
/// assert_eq!(s, "{}");
/// # Ok(())
/// # }
/// ```
pub fn new_none_type() -> Self {
CollectionPage {
part_of: None,
next: None,
prev: None,
inner: Collection::new_none_type(),
}
}
fn extending(object: Object<Kind>) -> Result<Self, serde_json::Error> {
let mut inner = Collection::extending(object)?;

View file

@ -147,7 +147,7 @@ pub trait LinkExt<Kind>: AsLink<Kind> {
where
Kind: 'a,
{
self.link_ref().hreflang.as_ref().map(|lr| lr.as_str())
self.link_ref().hreflang.as_deref()
}
/// Set the hreflang for the current object
@ -565,6 +565,33 @@ impl<Kind> Link<Kind> {
}
}
/// Create a new link with `None` for it's `kind` property
///
/// This means that no `type` field will be present in serialized JSON
///
/// ```rust
/// # fn main() -> Result<(), anyhow::Error> {
/// use activitystreams::link::Link;
///
/// let link = Link::<()>::new_none_type();
///
/// let s = serde_json::to_string(&link)?;
///
/// assert_eq!(s, "{}");
/// # Ok(())
/// # }
/// ```
pub fn new_none_type() -> Self {
Link {
href: None,
hreflang: None,
rel: None,
height: None,
width: None,
inner: Base::new_none_type(),
}
}
fn extending(mut inner: Base<Kind>) -> Result<Self, serde_json::Error> {
Ok(Link {
href: inner.remove("href")?,

View file

@ -2840,7 +2840,7 @@ pub trait ApObjectExt<Inner>: AsApObject<Inner> {
/// # }
/// ```
fn set_shares(&mut self, shares: Url) -> &mut Self {
self.ap_object_mut().shares = Some(shares.into());
self.ap_object_mut().shares = Some(shares);
self
}
@ -2913,7 +2913,7 @@ pub trait ApObjectExt<Inner>: AsApObject<Inner> {
/// # }
/// ```
fn set_likes(&mut self, likes: Url) -> &mut Self {
self.ap_object_mut().likes = Some(likes.into());
self.ap_object_mut().likes = Some(likes);
self
}
@ -3120,7 +3120,7 @@ pub trait ApObjectExt<Inner>: AsApObject<Inner> {
v.add(upload_media);
v
}
None => vec![upload_media.into()].into(),
None => vec![upload_media].into(),
};
self.ap_object_mut().upload_media = Some(v);
self
@ -4742,6 +4742,50 @@ impl<Kind> Object<Kind> {
}
}
/// Create a new object with `None` for it's `kind` property
///
/// This means that no `type` field will be present in serialized JSON
///
/// ```rust
/// # fn main() -> Result<(), anyhow::Error> {
/// use activitystreams::object::Object;
///
/// let object = Object::<()>::new_none_type();
///
/// let s = serde_json::to_string(&object)?;
///
/// assert_eq!(s, "{}");
/// # Ok(())
/// # }
/// ```
pub fn new_none_type() -> Self {
Object {
attachment: None,
attributed_to: None,
audience: None,
content: None,
summary: None,
url: None,
generator: None,
icon: None,
image: None,
location: None,
tag: None,
start_time: None,
end_time: None,
duration: None,
published: None,
updated: None,
in_reply_to: None,
replies: None,
to: None,
bto: None,
cc: None,
bcc: None,
inner: Base::new_none_type(),
}
}
fn extending(mut base: Base<Kind>) -> Result<Self, serde_json::Error> {
Ok(Object {
attachment: base.remove("attachment")?,

View file

@ -46,7 +46,7 @@ impl<T> OneOrMany<T> {
/// println!("{}", item);
/// }
/// ```
pub fn iter<'a>(&'a self) -> Iter<'a, T> {
pub fn iter(&self) -> Iter<'_, T> {
match self.0 {
Either::Left(ref t) => Iter(Either::Left(Some(t))),
Either::Right(ref v) => Iter(Either::Right(v.iter())),
@ -64,28 +64,13 @@ impl<T> OneOrMany<T> {
/// item.push_str("hey");
/// }
/// ```
pub fn iter_mut<'a>(&'a mut self) -> IterMut<'a, T> {
pub fn iter_mut(&mut self) -> IterMut<'_, T> {
match self.0 {
Either::Left(ref mut t) => IterMut(Either::Left(Some(t))),
Either::Right(ref mut v) => IterMut(Either::Right(v.iter_mut())),
}
}
/// Construct an iterator over the OneOrMany's contents, consuming the OneOrMany
///
/// ```rust
/// use activitystreams::primitives::OneOrMany;
///
/// let value = OneOrMany::from_one(String::from("hi"));
/// let vec = value.into_iter().map(|s| s + "hello").collect::<Vec<_>>();
/// ```
pub fn into_iter(self) -> IntoIter<T> {
match self.0 {
Either::Left(t) => IntoIter(Either::Left(Some(t))),
Either::Right(v) => IntoIter(Either::Right(v.into_iter())),
}
}
/// Create a OneOrMany referencing the existing one
///
/// ```rust
@ -346,8 +331,19 @@ impl<T> IntoIterator for OneOrMany<T> {
type Item = T;
type IntoIter = IntoIter<T>;
/// Construct an iterator over the OneOrMany's contents, consuming the OneOrMany
///
/// ```rust
/// use activitystreams::primitives::OneOrMany;
///
/// let value = OneOrMany::from_one(String::from("hi"));
/// let vec = value.into_iter().map(|s| s + "hello").collect::<Vec<_>>();
/// ```
fn into_iter(self) -> Self::IntoIter {
OneOrMany::into_iter(self)
match self.0 {
Either::Left(t) => IntoIter(Either::Left(Some(t))),
Either::Right(v) => IntoIter(Either::Right(v.into_iter())),
}
}
}