{"action":"created","issue":{"url":"https://api.github.com/repos/zslayton/stomp-rs/issues/46","labels_url":"https://api.github.com/repos/zslayton/stomp-rs/issues/46/labels{/name}","comments_url":"https://api.github.com/repos/zslayton/stomp-rs/issues/46/comments","events_url":"https://api.github.com/repos/zslayton/stomp-rs/issues/46/events","html_url":"https://github.com/zslayton/stomp-rs/issues/46","id":54005960,"number":46,"title":"Turn `Subscription` into a Trait","user":{"login":"zslayton","id":611616,"avatar_url":"https://avatars.githubusercontent.com/u/611616?v=3","gravatar_id":"","url":"https://api.github.com/users/zslayton","html_url":"https://github.com/zslayton","followers_url":"https://api.github.com/users/zslayton/followers","following_url":"https://api.github.com/users/zslayton/following{/other_user}","gists_url":"https://api.github.com/users/zslayton/gists{/gist_id}","starred_url":"https://api.github.com/users/zslayton/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zslayton/subscriptions","organizations_url":"https://api.github.com/users/zslayton/orgs","repos_url":"https://api.github.com/users/zslayton/repos","events_url":"https://api.github.com/users/zslayton/events{/privacy}","received_events_url":"https://api.github.com/users/zslayton/received_events","type":"User","site_admin":false},"labels":[],"state":"closed","locked":false,"assignee":null,"milestone":null,"comments":4,"created_at":"2015-01-11T21:35:24Z","updated_at":"2015-01-25T05:58:27Z","closed_at":"2015-01-25T05:58:04Z","body":"cc @fribeiro1 \r\n\r\nPossibly the greatest shortcoming in the `stomp` library is that the `on_message` callback is a bare function (`fn`). This burdens the message handler with creating its own resources each time a message is received. It is impossible[1], for example, to have the message handling function send a message somewhere meaningful via a `channel` or to keep count of how many times it has been called. This dramatically limits what can be done using this crate.\r\n\r\nThere are two possible solutions to this issue:\r\n\r\n1. Use closures instead of bare functions\r\n2. Create a `Subscription` trait that the developer can implement.\r\n\r\nHaving used the Stomp protocol in the past mostly from dynamic languages like JS and Python, closures seemed to me like the most ergonomic way of offering this functionality. (Note the existence of issue #33.) This would look something like:\r\n\r\n```rust \r\n  let topic = \"/topic/messages\";\r\n  let mut message_count = 0u64;\r\n  session.subscribe(topic, Client, |frame: &Frame| {\r\n    message_count += 1;\r\n    println!(\"Received {} messages\", message_count);\r\n  });\r\n```\r\nHowever, it may be more idiomatic to convert `Subscription` into a Trait and require the developer to create a struct with the desired environment which implements it. That would look something like:\r\n```rust\r\nstruct ExampleSubscription {\r\n  count: u64\r\n}\r\n\r\nimpl Subscription for ExampleSubscription {\r\n  fn on_message(&mut self) -> AckOrNack {\r\n    self.count += 1;\r\n    Ack\r\n  }\r\n}\r\n\r\nfn main() {\r\n  let subscription = ExampleSubscription::new();\r\n  session.subscribe(topic, Client, subscription);\r\n}\r\n```\r\n\r\nThis is obviously more verbose and isn't quite as nice for short demonstrations. However, it feels as though it may be more fitting for non-trivial programs relying on an MQ broker.\r\n\r\nI'm currently leaning towards the Trait approach, but I wanted to open this issue to request input on the topic before jumping into revisions.\r\n\r\n[1] It is possible to do something like this using static data structures, but this is not idiomatic Rust."},"comment":{"url":"https://api.github.com/repos/zslayton/stomp-rs/issues/comments/71354572","html_url":"https://github.com/zslayton/stomp-rs/issues/46#issuecomment-71354572","issue_url":"https://api.github.com/repos/zslayton/stomp-rs/issues/46","id":71354572,"user":{"login":"zslayton","id":611616,"avatar_url":"https://avatars.githubusercontent.com/u/611616?v=3","gravatar_id":"","url":"https://api.github.com/users/zslayton","html_url":"https://github.com/zslayton","followers_url":"https://api.github.com/users/zslayton/followers","following_url":"https://api.github.com/users/zslayton/following{/other_user}","gists_url":"https://api.github.com/users/zslayton/gists{/gist_id}","starred_url":"https://api.github.com/users/zslayton/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zslayton/subscriptions","organizations_url":"https://api.github.com/users/zslayton/orgs","repos_url":"https://api.github.com/users/zslayton/repos","events_url":"https://api.github.com/users/zslayton/events{/privacy}","received_events_url":"https://api.github.com/users/zslayton/received_events","type":"User","site_admin":false},"created_at":"2015-01-25T05:58:27Z","updated_at":"2015-01-25T05:58:27Z","body":"#51 tracks the creation of `ToMessageHandler`, which will allow for closures."}}