babbel_yaml 0.1.1

Fast, modular YAML 1.2 parser and emitter with anchors, aliases, and tags
//! # babbel_yaml
//!
//! A fast, modular YAML 1.2 parser and emitter in pure Rust, supporting anchors, aliases,
//! tags, multi-document streams, and embedded resource constraints.
//!
//! ## Key Capabilities
//! - Fast YAML 1.2 DOM parsing and document navigation
//! - Anchor and alias resolution with cycle detection
//! - File and buffer streaming I/O abstractions powered by `babbel_core`
//! - Pretty-printing and custom block scalar formatting
//! - Unicode-aware file handling and BOM detection
//!
//! Minimum supported Rust version: 1.88.0
//!
//! ## Feature Flags
//!
//! - `std` (default): Enable standard library support
//! - `alloc` (default): Enable allocation support (required for most features)
//! - `embedded`: Enable embedded systems optimizations and limits
//! - `parse-only`: Only enable parsing, disable serialization
//! - `stringify`: Enable YAML stringification (requires `alloc`)
//! - `format-converters`: Enable JSON, XML, TOML, Bencode converters
//! - `file-io`: Enable file I/O operations (requires `std`)

#![cfg_attr(not(feature = "std"), no_std)]

#[macro_use]
pub mod parser;

/// Common test helpers for integration/unit tests
pub mod test_helpers;

#[cfg(feature = "alloc")]
extern crate alloc;

#[cfg(feature = "alloc")]
use alloc::vec::Vec;

/// Module containing constants for the library
mod constants;
/// Module for developer tools (debugging, inspection, diffing, tracing)
#[cfg(feature = "alloc")]
pub mod devtools;
/// Module for embedded systems support
#[cfg(any(feature = "embedded", doc))]
pub mod embedded;
/// Module defining error types and handling for YAML operations.
pub mod error;
/// Module for detecting and handling different Unicode text file formats
#[cfg(feature = "file-io")]
mod file;
/// Module containing internal tests for the YAML library
/// These tests use internal APIs and are not pure integration tests
#[cfg(test)]
mod internal_tests;
/// Module providing input/output operations for reading and writing YAML data
mod io;
/// Module containing YAML data structure definitions and node types
mod nodes;
/// Module implementing YAML parsing and value extraction
/// Module for converting YAML structures to formatted strings
#[cfg(feature = "stringify")]
pub mod stringify;
/// Module for testing infrastructure (fuzzing, property testing, safety)
#[cfg(feature = "alloc")]
pub mod testing;
/// Module containing  utility functions for the YAML library
mod utils;
/// Module for YAML validation and schema support
#[cfg(feature = "validation")]
pub mod validation;

/// ============
/// babbel_yaml API
/// ============
// Error handling types
pub use error::ErrorKind;
pub use error::YamlError;
/// Enhanced error with suggestions and context
#[cfg(feature = "alloc")]
pub use error::enhanced::{EnhancedError, ErrorCode, ErrorSuggestion, Span, SuggestionBuilder};
/// Error recovery strategies and collection
#[cfg(feature = "alloc")]
pub use error::recovery::{
    ErrorCollection, ParserState, RecoveryContext, RecoveryHandler, RecoveryStrategy,
};

/// This enum represents different Unicode text file formats with their corresponding byte order marks (BOM)
#[cfg(feature = "file-io")]
pub use file::file::Format;
/// This function detects the Unicode format of a text file by examining its byte order mark (BOM)
#[cfg(feature = "file-io")]
pub use file::file::detect_format;
/// This function reads a text file and returns its content as a String, handling different Unicode formats
#[cfg(feature = "file-io")]
pub use file::file::read_file_to_string;
/// This function writes a string to a file in the specified Unicode format
#[cfg(feature = "file-io")]
pub use file::file::write_file_from_string;
/// Destination implementation for writing YAML data to a memory buffer
pub use io::destinations::buffer::Buffer as BufferDestination;
/// Destination implementation for writing YAML data to a file
#[cfg(feature = "file-io")]
pub use io::destinations::file::File as FileDestination;
/// Source implementation for reading YAML data from a memory buffer
pub use io::sources::buffer::Buffer as BufferSource;
/// Source implementation for reading YAML data from a file
#[cfg(feature = "file-io")]
pub use io::sources::file::File as FileSource;
/// Returns the base node of document number n (0-based), reporting any errors.
pub use nodes::node_utils::get_document_base as get_document;
/// Returns the number of documents in a YAML stream represented by the Documents node.
pub use nodes::node_utils::get_number_of_documents;

/// Returns the current version of the YAML library
pub use nodes::node_utils::get_version as version;
/// Fluent builder for constructing Array nodes
#[cfg(feature = "alloc")]
pub use nodes::node::ArrayBuilder;
/// Block style for string nodes
pub use nodes::node::BlockStyle;
/// Fluent builder for constructing Mapping nodes
#[cfg(feature = "alloc")]
pub use nodes::node::MappingBuilder;
/// Core data structure representing a YAML node in the parsed tree
pub use nodes::node::Node;
/// Core data structure representing a numeric value node in the parsed tree
pub use nodes::node::Numeric;
/// Quote type for string nodes
pub use nodes::node::QuoteType;
/// Fluent builder for constructing Set nodes
#[cfg(feature = "alloc")]
pub use nodes::node::SetBuilder;
/// Helper function to create a Node from any value that can be converted into a Node
pub use nodes::util::make_node;
/// Helper function to create a Set node from a vector, ensuring uniqueness
pub use nodes::util::make_set;
/// Parser configuration with builder pattern
pub use parser::config::ParserConfig;
/// Parser configuration builder
pub use parser::config::ParserConfigBuilder;
/// Parses YAML data into a Node tree structure
pub use parser::document::parse;

/// Internal helper that funnels all public parse_* APIs through the same
/// source-based entry point. This keeps configuration and future recovery
/// wiring centralized.
fn parse_from_source(
    source: &mut dyn crate::io::traits::ISource,
    _config: &ParserConfig,
) -> crate::error::Result<Node> {
    // ParserConfig enforcement is currently handled within the parser
    // implementation; this helper exists so future extensions (limits,
    // recovery, instrumentation) only need to be wired in one place.
    parser::document::parse(source)
}

/// Parse YAML from an in-memory string using the default parser configuration.
pub fn parse_string(yaml: &str) -> crate::error::Result<Node> {
    let mut source = BufferSource::new(yaml.as_bytes());
    let config = ParserConfig::default();
    parse_from_source(&mut source, &config)
}

/// Parse YAML from an in-memory string slice.
/// Canonical alias for [`parse_string`].
#[inline]
pub fn from_str(yaml: &str) -> crate::error::Result<Node> {
    parse_string(yaml)
}

/// Parse YAML from raw bytes using the default parser configuration.
#[inline]
pub fn from_bytes(bytes: &[u8]) -> crate::error::Result<Node> {
    let mut source = BufferSource::new(bytes);
    let config = ParserConfig::default();
    parse_from_source(&mut source, &config)
}

/// Parse YAML from any streaming source.
/// Canonical alias for [`parse`].
#[inline]
pub fn from_source(source: &mut dyn crate::io::traits::ISource) -> crate::error::Result<Node> {
    parse(source)
}

/// Parse YAML from a file path using the default parser configuration.
#[cfg(feature = "file-io")]
pub fn parse_file(path: &str) -> crate::error::Result<Node> {
    match read_file_to_string(path) {
        Ok(contents) => parse_string(&contents),
        Err(e) => Err(e.to_string().into()),
    }
}

/// Parse YAML from a string with a custom parser configuration.
pub fn parse_with_config(yaml: &str, config: ParserConfig) -> crate::error::Result<Node> {
    let mut source = BufferSource::new(yaml.as_bytes());
    parse_from_source(&mut source, &config)
}

/// Parse YAML from a string while preparing for future error recovery support.
///
/// Currently this behaves like `parse_string`, returning the parsed node and
/// an empty list of secondary errors; the `RecoveryHandler` will be wired into
/// the parser once full recovery support is implemented.
#[cfg(feature = "alloc")]
pub fn parse_string_with_recovery(
    yaml: &str,
    _handler: RecoveryHandler,
) -> crate::error::Result<(Node, Vec<YamlError>)> {
    let node = parse_string(yaml)?;
    Ok((node, Vec::new()))
}
/// Converts a Node tree to bencode format
#[cfg(feature = "format-converters")]
pub use stringify::bencode::stringify as to_bencode;
/// Converts a Node tree back to YAML format
#[cfg(feature = "stringify")]
pub use stringify::default::stringify;

/// Serialize a YAML [`Node`] into an owned [`String`].
#[cfg(feature = "stringify")]
pub fn to_string(node: &Node) -> crate::error::Result<String> {
    let mut dest = BufferDestination::new();
    stringify(node, &mut dest)?;
    Ok(dest.to_string())
}

/// Serialize a YAML [`Node`] into a byte vector (`Vec<u8>`).
#[cfg(feature = "stringify")]
pub fn to_vec(node: &Node) -> crate::error::Result<Vec<u8>> {
    let mut dest = BufferDestination::new();
    stringify(node, &mut dest)?;
    Ok(dest.into_vec())
}

/// Serialize a YAML [`Node`] to any [`IDestination`].
#[cfg(feature = "stringify")]
#[inline]
pub fn to_destination(node: &Node, dest: &mut dyn crate::io::traits::IDestination) -> crate::error::Result<()> {
    stringify(node, dest)
}
/// Converts a Node tree to JSON format
#[cfg(feature = "format-converters")]
pub use stringify::json::stringify as to_json;
#[cfg(feature = "format-converters")]
pub use stringify::json::stringify_pretty as to_json_pretty;
/// Converts a Node tree to TOML format
#[cfg(feature = "format-converters")]
pub use stringify::toml::stringify as to_toml;
#[cfg(feature = "format-converters")]
pub use stringify::toml::stringify_pretty as to_toml_pretty;
/// Converts a Node tree to XML format
#[cfg(feature = "format-converters")]
pub use stringify::xml::stringify as to_xml;
#[cfg(feature = "format-converters")]
pub use stringify::xml::stringify_pretty as to_xml_pretty;
/// Capacity hints for optimizing allocations during parsing
#[cfg(feature = "alloc")]
pub use utils::optimization::CapacityHints;
/// Fast path detector for common YAML patterns
#[cfg(feature = "alloc")]
pub use utils::optimization::FastPathDetector;
/// Lazy tag that defers type coercion until accessed
#[cfg(feature = "alloc")]
pub use utils::optimization::LazyTag;
/// Memory-efficient node builder that reuses allocations
#[cfg(feature = "alloc")]
pub use utils::optimization::NodeBuilder;
/// Performance optimizer combining multiple optimization strategies
#[cfg(feature = "alloc")]
pub use utils::optimization::PerformanceOptimizer;
/// String pool for deduplicating common strings during parsing
#[cfg(all(feature = "std", feature = "alloc"))]
/// Zero-copy string wrapper
#[cfg(feature = "alloc")]
pub use utils::optimization::ZeroCopyStr;
/// Document statistics for performance analysis
pub use utils::performance::DocumentStats;
/// Performance profiler for measuring multiple operations
#[cfg(all(feature = "std", feature = "alloc"))]
pub use utils::performance::Profiler;
/// Simple timer for measuring operation duration
#[cfg(feature = "std")]
pub use utils::performance::Timer;
/// Utility to compare performance of different approaches
#[cfg(feature = "std")]
pub use utils::performance::compare_performance;
/// Iterator for traversing node trees
#[cfg(feature = "alloc")]
pub use utils::streaming::NodeIterator;
/// Extension trait for Node providing iterator methods
#[cfg(feature = "alloc")]
pub use utils::streaming::NodeIteratorExt;
/// Path for accessing nested nodes
#[cfg(feature = "alloc")]
pub use utils::streaming::NodePath;
/// Stream processor for efficient large document handling
#[cfg(feature = "alloc")]
pub use utils::streaming::NodeStream;
/// Path segment (key or index) for node access
#[cfg(feature = "alloc")]
pub use utils::streaming::PathSegment;
/// Traversal order for iterating through nodes
#[cfg(feature = "alloc")]
pub use utils::streaming::TraversalOrder;
/// Common pre-interned strings for typical YAML keys
#[cfg(feature = "alloc")]
pub use utils::string_interner::CommonStrings;
/// Reference-counted interned string for memory deduplication
#[cfg(feature = "alloc")]
pub use utils::string_interner::InternedString;
/// Statistics about string interning performance
#[cfg(feature = "alloc")]
pub use utils::string_interner::InternerStats;
/// Simple single-threaded string interner
#[cfg(feature = "alloc")]
pub use utils::string_interner::SimpleInterner;
/// Thread-safe string interner with read-write lock
#[cfg(feature = "std")]
pub use utils::string_interner::StringInterner;

// Validation API
/// Validation engine and error types
#[cfg(feature = "validation")]
pub use validation::engine::{SchemaValidator, ValidationContext};
/// Schema types for defining validation rules
#[cfg(feature = "validation")]
pub use validation::schema::{ArraySchema, ObjectSchema, PropertySchema, Schema, SchemaType};
/// Built-in validators
#[cfg(feature = "validation")]
pub use validation::validators::{
    CustomValidator, EnumValidator, LengthValidator, PatternValidator, RangeValidator,
    RequiredValidator, TypeValidator, ValidationResult, Validator,
};

/// Custom serializer support
#[cfg(feature = "alloc")]
pub use stringify::serializer::{Serializer, SerializerRegistry, TaggedSerializer, TypeSerializer};
/// Streaming serialization
#[cfg(feature = "alloc")]
pub use stringify::streaming::StreamingSerializer;

// Testing API
/// Fuzzing infrastructure for discovering bugs
#[cfg(feature = "alloc")]
pub use testing::fuzzing::{FuzzResult, FuzzRng, YamlFuzzer, fuzz_parse, fuzz_roundtrip};
/// Property-based testing for checking invariants
#[cfg(feature = "alloc")]
pub use testing::property::{Property, PropertyResult, PropertySuite};
/// Memory safety auditing tools
#[cfg(feature = "alloc")]
pub use testing::safety::{
    MemoryStats, SafetyAudit, SafetyIssue, audit_node, calculate_memory_stats,
};

// Developer Tools API
/// Debugging utilities
#[cfg(feature = "alloc")]
pub use devtools::debug::{DebugAssert, DebugContext, DebugLevel, NodeDebugger};
/// Node diffing and comparison
#[cfg(feature = "alloc")]
pub use devtools::diff::{Diff, DiffResult, DiffType, diff_nodes};
/// Node inspection and introspection
#[cfg(feature = "alloc")]
pub use devtools::inspect::{
    NodeInfo, NodeType, find_by_type, has_anchor, has_tag, node_depth, node_size, node_summary,
    node_type, print_tree,
};
#[cfg(all(feature = "alloc", feature = "std"))]
pub use devtools::trace::TracedTimer;
/// Execution tracing
#[cfg(feature = "alloc")]
pub use devtools::trace::{TraceEntry, TraceEvent, TraceGuard, Tracer};