bem/lib.rs
1//! `bem` is a Rust crate that provides a simple and intuitive interface to work with BEM (Block Element Modifier) notation.
2//! It includes functions to parse BEM blocks, elements, and their modifiers, and to convert them to and from JSON representation.
3//!
4//! With this crate, you can easily serialize and deserialize BEM structures in your Rust applications,
5//! making it an excellent choice for web developers, CSS authors, and anyone working with BEM-based design.
6//!
7//! # Features
8//!
9//! - **Parse BEM Notation**: Use the `parse` function to interpret BEM strings and create corresponding Rust structures.
10//! - **JSON Serialization and Deserialization**: Convert BEM blocks to JSON strings and vice versa with the `to_json` and `from_json` functions.
11//! - **Customizable Models**: Work with `BEMBlock` and `BEMElement` structs to represent BEM structures, supporting custom modifiers and elements.
12//!
13//! # Quick Start
14//!
15//! Add the crate to your Cargo.toml and start working with BEM structures right away!
16//!
17//! ```
18//! use bem::{BEMBlock, to_json, from_json};
19//!
20//! let bem_block = BEMBlock { name: "media-player".to_string(), modifiers: vec![], elements: vec![] };
21//! let json = to_json(&bem_block).unwrap();
22//! let bem_block_from_json = from_json(&json).unwrap();
23//! ```
24//!
25//! Please see the individual function and structure documentation for detailed information and examples.
26
27pub use models::{ BEMBlock, BEMElement };
28pub use parser::parse;
29
30mod models;
31mod parser;
32
33/// Converts a `BEMBlock` into a JSON string.
34///
35/// This function takes a reference to a `BEMBlock` and serializes it into a JSON string.
36/// It returns a `Result` containing the JSON string if the conversion is successful, or
37/// a `serde_json::Error` if there is a problem during serialization.
38///
39/// # Arguments
40///
41/// * `bem_block`: &BEMBlock - A reference to the `BEMBlock` to be converted to JSON.
42///
43/// # Returns
44///
45/// * `Result<String, serde_json::Error>` - A result containing the JSON string or an error.
46///
47/// # Examples
48///
49/// ```
50/// use bem::{BEMBlock, to_json};
51///
52/// let bem_block = BEMBlock { name: "media-player".to_string(), modifiers: vec![], elements: vec![] };
53/// let json = to_json(&bem_block).unwrap();
54/// ```
55pub fn to_json(bem_block: &BEMBlock) -> Result<String, serde_json::Error> {
56 let json_output = serde_json::to_string(&bem_block)?;
57
58 Ok(json_output)
59}
60
61/// Converts a `BEMBlock` into a pretty-printed JSON string.
62///
63/// This function takes a reference to a `BEMBlock` and serializes it into a prett-printed JSON string.
64/// It returns a `Result` containing the pretty-printed JSON string if the conversion is successful, or
65/// a `serde_json::Error` if there is a problem during serialization.
66///
67/// # Arguments
68///
69/// * `bem_block`: &BEMBlock - A reference to the `BEMBlock` to be converted to JSON.
70///
71/// # Returns
72///
73/// * `Result<String, serde_json::Error>` - A result containing the pretty-printed JSON string or an error.
74///
75/// # Examples
76///
77/// ```
78/// use bem::{BEMBlock, to_json_pretty};
79///
80/// let bem_block = BEMBlock { name: "media-player".to_string(), modifiers: vec![], elements: vec![] };
81/// let json = to_json_pretty(&bem_block).unwrap();
82/// ```
83pub fn to_json_pretty(bem_block: &BEMBlock) -> Result<String, serde_json::Error> {
84 let json_output = serde_json::to_string_pretty(&bem_block)?;
85
86 Ok(json_output)
87}
88
89/// Converts a JSON string into a `BEMBlock`.
90///
91/// This function takes a JSON string and deserializes it into a `BEMBlock`.
92/// It returns a `Result` containing the `BEMBlock` if the conversion is successful, or
93/// a `serde_json::Error` if there is a problem during deserialization.
94///
95/// # Arguments
96///
97/// * `json`: &str - The JSON string to be converted to a `BEMBlock`.
98///
99/// # Returns
100///
101/// * `Result<BEMBlock, serde_json::Error>` - A result containing the `BEMBlock` or an error.
102///
103/// # Examples
104///
105/// ```
106/// use bem::{BEMBlock, from_json};
107///
108/// let json = "{\"name\":\"media-player\",\"modifiers\":[],\"elements\":[]}";
109/// let bem_block = from_json(json).unwrap();
110/// ```
111pub fn from_json(json: &str) -> Result<BEMBlock, serde_json::Error> {
112 let bem_block = serde_json::from_str(json)?;
113
114 Ok(bem_block)
115}
116
117#[cfg(test)]
118mod tests {
119 use super::{ BEMBlock, BEMElement };
120
121 fn create_test_bem_block() -> BEMBlock {
122 BEMBlock {
123 name: "media-player".to_string(),
124 modifiers: vec!["dark".to_string()],
125 elements: vec![
126 BEMElement {
127 name: "button".to_string(),
128 modifiers: vec!["fast-forward".to_string(), "rewind".to_string()],
129 },
130 BEMElement {
131 name: "timeline".to_string(),
132 modifiers: vec![],
133 }
134 ],
135 }
136 }
137
138 #[test]
139 fn test_to_json() {
140 let bem_block = create_test_bem_block();
141 let result = super::to_json(&bem_block);
142
143 assert!(result.is_ok());
144
145 insta::assert_snapshot!(result.unwrap());
146 }
147
148 #[test]
149 fn test_to_json_pretty() {
150 let bem_block = create_test_bem_block();
151 let result = super::to_json_pretty(&bem_block);
152
153 assert!(result.is_ok());
154
155 insta::assert_snapshot!(result.unwrap());
156 }
157
158 #[test]
159 fn test_from_json() {
160 let json =
161 "{\"name\":\"media-player\",\"modifiers\":[\"dark\"],\"elements\":[{\"name\":\"button\",\"modifiers\":[\"fast-forward\",\"rewind\"]},{\"name\":\"timeline\",\"modifiers\":[]}]}";
162 let result = super::from_json(json);
163
164 assert!(result.is_ok());
165
166 assert_eq!(result.unwrap(), create_test_bem_block());
167 }
168}