Add as_slice(), rename unwrap_to_vec() to into_vec()

This commit is contained in:
Aode (lion) 2021-11-17 19:20:56 -06:00
parent efc9cf2362
commit 47efc1c646
4 changed files with 105 additions and 27 deletions

View file

@ -1,7 +1,7 @@
[package]
name = "activitystreams"
description = "A set of core types and traits for activitystreams data"
version = "0.7.0-alpha.11"
version = "0.7.0-alpha.12"
license = "GPL-3.0"
authors = ["asonix <asonix@asonix.dog>"]
repository = "https://git.asonix.dog/Aardwolf/activitystreams"

View file

@ -1754,7 +1754,7 @@ impl OneOrMany<AnyBase> {
/// # }
/// ```
pub fn from_xsd_any_uri(id: Url) -> Self {
OneOrMany(Either::Left(AnyBase::from_xsd_any_uri(id)))
OneOrMany(Either::Left([AnyBase::from_xsd_any_uri(id)]))
}
/// Create a `OneOrMany<AnyBase>` from a String
@ -1765,7 +1765,7 @@ impl OneOrMany<AnyBase> {
/// let one = OneOrMany::<AnyBase>::from_xsd_string("hi".into());
/// ```
pub fn from_xsd_string(xsd_string: String) -> Self {
OneOrMany(Either::Left(AnyBase::from_xsd_string(xsd_string)))
OneOrMany(Either::Left([AnyBase::from_xsd_string(xsd_string)]))
}
/// Create a `OneOrMany<AnyBase>` from a `Base<serde_json::Value>`
@ -1779,7 +1779,7 @@ impl OneOrMany<AnyBase> {
/// let one = OneOrMany::from_base(base);
/// ```
pub fn from_base(base: Base<serde_json::Value>) -> Self {
OneOrMany(Either::Left(AnyBase::from_base(base)))
OneOrMany(Either::Left([AnyBase::from_base(base)]))
}
/// Overwrite the current object with a Url
@ -1795,7 +1795,7 @@ impl OneOrMany<AnyBase> {
/// assert!(one.as_single_xsd_any_uri().is_some());
/// ```
pub fn set_single_xsd_any_uri(&mut self, id: Url) -> &mut Self {
self.0 = Either::Left(AnyBase::from_xsd_any_uri(id));
self.0 = Either::Left([AnyBase::from_xsd_any_uri(id)]);
self
}
@ -1812,7 +1812,7 @@ impl OneOrMany<AnyBase> {
/// assert!(one.as_single_xsd_string().is_some());
/// ```
pub fn set_single_xsd_string(&mut self, xsd_string: String) -> &mut Self {
self.0 = Either::Left(AnyBase::from_xsd_string(xsd_string));
self.0 = Either::Left([AnyBase::from_xsd_string(xsd_string)]);
self
}
@ -1829,7 +1829,7 @@ impl OneOrMany<AnyBase> {
/// assert!(one.as_single_base().is_some());
/// ```
pub fn set_single_base(&mut self, base: Base<serde_json::Value>) -> &mut Self {
self.0 = Either::Left(AnyBase::from_base(base));
self.0 = Either::Left([AnyBase::from_base(base)]);
self
}

View file

@ -358,7 +358,7 @@ impl OneOrMany<&AnyString> {
/// ```
pub fn to_owned(self) -> OneOrMany<AnyString> {
match self.0 {
Either::Left(one_ref) => OneOrMany(Either::Left(one_ref.to_owned())),
Either::Left([one_ref]) => OneOrMany(Either::Left([one_ref.to_owned()])),
Either::Right(many_ref) => {
OneOrMany(Either::Right(many_ref.into_iter().cloned().collect()))
}

View file

@ -18,9 +18,8 @@ use crate::either::Either;
/// "key": [value, ...]
/// }
/// ```
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
#[serde(transparent)]
pub struct OneOrMany<T>(pub(crate) Either<T, Vec<T>>);
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct OneOrMany<T>(pub(crate) Either<[T; 1], Vec<T>>);
/// An iterator over a OneOrMany's borrowed contents
#[derive(Clone, Debug)]
@ -48,7 +47,7 @@ impl<T> OneOrMany<T> {
/// ```
pub fn iter(&self) -> Iter<'_, T> {
match self.0 {
Either::Left(ref t) => Iter(Either::Left(Some(t))),
Either::Left([ref t]) => Iter(Either::Left(Some(t))),
Either::Right(ref v) => Iter(Either::Right(v.iter())),
}
}
@ -66,7 +65,7 @@ impl<T> OneOrMany<T> {
/// ```
pub fn iter_mut(&mut self) -> IterMut<'_, T> {
match self.0 {
Either::Left(ref mut t) => IterMut(Either::Left(Some(t))),
Either::Left([ref mut t]) => IterMut(Either::Left(Some(t))),
Either::Right(ref mut v) => IterMut(Either::Right(v.iter_mut())),
}
}
@ -82,7 +81,7 @@ impl<T> OneOrMany<T> {
/// assert_eq!(value_ref.one(), Some(&String::from("hi")));
/// ```
pub fn as_ref(&self) -> OneOrMany<&T> {
OneOrMany(self.0.as_ref().map(|l| l, |r| r.iter().collect()))
OneOrMany(self.0.as_ref().map(|[l]| [l], |r| r.iter().collect()))
}
/// Map the value inside the OneOrMany from T to U
@ -99,7 +98,7 @@ impl<T> OneOrMany<T> {
where
F: Fn(T) -> U + Copy,
{
OneOrMany(self.0.map(f, |v| v.into_iter().map(f).collect()))
OneOrMany(self.0.map(|[l]| [f(l)], |v| v.into_iter().map(f).collect()))
}
/// Create a OneOrMany mutably referencing the existing one
@ -111,7 +110,7 @@ impl<T> OneOrMany<T> {
/// let value_mut = value.as_mut();
/// ```
pub fn as_mut(&mut self) -> OneOrMany<&mut T> {
OneOrMany(self.0.as_mut().map(|l| l, |r| r.iter_mut().collect()))
OneOrMany(self.0.as_mut().map(|[l]| [l], |r| r.iter_mut().collect()))
}
/// Get a reference to a single value
@ -124,7 +123,7 @@ impl<T> OneOrMany<T> {
/// }
/// ```
pub fn as_one(&self) -> Option<&T> {
self.0.as_ref().left()
self.0.as_ref().left().map(|[t]| t)
}
/// Borrow one as mutable
@ -141,7 +140,7 @@ impl<T> OneOrMany<T> {
/// assert_eq!(value.one(), Some(2));
/// ```
pub fn one_mut(&mut self) -> Option<&mut T> {
self.0.as_mut().left()
self.0.as_mut().left().map(|[t]| t)
}
/// Take a single value
@ -154,7 +153,7 @@ impl<T> OneOrMany<T> {
/// }
/// ```
pub fn one(self) -> Option<T> {
self.0.left()
self.0.left().map(|[t]| t)
}
/// Get a slice of values
@ -211,17 +210,33 @@ impl<T> OneOrMany<T> {
/// ```rust
/// # use activitystreams::primitives::OneOrMany;
/// # let value = OneOrMany::from_many(vec![1, 2, 3]);
/// for item in value.unwrap_to_vec() {
/// for item in value.into_vec() {
/// println!("{:?}", item);
/// }
/// ```
pub fn unwrap_to_vec(self) -> Vec<T> {
pub fn into_vec(self) -> Vec<T> {
match self.0 {
Either::Left(t) => vec![t],
Either::Left(t) => t.into(),
Either::Right(v) => v,
}
}
/// Return a slice of values contained by the OneOrMany
///
/// ```rust
/// # use activitystreams::primitives::OneOrMany;
/// # let value = OneOrMany::from_many(vec![1, 2, 3]);
/// for item in value.as_slice() {
/// println!("{:?}", item)
/// }
/// ```
pub fn as_slice(&self) -> &[T] {
match self.0 {
Either::Left(ref t) => t,
Either::Right(ref v) => v,
}
}
/// Produce a new object from one value
///
/// ```
@ -229,7 +244,7 @@ impl<T> OneOrMany<T> {
/// let v = OneOrMany::from_one(1234);
/// ```
pub fn from_one(t: T) -> Self {
OneOrMany(Either::Left(t))
OneOrMany(Either::Left([t]))
}
/// Produce a new object from a vec of values
@ -255,7 +270,7 @@ impl<T> OneOrMany<T> {
where
U: Into<T>,
{
self.0 = Either::Left(u.into());
self.0 = Either::Left([u.into()]);
self
}
@ -293,7 +308,7 @@ impl<T> OneOrMany<T> {
U: Into<T>,
{
let mut v = match std::mem::replace(&mut self.0, Either::Right(vec![])) {
Either::Left(one) => vec![one],
Either::Left(one) => one.into(),
Either::Right(v) => v,
};
v.push(u.into());
@ -318,7 +333,7 @@ impl<T> OneOrMany<T> {
U: Into<T>,
{
let mut v = match std::mem::replace(&mut self.0, Either::Right(vec![])) {
Either::Left(one) => vec![one],
Either::Left(one) => one.into(),
Either::Right(v) => v,
};
v.extend(items.into_iter().map(Into::into));
@ -341,7 +356,7 @@ impl<T> IntoIterator for OneOrMany<T> {
/// ```
fn into_iter(self) -> Self::IntoIter {
match self.0 {
Either::Left(t) => IntoIter(Either::Left(Some(t))),
Either::Left([t]) => IntoIter(Either::Left(Some(t))),
Either::Right(v) => IntoIter(Either::Right(v.into_iter())),
}
}
@ -557,10 +572,73 @@ impl<T> From<Vec<T>> for OneOrMany<T> {
}
}
impl<'de, T> serde::de::Deserialize<'de> for OneOrMany<T>
where
T: serde::de::Deserialize<'de>,
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
#[derive(serde::Deserialize)]
struct OneOrManyInner<T>(Either<T, Vec<T>>);
OneOrManyInner::deserialize(deserializer).map(|inner| match inner.0 {
Either::Left(one) => OneOrMany(Either::Left([one])),
Either::Right(vec) => OneOrMany(Either::Right(vec)),
})
}
}
impl<T> serde::Serialize for OneOrMany<T>
where
T: serde::ser::Serialize,
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
#[derive(serde::Serialize)]
struct OneOrManyInner<'a, T>(Either<&'a T, &'a [T]>);
let to_ser = match self.0 {
Either::Left([ref one]) => OneOrManyInner(Either::Left(one)),
Either::Right(ref v) => OneOrManyInner(Either::Right(v)),
};
to_ser.serialize(serializer)
}
}
#[cfg(test)]
mod tests {
use super::OneOrMany;
#[test]
fn ser_de() {
#[derive(Debug, PartialEq, Eq, serde::Deserialize, serde::Serialize)]
struct Hi {
inner: OneOrMany<String>,
}
let h1 = Hi {
inner: OneOrMany::from_one(String::from("hello")),
};
let s = serde_json::to_string(&h1).unwrap();
assert_eq!(s, r#"{"inner":"hello"}"#);
let h2: Hi = serde_json::from_str(&s).unwrap();
assert_eq!(h2, h1);
let h1 = Hi {
inner: OneOrMany::from_many(vec![String::from("hello"), String::from("hi")]),
};
let s = serde_json::to_string(&h1).unwrap();
assert_eq!(s, r#"{"inner":["hello","hi"]}"#);
let h2: Hi = serde_json::from_str(&s).unwrap();
assert_eq!(h2, h1);
}
#[test]
fn iter_works() {
let single = OneOrMany::from_one(1);