ferrous_opencc/
lib.rs

1//! # 纯 Rust 实现的 OpenCC
2//!
3//! 为繁体中文和简体中文之间提供高性能的转换。
4//!
5//! ## 示例
6//!
7//! ```no_run
8//! use ferrous_opencc::OpenCC;
9//!
10//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
11//! // 创建 OpenCC 实例
12//! let opencc = OpenCC::new("path/to/your/s2t.json")?;
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 compiler;
24pub mod config;
25pub mod conversion;
26pub mod dictionary;
27pub mod error;
28pub mod segmentation;
29
30use config::Config;
31use conversion::ConversionChain;
32use error::Result;
33use segmentation::{Segmentation, SegmentationType};
34use std::path::Path;
35
36#[cfg(feature = "embed-dictionaries")]
37include!(concat!(env!("OUT_DIR"), "/embedded_map.rs"));
38
39/// 核心的 OpenCC 转换器
40pub struct OpenCC {
41    /// 配置名称
42    name: String,
43    /// 分词器
44    segmentation: Box<dyn Segmentation>,
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 segmentation = SegmentationType::from_config(&config.segmentation, config_dir)?;
67
68        // 3. 初始化转换链
69        let conversion_chain = ConversionChain::from_config(&config.conversion_chain, config_dir)?;
70
71        Ok(Self {
72            name: config.name,
73            segmentation: segmentation.into_segmenter(),
74            conversion_chain,
75        })
76    }
77
78    // 从嵌入的资源创建 OpenCC 实例
79    #[cfg(feature = "embed-dictionaries")]
80    pub fn from_config_name(name: &str) -> Result<Self> {
81        use crate::dictionary::embedded;
82
83        let config_str = embedded::EMBEDDED_CONFIGS
84            .get(name)
85            .ok_or_else(|| error::OpenCCError::ConfigNotFound(name.to_string()))?;
86
87        // 从字符串解析配置
88        let config: Config = config_str.parse()?;
89
90        // 初始化分词器和转换链,并告诉它们使用嵌入式词典
91        let segmentation = SegmentationType::from_config_embedded(&config.segmentation)?;
92        let conversion_chain = ConversionChain::from_config_embedded(&config.conversion_chain)?;
93
94        Ok(Self {
95            name: config.name,
96            segmentation: segmentation.into_segmenter(),
97            conversion_chain,
98        })
99    }
100
101    /// 根据加载的配置转换字符串
102    ///
103    /// # 参数
104    ///
105    /// * `input`: 需要转换的字符串
106    ///
107    /// # 返回
108    ///
109    /// 转换后的字符串
110    pub fn convert(&self, input: &str) -> String {
111        // 1. 使用分词器进行分词
112        let segments = self.segmentation.segment(input);
113        // 2. 使用转换链进行转换
114        self.conversion_chain.convert(&segments)
115    }
116
117    /// 返回当前加载的配置名称
118    pub fn name(&self) -> &str {
119        &self.name
120    }
121}