pub fn read<'a, R, T>(
reader: &'a mut R,
) -> impl Iterator<Item = Result<T, Error>> + 'awhere
R: Read + 'a,
T: DeserializeOwned + 'a,Expand description
Create an iterator over YAML documents from any std::io::Read using default options.
This is a convenience wrapper around read_with_options that uses the
same defaults as Options::default except it disables the
max_reader_input_bytes budget to better support long-lived streams.
- It streams the reader without loading the whole input into memory.
- Each item produced by the returned iterator is one deserialized YAML document of type
T. - Empty, untagged null-like, and explicit
!!nulldocuments are skipped. Application-tagged roots are deserialized, even with null payloads.
Generic parameters
R: the concrete reader type implementingstd::io::Read. You almost never need to write this explicitly; the compiler will infer it from thereaderyou pass. When using turbofish, write_to let the compiler inferR.T: the type to deserialize each YAML document into. Must implement [serde::de::DeserializeOwned].
Lifetimes
'a: the lifetime of the returned iterator, tied to the lifetime of the providedreader. The iterator cannot outlive the reader it was created from.
Limits and budget
- Uses the same limits as
Options::default()(events, nodes, nesting depth, total scalar bytes, total comment bytes) and the default alias-replay caps. The only change is thatBudget::max_reader_input_bytesis set toNoneso the streaming iterator can handle arbitrarily long inputs. To customize these limits, callread_with_optionsand setOptions::budget.max_reader_input_bytesin the providedOptions. - Alias replay limits are also enforced with their default values to mitigate alias bombs.
use serde::Deserialize;
#[derive(Debug, Deserialize, PartialEq)]
struct Simple { id: usize }
let yaml = b"id: 1\n---\nid: 2\n";
let mut reader = std::io::Cursor::new(&yaml[..]);
// Type `T` is inferred from the collection target (Vec<Simple>).
let values: Vec<Simple> = serde_saphyr::read(&mut reader)
.map(|r| r.unwrap())
.collect();
assert_eq!(values.len(), 2);
assert_eq!(values[0].id, 1);Specifying only T with turbofish and letting R be inferred using _:
use serde::Deserialize;
#[derive(Debug, Deserialize, PartialEq)]
struct Simple { id: usize }
let yaml = b"id: 10\n---\nid: 20\n";
let mut reader = std::io::Cursor::new(&yaml[..]);
// First turbofish parameter is R (reader type), `_` lets the compiler infer it.
let iter = serde_saphyr::read::<_, Simple>(&mut reader);
let ids: Vec<usize> = iter.map(|res| res.unwrap().id).collect();
assert_eq!(ids, vec![10, 20]);- Each
next()yields eitherOk(T)for a successfully deserialized document orErr(Error)if parsing or deserialization fails. - After a deserialization error (e.g., type mismatch, missing field), the iterator
skips to the next document boundary (
---) and continues. - After a syntax error or budget/alias limit exceeded, the iterator ends.
- Null documents without an application tag are skipped and produce no items.
Note Some content of the next document is read before the current parsed document is emitted.
Hence, while streaming is good for safely parsing large files with multiple documents without
loading it into RAM in advance, it does not emit each document exactly
after --- is encountered.