schema: implement split_list iterator
and reuse splitting code in no_schema's SeqAccess as well Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com> Reviewed-by: Lukas Wagner <l.wagner@proxmox.com>
This commit is contained in:
parent
ae7454b05e
commit
5df9da2af4
@ -19,6 +19,8 @@ pub use extract::ExtractValueDeserializer;
|
|||||||
|
|
||||||
use cow3::{str_slice_to_range, Cow3};
|
use cow3::{str_slice_to_range, Cow3};
|
||||||
|
|
||||||
|
pub use no_schema::{split_list, SplitList};
|
||||||
|
|
||||||
// Used to disable calling `check_constraints` on a `StringSchema` if it is being deserialized
|
// Used to disable calling `check_constraints` on a `StringSchema` if it is being deserialized
|
||||||
// for a `PropertyString`, which performs its own checking.
|
// for a `PropertyString`, which performs its own checking.
|
||||||
thread_local! {
|
thread_local! {
|
||||||
@ -350,7 +352,7 @@ impl<'de, 'i> de::Deserializer<'de> for SchemaDeserializer<'de, 'i> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn next_str_entry(input: &str, at: &mut usize, has_null: bool) -> Option<Range<usize>> {
|
pub(crate) fn next_str_entry(input: &str, at: &mut usize, has_null: bool) -> Option<Range<usize>> {
|
||||||
while *at != input.len() {
|
while *at != input.len() {
|
||||||
let begin = *at;
|
let begin = *at;
|
||||||
|
|
||||||
@ -373,7 +375,7 @@ fn next_str_entry(input: &str, at: &mut usize, has_null: bool) -> Option<Range<u
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if input[..end].is_empty() {
|
if begin == end || input[..end].is_empty() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -420,10 +422,6 @@ impl<'de, 'i, 's> de::SeqAccess<'de> for SeqAccess<'de, 'i, 's> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
while let Some(el_range) = next_str_entry(&self.input, &mut self.at, self.has_null) {
|
while let Some(el_range) = next_str_entry(&self.input, &mut self.at, self.has_null) {
|
||||||
if el_range.is_empty() {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(max) = self.schema.max_length {
|
if let Some(max) = self.schema.max_length {
|
||||||
if self.count == max {
|
if self.count == max {
|
||||||
return Err(Error::msg("too many elements"));
|
return Err(Error::msg("too many elements"));
|
||||||
|
@ -271,41 +271,39 @@ impl<'de, 'i> de::SeqAccess<'de> for SimpleSeqAccess<'de, 'i> {
|
|||||||
where
|
where
|
||||||
T: de::DeserializeSeed<'de>,
|
T: de::DeserializeSeed<'de>,
|
||||||
{
|
{
|
||||||
while self.at != self.input.len() {
|
let range = match super::next_str_entry(&self.input, &mut self.at, self.has_null) {
|
||||||
let begin = self.at;
|
None => return Ok(None),
|
||||||
|
Some(range) => range,
|
||||||
|
};
|
||||||
|
|
||||||
let input = &self.input[self.at..];
|
seed.deserialize(NoSchemaDeserializer::new(match &self.input {
|
||||||
|
Cow3::Original(input) => Cow::Borrowed(&input[range]),
|
||||||
let end = if self.has_null {
|
Cow3::Intermediate(input) => Cow::Owned(input[range].to_string()),
|
||||||
input.find('\0')
|
Cow3::Owned(input) => Cow::Owned(input[range].to_string()),
|
||||||
} else {
|
}))
|
||||||
input.find(|c: char| c == ',' || c == ';' || char::is_ascii_whitespace(&c))
|
.map(Some)
|
||||||
};
|
}
|
||||||
|
}
|
||||||
let end = match end {
|
|
||||||
None => {
|
pub fn split_list(input: &str) -> SplitList<'_> {
|
||||||
self.at = self.input.len();
|
SplitList {
|
||||||
input.len()
|
has_null: input.contains('\0'),
|
||||||
}
|
input,
|
||||||
Some(pos) => {
|
at: 0,
|
||||||
self.at += pos + 1;
|
}
|
||||||
pos
|
}
|
||||||
}
|
|
||||||
};
|
pub struct SplitList<'a> {
|
||||||
|
input: &'a str,
|
||||||
if input[..end].is_empty() {
|
has_null: bool,
|
||||||
continue;
|
at: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
return seed
|
impl<'a> Iterator for SplitList<'a> {
|
||||||
.deserialize(NoSchemaDeserializer::new(match &self.input {
|
type Item = &'a str;
|
||||||
Cow3::Original(input) => Cow::Borrowed(&input[begin..end]),
|
|
||||||
Cow3::Intermediate(input) => Cow::Owned(input[begin..end].to_string()),
|
fn next(&mut self) -> Option<&'a str> {
|
||||||
Cow3::Owned(input) => Cow::Owned(input[begin..end].to_string()),
|
let range = super::next_str_entry(&self.input, &mut self.at, self.has_null)?;
|
||||||
}))
|
Some(&self.input[range])
|
||||||
.map(Some);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(None)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user