add IgnoreAll directive to deserializer
Signed-off-by: Jason Volk <jason@zemos.net>
This commit is contained in:
parent
d3d11356ee
commit
19880ce12b
2 changed files with 26 additions and 3 deletions
|
@ -5,6 +5,7 @@ use serde::{
|
||||||
Deserialize,
|
Deserialize,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Deserialize into T from buffer.
|
||||||
pub(crate) fn from_slice<'a, T>(buf: &'a [u8]) -> Result<T>
|
pub(crate) fn from_slice<'a, T>(buf: &'a [u8]) -> Result<T>
|
||||||
where
|
where
|
||||||
T: Deserialize<'a>,
|
T: Deserialize<'a>,
|
||||||
|
@ -22,6 +23,7 @@ where
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Deserialization state.
|
||||||
pub(crate) struct Deserializer<'de> {
|
pub(crate) struct Deserializer<'de> {
|
||||||
buf: &'de [u8],
|
buf: &'de [u8],
|
||||||
pos: usize,
|
pos: usize,
|
||||||
|
@ -33,6 +35,11 @@ pub(crate) struct Deserializer<'de> {
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
pub struct Ignore;
|
pub struct Ignore;
|
||||||
|
|
||||||
|
/// Directive to ignore all remaining records. This can be used in a sequence to
|
||||||
|
/// ignore the rest of the sequence.
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
pub struct IgnoreAll;
|
||||||
|
|
||||||
impl<'de> Deserializer<'de> {
|
impl<'de> Deserializer<'de> {
|
||||||
/// Record separator; an intentionally invalid-utf8 byte.
|
/// Record separator; an intentionally invalid-utf8 byte.
|
||||||
const SEP: u8 = b'\xFF';
|
const SEP: u8 = b'\xFF';
|
||||||
|
@ -53,6 +60,13 @@ impl<'de> Deserializer<'de> {
|
||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Called at the start of arrays and tuples
|
||||||
|
#[inline]
|
||||||
|
fn sequence_start(&mut self) {
|
||||||
|
debug_assert!(!self.seq, "Nested sequences are not handled at this time");
|
||||||
|
self.seq = true;
|
||||||
|
}
|
||||||
|
|
||||||
/// Consume the current record to ignore it. Inside a sequence the next
|
/// Consume the current record to ignore it. Inside a sequence the next
|
||||||
/// record is skipped but at the top-level all records are skipped such that
|
/// record is skipped but at the top-level all records are skipped such that
|
||||||
/// deserialization completes with self.finished() == Ok.
|
/// deserialization completes with self.finished() == Ok.
|
||||||
|
@ -61,10 +75,16 @@ impl<'de> Deserializer<'de> {
|
||||||
if self.seq {
|
if self.seq {
|
||||||
self.record_next();
|
self.record_next();
|
||||||
} else {
|
} else {
|
||||||
self.record_trail();
|
self.record_ignore_all();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Consume the current and all remaining records to ignore them. Similar to
|
||||||
|
/// Ignore at the top-level, but it can be provided in a sequence to Ignore
|
||||||
|
/// all remaining elements.
|
||||||
|
#[inline]
|
||||||
|
fn record_ignore_all(&mut self) { self.record_trail(); }
|
||||||
|
|
||||||
/// Consume the current record. The position pointer is moved to the start
|
/// Consume the current record. The position pointer is moved to the start
|
||||||
/// of the next record. Slice of the current record is returned.
|
/// of the next record. Slice of the current record is returned.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -101,7 +121,6 @@ impl<'de> Deserializer<'de> {
|
||||||
);
|
);
|
||||||
|
|
||||||
self.inc_pos(started.into());
|
self.inc_pos(started.into());
|
||||||
self.seq = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Consume all remaining bytes, which may include record separators,
|
/// Consume all remaining bytes, which may include record separators,
|
||||||
|
@ -128,6 +147,7 @@ impl<'a, 'de: 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
|
||||||
where
|
where
|
||||||
V: Visitor<'de>,
|
V: Visitor<'de>,
|
||||||
{
|
{
|
||||||
|
self.sequence_start();
|
||||||
visitor.visit_seq(self)
|
visitor.visit_seq(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,6 +155,7 @@ impl<'a, 'de: 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
|
||||||
where
|
where
|
||||||
V: Visitor<'de>,
|
V: Visitor<'de>,
|
||||||
{
|
{
|
||||||
|
self.sequence_start();
|
||||||
visitor.visit_seq(self)
|
visitor.visit_seq(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,6 +163,7 @@ impl<'a, 'de: 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
|
||||||
where
|
where
|
||||||
V: Visitor<'de>,
|
V: Visitor<'de>,
|
||||||
{
|
{
|
||||||
|
self.sequence_start();
|
||||||
visitor.visit_seq(self)
|
visitor.visit_seq(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,6 +192,7 @@ impl<'a, 'de: 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
|
||||||
{
|
{
|
||||||
match name {
|
match name {
|
||||||
"Ignore" => self.record_ignore(),
|
"Ignore" => self.record_ignore(),
|
||||||
|
"IgnoreAll" => self.record_ignore_all(),
|
||||||
_ => unimplemented!("Unrecognized deserialization Directive {name:?}"),
|
_ => unimplemented!("Unrecognized deserialization Directive {name:?}"),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@ extern crate rust_rocksdb as rocksdb;
|
||||||
|
|
||||||
pub use self::{
|
pub use self::{
|
||||||
database::Database,
|
database::Database,
|
||||||
de::Ignore,
|
de::{Ignore, IgnoreAll},
|
||||||
deserialized::Deserialized,
|
deserialized::Deserialized,
|
||||||
handle::Handle,
|
handle::Handle,
|
||||||
keyval::{KeyVal, Slice},
|
keyval::{KeyVal, Slice},
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue