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
// Copyright 2018 Eduardo Sánchez Muñoz
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.

//! SISE (Simple S-expression) is a file format based on S-expressions.

#[cfg(test)]
mod tests {
    mod parser;
    mod serializer;
    mod read_util;
    mod util;
}

mod pos;
pub use self::pos::Pos;
pub use self::pos::ReprPosValue;
pub use self::pos::PosTree;

mod node;
pub use self::node::Node;

mod builder;
pub use self::builder::BuilderBase;
pub use self::builder::Builder;

mod parser;
pub use self::parser::ParseLimits;
pub use self::parser::ParseError;
pub use self::parser::parse;
pub use self::parser::Token;

mod serializer;
pub use self::serializer::SerializeStyle;
pub use self::serializer::CompactSerializeStyle;
pub use self::serializer::SerializeLineEnding;
pub use self::serializer::SerializeIndentChar;
pub use self::serializer::SerializeSpacingConfig;
pub use self::serializer::SpacedSerializeStyle;
pub use self::serializer::serialize_into;
pub use self::serializer::serialize;

mod read_util;
pub use self::read_util::ReadUtilError;
pub use self::read_util::NodeReadUtil;
pub use self::read_util::AtomNodeReadUtil;
pub use self::read_util::ListNodeReadUtil;
pub use self::read_util::ListNodeReadUtilIter;

mod util;
pub use self::util::is_atom_chr;
pub use self::util::is_atom_string_chr;
pub use self::util::check_atom;

/// Macro to define values with a lighter syntax.
///
/// # Example
///
/// ```
/// use sise::sise_expr;
///
/// // atom
/// let value1 = sise::Node::Atom(String::from("atom"));
/// let value2 = sise_expr!("atom");
/// assert_eq!(value1, value2);
///
/// // ()
/// let value1 = sise::Node::List(vec![]);
/// let value2 = sise_expr!([]);
/// assert_eq!(value1, value2);
///
/// // (atom)
/// let value1 = sise::Node::List(vec![
///     sise::Node::Atom(String::from("atom"))
/// ]);
/// let value2 = sise_expr!(["atom"]);
/// assert_eq!(value1, value2);
///
/// // (atom (1 2 3) (a b c))
/// let value1 = sise::Node::List(vec![
///     sise::Node::Atom(String::from("atom")),
///     sise::Node::List(vec![
///         sise::Node::Atom(String::from("1")),
///         sise::Node::Atom(String::from("2")),
///         sise::Node::Atom(String::from("3")),
///     ]),
///     sise::Node::List(vec![
///         sise::Node::Atom(String::from("a")),
///         sise::Node::Atom(String::from("b")),
///         sise::Node::Atom(String::from("c")),
///     ]),
/// ]);
/// let value2 = sise_expr!(["atom", ["1", "2", "3"], ["a", "b", "c"]]);
/// assert_eq!(value1, value2);
/// ```
#[macro_export]
macro_rules! sise_expr {
    ([$($item:tt),*]) => { $crate::Node::List(vec![$(sise_expr!($item)),*]) };
    ([$($item:tt,)*]) => { $crate::Node::List(vec![$(sise_expr!($item)),*]) };
    ($node:expr) => { $crate::Node::from($node) };
}