1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
#![deny(missing_docs)]
#![warn(rust_2018_idioms)]

//! This crate provides [Serde]-based serialization and deserialization from
//! statically-typed Rust data structures to S-expressions, both using the
//! [`lexpr::Value`] type and to S-expression textual representation.
//!
//! # About representations
//!
//! The guiding principle for choosing the S-expression representation of Rust
//! types is that it should look "natural" (or ideomatic) to a Lisp programmer,
//! without introducing ambiguities.
//!
//! ## Sequences
//!
//! The serializer will represent serde sequences as lists. Note that `Vec` is
//! considered a sequence, so it will be, perhaps counterintuitevely, be
//! represented by an S-expression list, instead of an S-expression
//! vector. While it would be possible to serialize all sequences as
//! S-expression vectors instead, this would lead to unideomatic (noisy)
//! S-expressions. When deserializing, both vectors and (proper) lists are
//! accepted when a Serde sequence is expected.
//!
//! ```
//! use serde_lexpr::{from_str, to_string};
//!
//! let v1: Vec<u32> = from_str("(1 2 3)").unwrap();
//! assert_eq!(v1, vec![1, 2, 3]);
//! assert_eq!(to_string(&v1).unwrap(), "(1 2 3)".to_string());
//! let v2: Vec<u32> = from_str("#(1 2 3)").unwrap();
//! assert_eq!(v1, v2);
//! assert_eq!(to_string(&v2).unwrap(), "(1 2 3)".to_string());
//! ```
//!
//! # Option
//!
//! The two variants of the `Option` type are represented as empty list
//! (representing `None`) or a single-element list (representing
//! `Some(x)`). This representation is chosen for unambiguity over using a
//! special "missing" value (such as `#nil`) for `None` and a plain value for
//! `Some`. It also combines nicely with struct fields containing option values.
//!
//! ```
//! use serde_lexpr::{from_str, to_string};
//!
//! let answer: Option<u32> = from_str("(42)").unwrap();
//! assert_eq!(answer, Some(42));
//! let no_answer: Option<u32> = from_str("()").unwrap();
//! assert_eq!(no_answer, None);
//! ```
//!
//! ## Tuples and tuple structs
//!
//! Tuples and tuple structs are serialized as S-expression vectors.
//!
//! ```
//! use serde_lexpr::{from_str, to_string};
//! use serde_derive::{Serialize, Deserialize};
//!
//! assert_eq!(to_string(&(1, "two", 3)).unwrap(), "#(1 \"two\" 3)".to_string());
//! let tuple: (u8, String, u64) = from_str("(1 \"two\" 3)").unwrap();
//! assert_eq!(tuple, (1, "two".to_string(), 3));
//!
//! #[derive(Serialize, Deserialize, Debug, PartialEq, Eq)]
//! struct Person(String, u8);
//!
//! assert_eq!(to_string(&Person("Billy".into(), 42)).unwrap(), "#(\"Billy\" 42)".to_string());
//! let joanne: Person = from_str("#(\"Joanne\" 23)").unwrap();
//! assert_eq!(joanne, Person("Joanne".into(), 23));
//! ```
//!
//! ## Structs
//!
//! Structs are serialized as association lists, i.e. a list consisting of cons
//! cells, where each cell's `car` is the name of the struct field (as a
//! symbol), and the `cdr` containing the field's value.
//!
//! ```
//! use serde_lexpr::{from_str, to_string};
//! use serde_derive::{Serialize, Deserialize};
//!
//! #[derive(Serialize, Deserialize, Debug, PartialEq, Eq)]
//! struct Person {
//!   name: String,
//!   age: u8,
//! };
//!
//! let billy = Person { name: "Billy".into(), age: 42 };
//! assert_eq!(to_string(&billy).unwrap(), "((name . \"Billy\") (age . 42))".to_string());
//! let joanne: Person = from_str("((name . \"Joanne\") (age . 23))").unwrap();
//! assert_eq!(joanne, Person { name: "Joanne".into(), age: 23 });
//! ```
//!
//! ## Enums
//!
//! Enum variants without data are serialized as plain symbols. Tuple variants
//! are serialized as a list starting with the variant name as a symbol,
//! followed by the values. This representation is chosen over using a vector to
//! keep the emitted S-expressions less noisy and hopefully a bit more
//! ideomatic. Struct variants are serialized like structs (i.e. as association
//! lists), but have the variant name prepended as a symbol.
//!
//! ```
//! use serde_lexpr::{from_str, to_string};
//! use serde_derive::{Serialize, Deserialize};
//!
//! #[derive(Serialize, Deserialize, Debug, PartialEq, Eq)]
//! #[serde(rename_all = "kebab-case")]
//! enum Choice {
//!   Yes,
//!   No,
//!   Other(String),
//! }
//!
//! let choices: Vec<Choice> = from_str("(yes no (other . \"foo\"))").unwrap();
//! assert_eq!(choices, vec![Choice::Yes, Choice::No, Choice::Other("foo".into())]);
//!
//! #[derive(Serialize, Deserialize, Debug, PartialEq, Eq)]
//! #[serde(rename_all = "kebab-case")]
//! enum Example {
//!   Unit,
//!   Newtype(u32),
//!   NewtypeOption(Option<u32>),
//!   Tuple(u32, u32),
//!   Struct { foo: bool, bar: u32 },
//! }
//!
//! let unit: Example = from_str("unit").unwrap();
//! assert_eq!(unit, Example::Unit);
//!
//! let newtype: Example = from_str("(newtype . 42)").unwrap();
//! assert_eq!(newtype, Example::Newtype(42));
//!
//! let newtype_some: Example = from_str("(newtype-option 23)").unwrap();
//! assert_eq!(newtype_some, Example::NewtypeOption(Some(23)));
//!
//! let newtype_none: Example = from_str("(newtype-option)").unwrap();
//! assert_eq!(newtype_none, Example::NewtypeOption(None));
//!
//! let tuple: Example = from_str("(tuple 1 2)").unwrap();
//! assert_eq!(tuple, Example::Tuple(1, 2));
//!
//! let struct_variant: Example = from_str("(struct (foo . #t) (bar . 3))").unwrap();
//! assert_eq!(struct_variant, Example::Struct { foo: true, bar: 3 });
//! ```
//!
//! [Serde]: https://crates.io/crates/serde
//! [`lexpr::Value`]: https://docs.rs/lexpr/*/lexpr/enum.Value.html

mod de;
mod ser;
mod value;

pub mod error;
pub use de::{
    from_reader, from_reader_custom, from_slice, from_slice_custom, from_str, from_str_custom,
};
pub use error::{Error, Result};
pub use ser::{to_string, to_string_custom, to_vec, to_vec_custom, to_writer, to_writer_custom};
pub use value::{from_value, to_value, Cons, Value};

// This is exposed for convenience (allowing importing via `serde_lexpr`) and so
// that links from the `Value` documentation work.
pub use lexpr::{parse, print};