//! # Representing, reading, and writing Preserves `Value`s as Rust data //! //! ``` //! use preserves::value::{IOValue, text, packed}; //! let v: IOValue = text::iovalue_from_str("")?; //! let w: IOValue = packed::iovalue_from_bytes(b"\xb4\xb3\x02hi\x84")?; //! assert_eq!(v, w); //! assert_eq!(text::TextWriter::encode_iovalue(&v)?, ""); //! assert_eq!(packed::PackedWriter::encode_iovalue(&v)?, b"\xb4\xb3\x02hi\x84"); //! # Ok::<(), std::io::Error>(()) //! ``` //! //! Preserves `Value`s are categorized in the following way. The core representation type, //! [crate::value::repr::Value], reflects this structure. However, most of the time you will //! work with [IOValue] or some other implementation of trait [NestedValue], which augments an //! underlying [Value] with [*annotations*][crate::value::repr::Annotations] (e.g. comments) and fixes a strategy //! for memory management. //! #![doc = include_str!("../../doc/value-grammar.md")] //! //! ## Memory management //! //! Each implementation of [NestedValue] chooses a different point in the space of possible //! approaches to memory management for `Value`s. //! //! ##### `IOValue` //! //! The most commonly-used and versatile implementation, [IOValue], uses [std::sync::Arc] for //! internal links in compound `Value`s. Unlike many of the other implementations of //! [NestedValue], [IOValue] doesn't offer flexibility in the Rust data type to be used for //! Preserves [embedded values](https://preserves.dev/preserves.html#embeddeds): instead, //! embedded values in an [IOValue] are themselves [IOValue]s. //! //! ##### `ArcValue`, `RcValue`, and `PlainValue` //! //! For control over the Rust type to use for embedded values, choose [ArcValue], [RcValue], or //! [PlainValue]. Use [ArcValue] when you wish to transfer values among threads. [RcValue] is //! more niche; it may be useful for complex terms that do not need to cross thread boundaries. //! [PlainValue] is even more niche: it does not use a reference-counted pointer type, meaning //! it does not offer any kind of aliasing or sharing among subterms at all. //! //! # Parsing, pretty-printing, encoding and decoding `Value`s //! //! Modules [reader] and [writer] supply generic [Reader] and [Writer] traits for parsing and //! unparsing Preserves data. Implementations of [Reader] and [Writer] connect Preserves data //! to specific transfer syntaxes: //! //! - module [packed] supplies tools for working with the machine-oriented binary syntax //! - module [text] supplies tools for working with human-readable text syntax pub mod boundary; pub mod de; pub mod domain; pub mod magic; pub mod merge; pub mod packed; pub mod reader; pub mod repr; pub mod ser; pub mod signed_integer; pub mod suspendable; pub mod text; pub mod writer; pub use de::from_value; pub use de::Deserializer; pub use domain::DebugDomainEncode; pub use domain::DomainDecode; pub use domain::DomainEncode; pub use domain::DomainParse; pub use domain::FromStrDomainParse; pub use domain::IOValueDomainCodec; pub use domain::NoEmbeddedDomainCodec; pub use domain::ViaCodec; pub use merge::merge; pub use packed::PackedReader; pub use packed::PackedWriter; pub use reader::BinarySource; pub use reader::BytesBinarySource; pub use reader::ConfiguredReader; pub use reader::IOBinarySource; pub use reader::Reader; pub use reader::Token; pub use repr::AnnotatedValue; pub use repr::ArcValue; pub use repr::AtomClass; pub use repr::CompoundClass; pub use repr::Domain; pub use repr::Double; pub use repr::DummyValue; pub use repr::Embeddable; pub use repr::IOValue; pub use repr::Map; pub use repr::NestedValue; pub use repr::PlainValue; pub use repr::RcValue; pub use repr::Record; pub use repr::Set; pub use repr::UnwrappedIOValue; pub use repr::Value; pub use repr::ValueClass; pub use ser::to_value; pub use ser::Serializer; pub use text::TextReader; pub use text::ToplevelWhitespaceMode; pub use text::TextWriter; pub use writer::Writer; #[doc(hidden)] pub fn invert_map(m: &Map) -> Map where A: Clone, B: Clone + Ord, { m.iter().map(|(a, b)| (b.clone(), a.clone())).collect() }