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
// for a `PropertyString`, which performs its own checking.
thread_local! {
}
}
-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() {
let begin = *at;
}
};
- if input[..end].is_empty() {
+ if begin == end || input[..end].is_empty() {
continue;
}
}
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 self.count == max {
return Err(Error::msg("too many elements"));
where
T: de::DeserializeSeed<'de>,
{
- while self.at != self.input.len() {
- let begin = self.at;
-
- let input = &self.input[self.at..];
-
- let end = if self.has_null {
- input.find('\0')
- } else {
- input.find(|c: char| c == ',' || c == ';' || char::is_ascii_whitespace(&c))
- };
-
- let end = match end {
- None => {
- self.at = self.input.len();
- input.len()
- }
- Some(pos) => {
- self.at += pos + 1;
- pos
- }
- };
-
- if input[..end].is_empty() {
- continue;
- }
-
- return seed
- .deserialize(NoSchemaDeserializer::new(match &self.input {
- Cow3::Original(input) => Cow::Borrowed(&input[begin..end]),
- Cow3::Intermediate(input) => Cow::Owned(input[begin..end].to_string()),
- Cow3::Owned(input) => Cow::Owned(input[begin..end].to_string()),
- }))
- .map(Some);
- }
+ let range = match super::next_str_entry(&self.input, &mut self.at, self.has_null) {
+ None => return Ok(None),
+ Some(range) => range,
+ };
+
+ seed.deserialize(NoSchemaDeserializer::new(match &self.input {
+ Cow3::Original(input) => Cow::Borrowed(&input[range]),
+ Cow3::Intermediate(input) => Cow::Owned(input[range].to_string()),
+ Cow3::Owned(input) => Cow::Owned(input[range].to_string()),
+ }))
+ .map(Some)
+ }
+}
+
+pub fn split_list(input: &str) -> SplitList<'_> {
+ SplitList {
+ has_null: input.contains('\0'),
+ input,
+ at: 0,
+ }
+}
+
+pub struct SplitList<'a> {
+ input: &'a str,
+ has_null: bool,
+ at: usize,
+}
+
+impl<'a> Iterator for SplitList<'a> {
+ type Item = &'a str;
- Ok(None)
+ fn next(&mut self) -> Option<&'a str> {
+ let range = super::next_str_entry(&self.input, &mut self.at, self.has_null)?;
+ Some(&self.input[range])
}
}