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
//! An [SDLang][sdlang] parser library. //! //! [SDLang][sdlang] is a simple and concise way to textually represent data. //! It has an XML-like structure - tags, values, and attributes - which makes //! it a versatily choice for data serialization, configuration files, or //! declarative languages. Its syntax was inspired by the C family of languages //! (C/C++, C#, D, Java, ...). //! //! Here's an example from the official website: //! ```sdlang //! // This is a node with a single string value //! title "Hello, World" //! //! // Multiple values are supported, too //! bookmarks 12 15 188 1234 //! //! // Nodes can have attributes //! author "Peter Parker" email="peter@example.org" active=true //! //! // Nodes can be arbitrarily nested //! contents { //! section "First Section" { //! paragraph "This is the first paragraph" //! paragraph "This is the second paragraph" //! } //! } //! //! // Anonymous nodes are supported //! "This text is the value of an anonymous node!" //! //! // This makes things like matrix definiotns very convenient //! matrix { //! 1 0 0 //! 0 1 0 //! 0 0 1 //! } //! ``` //! //! Parsing is made as easy as this: //! ```rust //! extern crate sdlang; //! //! // Prints `tag hello_world: "text"` //! println!("{}", sdlang::parse_text("hello_world \"text\"").unwrap()); //! ``` //! Note that all SDLang-related types (i.e `Tag`, `Attribute` and `Value`) //! implement `FromStr` so that they can be used with `str::parse`. Note, //! however, that in order to parse a whole file, which may have multiple root //! tags, use `parse_text` or `parse_file`. //! //! [sdlang]: https://sdlang.org "Official SDLang Website" // Crates extern crate base64; extern crate chrono; extern crate itertools; extern crate pest; #[macro_use] extern crate pest_derive; // Modules mod grammar; mod types; mod parse; // Public types pub use grammar::{Error, ParseRes as Result}; pub use types::{Value, Attribute, Tag, Date, DateTime}; // Internal usage here use std::{io, io::Read}; /// Reads everything from the given Reader and parses it. /// /// Look at `parse_text` for more information. /// /// The reader is internally buffered using `std::io::BufReader`. pub fn parse_file<R>(data: R) -> io::Result<Result<Tag>> where R: io::Read { let mut res = String::new(); io::BufReader::new(data).read_to_string(&mut res)?; Ok(parse_text(res.as_str())) } /// Parses the given text into a root tag. /// /// The name of the root tag is `""` (nothing); It has no namespace, values, or /// attributes; it only has a list of child tags. pub fn parse_text(data: &str) -> Result<Tag> { Ok(Tag::new(String::new()) .tags(grammar::parse(grammar::Rule::tagtree, data) .and_then(parse::tagtree)?)) }