mirror of
https://github.com/girlbossceo/conduwuit.git
synced 2025-03-14 18:55:37 +00:00
add Option support to database deserializer
Signed-off-by: Jason Volk <jason@zemos.net>
This commit is contained in:
parent
2fa9621f3a
commit
ea49b60273
2 changed files with 176 additions and 6 deletions
|
@ -22,7 +22,7 @@ pub(crate) fn from_slice<'a, T>(buf: &'a [u8]) -> Result<T>
|
|||
where
|
||||
T: Deserialize<'a>,
|
||||
{
|
||||
let mut deserializer = Deserializer { buf, pos: 0, seq: false };
|
||||
let mut deserializer = Deserializer { buf, pos: 0, rec: 0, seq: false };
|
||||
|
||||
T::deserialize(&mut deserializer).debug_inspect(|_| {
|
||||
deserializer
|
||||
|
@ -35,6 +35,7 @@ where
|
|||
pub(crate) struct Deserializer<'de> {
|
||||
buf: &'de [u8],
|
||||
pos: usize,
|
||||
rec: usize,
|
||||
seq: bool,
|
||||
}
|
||||
|
||||
|
@ -107,7 +108,7 @@ impl<'de> Deserializer<'de> {
|
|||
/// consumed None is returned instead.
|
||||
#[inline]
|
||||
fn record_peek_byte(&self) -> Option<u8> {
|
||||
let started = self.pos != 0;
|
||||
let started = self.pos != 0 || self.rec > 0;
|
||||
let buf = &self.buf[self.pos..];
|
||||
debug_assert!(
|
||||
!started || buf[0] == Self::SEP,
|
||||
|
@ -121,13 +122,14 @@ impl<'de> Deserializer<'de> {
|
|||
/// the start of the next record. (Case for some sequences)
|
||||
#[inline]
|
||||
fn record_start(&mut self) {
|
||||
let started = self.pos != 0;
|
||||
let started = self.pos != 0 || self.rec > 0;
|
||||
debug_assert!(
|
||||
!started || self.buf[self.pos] == Self::SEP,
|
||||
"Missing expected record separator at current position"
|
||||
);
|
||||
|
||||
self.inc_pos(started.into());
|
||||
self.inc_rec(1);
|
||||
}
|
||||
|
||||
/// Consume all remaining bytes, which may include record separators,
|
||||
|
@ -157,6 +159,9 @@ impl<'de> Deserializer<'de> {
|
|||
debug_assert!(self.pos <= self.buf.len(), "pos out of range");
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn inc_rec(&mut self, n: usize) { self.rec = self.rec.saturating_add(n); }
|
||||
|
||||
/// Unconsumed input bytes.
|
||||
#[inline]
|
||||
fn remaining(&self) -> Result<usize> {
|
||||
|
@ -270,8 +275,16 @@ impl<'a, 'de: 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
|
|||
}
|
||||
|
||||
#[cfg_attr(unabridged, tracing::instrument(level = "trace", skip_all))]
|
||||
fn deserialize_option<V: Visitor<'de>>(self, _visitor: V) -> Result<V::Value> {
|
||||
unhandled!("deserialize Option not implemented")
|
||||
fn deserialize_option<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
|
||||
if self
|
||||
.buf
|
||||
.get(self.pos)
|
||||
.is_none_or(|b| *b == Deserializer::SEP)
|
||||
{
|
||||
visitor.visit_none()
|
||||
} else {
|
||||
visitor.visit_some(self)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg_attr(unabridged, tracing::instrument(level = "trace", skip_all))]
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
use std::fmt::Debug;
|
||||
|
||||
use arrayvec::ArrayVec;
|
||||
use conduwuit::ruma::{serde::Raw, RoomId, UserId};
|
||||
use conduwuit::ruma::{serde::Raw, EventId, RoomId, UserId};
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::{
|
||||
|
@ -389,3 +389,160 @@ fn de_complex() {
|
|||
|
||||
assert_eq!(arr, key, "deserialization of serialization does not match");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn serde_tuple_option_value_some() {
|
||||
let room_id: &RoomId = "!room:example.com".try_into().unwrap();
|
||||
let user_id: &UserId = "@user:example.com".try_into().unwrap();
|
||||
|
||||
let mut aa = Vec::<u8>::new();
|
||||
aa.extend_from_slice(room_id.as_bytes());
|
||||
aa.push(0xFF);
|
||||
aa.extend_from_slice(user_id.as_bytes());
|
||||
|
||||
let bb: (&RoomId, Option<&UserId>) = (room_id, Some(user_id));
|
||||
let bbs = serialize_to_vec(&bb).expect("failed to serialize tuple");
|
||||
assert_eq!(aa, bbs);
|
||||
|
||||
let cc: (&RoomId, Option<&UserId>) =
|
||||
de::from_slice(&bbs).expect("failed to deserialize tuple");
|
||||
|
||||
assert_eq!(bb.1, cc.1);
|
||||
assert_eq!(cc.0, bb.0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn serde_tuple_option_value_none() {
|
||||
let room_id: &RoomId = "!room:example.com".try_into().unwrap();
|
||||
|
||||
let mut aa = Vec::<u8>::new();
|
||||
aa.extend_from_slice(room_id.as_bytes());
|
||||
aa.push(0xFF);
|
||||
|
||||
let bb: (&RoomId, Option<&UserId>) = (room_id, None);
|
||||
let bbs = serialize_to_vec(&bb).expect("failed to serialize tuple");
|
||||
assert_eq!(aa, bbs);
|
||||
|
||||
let cc: (&RoomId, Option<&UserId>) =
|
||||
de::from_slice(&bbs).expect("failed to deserialize tuple");
|
||||
|
||||
assert_eq!(None, cc.1);
|
||||
assert_eq!(cc.0, bb.0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn serde_tuple_option_none_value() {
|
||||
let user_id: &UserId = "@user:example.com".try_into().unwrap();
|
||||
|
||||
let mut aa = Vec::<u8>::new();
|
||||
aa.push(0xFF);
|
||||
aa.extend_from_slice(user_id.as_bytes());
|
||||
|
||||
let bb: (Option<&RoomId>, &UserId) = (None, user_id);
|
||||
let bbs = serialize_to_vec(&bb).expect("failed to serialize tuple");
|
||||
assert_eq!(aa, bbs);
|
||||
|
||||
let cc: (Option<&RoomId>, &UserId) =
|
||||
de::from_slice(&bbs).expect("failed to deserialize tuple");
|
||||
|
||||
assert_eq!(None, cc.0);
|
||||
assert_eq!(cc.1, bb.1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn serde_tuple_option_some_value() {
|
||||
let room_id: &RoomId = "!room:example.com".try_into().unwrap();
|
||||
let user_id: &UserId = "@user:example.com".try_into().unwrap();
|
||||
|
||||
let mut aa = Vec::<u8>::new();
|
||||
aa.extend_from_slice(room_id.as_bytes());
|
||||
aa.push(0xFF);
|
||||
aa.extend_from_slice(user_id.as_bytes());
|
||||
|
||||
let bb: (Option<&RoomId>, &UserId) = (Some(room_id), user_id);
|
||||
let bbs = serialize_to_vec(&bb).expect("failed to serialize tuple");
|
||||
assert_eq!(aa, bbs);
|
||||
|
||||
let cc: (Option<&RoomId>, &UserId) =
|
||||
de::from_slice(&bbs).expect("failed to deserialize tuple");
|
||||
|
||||
assert_eq!(bb.0, cc.0);
|
||||
assert_eq!(cc.1, bb.1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn serde_tuple_option_some_some() {
|
||||
let room_id: &RoomId = "!room:example.com".try_into().unwrap();
|
||||
let user_id: &UserId = "@user:example.com".try_into().unwrap();
|
||||
|
||||
let mut aa = Vec::<u8>::new();
|
||||
aa.extend_from_slice(room_id.as_bytes());
|
||||
aa.push(0xFF);
|
||||
aa.extend_from_slice(user_id.as_bytes());
|
||||
|
||||
let bb: (Option<&RoomId>, Option<&UserId>) = (Some(room_id), Some(user_id));
|
||||
let bbs = serialize_to_vec(&bb).expect("failed to serialize tuple");
|
||||
assert_eq!(aa, bbs);
|
||||
|
||||
let cc: (Option<&RoomId>, Option<&UserId>) =
|
||||
de::from_slice(&bbs).expect("failed to deserialize tuple");
|
||||
|
||||
assert_eq!(cc.0, bb.0);
|
||||
assert_eq!(bb.1, cc.1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn serde_tuple_option_none_none() {
|
||||
let aa = vec![0xFF];
|
||||
|
||||
let bb: (Option<&RoomId>, Option<&UserId>) = (None, None);
|
||||
let bbs = serialize_to_vec(&bb).expect("failed to serialize tuple");
|
||||
assert_eq!(aa, bbs);
|
||||
|
||||
let cc: (Option<&RoomId>, Option<&UserId>) =
|
||||
de::from_slice(&bbs).expect("failed to deserialize tuple");
|
||||
|
||||
assert_eq!(cc.0, bb.0);
|
||||
assert_eq!(None, cc.1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn serde_tuple_option_some_none_some() {
|
||||
let room_id: &RoomId = "!room:example.com".try_into().unwrap();
|
||||
let user_id: &UserId = "@user:example.com".try_into().unwrap();
|
||||
|
||||
let mut aa = Vec::<u8>::new();
|
||||
aa.extend_from_slice(room_id.as_bytes());
|
||||
aa.push(0xFF);
|
||||
aa.push(0xFF);
|
||||
aa.extend_from_slice(user_id.as_bytes());
|
||||
|
||||
let bb: (Option<&RoomId>, Option<&EventId>, Option<&UserId>) =
|
||||
(Some(room_id), None, Some(user_id));
|
||||
|
||||
let bbs = serialize_to_vec(&bb).expect("failed to serialize tuple");
|
||||
assert_eq!(aa, bbs);
|
||||
|
||||
let cc: (Option<&RoomId>, Option<&EventId>, Option<&UserId>) =
|
||||
de::from_slice(&bbs).expect("failed to deserialize tuple");
|
||||
|
||||
assert_eq!(bb.0, cc.0);
|
||||
assert_eq!(None, cc.1);
|
||||
assert_eq!(bb.1, cc.1);
|
||||
assert_eq!(bb.2, cc.2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn serde_tuple_option_none_none_none() {
|
||||
let aa = vec![0xFF, 0xFF];
|
||||
|
||||
let bb: (Option<&RoomId>, Option<&EventId>, Option<&UserId>) = (None, None, None);
|
||||
let bbs = serialize_to_vec(&bb).expect("failed to serialize tuple");
|
||||
assert_eq!(aa, bbs);
|
||||
|
||||
let cc: (Option<&RoomId>, Option<&EventId>, Option<&UserId>) =
|
||||
de::from_slice(&bbs).expect("failed to deserialize tuple");
|
||||
|
||||
assert_eq!(None, cc.0);
|
||||
assert_eq!(bb, cc);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue