Skip to content

Commit

Permalink
One way serialize for subscriber type (#371)
Browse files Browse the repository at this point in the history
* WIP: 2018 compile tests with one way serialization

* WIP: attempting to get traitbounds to work with compiletests

* Failing compile test for one way serialise Subscription type

* One way Serialize for generic type only used in Subscriber
  • Loading branch information
ascjones authored and tomusdrw committed Jan 30, 2019
1 parent 37b62a3 commit 2fe3bfc
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 10 deletions.
18 changes: 9 additions & 9 deletions derive/src/to_delegate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -336,12 +336,14 @@ fn is_option_type(ty: &syn::Type) -> bool {
}

fn generate_where_clause_serialization_predicates(item_trait: &syn::ItemTrait) -> Vec<syn::WherePredicate> {
#[derive(Default)]
struct FindTyParams {
trait_generics: HashSet<syn::Ident>,
serialize_type_params: HashSet<syn::Ident>,
deserialize_type_params: HashSet<syn::Ident>,
visiting_return_type: bool,
visiting_fn_arg: bool,
visiting_subscriber_arg: bool,
}
impl<'ast> Visit<'ast> for FindTyParams {
fn visit_type_param(&mut self, ty_param: &'ast syn::TypeParam) {
Expand All @@ -356,24 +358,22 @@ fn generate_where_clause_serialization_predicates(item_trait: &syn::ItemTrait) -
if self.visiting_return_type && self.trait_generics.contains(&segment.ident) {
self.serialize_type_params.insert(segment.ident.clone());
}
if self.visiting_fn_arg && self.trait_generics.contains(&segment.ident) {
if self.visiting_fn_arg &&
self.trait_generics.contains(&segment.ident) &&
!self.visiting_subscriber_arg {
self.deserialize_type_params.insert(segment.ident.clone());
}
visit::visit_path_segment(self, segment)
self.visiting_subscriber_arg = self.visiting_fn_arg && segment.ident == SUBCRIBER_TYPE_IDENT;
visit::visit_path_segment(self, segment);
self.visiting_subscriber_arg = false;
}
fn visit_fn_arg(&mut self, arg: &'ast syn::FnArg) {
self.visiting_fn_arg = true;
visit::visit_fn_arg(self, arg);
self.visiting_fn_arg = false;
}
}
let mut visitor = FindTyParams {
visiting_return_type: false,
visiting_fn_arg: false,
trait_generics: HashSet::new(),
serialize_type_params: HashSet::new(),
deserialize_type_params: HashSet::new(),
};
let mut visitor = FindTyParams::default();
visitor.visit_item_trait(item_trait);

item_trait.generics
Expand Down
7 changes: 6 additions & 1 deletion derive/tests/compiletests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@ fn run_mode(mode: &'static str) {

config.mode = mode.parse().expect("Invalid mode");
config.src_base = PathBuf::from(format!("tests/{}", mode));
config.target_rustcflags = Some("-L ../target/debug/ -L ../target/debug/deps/".to_owned());
config.target_rustcflags = Some(String::from(
"\
-L ../target/debug/ \
-L ../target/debug/deps/ \
"));
config.clean_rmeta(); // If your tests import the parent crate, this helps with E0464

compiletest::run_tests(&config);
Expand All @@ -16,4 +20,5 @@ fn run_mode(mode: &'static str) {
#[test]
fn compile_test() {
run_mode("ui");
run_mode("run-pass");
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate jsonrpc_core;
extern crate jsonrpc_pubsub;
#[macro_use]
extern crate jsonrpc_derive;

use std::sync::Arc;
use jsonrpc_core::Result;
use jsonrpc_pubsub::{typed::Subscriber, SubscriptionId, Session, PubSubHandler};

#[rpc]
pub trait Rpc<T> {
type Metadata;

/// Hello subscription
#[pubsub(subscription = "hello", subscribe, name = "hello_subscribe", alias("hello_sub"))]
fn subscribe(&self, _: Self::Metadata, _: Subscriber<T>);

/// Unsubscribe from hello subscription.
#[pubsub(subscription = "hello", unsubscribe, name = "hello_unsubscribe")]
fn unsubscribe(&self, _: Option<Self::Metadata>, _: SubscriptionId) -> Result<bool>;
}

// One way serialization
#[derive(Serialize)]
struct SerializeOnly {
foo: String,
}

struct RpcImpl;
impl Rpc<SerializeOnly> for RpcImpl {
type Metadata = Arc<Session>;

fn subscribe(&self, _: Self::Metadata, _: Subscriber<SerializeOnly>) {
unimplemented!();
}

fn unsubscribe(&self, _: Option<Self::Metadata>, _: SubscriptionId) -> Result<bool> {
unimplemented!();
}
}

fn main() {
let mut io = PubSubHandler::default();
let rpc = RpcImpl;
io.extend_with(rpc.to_delegate());
}

0 comments on commit 2fe3bfc

Please sign in to comment.