Skip to content

Commit 677b67f

Browse files
authored
Merge pull request #30 from alecmocatta/sc
Add convenience traits for serde_closure::traits::*
2 parents 3a739ec + 57f3136 commit 677b67f

File tree

6 files changed

+194
-20
lines changed

6 files changed

+194
-20
lines changed

Cargo.toml

+5-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "serde_traitobject"
3-
version = "0.2.6"
3+
version = "0.2.7"
44
license = "MIT OR Apache-2.0"
55
authors = ["Alec Mocatta <[email protected]>"]
66
categories = ["development-tools","encoding","rust-patterns","network-programming"]
@@ -12,7 +12,7 @@ This library enables the serialization and deserialization of trait objects such
1212
"""
1313
repository = "https://github.com/alecmocatta/serde_traitobject"
1414
homepage = "https://github.com/alecmocatta/serde_traitobject"
15-
documentation = "https://docs.rs/serde_traitobject/0.2.6"
15+
documentation = "https://docs.rs/serde_traitobject"
1616
readme = "README.md"
1717
edition = "2018"
1818

@@ -25,12 +25,13 @@ serde = "1.0"
2525
erased-serde = "0.3"
2626
metatype = "0.2"
2727
relative = "0.2"
28+
serde_closure = { version = "0.3", optional = true }
2829

2930
[dev-dependencies]
31+
bincode = "1.0"
32+
serde_closure = "0.3"
3033
serde_derive = "1.0"
3134
serde_json = "1.0"
32-
bincode = "1.0"
33-
serde_closure = "0.2.2"
3435
wasm-bindgen-test = "0.3"
3536

3637
[[test]]

README.md

+5-5
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@
44
[![MIT / Apache 2.0 licensed](https://img.shields.io/crates/l/serde_traitobject.svg?maxAge=2592000)](#License)
55
[![Build Status](https://dev.azure.com/alecmocatta/serde_traitobject/_apis/build/status/tests?branchName=master)](https://dev.azure.com/alecmocatta/serde_traitobject/_build?definitionId=9)
66

7-
[📖 Docs](https://docs.rs/serde_traitobject/0.2.6/serde_traitobject/) | [💬 Chat](https://constellation.zulipchat.com/#narrow/stream/213236-subprojects)
7+
[📖 Docs](https://docs.rs/serde_traitobject) | [💬 Chat](https://constellation.zulipchat.com/#narrow/stream/213236-subprojects)
88

99
**Serializable and deserializable trait objects.**
1010

1111
This library enables the serialization and deserialization of trait objects so they can be sent between other processes running the same binary.
1212

1313
For example, if you have multiple forks of a process, or the same binary running on each of a cluster of machines, this library lets you send trait objects between them.
1414

15-
Any trait can be made (de)serializable when made into a trait object by adding this crate's [Serialize](https://docs.rs/serde_traitobject/0.2.6/serde_traitobject/trait.Serialize.html) and [Deserialize](https://docs.rs/serde_traitobject/0.2.6/serde_traitobject/trait.Deserialize.html) traits as supertraits:
15+
Any trait can be made (de)serializable when made into a trait object by adding this crate's [Serialize](https://docs.rs/serde_traitobject/0.2/serde_traitobject/trait.Serialize.html) and [Deserialize](https://docs.rs/serde_traitobject/0.2/serde_traitobject/trait.Deserialize.html) traits as supertraits:
1616

1717
```rust
1818
trait MyTrait: serde_traitobject::Serialize + serde_traitobject::Deserialize {
@@ -31,12 +31,12 @@ struct Message {
3131
And that's it! The two traits are automatically implemented for all `T: serde::Serialize` and all `T: serde::de::DeserializeOwned`, so as long as all implementors of your trait are themselves serializable then you're good to go.
3232

3333
There are two ways to (de)serialize your trait object:
34-
* Apply the `#[serde(with = "serde_traitobject")]` [field attribute](https://serde.rs/attributes.html), which instructs serde to use this crate's [serialize](https://docs.rs/serde_traitobject/0.2.6/serde_traitobject/fn.serialize.html) and [deserialize](https://docs.rs/serde_traitobject/0.2.6/serde_traitobject/fn.deserialize.html) functions;
35-
* The [Box](https://docs.rs/serde_traitobject/0.2.6/serde_traitobject/struct.Box.html), [Rc](https://docs.rs/serde_traitobject/0.2.6/serde_traitobject/struct.Rc.html) and [Arc](https://docs.rs/serde_traitobject/0.2.6/serde_traitobject/struct.Arc.html) structs, which are simple wrappers around their stdlib counterparts that automatically handle (de)serialization without needing the above annotation;
34+
* Apply the `#[serde(with = "serde_traitobject")]` [field attribute](https://serde.rs/attributes.html), which instructs serde to use this crate's [serialize](https://docs.rs/serde_traitobject/0.2/serde_traitobject/fn.serialize.html) and [deserialize](https://docs.rs/serde_traitobject/0.2/serde_traitobject/fn.deserialize.html) functions;
35+
* The [Box](https://docs.rs/serde_traitobject/0.2/serde_traitobject/struct.Box.html), [Rc](https://docs.rs/serde_traitobject/0.2/serde_traitobject/struct.Rc.html) and [Arc](https://docs.rs/serde_traitobject/0.2/serde_traitobject/struct.Arc.html) structs, which are simple wrappers around their stdlib counterparts that automatically handle (de)serialization without needing the above annotation;
3636

3737
Additionally, there are several convenience traits implemented that extend their stdlib counterparts:
3838

39-
* [Any](https://docs.rs/serde_traitobject/0.2.6/serde_traitobject/trait.Any.html), [Debug](https://docs.rs/serde_traitobject/0.2.6/serde_traitobject/trait.Debug.html), [Display](https://docs.rs/serde_traitobject/0.2.6/serde_traitobject/trait.Display.html), [Error](https://docs.rs/serde_traitobject/0.2.6/serde_traitobject/trait.Error.html), [Fn](https://docs.rs/serde_traitobject/0.2.6/serde_traitobject/trait.Fn.html), [FnMut](https://docs.rs/serde_traitobject/0.2.6/serde_traitobject/trait.FnMut.html), [FnOnce](https://docs.rs/serde_traitobject/0.2.6/serde_traitobject/trait.FnOnce.html)
39+
* [Any](https://docs.rs/serde_traitobject/0.2/serde_traitobject/trait.Any.html), [Debug](https://docs.rs/serde_traitobject/0.2/serde_traitobject/trait.Debug.html), [Display](https://docs.rs/serde_traitobject/0.2/serde_traitobject/trait.Display.html), [Error](https://docs.rs/serde_traitobject/0.2/serde_traitobject/trait.Error.html), [Fn](https://docs.rs/serde_traitobject/0.2/serde_traitobject/trait.Fn.html), [FnMut](https://docs.rs/serde_traitobject/0.2/serde_traitobject/trait.FnMut.html), [FnOnce](https://docs.rs/serde_traitobject/0.2/serde_traitobject/trait.FnOnce.html)
4040

4141
These are automatically implemented on all implementors of their stdlib counterparts that also implement `serde::Serialize` and `serde::de::DeserializeOwned`.
4242

azure-pipelines.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ jobs:
1414
endpoint: alecmocatta
1515
default:
1616
rust_toolchain: nightly
17-
rust_lint_toolchain: nightly-2020-06-25
17+
rust_lint_toolchain: nightly-2020-07-12
1818
rust_flags: ''
19-
rust_features: ''
19+
rust_features: ';serde_closure'
2020
rust_target_check: ''
2121
rust_target_build: ''
2222
rust_target_run: ''

src/convenience.rs

+181-5
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ impl Box<dyn Any> {
2525
self.0.into_any()
2626
}
2727
}
28-
#[allow(clippy::use_self)]
2928
impl Box<dyn Any + Send> {
3029
/// Convert into a `std::boxed::Box<dyn std::any::Any + Send>`.
3130
pub fn into_any_send(self) -> boxed::Box<dyn any::Any + Send> {
@@ -34,7 +33,6 @@ impl Box<dyn Any + Send> {
3433
}
3534
}
3635
}
37-
#[allow(clippy::use_self)]
3836
impl Box<dyn Any + Sync> {
3937
/// Convert into a `std::boxed::Box<dyn std::any::Any + Sync>`.
4038
pub fn into_any_sync(self) -> boxed::Box<dyn any::Any + Sync> {
@@ -43,7 +41,6 @@ impl Box<dyn Any + Sync> {
4341
}
4442
}
4543
}
46-
#[allow(clippy::use_self)]
4744
impl Box<dyn Any + Send + Sync> {
4845
/// Convert into a `std::boxed::Box<dyn std::any::Any + Send + Sync>`.
4946
pub fn into_any_send_sync(self) -> boxed::Box<dyn any::Any + Send + Sync> {
@@ -504,13 +501,11 @@ impl<'a> AsRef<Self> for dyn Error + Send + 'a {
504501
}
505502
}
506503

507-
#[allow(clippy::use_self)]
508504
impl<'a, E: error::Error + Serialize + Deserialize + 'a> From<E> for Box<dyn Error + 'a> {
509505
fn from(err: E) -> Self {
510506
Box::new(err)
511507
}
512508
}
513-
#[allow(clippy::use_self)]
514509
impl<'a, E: error::Error + Serialize + Deserialize + 'a> From<E> for boxed::Box<dyn Error + 'a> {
515510
fn from(err: E) -> Self {
516511
boxed::Box::new(err)
@@ -858,3 +853,184 @@ impl<'de, Args: 'static, Output: 'static> serde::de::Deserialize<'de>
858853
.map(|x| x.0)
859854
}
860855
}
856+
857+
/// Convenience traits implemented on all (de)serializable implementors of [`serde_closure::traits::*`](serde_closure::traits).
858+
#[cfg(feature = "serde_closure")]
859+
pub mod sc {
860+
use super::{serialize, Box, Deserialize, Serialize};
861+
use serde_closure::traits as sc;
862+
use std::boxed;
863+
864+
/// A convenience trait implemented on all (de)serializable implementors of [`serde_closure::traits::FnOnce`].
865+
///
866+
/// It can be made into a trait object which is then (de)serializable.
867+
pub trait FnOnce<Args>: sc::FnOnceBox<Args> + Serialize + Deserialize {}
868+
impl<T: ?Sized, Args> FnOnce<Args> for T where T: sc::FnOnceBox<Args> + Serialize + Deserialize {}
869+
870+
impl<'a, Args, Output> AsRef<Self> for dyn FnOnce<Args, Output = Output> + 'a {
871+
fn as_ref(&self) -> &Self {
872+
self
873+
}
874+
}
875+
impl<'a, Args, Output> AsRef<Self> for dyn FnOnce<Args, Output = Output> + Send + 'a {
876+
fn as_ref(&self) -> &Self {
877+
self
878+
}
879+
}
880+
881+
impl<Args: 'static, Output: 'static> serde::ser::Serialize for dyn FnOnce<Args, Output = Output> {
882+
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
883+
where
884+
S: serde::Serializer,
885+
{
886+
serialize(self, serializer)
887+
}
888+
}
889+
impl<'de, Args: 'static, Output: 'static> serde::de::Deserialize<'de>
890+
for boxed::Box<dyn FnOnce<Args, Output = Output> + 'static>
891+
{
892+
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
893+
where
894+
D: serde::Deserializer<'de>,
895+
{
896+
<Box<dyn FnOnce<Args, Output = Output> + 'static>>::deserialize(deserializer)
897+
.map(|x| x.0)
898+
}
899+
}
900+
impl<Args: 'static, Output: 'static> serde::ser::Serialize
901+
for dyn FnOnce<Args, Output = Output> + Send
902+
{
903+
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
904+
where
905+
S: serde::Serializer,
906+
{
907+
serialize(self, serializer)
908+
}
909+
}
910+
impl<'de, Args: 'static, Output: 'static> serde::de::Deserialize<'de>
911+
for boxed::Box<dyn FnOnce<Args, Output = Output> + Send + 'static>
912+
{
913+
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
914+
where
915+
D: serde::Deserializer<'de>,
916+
{
917+
<Box<dyn FnOnce<Args, Output = Output> + Send + 'static>>::deserialize(deserializer)
918+
.map(|x| x.0)
919+
}
920+
}
921+
922+
/// A convenience trait implemented on all (de)serializable implementors of [`serde_closure::traits::FnMut`].
923+
///
924+
/// It can be made into a trait object which is then (de)serializable.
925+
pub trait FnMut<Args>: sc::FnMut<Args> + Serialize + Deserialize {}
926+
impl<T: ?Sized, Args> FnMut<Args> for T where T: sc::FnMut<Args> + Serialize + Deserialize {}
927+
928+
impl<'a, Args, Output> AsRef<Self> for dyn FnMut<Args, Output = Output> + 'a {
929+
fn as_ref(&self) -> &Self {
930+
self
931+
}
932+
}
933+
impl<'a, Args, Output> AsRef<Self> for dyn FnMut<Args, Output = Output> + Send + 'a {
934+
fn as_ref(&self) -> &Self {
935+
self
936+
}
937+
}
938+
939+
impl<Args: 'static, Output: 'static> serde::ser::Serialize for dyn FnMut<Args, Output = Output> {
940+
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
941+
where
942+
S: serde::Serializer,
943+
{
944+
serialize(self, serializer)
945+
}
946+
}
947+
impl<'de, Args: 'static, Output: 'static> serde::de::Deserialize<'de>
948+
for boxed::Box<dyn FnMut<Args, Output = Output> + 'static>
949+
{
950+
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
951+
where
952+
D: serde::Deserializer<'de>,
953+
{
954+
<Box<dyn FnMut<Args, Output = Output> + 'static>>::deserialize(deserializer)
955+
.map(|x| x.0)
956+
}
957+
}
958+
impl<Args: 'static, Output: 'static> serde::ser::Serialize
959+
for dyn FnMut<Args, Output = Output> + Send
960+
{
961+
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
962+
where
963+
S: serde::Serializer,
964+
{
965+
serialize(self, serializer)
966+
}
967+
}
968+
impl<'de, Args: 'static, Output: 'static> serde::de::Deserialize<'de>
969+
for boxed::Box<dyn FnMut<Args, Output = Output> + Send + 'static>
970+
{
971+
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
972+
where
973+
D: serde::Deserializer<'de>,
974+
{
975+
<Box<dyn FnMut<Args, Output = Output> + Send + 'static>>::deserialize(deserializer)
976+
.map(|x| x.0)
977+
}
978+
}
979+
980+
/// A convenience trait implemented on all (de)serializable implementors of [`serde_closure::traits::Fn`].
981+
///
982+
/// It can be made into a trait object which is then (de)serializable.
983+
pub trait Fn<Args>: sc::Fn<Args> + Serialize + Deserialize {}
984+
impl<T: ?Sized, Args> Fn<Args> for T where T: sc::Fn<Args> + Serialize + Deserialize {}
985+
986+
impl<'a, Args, Output> AsRef<Self> for dyn Fn<Args, Output = Output> + 'a {
987+
fn as_ref(&self) -> &Self {
988+
self
989+
}
990+
}
991+
impl<'a, Args, Output> AsRef<Self> for dyn Fn<Args, Output = Output> + Send + 'a {
992+
fn as_ref(&self) -> &Self {
993+
self
994+
}
995+
}
996+
997+
impl<Args: 'static, Output: 'static> serde::ser::Serialize for dyn Fn<Args, Output = Output> {
998+
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
999+
where
1000+
S: serde::Serializer,
1001+
{
1002+
serialize(self, serializer)
1003+
}
1004+
}
1005+
impl<'de, Args: 'static, Output: 'static> serde::de::Deserialize<'de>
1006+
for boxed::Box<dyn Fn<Args, Output = Output> + 'static>
1007+
{
1008+
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1009+
where
1010+
D: serde::Deserializer<'de>,
1011+
{
1012+
<Box<dyn Fn<Args, Output = Output> + 'static>>::deserialize(deserializer).map(|x| x.0)
1013+
}
1014+
}
1015+
impl<Args: 'static, Output: 'static> serde::ser::Serialize
1016+
for dyn Fn<Args, Output = Output> + Send
1017+
{
1018+
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1019+
where
1020+
S: serde::Serializer,
1021+
{
1022+
serialize(self, serializer)
1023+
}
1024+
}
1025+
impl<'de, Args: 'static, Output: 'static> serde::de::Deserialize<'de>
1026+
for boxed::Box<dyn Fn<Args, Output = Output> + Send + 'static>
1027+
{
1028+
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1029+
where
1030+
D: serde::Deserializer<'de>,
1031+
{
1032+
<Box<dyn Fn<Args, Output = Output> + Send + 'static>>::deserialize(deserializer)
1033+
.map(|x| x.0)
1034+
}
1035+
}
1036+
}

src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@
9999
//!
100100
//! This crate currently requires Rust nightly.
101101
102-
#![doc(html_root_url = "https://docs.rs/serde_traitobject/0.2.6")]
102+
#![doc(html_root_url = "https://docs.rs/serde_traitobject/0.2.7")]
103103
#![feature(
104104
arbitrary_self_types,
105105
coerce_unsized,

tests/test.rs

-3
Original file line numberDiff line numberDiff line change
@@ -56,19 +56,16 @@ trait Hello {
5656
trait HelloSerialize: Hello + Serialize + Deserialize {}
5757
impl<T> HelloSerialize for T where T: Hello + Serialize + Deserialize {}
5858

59-
#[allow(clippy::use_self)]
6059
impl Hello for u32 {
6160
fn hi(&self) -> String {
6261
format!("hi u32! {:?}", self)
6362
}
6463
}
65-
#[allow(clippy::use_self)]
6664
impl Hello for u16 {
6765
fn hi(&self) -> String {
6866
format!("hi u16! {:?}", self)
6967
}
7068
}
71-
#[allow(clippy::use_self)]
7269
impl Hello for u8 {
7370
fn hi(&self) -> String {
7471
format!("hi u8! {:?}", self)

0 commit comments

Comments
 (0)