ron2/lib.rs
1//! RON2 - Rusty Object Notation parser with full AST access
2//!
3//! This crate provides a standalone RON parser with three APIs:
4//! - **AST API**: Full fidelity parsing with perfect round-trip support
5//! - **Value API**: Simplified access to semantic content only
6//! - **Typed Conversions**: [`FromRon`] and [`ToRon`] traits for Rust types
7//!
8//! No serde dependency required.
9//!
10//! # AST Example (full fidelity)
11//!
12//! ```
13//! use ron2::ast::{parse_document, serialize_document};
14//!
15//! let source = "// config\nPoint(x: 1, y: 2)";
16//! let doc = parse_document(source).unwrap();
17//! let output = serialize_document(&doc).unwrap();
18//! assert_eq!(source, output); // Perfect round-trip
19//! ```
20//!
21//! # Value Example (semantic only)
22//!
23//! ```
24//! use ron2::Value;
25//!
26//! let value: Value = "[1, 2, 3]".parse().unwrap();
27//! assert!(matches!(value, Value::Seq(_)));
28//! ```
29//!
30//! # Typed Conversions
31//!
32//! ```
33//! use ron2::{FromRon, ToRon};
34//!
35//! let numbers: Vec<i32> = Vec::from_ron("[1, 2, 3]").unwrap();
36//! assert_eq!(numbers, vec![1, 2, 3]);
37//!
38//! let ron_string = numbers.to_ron().unwrap();
39//! ```
40
41#![deny(clippy::correctness)]
42#![deny(clippy::suspicious)]
43#![deny(clippy::complexity)]
44#![deny(clippy::perf)]
45#![deny(clippy::style)]
46#![warn(clippy::pedantic)]
47#![cfg_attr(not(test), deny(clippy::unwrap_used))]
48#![cfg_attr(not(test), deny(clippy::expect_used))]
49#![cfg_attr(not(test), deny(clippy::panic))]
50#![warn(clippy::todo)]
51#![deny(clippy::unimplemented)]
52#![deny(clippy::unreachable)]
53#![deny(unsafe_code)]
54#![allow(clippy::missing_errors_doc)]
55#![warn(clippy::alloc_instead_of_core)]
56#![warn(clippy::std_instead_of_alloc)]
57#![warn(clippy::std_instead_of_core)]
58
59extern crate std;
60
61extern crate alloc;
62extern crate self as ron2;
63
64pub mod ast;
65pub(crate) mod chars;
66pub mod convert;
67pub mod error;
68pub(crate) mod lexer;
69pub mod schema;
70pub(crate) mod token;
71mod util;
72pub mod value;
73
74// Re-export formatting config types from ast::fmt
75// Re-export derive macros when the derive feature is enabled
76#[cfg(feature = "derive")]
77pub use ron2_derive::{FromRon, Ron, RonSchema, ToRon};
78
79pub use crate::{
80 ast::{CommentMode, CompactTypes, Compaction, FormatConfig, Spacing},
81 convert::{
82 AstMapAccess, FromRon, FromRonFields, SerializeConfig, Spanned, ToRon, ToRonDocument,
83 },
84 error::{Error, ErrorKind, PathSegment, Position, Result, Span},
85 value::{Map, NamedContent, Number, StructFields, Value},
86};
87
88/// Internal module for benchmarks. Not part of the public API.
89#[doc(hidden)]
90pub mod __internal {
91 pub use crate::lexer::Lexer;
92}
93
94/// Format RON source with the given configuration.
95///
96/// # Example
97/// ```
98/// use ron2::FormatConfig;
99///
100/// let source = "(x:1,y:2)";
101/// let formatted = ron2::format(source, &FormatConfig::default())?;
102/// # Ok::<(), ron2::Error>(())
103/// ```
104pub fn format(source: &str, config: &FormatConfig) -> Result<alloc::string::String> {
105 let doc = ast::parse_document(source)?;
106 Ok(ast::format_document(&doc, config))
107}
108
109/// Parse a RON string into a type that implements `FromRon`.
110///
111/// # Example
112/// ```
113/// use ron2::from_str;
114///
115/// let value: i32 = ron2::from_str("42")?;
116/// assert_eq!(value, 42);
117/// # Ok::<(), ron2::Error>(())
118/// ```
119pub fn from_str<T: FromRon>(s: &str) -> Result<T> {
120 T::from_ron(s)
121}
122
123/// Serialize a value to a RON string with default formatting.
124///
125/// The output includes a `#![type = "..."]` attribute using [`core::any::type_name`].
126///
127/// # Example
128/// ```
129/// use ron2::{to_string, Value};
130///
131/// let value = Value::Bool(true);
132/// let ron = ron2::to_string(&value)?;
133/// assert!(ron.contains("#![type ="));
134/// assert!(ron.contains("true"));
135/// # Ok::<(), ron2::Error>(())
136/// ```
137pub fn to_string<T: ToRonDocument>(value: &T) -> Result<alloc::string::String> {
138 value.to_typed_ron()
139}
140
141/// Serialize a value to a RON string with custom settings.
142///
143/// If [`SerializeConfig::include_type_attribute`] is true (the default), the output
144/// will include a `#![type = "..."]` attribute using [`core::any::type_name`].
145///
146/// # Example
147/// ```
148/// use ron2::{to_string_with, SerializeConfig, Value};
149///
150/// let value = Value::Bool(true);
151///
152/// // With type attribute (default)
153/// let ron = ron2::to_string_with(&value, &SerializeConfig::default())?;
154/// assert!(ron.contains("#![type ="));
155/// assert!(ron.contains("true"));
156///
157/// // Without type attribute
158/// let ron = ron2::to_string_with(&value, &SerializeConfig::without_type_attribute())?;
159/// assert_eq!(ron.trim(), "true");
160/// # Ok::<(), ron2::Error>(())
161/// ```
162pub fn to_string_with<T: ToRonDocument>(
163 value: &T,
164 config: &SerializeConfig,
165) -> Result<alloc::string::String> {
166 value.to_typed_ron_with(config)
167}