use std::fmt;
use std::slice;
use std::vec;
use std::io;
use std::path::Path;
use buffered_reader::BufferedReader;
use crate::Result;
use crate::Error;
use crate::Packet;
use crate::packet::{self, Container};
use crate::parse::PacketParserResult;
use crate::parse::PacketParserBuilder;
use crate::parse::Parse;
use crate::parse::Cookie;
/// An unstructured packet sequence.
///
/// To deserialize an OpenPGP packet stream, use either
/// [`PacketParser`], [`PacketPileParser`], or
/// [`PacketPile::from_file`] (or related routines).
///
/// Normally, you'll want to convert the `PacketPile` to a Cert or a
/// `Message`.
///
/// [`PacketParser`]: parse/struct.PacketParser.html
/// [`PacketPileParser`]: parse/struct.PacketPileParser.html
/// [`PacketPile::from_file`]: struct.PacketPile.html#method.from_file
#[derive(PartialEq, Clone, Default)]
pub struct PacketPile {
/// At the top level, we have a sequence of packets, which may be
/// containers.
top_level: Container,
}
impl fmt::Debug for PacketPile {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("PacketPile")
.field("packets", &self.top_level.children_ref())
.finish()
}
}
impl<'a> Parse<'a, PacketPile> for PacketPile {
/// Deserializes the OpenPGP message stored in a `std::io::Read`
/// object.
///
/// Although this method is easier to use to parse a sequence of
/// OpenPGP packets than a [`PacketParser`] or a
/// [`PacketPileParser`], this interface buffers the whole message
/// in memory. Thus, the caller must be certain that the
/// *deserialized* message is not too large.
///
/// Note: this interface *does* buffer the contents of packets.
///
/// [`PacketParser`]: parse/struct.PacketParser.html
/// [`PacketPileParser`]: parse/struct.PacketPileParser.html
fn from_reader<R: 'a + io::Read>(reader: R) -> Result<PacketPile> {
let bio = buffered_reader::Generic::with_cookie(
reader, None, Cookie::default());
PacketPile::from_buffered_reader(Box::new(bio))
}
/// Deserializes the OpenPGP message stored in the file named by
/// `path`.
///
/// See `from_reader` for more details and caveats.
fn from_file<P: AsRef<Path>>(path: P) -> Result<PacketPile> {
PacketPile::from_buffered_reader(
Box::new(buffered_reader::File::with_cookie(path, Cookie::default())?))
}
/// Deserializes the OpenPGP message stored in the provided buffer.
///
/// See `from_reader` for more details and caveats.
fn from_bytes<D: AsRef<[u8]> + ?Sized>(data: &'a D) -> Result<PacketPile> {
let bio = buffered_reader::Memory::with_cookie(
data.as_ref(), Cookie::default());
PacketPile::from_buffered_reader(Box::new(bio))
}
}
impl std::str::FromStr for PacketPile {
type Err = anyhow::Error;
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
Self::from_bytes(s.as_bytes())
}
}
impl From<Vec<Packet>>