# PEM Iterator
Iterate over PEM-encoded data.
## Features
* Enables decoding PEM formatted data via iterators.
* Parses the pre-encapsulation boundary immediately, lazily parses the rest.
* No dependencies, no unsafe, only requires `core`.
* Optional encapsulation boundary label matching.
## Configuration
### `std` and `store_label`
This is the default configuration. It requires a single allocation, that being the string to store the label.
### `store_label`
Under this configuration, labels are stored in a fixed size buffer (currently 64 bytes) and overflow will result in an error.
### `std`
With this configuration, no allocations are required, as the label is not stored. Consequently labels are not required to match
### No default features
Same as above. Also some minor convenience methods are missing (like the ability to collect `chunked` into a `Vec<u8>`).
## Chunked vs Single
The package provides 2 iterators, `chunked` and `single`. The basic difference is `chunked` reads 3 bytes of output at a time (corresponding to 4 characters of input), while `single` attempts to read only 1 at a time. As a result, `chunked` tends to be faster, with some minor trade offs in usability.
Should `chunked` encounter an error, it will stop parsing, return the error, and then return `None` from then on. Even errors generated by the underlying stream (such as `io::Error`s) will exhibit this behavior.
On the other hand, `single` is more resistant to errors in the underlying stream. Clearing the error should enable `single` to resume parsing. `single` can also recover from errors in the body of the PEM.
Once `single` encounters a `-` character, it will yield any incomplete bytes as if they were padded, and begin parsing the post-encapsulation boundary. `ParseError`s encountered at this point are fatal and halt parsing any further characters from the stream. `SourceError`s should never prevent further parsing, as long as the stream is able to yield further characters.
## Usage
Add this to your `Cargo.toml`:
```toml
[dependencies]
pem-iterator = "0.1"
```
and this to your crate root:
```rust
extern crate pem_iterator;
```
## Example
```rust
extern crate pem_iterator;
use pem_iterator::chunked::Pem;
const SAMPLE: &'static str = "-----BEGIN RSA PRIVATE KEY-----
MIIBPQIBAAJBAOsfi5AGYhdRs/x6q5H7kScxA0Kzzqe6WI6gf6+tc6IvKQJo5rQc
dWWSQ0nRGt2hOPDO+35NKhQEjBQxPh/v7n0CAwEAAQJBAOGaBAyuw0ICyENy5NsO
2gkT00AWTSzM9Zns0HedY31yEabkuFvrMCHjscEF7u3Y6PB7An3IzooBHchsFDei
AAECIQD/JahddzR5K3A6rzTidmAf1PBtqi7296EnWv8WvpfAAQIhAOvowIXZI4Un
DXjgZ9ekuUjZN+GUQRAVlkEEohGLVy59AiEA90VtqDdQuWWpvJX0cM08V10tLXrT
TTGsEtITid1ogAECIQDAaFl90ZgS5cMrL3wCeatVKzVUmuJmB/VAmlLFFGzK0QIh
ANJGc7AFk4fyFD/OezhwGHbWmo/S+bfeAiIh2Ss2FxKJ
-----END RSA PRIVATE KEY-----";
let pem = Pem::from_chars(SAMPLE.chars())?;
println!("PEM label: {}", pem.label());
let data: Result<Vec<u8>, _> = pem.collect();
let data = data?;
println!("data label: {:?}", data);
```