use std::{borrow::Cow, cmp::min, io};
use saturating::Saturating as S;
use crate::{
binlog::{
consts::{BinlogVersion, EventType},
BinlogCtx, BinlogEvent, BinlogStruct,
},
io::ParseBuf,
misc::raw::{bytes::EofBytes, int::*, RawBytes},
proto::{MyDeserialize, MySerialize},
};
use super::BinlogEventHeader;
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
pub struct RotateEvent<'a> {
position: RawInt<LeU64>,
name: RawBytes<'a, EofBytes>,
}
impl<'a> RotateEvent<'a> {
pub fn new(position: u64, name: impl Into<Cow<'a, [u8]>>) -> Self {
Self {
position: RawInt::new(position),
name: RawBytes::new(name),
}
}
pub fn with_position(mut self, position: u64) -> Self {
self.position = RawInt::new(position);
self
}
pub fn with_name(mut self, name: impl Into<Cow<'a, [u8]>>) -> Self {
self.name = RawBytes::new(name);
self
}
pub fn position(&self) -> u64 {
self.position.0
}
pub fn name_raw(&'a self) -> &'a [u8] {
self.name.as_bytes()
}
pub fn name(&'a self) -> Cow<'a, str> {
self.name.as_str()
}
pub fn is_fake(&self) -> bool {
self.position() == 0
}
pub fn into_owned(self) -> RotateEvent<'static> {
RotateEvent {
position: self.position,
name: self.name.into_owned(),
}
}
}
impl<'de> MyDeserialize<'de> for RotateEvent<'de> {
const SIZE: Option<usize> = None;
type Ctx = BinlogCtx<'de>;
fn deserialize(_ctx: Self::Ctx, buf: &mut ParseBuf<'de>) -> io::Result<Self> {
Ok(Self {
position: buf.parse(())?,
name: buf.parse(())?,
})
}
}
impl MySerialize for RotateEvent<'_> {
fn serialize(&self, buf: &mut Vec<u8>) {
self.position.serialize(&mut *buf);
self.name.serialize(&mut *buf);
}
}
impl<'a> BinlogEvent<'a> for RotateEvent<'a> {
const EVENT_TYPE: EventType = EventType::ROTATE_EVENT;
}
impl<'a> BinlogStruct<'a> for RotateEvent<'a> {
fn len(&self, _version: BinlogVersion) -> usize {
let mut len = S(0);
len += S(8);
len += S(self.name.0.len());
min(len.0, u32::MAX as usize - BinlogEventHeader::LEN)
}
}