oxirs_ttl/
lib.rs

1//! # OxiRS Turtle - RDF Format Parser
2//!
3//! [![Version](https://img.shields.io/badge/version-0.1.0-blue)](https://github.com/cool-japan/oxirs/releases)
4//! [![docs.rs](https://docs.rs/oxirs-ttl/badge.svg)](https://docs.rs/oxirs-ttl)
5//!
6//! **Status**: Production Release (v0.1.0)
7//! **Stability**: Production-ready with 461 passing tests and 97% W3C compliance.
8//!
9//! High-performance parsing and serialization for RDF formats in the Turtle family.
10//! Supports Turtle, TriG, N-Triples, N-Quads, and N3 with streaming and error recovery.
11//!
12//! Ported from Oxigraph's oxttl crate with adaptations for OxiRS.
13//!
14//! # Features
15//!
16//! - **Streaming support**: Process large files with minimal memory usage
17//! - **Error recovery**: Continue parsing despite syntax errors
18//! - **Async I/O**: Optional Tokio async support
19//! - **Parallel processing**: Process files in parallel chunks
20//! - **RDF 1.2 support**: Quoted triples and directional language tags
21//! - **Incremental parsing**: Parse as bytes arrive with checkpointing
22//!
23//! # Quick Start
24//!
25//! ## Basic Turtle Parsing
26//!
27//! ```rust
28//! use oxirs_ttl::{turtle::TurtleParser, Parser};
29//! use std::io::Cursor;
30//!
31//! let turtle_data = r#"
32//! @prefix ex: <http://example.org/> .
33//! ex:subject ex:predicate "object" .
34//! "#;
35//!
36//! let parser = TurtleParser::new();
37//! for result in parser.for_reader(Cursor::new(turtle_data)) {
38//!     let triple = result?;
39//!     println!("{}", triple);
40//! }
41//! # Ok::<(), Box<dyn std::error::Error>>(())
42//! ```
43//!
44//! ## Error Recovery with Lenient Mode
45//!
46//! ```rust
47//! use oxirs_ttl::turtle::TurtleParser;
48//!
49//! let turtle_with_errors = r#"
50//! @prefix ex: <http://example.org/> .
51//! ex:good ex:pred "value" .
52//! ex:also_good ex:pred "value2" .
53//! "#;
54//!
55//! // Lenient mode continues parsing after errors
56//! let parser = TurtleParser::new_lenient();
57//! let triples = parser.parse_document(turtle_with_errors)?;
58//! println!("Parsed {} triples", triples.len());
59//! # Ok::<(), Box<dyn std::error::Error>>(())
60//! ```
61//!
62//! ## Streaming Large Files
63//!
64//! ```rust
65//! use oxirs_ttl::{StreamingParser, StreamingConfig};
66//! use std::io::Cursor;
67//!
68//! let config = StreamingConfig::default()
69//!     .with_batch_size(10000);  // Process 10K triples per batch
70//!
71//! let data = Cursor::new(b"<http://s> <http://p> <http://o> .");
72//! let parser = StreamingParser::with_config(data, config);
73//! let mut total = 0;
74//!
75//! for batch in parser.batches() {
76//!     let triples = batch?;
77//!     total += triples.len();
78//!     println!("Processed batch of {} triples", triples.len());
79//! }
80//! println!("Total: {} triples", total);
81//! # Ok::<(), Box<dyn std::error::Error>>(())
82//! ```
83//!
84//! ## Incremental Parsing
85//!
86//! ```rust
87//! use oxirs_ttl::{IncrementalParser, ParseState};
88//!
89//! let mut parser = IncrementalParser::new();
90//!
91//! // Feed data as it arrives
92//! parser.push_data(b"@prefix ex: <http://example.org/> .\n")?;
93//! parser.push_data(b"ex:s ex:p \"object\" .\n")?;
94//! parser.push_eof();
95//!
96//! // Parse available complete statements
97//! let triples = parser.parse_available()?;
98//! println!("Parsed {} triples", triples.len());
99//!
100//! assert_eq!(parser.state(), ParseState::Complete);
101//! # Ok::<(), Box<dyn std::error::Error>>(())
102//! ```
103//!
104//! ## Serialization with Pretty Printing
105//!
106//! ```rust
107//! use oxirs_ttl::turtle::TurtleSerializer;
108//! use oxirs_ttl::toolkit::{Serializer, SerializationConfig};
109//! use oxirs_core::model::{NamedNode, Triple};
110//!
111//! let triple = Triple::new(
112//!     NamedNode::new("http://example.org/subject")?,
113//!     NamedNode::new("http://example.org/predicate")?,
114//!     NamedNode::new("http://example.org/object")?
115//! );
116//!
117//! // Create config with pretty printing
118//! let config = SerializationConfig::default()
119//!     .with_pretty(true)
120//!     .with_use_prefixes(true);
121//!
122//! let serializer = TurtleSerializer::with_config(config);
123//!
124//! let mut output = Vec::new();
125//! serializer.serialize(&vec![triple], &mut output)?;
126//!
127//! let turtle_string = String::from_utf8(output)?;
128//! println!("{}", turtle_string);
129//! # Ok::<(), Box<dyn std::error::Error>>(())
130//! ```
131
132#![warn(missing_docs)]
133#![cfg_attr(docsrs, feature(doc_cfg))]
134
135pub mod convenience;
136pub mod error;
137pub mod formats;
138pub mod incremental;
139pub mod lexer;
140pub mod profiling;
141pub mod streaming;
142pub mod toolkit;
143
144#[cfg(feature = "parallel")]
145pub mod parallel;
146
147#[cfg(feature = "async-tokio")]
148pub mod async_parser;
149
150// Re-export the main format APIs
151pub mod turtle {
152    //! Turtle format parser and serializer
153    pub use crate::formats::turtle::*;
154}
155
156pub mod trig {
157    //! TriG format parser and serializer
158    pub use crate::formats::trig::*;
159}
160
161pub mod ntriples {
162    //! N-Triples format parser and serializer
163    pub use crate::formats::ntriples::*;
164}
165
166pub mod nquads {
167    //! N-Quads format parser and serializer
168    pub use crate::formats::nquads::*;
169}
170
171pub mod n3 {
172    //! N3 format parser and reasoning (experimental)
173    pub use crate::formats::n3::*;
174    pub use crate::formats::n3_parser::*;
175    pub use crate::formats::n3_serializer::*;
176    pub use crate::formats::n3_types::*;
177
178    /// N3 reasoning primitives
179    pub mod reasoning {
180        pub use crate::formats::n3_reasoning::*;
181    }
182}
183
184// Re-export common types
185pub use error::{TurtleParseError, TurtleSyntaxError};
186pub use incremental::{IncrementalParser, ParseCheckpoint, ParseState};
187pub use profiling::{ParsingStats, TtlProfiler};
188pub use streaming::{PrintProgress, ProgressCallback, StreamingConfig, StreamingParser};
189pub use toolkit::{Parser, RuleRecognizer, Serializer, TokenRecognizer};