mysql_common/binlog/events/
user_var_event.rs1use std::{
10 borrow::Cow,
11 cmp::min,
12 io::{self},
13};
14
15use bytes::BufMut;
16use saturating::Saturating as S;
17
18use crate::{
19 binlog::{
20 BinlogCtx, BinlogEvent, BinlogStruct,
21 consts::{BinlogVersion, EventType, UserVarFlags},
22 },
23 constants::{ItemResult, UnknownItemResultType},
24 io::ParseBuf,
25 misc::raw::{RawBytes, RawConst, RawFlags, bytes::U32Bytes, int::*},
26 proto::{MyDeserialize, MySerialize},
27};
28
29use super::BinlogEventHeader;
30
31#[derive(Debug, Clone, Eq, PartialEq, Hash)]
41pub struct UserVarEvent<'a> {
42 name: RawBytes<'a, U32Bytes>,
44 is_null: bool,
46 value_type: RawConst<i8, ItemResult>,
48 charset: RawInt<LeU32>,
50 value: RawBytes<'a, U32Bytes>,
52 flags: RawFlags<UserVarFlags, u8>,
54}
55
56impl<'a> UserVarEvent<'a> {
57 pub fn name_raw(&'a self) -> &'a [u8] {
59 self.name.as_bytes()
60 }
61
62 pub fn name(&'a self) -> Cow<'a, str> {
64 self.name.as_str()
65 }
66
67 pub fn is_null(&self) -> bool {
69 self.is_null
70 }
71
72 pub fn value_type(&self) -> Result<ItemResult, UnknownItemResultType> {
74 self.value_type.get()
75 }
76
77 pub fn charset(&self) -> u32 {
79 self.charset.0
80 }
81
82 pub fn value(&'a self) -> &'a [u8] {
84 self.value.as_bytes()
85 }
86
87 pub fn flags_raw(&self) -> u8 {
89 self.flags.0
90 }
91
92 pub fn flags(&self) -> UserVarFlags {
94 self.flags.get()
95 }
96
97 pub fn into_owned(self) -> UserVarEvent<'static> {
98 UserVarEvent {
99 name: self.name.into_owned(),
100 is_null: self.is_null,
101 value_type: self.value_type,
102 charset: self.charset,
103 value: self.value.into_owned(),
104 flags: self.flags,
105 }
106 }
107}
108
109impl<'de> MyDeserialize<'de> for UserVarEvent<'de> {
110 const SIZE: Option<usize> = None;
111 type Ctx = BinlogCtx<'de>;
112
113 fn deserialize(_ctx: Self::Ctx, buf: &mut ParseBuf<'de>) -> io::Result<Self> {
114 let name = buf.parse(())?;
115 let is_null = buf.parse::<RawInt<u8>>(())?.0 != 0;
116
117 if is_null {
118 return Ok(Self {
119 name,
120 is_null,
121 value_type: RawConst::new(ItemResult::STRING_RESULT as i8),
122 charset: RawInt::new(63),
123 value: RawBytes::default(),
124 flags: RawFlags::default(),
125 });
126 }
127
128 let mut sbuf: ParseBuf<'_> = buf.parse(5)?;
129 let value_type = sbuf.parse_unchecked(())?;
130 let charset = sbuf.parse_unchecked(())?;
131
132 let value = buf.parse(())?;
133
134 let flags = if !buf.is_empty() {
136 buf.parse_unchecked(())?
137 } else {
138 Default::default()
139 };
140
141 Ok(Self {
142 name,
143 is_null,
144 value_type,
145 charset,
146 value,
147 flags,
148 })
149 }
150}
151
152impl MySerialize for UserVarEvent<'_> {
153 fn serialize(&self, buf: &mut Vec<u8>) {
154 self.name.serialize(&mut *buf);
155 buf.put_u8(self.is_null as u8);
156 if !self.is_null {
157 self.value_type.serialize(&mut *buf);
158 self.charset.serialize(&mut *buf);
159 self.value.serialize(&mut *buf);
160 self.flags.serialize(&mut *buf);
161 }
162 }
163}
164
165impl<'a> BinlogEvent<'a> for UserVarEvent<'a> {
166 const EVENT_TYPE: EventType = EventType::USER_VAR_EVENT;
167}
168
169impl<'a> BinlogStruct<'a> for UserVarEvent<'a> {
170 fn len(&self, _version: BinlogVersion) -> usize {
171 let mut len = S(0);
172
173 len += S(4);
174 len += S(min(self.name.0.len(), u32::MAX as usize));
175 len += S(1);
176
177 if !self.is_null {
178 len += S(1);
179 len += S(4);
180 len += S(4);
181 len += S(min(self.value.len(), u32::MAX as usize));
182 len += S(1);
183 }
184
185 min(len.0, u32::MAX as usize - BinlogEventHeader::LEN)
186 }
187}