use bytes::Bytes;
use ruststream::{BuildContext, Field};
use crate::message::KafkaMessage;
#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub struct KafkaContext {
topic: String,
partition: i32,
offset: i64,
timestamp_millis: Option<i64>,
key: Option<Bytes>,
}
impl KafkaContext {
#[must_use]
pub fn topic(&self) -> &str {
&self.topic
}
#[must_use]
pub fn partition(&self) -> i32 {
self.partition
}
#[must_use]
pub fn offset(&self) -> i64 {
self.offset
}
#[must_use]
pub fn timestamp_millis(&self) -> Option<i64> {
self.timestamp_millis
}
#[must_use]
pub fn key(&self) -> Option<&[u8]> {
self.key.as_deref()
}
}
impl BuildContext<KafkaMessage> for KafkaContext {
fn build(msg: &KafkaMessage) -> Self {
Self {
topic: msg.topic().to_owned(),
partition: msg.partition(),
offset: msg.offset(),
timestamp_millis: msg.timestamp_millis(),
key: msg.key().map(Bytes::copy_from_slice),
}
}
}
pub mod keys {
use ruststream::ContextField;
use super::{Field, KafkaContext};
use crate::eos::SourceOffset;
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub struct Topic;
impl Field<KafkaContext> for Topic {
type Value<'a> = &'a str;
fn get(self, src: &KafkaContext) -> &str {
src.topic()
}
}
impl ContextField for Topic {
type Context = KafkaContext;
type Value = String;
fn read(self, src: &KafkaContext) -> String {
src.topic().to_owned()
}
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub struct Partition;
impl Field<KafkaContext> for Partition {
type Value<'a> = i32;
fn get(self, src: &KafkaContext) -> i32 {
src.partition()
}
}
impl ContextField for Partition {
type Context = KafkaContext;
type Value = i32;
fn read(self, src: &KafkaContext) -> i32 {
src.partition()
}
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub struct Offset;
impl Field<KafkaContext> for Offset {
type Value<'a> = i64;
fn get(self, src: &KafkaContext) -> i64 {
src.offset()
}
}
impl ContextField for Offset {
type Context = KafkaContext;
type Value = i64;
fn read(self, src: &KafkaContext) -> i64 {
src.offset()
}
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub struct TimestampMillis;
impl Field<KafkaContext> for TimestampMillis {
type Value<'a> = Option<i64>;
fn get(self, src: &KafkaContext) -> Option<i64> {
src.timestamp_millis()
}
}
impl ContextField for TimestampMillis {
type Context = KafkaContext;
type Value = Option<i64>;
fn read(self, src: &KafkaContext) -> Option<i64> {
src.timestamp_millis()
}
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub struct Key;
impl Field<KafkaContext> for Key {
type Value<'a> = Option<&'a [u8]>;
fn get(self, src: &KafkaContext) -> Option<&[u8]> {
src.key()
}
}
impl ContextField for Key {
type Context = KafkaContext;
type Value = Option<Vec<u8>>;
fn read(self, src: &KafkaContext) -> Option<Vec<u8>> {
src.key().map(<[u8]>::to_vec)
}
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub struct Source;
impl Field<KafkaContext> for Source {
type Value<'a> = SourceOffset;
fn get(self, src: &KafkaContext) -> SourceOffset {
SourceOffset::new(src.topic(), src.partition(), src.offset())
}
}
impl ContextField for Source {
type Context = KafkaContext;
type Value = SourceOffset;
fn read(self, src: &KafkaContext) -> SourceOffset {
SourceOffset::new(src.topic(), src.partition(), src.offset())
}
}
}