apple_plist/lib.rs
1//! Apple property-list serialization for Rust: XML, binary (`bplist00`),
2//! OpenStep, and GNUStep — encode and decode.
3//!
4//! `apple-plist` is a serde-native Rust library for Apple property lists.
5//! Unlike most Rust plist crates it targets **all four** Apple property-list
6//! dialects in both directions, handling the edge cases that show up in
7//! real-world files.
8//!
9//! # Quick start
10//!
11//! Decoding auto-detects the format; encoding picks the format you name:
12//!
13//! ```
14//! use apple_plist::{Format, Value, detect};
15//!
16//! let bytes = apple_plist::to_vec(&true, Format::Xml)?;
17//! assert!(bytes.ends_with(b"<true/></plist>"));
18//!
19//! let value: Value = apple_plist::from_slice(&bytes)?;
20//! assert_eq!(value, Value::Boolean(true));
21//! assert_eq!(detect(&bytes), Some(Format::Xml));
22//! # Ok::<(), apple_plist::Error>(())
23//! ```
24//!
25//! Streaming and `Value`-tree variants live on [`Encoder`] and [`Decoder`];
26//! both compile with every feature combination and work without `serde`.
27//!
28//! # Status
29//!
30//! The full surface is implemented: the core data model ([`Value`] and its
31//! nine cases, [`Integer`], [`Real`], [`Date`], [`Uid`], the [`Error`]
32//! model, [`Format`], the depth bound), all four codecs behind their feature
33//! gates, format auto-detection ([`detect`], the XML-to-text retry ladder),
34//! and the serde bridge ([`to_vec`], [`from_slice`], [`to_value`],
35//! [`from_value`], and friends).
36//!
37//! # Cargo features
38//!
39//! All on by default; every combination compiles and features only add API:
40//!
41//! - `serde` — derive-driven (de)serialization: [`Encoder::encode`],
42//! [`Decoder::decode`], and the free functions [`to_vec`],
43//! [`to_vec_indent`], [`to_writer`], [`from_slice`], [`from_reader`],
44//! [`to_value`], [`from_value`].
45//! - `xml` — the XML codec.
46//! - `binary` — the binary (`bplist00`) codec.
47//! - `openstep` — the OpenStep/GNUStep text codec (one feature: the two
48//! dialects share a parser, and OpenStep-versus-GNUStep is a runtime
49//! outcome).
50//!
51//! Decoding a format whose feature is compiled out fails with
52//! [`Error::InvalidPlist`] from its rung of the detection ladder; encoding
53//! one fails with [`Error::FeatureDisabled`].
54
55mod date;
56mod depth;
57mod error;
58mod format;
59#[cfg(any(test, feature = "serde", feature = "xml", feature = "openstep"))]
60mod scalar;
61mod uid;
62mod value;
63
64#[cfg(feature = "binary")]
65mod binary;
66mod de;
67mod ser;
68#[cfg(feature = "openstep")]
69mod text;
70#[cfg(feature = "xml")]
71mod xml;
72
73pub use crate::date::Date;
74pub use crate::de::{Decoder, detect};
75#[cfg(feature = "serde")]
76pub use crate::de::{from_reader, from_slice};
77pub use crate::depth::MAX_PARSE_DEPTH;
78pub use crate::error::{Error, Result};
79pub use crate::format::Format;
80pub use crate::ser::Encoder;
81#[cfg(feature = "serde")]
82pub use crate::ser::{to_vec, to_vec_indent, to_writer};
83pub use crate::uid::Uid;
84#[cfg(feature = "serde")]
85pub use crate::value::de::from_value;
86#[cfg(feature = "serde")]
87pub use crate::value::ser::to_value;
88pub use crate::value::{Dictionary, Integer, Real, Value};