preserves/value/mod.rs
1//! # Representing, reading, and writing Preserves `Value`s as Rust data
2//!
3//! ```
4//! use preserves::value::{IOValue, text, packed};
5//! let v: IOValue = text::iovalue_from_str("<hi>")?;
6//! let w: IOValue = packed::iovalue_from_bytes(b"\xb4\xb3\x02hi\x84")?;
7//! assert_eq!(v, w);
8//! assert_eq!(text::TextWriter::encode_iovalue(&v)?, "<hi>");
9//! assert_eq!(packed::PackedWriter::encode_iovalue(&v)?, b"\xb4\xb3\x02hi\x84");
10//! # Ok::<(), std::io::Error>(())
11//! ```
12//!
13//! Preserves `Value`s are categorized in the following way. The core representation type,
14//! [crate::value::repr::Value], reflects this structure. However, most of the time you will
15//! work with [IOValue] or some other implementation of trait [NestedValue], which augments an
16//! underlying [Value] with [*annotations*][crate::value::repr::Annotations] (e.g. comments) and fixes a strategy
17//! for memory management.
18//!
19#![doc = include_str!("../../doc/value-grammar.md")]
20//!
21//! ## Memory management
22//!
23//! Each implementation of [NestedValue] chooses a different point in the space of possible
24//! approaches to memory management for `Value`s.
25//!
26//! ##### `IOValue`
27//!
28//! The most commonly-used and versatile implementation, [IOValue], uses [std::sync::Arc] for
29//! internal links in compound `Value`s. Unlike many of the other implementations of
30//! [NestedValue], [IOValue] doesn't offer flexibility in the Rust data type to be used for
31//! Preserves [embedded values](https://preserves.dev/preserves.html#embeddeds): instead,
32//! embedded values in an [IOValue] are themselves [IOValue]s.
33//!
34//! ##### `ArcValue<D>`, `RcValue<D>`, and `PlainValue<D>`
35//!
36//! For control over the Rust type to use for embedded values, choose [ArcValue], [RcValue], or
37//! [PlainValue]. Use [ArcValue] when you wish to transfer values among threads. [RcValue] is
38//! more niche; it may be useful for complex terms that do not need to cross thread boundaries.
39//! [PlainValue] is even more niche: it does not use a reference-counted pointer type, meaning
40//! it does not offer any kind of aliasing or sharing among subterms at all.
41//!
42//! # Parsing, pretty-printing, encoding and decoding `Value`s
43//!
44//! Modules [reader] and [writer] supply generic [Reader] and [Writer] traits for parsing and
45//! unparsing Preserves data. Implementations of [Reader] and [Writer] connect Preserves data
46//! to specific transfer syntaxes:
47//!
48//! - module [packed] supplies tools for working with the machine-oriented binary syntax
49//! - module [text] supplies tools for working with human-readable text syntax
50
51pub mod boundary;
52pub mod de;
53pub mod domain;
54pub mod magic;
55pub mod merge;
56pub mod packed;
57pub mod reader;
58pub mod repr;
59pub mod ser;
60pub mod signed_integer;
61pub mod suspendable;
62pub mod text;
63pub mod writer;
64
65pub use de::from_value;
66pub use de::Deserializer;
67pub use domain::DebugDomainEncode;
68pub use domain::DomainDecode;
69pub use domain::DomainEncode;
70pub use domain::DomainParse;
71pub use domain::FromStrDomainParse;
72pub use domain::IOValueDomainCodec;
73pub use domain::NoEmbeddedDomainCodec;
74pub use domain::ViaCodec;
75pub use merge::merge;
76pub use packed::PackedReader;
77pub use packed::PackedWriter;
78pub use reader::BinarySource;
79pub use reader::BytesBinarySource;
80pub use reader::ConfiguredReader;
81pub use reader::IOBinarySource;
82pub use reader::Reader;
83pub use reader::Token;
84pub use repr::AnnotatedValue;
85pub use repr::ArcValue;
86pub use repr::AtomClass;
87pub use repr::CompoundClass;
88pub use repr::Domain;
89pub use repr::Double;
90pub use repr::DummyValue;
91pub use repr::Embeddable;
92pub use repr::IOValue;
93pub use repr::Map;
94pub use repr::NestedValue;
95pub use repr::PlainValue;
96pub use repr::RcValue;
97pub use repr::Record;
98pub use repr::Set;
99pub use repr::UnwrappedIOValue;
100pub use repr::Value;
101pub use repr::ValueClass;
102pub use ser::to_value;
103pub use ser::Serializer;
104pub use text::TextReader;
105pub use text::ToplevelWhitespaceMode;
106pub use text::TextWriter;
107pub use writer::Writer;
108
109#[doc(hidden)]
110pub fn invert_map<A, B>(m: &Map<A, B>) -> Map<B, A>
111where
112 A: Clone,
113 B: Clone + Ord,
114{
115 m.iter().map(|(a, b)| (b.clone(), a.clone())).collect()
116}