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
40/// 核心的 `OpenCC` 转换器
41#[cfg_attr(feature = "wasm", wasm_bindgen)]
42pub struct OpenCC {
43    /// 配置名称
44    name: String,
45    /// 用于执行转换的词典链
46    conversion_chain: ConversionChain,
47}
48
49impl OpenCC {
50    /// 从配置文件创建一个新的 `OpenCC` 实例。
51    /// 解析 JSON 配置文件,加载所有必需的词典,并构建转换流程。
52    ///
53    /// # 参数
54    ///
55    /// * `config_path`: 指向主 JSON 配置文件(例如 `s2t.json`)的路径
56    ///
57    /// # 返回
58    ///
59    /// 一个 `Result`,其中包含新的 `OpenCC` 实例,或者在加载失败时返回错误
60    pub fn new<P: AsRef<Path>>(config_path: P) -> Result<Self> {
61        // 1. 解析配置文件
62        let config = Config::from_file(config_path)?;
63        let config_dir = config.get_config_directory();
64
65        // 2. 初始化转换链
66        let conversion_chain = ConversionChain::from_config(&config.conversion_chain, config_dir)?;
67
68        Ok(Self {
69            name: config.name,
70            conversion_chain,
71        })
72    }
73
74    /// 从内置的配置创建 `OpenCC` 实例。
75    ///
76    /// # 示例
77    /// ```
78    /// use ferrous_opencc::{OpenCC, config::BuiltinConfig, error::Result};
79    ///
80    /// fn main() -> Result<()> {
81    ///     let opencc = OpenCC::from_config(BuiltinConfig::S2t)?;
82    ///     Ok(())
83    /// }
84    /// ```
85    pub fn from_config(config_enum: BuiltinConfig) -> Result<Self> {
86        let name = config_enum.to_filename();
87        let config_str = embedded::EMBEDDED_CONFIGS
88            .get(name)
89            .ok_or_else(|| error::OpenCCError::ConfigNotFound(name.to_string()))?;
90
91        let config: Config = config_str.parse()?;
92
93        let conversion_chain = ConversionChain::from_config_embedded(&config.conversion_chain)?;
94
95        Ok(Self {
96            name: config.name,
97            conversion_chain,
98        })
99    }
100
101    /// 根据加载的配置转换字符串
102    ///
103    /// # 参数
104    ///
105    /// * `input`: 需要转换的字符串
106    ///
107    /// # 返回
108    ///
109    /// 转换后的字符串
110    #[must_use]
111    pub fn convert(&self, input: &str) -> String {
112        self.conversion_chain.convert(input)
113    }
114
115    /// 返回当前加载的配置名称
116    #[must_use]
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 {`string`} `config_name` - 要使用的内置配置名称, 例如 "s2t.json"。
128    /// @returns {`OpenCC`} - 一个 `OpenCC` 实例。
129    /// @throws {`JsValue`} - 如果配置加载失败,则抛出一个错误对象。
130    ///
131    /// @example
132    /// ```javascript
133    /// import init, { OpenCC } from './pkg/ferrous_opencc.js';
134    ///
135    /// async function main() {
136    ///   await init();
137    ///   try {
138    ///     const converter = new OpenCC("s2t.json");
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_name: &str) -> std::result::Result<Self, JsValue> {
148        let config_enum = BuiltinConfig::from_filename(config_name)
149            .map_err(|e| JsValue::from_str(&e.to_string()))?;
150        Self::from_config(config_enum).map_err(|e| JsValue::from_str(&e.to_string()))
151    }
152
153    /// 根据加载的配置转换字符串。
154    ///
155    /// @param {string} input - 需要转换的字符串。
156    /// @returns {string} - 转换后的字符串。
157    ///
158    /// @example
159    /// ```javascript
160    /// const traditionalText = converter.convert("开放中文转换");
161    /// console.log(traditionalText); // 预期: 開放中文轉換
162    /// ```
163    #[wasm_bindgen(js_name = convert)]
164    #[must_use]
165    pub fn convert_wasm(&self, input: &str) -> String {
166        self.convert(input)
167    }
168
169    /// 获取当前加载的配置的名称。
170    ///
171    /// @returns {string} - 配置的名称。
172    ///
173    /// @example
174    /// ```javascript
175    /// const configName = converter.name;
176    /// console.log(configName);
177    /// ```
178    #[wasm_bindgen(getter, js_name = name)]
179    #[must_use]
180    pub fn name_wasm(&self) -> String {
181        self.name.clone()
182    }
183}