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
//! ![](https://raw.githubusercontent.com/gura-conf/gura/master/static/img/logos/gura-200.png)
//!
//! # Gura Rust
//!
//! [Gura](https://gura.netlify.app/) is a file format for configuration files. Gura is as readable as YAML and simple as TOML. Its syntax is clear and powerful, yet familiar for YAML/TOML users.
//!
//! This crate parses Gura strings into Rust structures and vice versa:
//!
//! ```
//! use gura::{dump, parse, GuraType};
//!
//! let gura_string = r##"
//! title: "Gura Example"
//!
//! an_object:
//!     username: "Stephen"
//!     pass: "Hawking"
//!
//! hosts: [
//!   "alpha",
//!   "omega"
//! ]"##;
//!
//! // Parse: transforms a Gura string into a dictionary
//! let parsed = parse(&gura_string).unwrap();
//!
//! // Debug and Display
//! // println!("{:#?}", parsed);
//! // println!("{}", parsed);
//!
//! // Access a specific field
//! println!("Title -> {}", parsed["title"]);
//!
//! // Iterate over structure
//! println!("\nHosts:");
//! if let GuraType::Array(hosts) = &parsed["hosts"] {
//!     for host in hosts.iter() {
//!         println!("Host -> {}", *host);
//!     }
//! }
//!
//! // Dump: transforms a dictionary into a Gura string
//! let string_again = dump(&parsed);
//! println!("\n+++++ Dump result +++++");
//! println!("{}", string_again);
//! ```
//!
//! ## Easy creation, easy access
//!
//! Using macros and indexing, it's easy to work with the data.
//!
//! ```
//! use gura::{object, dump, GuraType};
//!
//! let object = object! {
//!     a_number: 55,
//!     nested: {
//!         array: [1, 2, 3],
//!         nested_ar: [1, [2, 3], 4]
//!     },
//!     a_string: "Gura Rust"
//! };
//!
//! // Access a specific field
//! assert_eq!(object["a_number"], 55);
//! assert_eq!(object["a_string"], "Gura Rust");
//!
//! // Iterate over structure
//! println!("\nNested/Array:");
//! if let GuraType::Array(numbers) = &object["nested"]["array"] {
//!     for number in numbers.iter() {
//!         println!("Number in array -> {}", *number);
//!     }
//! }
//!
//! // Dump: transforms a dictionary into a Gura string
//! let object_string = dump(&object);
//! println!("\n+++++ Dump result +++++");
//! println!("{}", object_string);
//! ```
//! 
//! ## Working with errors
//! 
//! One of Gura's strengths is the standardization of errors. Now you can find the type and position of the problem directly:
//! ```
//! use gura::{errors::Error, parse};
//! 
//! let gura_string = r##"
//! # This is a Gura document.
//! title: "Gura Example"
//! 
//! some_invalid: $non_existent_var 
//! "##;
//! 
//! // Checks parsing result
//! match parse(&gura_string) {
//!     Ok(parsed) => {
//!         println!("Title -> {}", parsed["title"]);
//!     }
//!     Err(e) => {
//!         println!("Error: {}", e); // Error implements fmt::Display
//! 
//!         match e.kind {
//!             Error::ParseError => println!("Syntax is wrong!"),
//!             Error::VariableNotDefinedError => println!("A non defined variable was used! "),
//!             Error::InvalidIndentationError => println!("Indentation is invalid!"),
//!             Error::DuplicatedVariableError => {
//!                 println!("A variable was defined more than once!")
//!             }
//!             Error::DuplicatedKeyError => println!("A key was defined more than once!"),
//!             Error::FileNotFoundError => println!("An imported file does not exist!"),
//!             Error::DuplicatedImportError => {
//!                 println!("The same Gura file was imported more than once!")
//!             }
//!         }
//!     }
//! }
//! ```


pub mod errors;
pub mod macros;
pub mod parser;
mod pretty_print_float;

// Re-exporting
pub use self::parser::dump;
pub use self::parser::parse;
pub use self::parser::GuraType;