1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
//! FST serialization and deserialization in multiple formats.
//!
//! This module provides comprehensive I/O capabilities for reading and writing
//! finite-state transducers (FSTs) in various formats. It supports interoperability
//! with other FST libraries (particularly OpenFST) and provides both human-readable
//! and efficient binary formats optimized for different use cases.
//!
//! # Supported Formats
//!
//! ## Text Format
//!
//! A human-readable, line-based format suitable for debugging and manual editing.
//!
//! - **Functions:** [`read_text()`], [`write_text()`]
//! - **Features:** Version control friendly, easy to edit, portable
//! - **Use cases:** Debugging, testing, small FSTs, manual construction
//! - **Extension:** `.txt` (conventional)
//!
//! Example text format:
//! ```text
//! START 0
//! STATE 0
//! STATE 1
//! 0 1 a b 0.5
//! FINAL 1 0.0
//! ```
//!
//! ## OpenFST Binary Format
//!
//! The de facto industry standard binary format, compatible with the OpenFST
//! C++ library and its extensive ecosystem of tools.
//!
//! - **Functions:** [`read_openfst()`], [`write_openfst()`]
//! - **Features:** Fast I/O, compact storage, broad tool compatibility
//! - **Use cases:** Production systems, interoperability with Kaldi/ESPnet
//! - **Extension:** `.fst` (standard)
//! - **Limitation:** Currently supports TropicalWeight FSTs only
//!
//! ## Native Binary Format
//!
//! A Rust-native binary format using serde/bincode for type-safe serialization.
//!
//! - **Functions:** [`read_binary()`], [`write_binary()`] (requires `serde` feature)
//! - **Features:** Type-safe, versioned, supports all semiring types
//! - **Use cases:** Caching, persistence, Rust-to-Rust communication
//! - **Extension:** `.fstb` (recommended)
//!
//! ## Zero-Copy rkyv Format
//!
//! Ultra-fast serialization using rkyv for zero-copy deserialization.
//!
//! - **Module:** [`rkyv_format`] (requires `zero-copy` feature)
//! - **Features:** Zero deserialization overhead, memory-mapped file support
//! - **Use cases:** Large models, latency-critical applications
//! - **Extension:** `.fst.rkyv` (recommended)
//!
//! ## FST Archive (FAR) Format
//!
//! Container format for storing multiple FSTs in a single file.
//!
//! - **Types:** [`FarReader`], [`FarWriter`]
//! - **Functions:** [`open_far()`], [`create_far()`]
//! - **Use cases:** Model collections, lexicons, rule sets
//! - **Extension:** `.far` (standard)
//!
//! # Format Selection Guide
//!
//! | Format | Read Speed | Write Speed | Size | Compatibility | Human-Readable |
//! |--------|------------|-------------|------|---------------|----------------|
//! | Text | Slow | Slow | Large | Universal | Yes |
//! | OpenFST | Fast | Fast | Medium | OpenFST ecosystem | No |
//! | Binary | Fast | Fast | Small | Rust only | No |
//! | rkyv | Instant | Fast | Medium | Rust only | No |
//!
//! # Examples
//!
//! ## Reading and Writing Text Format
//!
//! ```no_run
//! use arcweight::prelude::*;
//! use std::fs::File;
//! use std::io::{BufReader, BufWriter};
//!
//! // Create an FST
//! let mut fst = VectorFst::<TropicalWeight>::new();
//! let s0 = fst.add_state();
//! let s1 = fst.add_state();
//! fst.set_start(s0);
//! fst.set_final(s1, TropicalWeight::new(0.0));
//! fst.add_arc(s0, Arc::new(1, 2, TropicalWeight::new(0.5), s1));
//!
//! // Write to text file
//! let file = File::create("fst.txt").unwrap();
//! let mut writer = BufWriter::new(file);
//! write_text(&fst, &mut writer, None, None).unwrap();
//!
//! // Read from text file
//! let file = File::open("fst.txt").unwrap();
//! let mut reader = BufReader::new(file);
//! let loaded: VectorFst<TropicalWeight> = read_text(&mut reader, None, None).unwrap();
//! ```
//!
//! ## OpenFST Interoperability
//!
//! ```no_run
//! use arcweight::prelude::*;
//! use std::fs::File;
//!
//! // Read FST created by OpenFST tools (fstcompile, etc.)
//! let mut file = File::open("model.fst").unwrap();
//! let fst: VectorFst<TropicalWeight> = read_openfst(&mut file).unwrap();
//!
//! // Process with ArcWeight algorithms
//! let minimized: VectorFst<TropicalWeight> = minimize(&fst).unwrap();
//!
//! // Write back for use with OpenFST tools (fstinfo, fstdraw, etc.)
//! let mut out_file = File::create("minimized.fst").unwrap();
//! write_openfst(&minimized, &mut out_file).unwrap();
//! ```
//!
//! ## Binary Serialization
//!
//! ```
//! # #[cfg(feature = "serde")]
//! # {
//! use arcweight::prelude::*;
//! use arcweight::io::{write_binary, read_binary};
//! use std::io::Cursor;
//!
//! # fn example() -> Result<()> {
//! // Serialize FST to bytes
//! let fst = VectorFst::<LogWeight>::new();
//! let mut buffer = Vec::new();
//! write_binary(&fst, &mut buffer)?;
//!
//! // Deserialize from bytes
//! let mut cursor = Cursor::new(buffer);
//! let loaded: VectorFst<LogWeight> = read_binary(&mut cursor)?;
//! # Ok(())
//! # }
//! # }
//! ```
//!
//! ## Symbol Table Integration
//!
//! Symbol tables provide human-readable labels for arc input/output symbols.
//!
//! ```no_run
//! use arcweight::prelude::*;
//! use arcweight::utils::SymbolTable;
//! use arcweight::io::write_text;
//! use std::io::stdout;
//!
//! // Create symbol tables for input and output alphabets
//! let mut isyms = SymbolTable::new();
//! let mut osyms = SymbolTable::new();
//!
//! let cat = isyms.add_symbol("cat");
//! let chat = osyms.add_symbol("chat");
//!
//! // Build FST using symbol IDs
//! let mut fst = VectorFst::<TropicalWeight>::new();
//! let s0 = fst.add_state();
//! let s1 = fst.add_state();
//! fst.set_start(s0);
//! fst.set_final(s1, TropicalWeight::one());
//! fst.add_arc(s0, Arc::new(cat, chat, TropicalWeight::new(0.5), s1));
//!
//! // Write with symbolic labels
//! write_text(&fst, &mut stdout(), Some(&isyms), Some(&osyms)).unwrap();
//! // Output: 0 1 cat chat 0.5
//! ```
//!
//! # Error Handling
//!
//! All I/O operations return [`Result<T, Error>`](crate::Result) with descriptive
//! error types:
//!
//! - [`Error::Io`](crate::Error::Io) - Underlying I/O failures
//! - [`Error::Serialization`](crate::Error::Serialization) - Format/parsing errors
//!
//! # Performance Considerations
//!
//! - **Text format:** Best for FSTs under 10,000 states; O(n) parsing overhead
//! - **OpenFST format:** Efficient for any size; standard choice for production
//! - **Binary format:** Best for Rust-only workflows; smallest file size
//! - **rkyv format:** Best for latency-critical loading; zero parsing overhead
//!
//! For very large FSTs (millions of states), consider:
//! - Memory-mapped files with rkyv format
//! - Streaming/lazy FST implementations
//! - Sharded FST archives
//!
//! # References
//!
//! - Allauzen, C., Riley, M., Schalkwyk, J., Skut, W., & Mohri, M. (2007).
//! OpenFst: A general and efficient weighted finite-state transducer library.
//! In *Implementation and Application of Automata* (pp. 11-23). Springer.
//! <https://www.openfst.org/>
//!
//! - Mohri, M. (2009). Weighted automata algorithms.
//! In *Handbook of Weighted Automata* (pp. 213-254). Springer.
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;