ferrous_opencc/
lib.rs

1//! # 纯 Rust 实现的 OpenCC
2//!
3//! 为繁体中文和简体中文之间提供高性能的转换。
4//!
5//! ## 示例
6//!
7//! ```
8//! use ferrous_opencc::OpenCC;
9//!
10//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
11//! // 创建 OpenCC 实例
12//! let opencc = OpenCC::from_config(ferrous_opencc::config::BuiltinConfig::S2t)?;
13//!
14//! // 转换文本
15//! let text = "开放中文转换是完全由 Rust 实现的。";
16//! let converted = opencc.convert(text);
17//!
18//! assert_eq!(converted, "開放中文轉換是完全由 Rust 實現的。");
19//! # Ok(())
20//! # }
21//! ```
22
23pub mod config;
24pub mod conversion;
25pub mod dictionary;
26pub mod error;
27#[cfg(not(target_arch = "wasm32"))]
28pub mod ffi;
29
30#[cfg(feature = "wasm")]
31use wasm_bindgen::prelude::*;
32
33use config::Config;
34use conversion::ConversionChain;
35use error::Result;
36use std::path::Path;
37
38use crate::{config::BuiltinConfig, dictionary::embedded};
39
40include!(concat!(env!("OUT_DIR"), "/embedded_map.rs"));
41
42/// 核心的 OpenCC 转换器
43#[cfg_attr(feature = "wasm", wasm_bindgen)]
44pub struct OpenCC {
45    /// 配置名称
46    name: String,
47    /// 用于执行转换的词典链
48    conversion_chain: ConversionChain,
49}
50
51impl OpenCC {
52    /// 从配置文件创建一个新的 `OpenCC` 实例。
53    /// 解析 JSON 配置文件,加载所有必需的词典,并构建转换流程。
54    ///
55    /// # 参数
56    ///
57    /// * `config_path`: 指向主 JSON 配置文件(例如 `s2t.json`)的路径
58    ///
59    /// # 返回
60    ///
61    /// 一个 `Result`,其中包含新的 `OpenCC` 实例,或者在加载失败时返回错误
62    pub fn new<P: AsRef<Path>>(config_path: P) -> Result<Self> {
63        // 1. 解析配置文件
64        let config = Config::from_file(config_path)?;
65        let config_dir = config.get_config_directory();
66
67        // 2. 初始化转换链
68        let conversion_chain = ConversionChain::from_config(&config.conversion_chain, config_dir)?;
69
70        Ok(Self {
71            name: config.name,
72            conversion_chain,
73        })
74    }
75
76    /// 从内置的配置创建 OpenCC 实例。
77    ///
78    /// # 示例
79    /// ```
80    /// use ferrous_opencc::{OpenCC, config::BuiltinConfig, error::Result};
81    ///
82    /// fn main() -> Result<()> {
83    ///     let opencc = OpenCC::from_config(BuiltinConfig::S2t)?;
84    ///     Ok(())
85    /// }
86    /// ```
87    pub fn from_config(config_enum: BuiltinConfig) -> Result<Self> {
88        let name = config_enum.to_filename();
89        let config_str = embedded::EMBEDDED_CONFIGS
90            .get(name)
91            .ok_or_else(|| error::OpenCCError::ConfigNotFound(name.to_string()))?;
92
93        let config: Config = config_str.parse()?;
94
95        let conversion_chain = ConversionChain::from_config_embedded(&config.conversion_chain)?;
96
97        Ok(Self {
98            name: config.name,
99            conversion_chain,
100        })
101    }
102
103    /// 根据加载的配置转换字符串
104    ///
105    /// # 参数
106    ///
107    /// * `input`: 需要转换的字符串
108    ///
109    /// # 返回
110    ///
111    /// 转换后的字符串
112    pub fn convert(&self, input: &str) -> String {
113        self.conversion_chain.convert(input)
114    }
115
116    /// 返回当前加载的配置名称
117    pub fn name(&self) -> &str {
118        &self.name
119    }
120}
121
122#[cfg(feature = "wasm")]
123#[wasm_bindgen]
124impl OpenCC {
125    /// 创建一个新的 `OpenCC` 实例。
126    ///
127    /// @param {BuiltinConfig} config - 要使用的内置配置枚举。
128    /// @returns {Promise<OpenCC>} - 一个 Promise,成功时解析为 OpenCC 实例。
129    /// @throws {JsValue} - 如果配置加载失败,则抛出一个错误对象。
130    ///
131    /// @example
132    /// ```javascript
133    /// import init, { OpenCC, BuiltinConfig } from './pkg/ferrous_opencc.js';
134    ///
135    /// async function main() {
136    ///   await init();
137    ///   try {
138    ///     const converter = new OpenCC(BuiltinConfig.S2t);
139    ///     console.log('加载成功:', converter.name);
140    ///   } catch (err) {
141    ///     console.error('加载失败:', err);
142    ///   }
143    /// }
144    /// main();
145    /// ```
146    #[wasm_bindgen(constructor)]
147    pub fn new_wasm(config: BuiltinConfig) -> std::result::Result<OpenCC, JsValue> {
148        OpenCC::from_config(config).map_err(|e| JsValue::from_str(&e.to_string()))
149    }
150
151    /// 根据加载的配置转换字符串。
152    ///
153    /// @param {string} input - 需要转换的字符串。
154    /// @returns {string} - 转换后的字符串。
155    ///
156    /// @example
157    /// ```javascript
158    /// const traditionalText = converter.convert("开放中文转换");
159    /// console.log(traditionalText); // 预期: 開放中文轉換
160    /// ```
161    #[wasm_bindgen(js_name = convert)]
162    pub fn convert_wasm(&self, input: &str) -> String {
163        self.convert(input)
164    }
165
166    /// 获取当前加载的配置的名称。
167    ///
168    /// @returns {string} - 配置的名称。
169    ///
170    /// @example
171    /// ```javascript
172    /// const configName = converter.name;
173    /// console.log(configName);
174    /// ```
175    #[wasm_bindgen(getter, js_name = name)]
176    pub fn name_wasm(&self) -> String {
177        self.name.clone()
178    }
179}