Skip to content

Commit 2fe3bfc

Browse files
ascjonestomusdrw
authored andcommitted
One way serialize for subscriber type (#371)
* 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
1 parent 37b62a3 commit 2fe3bfc

File tree

3 files changed

+64
-10
lines changed

3 files changed

+64
-10
lines changed

derive/src/to_delegate.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -336,12 +336,14 @@ fn is_option_type(ty: &syn::Type) -> bool {
336336
}
337337

338338
fn generate_where_clause_serialization_predicates(item_trait: &syn::ItemTrait) -> Vec<syn::WherePredicate> {
339+
#[derive(Default)]
339340
struct FindTyParams {
340341
trait_generics: HashSet<syn::Ident>,
341342
serialize_type_params: HashSet<syn::Ident>,
342343
deserialize_type_params: HashSet<syn::Ident>,
343344
visiting_return_type: bool,
344345
visiting_fn_arg: bool,
346+
visiting_subscriber_arg: bool,
345347
}
346348
impl<'ast> Visit<'ast> for FindTyParams {
347349
fn visit_type_param(&mut self, ty_param: &'ast syn::TypeParam) {
@@ -356,24 +358,22 @@ fn generate_where_clause_serialization_predicates(item_trait: &syn::ItemTrait) -
356358
if self.visiting_return_type && self.trait_generics.contains(&segment.ident) {
357359
self.serialize_type_params.insert(segment.ident.clone());
358360
}
359-
if self.visiting_fn_arg && self.trait_generics.contains(&segment.ident) {
361+
if self.visiting_fn_arg &&
362+
self.trait_generics.contains(&segment.ident) &&
363+
!self.visiting_subscriber_arg {
360364
self.deserialize_type_params.insert(segment.ident.clone());
361365
}
362-
visit::visit_path_segment(self, segment)
366+
self.visiting_subscriber_arg = self.visiting_fn_arg && segment.ident == SUBCRIBER_TYPE_IDENT;
367+
visit::visit_path_segment(self, segment);
368+
self.visiting_subscriber_arg = false;
363369
}
364370
fn visit_fn_arg(&mut self, arg: &'ast syn::FnArg) {
365371
self.visiting_fn_arg = true;
366372
visit::visit_fn_arg(self, arg);
367373
self.visiting_fn_arg = false;
368374
}
369375
}
370-
let mut visitor = FindTyParams {
371-
visiting_return_type: false,
372-
visiting_fn_arg: false,
373-
trait_generics: HashSet::new(),
374-
serialize_type_params: HashSet::new(),
375-
deserialize_type_params: HashSet::new(),
376-
};
376+
let mut visitor = FindTyParams::default();
377377
visitor.visit_item_trait(item_trait);
378378

379379
item_trait.generics

derive/tests/compiletests.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,11 @@ fn run_mode(mode: &'static str) {
77

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

1317
compiletest::run_tests(&config);
@@ -16,4 +20,5 @@ fn run_mode(mode: &'static str) {
1620
#[test]
1721
fn compile_test() {
1822
run_mode("ui");
23+
run_mode("run-pass");
1924
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
extern crate serde;
2+
#[macro_use]
3+
extern crate serde_derive;
4+
extern crate jsonrpc_core;
5+
extern crate jsonrpc_pubsub;
6+
#[macro_use]
7+
extern crate jsonrpc_derive;
8+
9+
use std::sync::Arc;
10+
use jsonrpc_core::Result;
11+
use jsonrpc_pubsub::{typed::Subscriber, SubscriptionId, Session, PubSubHandler};
12+
13+
#[rpc]
14+
pub trait Rpc<T> {
15+
type Metadata;
16+
17+
/// Hello subscription
18+
#[pubsub(subscription = "hello", subscribe, name = "hello_subscribe", alias("hello_sub"))]
19+
fn subscribe(&self, _: Self::Metadata, _: Subscriber<T>);
20+
21+
/// Unsubscribe from hello subscription.
22+
#[pubsub(subscription = "hello", unsubscribe, name = "hello_unsubscribe")]
23+
fn unsubscribe(&self, _: Option<Self::Metadata>, _: SubscriptionId) -> Result<bool>;
24+
}
25+
26+
// One way serialization
27+
#[derive(Serialize)]
28+
struct SerializeOnly {
29+
foo: String,
30+
}
31+
32+
struct RpcImpl;
33+
impl Rpc<SerializeOnly> for RpcImpl {
34+
type Metadata = Arc<Session>;
35+
36+
fn subscribe(&self, _: Self::Metadata, _: Subscriber<SerializeOnly>) {
37+
unimplemented!();
38+
}
39+
40+
fn unsubscribe(&self, _: Option<Self::Metadata>, _: SubscriptionId) -> Result<bool> {
41+
unimplemented!();
42+
}
43+
}
44+
45+
fn main() {
46+
let mut io = PubSubHandler::default();
47+
let rpc = RpcImpl;
48+
io.extend_with(rpc.to_delegate());
49+
}

0 commit comments

Comments
 (0)