use crate::de::ParserConfig;
use crate::error::Result;
use crate::parser;
use crate::prelude::*;
#[cfg(feature = "std")]
use crate::span_context::{self, SpanTree};
use crate::value::Value;
#[cfg(not(feature = "std"))]
use alloc::vec::IntoIter;
#[cfg(feature = "std")]
use std::vec::IntoIter;
#[derive(Debug)]
pub struct DocumentIterator {
docs: IntoIter<Value>,
#[cfg(feature = "std")]
_span_trees: Vec<SpanTree>,
total: usize,
}
impl DocumentIterator {
#[must_use]
pub fn len(&self) -> usize {
self.total
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.total == 0
}
}
impl Iterator for DocumentIterator {
type Item = Result<Value>;
fn next(&mut self) -> Option<Self::Item> {
self.docs.next().map(Ok)
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.docs.size_hint()
}
}
impl ExactSizeIterator for DocumentIterator {}
pub fn load_all(input: &str) -> Result<DocumentIterator> {
load_all_with_config(input, &ParserConfig::default())
}
pub fn load_all_with_config(input: &str, config: &ParserConfig) -> Result<DocumentIterator> {
if input.len() > config.max_document_length {
return Err(crate::error::Error::Parse(format!(
"document exceeds maximum length of {} bytes",
config.max_document_length
)));
}
let parse_config = parser::ParseConfig::from(config);
#[cfg(feature = "std")]
{
let pairs = parser::parse(input, &parse_config)?;
let (docs, span_trees): (Vec<_>, Vec<_>) = pairs.into_iter().unzip();
let total = docs.len();
Ok(DocumentIterator {
docs: docs.into_iter(),
_span_trees: span_trees,
total,
})
}
#[cfg(not(feature = "std"))]
{
let docs = parser::parse_all_values(input, &parse_config)?;
let total = docs.len();
Ok(DocumentIterator {
docs: docs.into_iter(),
total,
})
}
}
pub fn try_load_all(input: &str) -> Result<DocumentIterator> {
load_all(input)
}
pub fn load_all_as<T>(input: &str) -> Result<Vec<T>>
where
T: for<'de> serde::Deserialize<'de> + 'static,
{
let parse_config = parser::ParseConfig::from(&ParserConfig::default());
#[cfg(feature = "std")]
{
let pairs = parser::parse(input, &parse_config)?;
let mut results = Vec::with_capacity(pairs.len());
let source: Arc<str> = input.into();
for (value, span_tree) in &pairs {
let spans = span_context::build_span_map(value, span_tree);
let ctx = span_context::SpanContext {
spans,
source: source.clone(),
};
let _guard = span_context::set_span_context(ctx);
let typed: T = crate::from_value(value)?;
results.push(typed);
}
Ok(results)
}
#[cfg(not(feature = "std"))]
{
let docs = parser::parse_all_values(input, &parse_config)?;
let mut results = Vec::with_capacity(docs.len());
for value in &docs {
let typed: T = crate::from_value(value)?;
results.push(typed);
}
Ok(results)
}
}