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}