Skip to main content

PubsubEvent

Enum PubsubEvent 

Source
#[non_exhaustive]
pub enum PubsubEvent { Subscribe { channel: Vec<u8>, count: i64, }, Psubscribe { pattern: Vec<u8>, count: i64, }, Unsubscribe { channel: Option<Vec<u8>>, count: i64, }, Punsubscribe { pattern: Option<Vec<u8>>, count: i64, }, Message { channel: Vec<u8>, payload: Vec<u8>, }, Pmessage { pattern: Vec<u8>, channel: Vec<u8>, payload: Vec<u8>, }, }
Expand description

One pub/sub event delivered to a Subscription — the same type the network clients receive, so a consumer handles either source alike. One pubsub frame received from the bus or the wire.

Unsubscribe / Punsubscribe’s channel / pattern is None when the server acknowledges “unsubscribed from everything” with a nil bulk — matching the Redis wire shape.

use kevy_resp::{PubsubEvent, parse_reply};

let (reply, _) = parse_reply(b"*3\r\n$7\r\nmessage\r\n$4\r\nnews\r\n$2\r\nhi\r\n")?
    .expect("complete frame");
match PubsubEvent::try_from(reply)? {
    PubsubEvent::Message { channel, payload } => {
        assert_eq!((channel, payload), (b"news".to_vec(), b"hi".to_vec()));
    }
    other => panic!("unexpected {other:?}"),
}

Variants (Non-exhaustive)§

This enum is marked as non-exhaustive
Non-exhaustive enums could have additional variants added in future. Therefore, when matching against variants of non-exhaustive enums, an extra wildcard arm must be added to account for any future variants.
§

Subscribe

SUBSCRIBE ack per channel.

use kevy_resp::{PubsubEvent, parse_reply};
let (reply, _) = parse_reply(b"*3\r\n$9\r\nsubscribe\r\n$4\r\nnews\r\n:1\r\n")?.expect("complete frame");
let event = PubsubEvent::try_from(reply)?;
assert_eq!(event, PubsubEvent::Subscribe { channel: b"news".to_vec(), count: 1 });

Fields

§channel: Vec<u8>

Channel that was just subscribed.

use kevy_resp::{PubsubEvent, parse_reply};
let (reply, _) = parse_reply(b"*3\r\n$9\r\nsubscribe\r\n$4\r\nnews\r\n:1\r\n")?.expect("complete frame");
let event = PubsubEvent::try_from(reply)?;
let PubsubEvent::Subscribe { channel, .. } = event else { panic!("not subscribe") };
assert_eq!(channel, b"news");
§count: i64

Total channels + patterns subscribed.

use kevy_resp::{PubsubEvent, parse_reply};
let (reply, _) = parse_reply(b"*3\r\n$9\r\nsubscribe\r\n$4\r\nnews\r\n:1\r\n")?.expect("complete frame");
let event = PubsubEvent::try_from(reply)?;
let PubsubEvent::Subscribe { count, .. } = event else { panic!("not subscribe") };
assert_eq!(count, 1);
§

Psubscribe

PSUBSCRIBE ack per pattern.

use kevy_resp::{PubsubEvent, parse_reply};
let (reply, _) = parse_reply(b"*3\r\n$10\r\npsubscribe\r\n$3\r\nn.*\r\n:2\r\n")?.expect("complete frame");
let event = PubsubEvent::try_from(reply)?;
assert_eq!(event, PubsubEvent::Psubscribe { pattern: b"n.*".to_vec(), count: 2 });

Fields

§pattern: Vec<u8>

Pattern that was just subscribed.

use kevy_resp::{PubsubEvent, parse_reply};
let (reply, _) = parse_reply(b"*3\r\n$10\r\npsubscribe\r\n$3\r\nn.*\r\n:2\r\n")?.expect("complete frame");
let event = PubsubEvent::try_from(reply)?;
let PubsubEvent::Psubscribe { pattern, .. } = event else { panic!("not psubscribe") };
assert_eq!(pattern, b"n.*");
§count: i64

Total channels + patterns subscribed.

use kevy_resp::{PubsubEvent, parse_reply};
let (reply, _) = parse_reply(b"*3\r\n$10\r\npsubscribe\r\n$3\r\nn.*\r\n:2\r\n")?.expect("complete frame");
let event = PubsubEvent::try_from(reply)?;
// the connection now holds one channel and this pattern
let PubsubEvent::Psubscribe { count, .. } = event else { panic!("not psubscribe") };
assert_eq!(count, 2);
§

Unsubscribe

UNSUBSCRIBE ack.

use kevy_resp::{PubsubEvent, parse_reply};
let (reply, _) = parse_reply(b"*3\r\n$11\r\nunsubscribe\r\n$4\r\nnews\r\n:0\r\n")?.expect("complete frame");
let event = PubsubEvent::try_from(reply)?;
assert_eq!(event, PubsubEvent::Unsubscribe { channel: Some(b"news".to_vec()), count: 0 });

Fields

§channel: Option<Vec<u8>>

Channel just unsubscribed (None for “all”/“none” nil bulk).

use kevy_resp::{PubsubEvent, parse_reply};
let (reply, _) = parse_reply(b"*3\r\n$11\r\nunsubscribe\r\n$-1\r\n:0\r\n")?.expect("complete frame");
let event = PubsubEvent::try_from(reply)?;
// "unsubscribed from everything" arrives as a nil bulk
let PubsubEvent::Unsubscribe { channel, .. } = event else { panic!("not unsubscribe") };
assert_eq!(channel, None);
§count: i64

Total channels + patterns still subscribed.

use kevy_resp::{PubsubEvent, parse_reply};
let (reply, _) = parse_reply(b"*3\r\n$11\r\nunsubscribe\r\n$4\r\nnews\r\n:0\r\n")?.expect("complete frame");
let event = PubsubEvent::try_from(reply)?;
let PubsubEvent::Unsubscribe { count, .. } = event else { panic!("not unsubscribe") };
assert_eq!(count, 0);
§

Punsubscribe

PUNSUBSCRIBE ack.

use kevy_resp::{PubsubEvent, parse_reply};
let (reply, _) = parse_reply(b"*3\r\n$12\r\npunsubscribe\r\n$3\r\nn.*\r\n:1\r\n")?.expect("complete frame");
let event = PubsubEvent::try_from(reply)?;
assert_eq!(event, PubsubEvent::Punsubscribe { pattern: Some(b"n.*".to_vec()), count: 1 });

Fields

§pattern: Option<Vec<u8>>

Pattern just unsubscribed (None for “all”/“none” nil bulk).

use kevy_resp::{PubsubEvent, parse_reply};
let (reply, _) = parse_reply(b"*3\r\n$12\r\npunsubscribe\r\n$-1\r\n:0\r\n")?.expect("complete frame");
let event = PubsubEvent::try_from(reply)?;
let PubsubEvent::Punsubscribe { pattern, .. } = event else { panic!("not punsubscribe") };
assert_eq!(pattern, None);
§count: i64

Total channels + patterns still subscribed.

use kevy_resp::{PubsubEvent, parse_reply};
let (reply, _) = parse_reply(b"*3\r\n$12\r\npunsubscribe\r\n$3\r\nn.*\r\n:1\r\n")?.expect("complete frame");
let event = PubsubEvent::try_from(reply)?;
// one channel subscription is still active
let PubsubEvent::Punsubscribe { count, .. } = event else { panic!("not punsubscribe") };
assert_eq!(count, 1);
§

Message

Plain PUBLISH delivery on a subscribed channel.

use kevy_resp::{PubsubEvent, parse_reply};
// a RESP3 push frame
let (reply, _) = parse_reply(b">3\r\n$7\r\nmessage\r\n$4\r\nnews\r\n$2\r\nhi\r\n")?.expect("complete frame");
let event = PubsubEvent::try_from(reply)?;
assert_eq!(event, PubsubEvent::Message { channel: b"news".to_vec(), payload: b"hi".to_vec() });

Fields

§channel: Vec<u8>

Channel the publish was made to.

use kevy_resp::{PubsubEvent, parse_reply};
let (reply, _) = parse_reply(b">3\r\n$7\r\nmessage\r\n$4\r\nnews\r\n$2\r\nhi\r\n")?.expect("complete frame");
let event = PubsubEvent::try_from(reply)?;
let PubsubEvent::Message { channel, .. } = event else { panic!("not message") };
assert_eq!(channel, b"news");
§payload: Vec<u8>

Raw payload bytes.

use kevy_resp::{PubsubEvent, parse_reply};
let (reply, _) = parse_reply(b">3\r\n$7\r\nmessage\r\n$4\r\nnews\r\n$2\r\nhi\r\n")?.expect("complete frame");
let event = PubsubEvent::try_from(reply)?;
assert_eq!(event.into_payload(), Some(b"hi".to_vec()));
§

Pmessage

Pattern-match delivery.

use kevy_resp::{PubsubEvent, parse_reply};
let (reply, _) = parse_reply(b"*4\r\n$8\r\npmessage\r\n$3\r\nn.*\r\n$4\r\nnews\r\n$2\r\nhi\r\n")?.expect("complete frame");
let event = PubsubEvent::try_from(reply)?;
let expected = PubsubEvent::Pmessage {
    pattern: b"n.*".to_vec(),
    channel: b"news".to_vec(),
    payload: b"hi".to_vec(),
};
assert_eq!(event, expected);

Fields

§pattern: Vec<u8>

Pattern the channel matched.

use kevy_resp::{PubsubEvent, parse_reply};
let (reply, _) = parse_reply(b"*4\r\n$8\r\npmessage\r\n$3\r\nn.*\r\n$4\r\nnews\r\n$2\r\nhi\r\n")?.expect("complete frame");
let event = PubsubEvent::try_from(reply)?;
let PubsubEvent::Pmessage { pattern, .. } = event else { panic!("not pmessage") };
assert_eq!(pattern, b"n.*");
§channel: Vec<u8>

Channel the publish was made to.

use kevy_resp::{PubsubEvent, parse_reply};
let (reply, _) = parse_reply(b"*4\r\n$8\r\npmessage\r\n$3\r\nn.*\r\n$4\r\nnews\r\n$2\r\nhi\r\n")?.expect("complete frame");
let event = PubsubEvent::try_from(reply)?;
let PubsubEvent::Pmessage { channel, .. } = event else { panic!("not pmessage") };
assert_eq!(channel, b"news");
§payload: Vec<u8>

Raw payload bytes.

use kevy_resp::{PubsubEvent, parse_reply};
let (reply, _) = parse_reply(b"*4\r\n$8\r\npmessage\r\n$3\r\nn.*\r\n$4\r\nnews\r\n$2\r\nhi\r\n")?.expect("complete frame");
let event = PubsubEvent::try_from(reply)?;
let PubsubEvent::Pmessage { payload, .. } = event else { panic!("not pmessage") };
assert_eq!(payload, b"hi");

Implementations§

Source§

impl PubsubEvent

Turn a RESP reply into a PubsubEvent. Handles both RESP2 (*N\r\n… arrays) and RESP3 (>N\r\n… push frames).

use kevy_resp::{PubsubEvent, Reply};

let r = Reply::Array(vec![
    Reply::Bulk(b"message".to_vec()),
    Reply::Bulk(b"news".to_vec()),
    Reply::Bulk(b"hi".to_vec()),
]);
assert!(matches!(PubsubEvent::try_from(r)?, PubsubEvent::Message { .. }));
Source

pub fn into_payload(self) -> Option<Vec<u8>>

The raw message payload, moved out of the event.

Some(payload) for the two deliveries (Message and Pmessage); None for every control/ack event (subscribe / unsubscribe / …), which carries no payload. Consuming self lets a scalar drain hand a push subscriber just the bytes with no extra copy. The channel and the message-vs-pmessage distinction are dropped; a caller that needs either keeps matching on the event.

use kevy_resp::PubsubEvent;

let m = PubsubEvent::Message { channel: b"c".to_vec(), payload: b"p".to_vec() };
assert_eq!(m.into_payload(), Some(b"p".to_vec()));
let ack = PubsubEvent::Subscribe { channel: b"c".to_vec(), count: 1 };
assert_eq!(ack.into_payload(), None);

Trait Implementations§

Source§

impl Clone for PubsubEvent

Source§

fn clone(&self) -> PubsubEvent

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for PubsubEvent

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
Source§

impl Eq for PubsubEvent

Source§

impl PartialEq for PubsubEvent

Source§

fn eq(&self, other: &PubsubEvent) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl StructuralPartialEq for PubsubEvent

Source§

impl TryFrom<Reply> for PubsubEvent

Source§

type Error = Error

The type returned in the event of a conversion error.
Source§

fn try_from(reply: Reply) -> Result<PubsubEvent, Error>

Performs the conversion.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.