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
36include!(concat!(env!("OUT_DIR"), "/embedded_map.rs"));
37
38/// 核心的 OpenCC 转换器
39pub struct OpenCC {
40    /// 配置名称
41    name: String,
42    /// 分词器
43    segmentation: Box<dyn Segmentation>,
44    /// 用于执行转换的词典链
45    conversion_chain: ConversionChain,
46}
47
48impl OpenCC {
49    /// 从配置文件创建一个新的 `OpenCC` 实例。
50    /// 解析 JSON 配置文件,加载所有必需的词典,并构建转换流程。
51    ///
52    /// # 参数
53    ///
54    /// * `config_path`: 指向主 JSON 配置文件(例如 `s2t.json`)的路径
55    ///
56    /// # 返回
57    ///
58    /// 一个 `Result`,其中包含新的 `OpenCC` 实例,或者在加载失败时返回错误
59    pub fn new<P: AsRef<Path>>(config_path: P) -> Result<Self> {
60        // 1. 解析配置文件
61        let config = Config::from_file(config_path)?;
62        let config_dir = config.get_config_directory();
63
64        // 2. 初始化分词器
65        let segmentation = SegmentationType::from_config(&config.segmentation, config_dir)?;
66
67        // 3. 初始化转换链
68        let conversion_chain = ConversionChain::from_config(&config.conversion_chain, config_dir)?;
69
70        Ok(Self {
71            name: config.name,
72            segmentation: segmentation.into_segmenter(),
73            conversion_chain,
74        })
75    }
76
77    // 从嵌入的资源创建 OpenCC 实例
78    pub fn from_config_name(name: &str) -> Result<Self> {
79        use crate::dictionary::embedded;
80
81        let config_str = embedded::EMBEDDED_CONFIGS
82            .get(name)
83            .ok_or_else(|| error::OpenCCError::ConfigNotFound(name.to_string()))?;
84
85        // 从字符串解析配置
86        let config: Config = config_str.parse()?;
87
88        // 初始化分词器和转换链,并告诉它们使用嵌入式词典
89        let segmentation = SegmentationType::from_config_embedded(&config.segmentation)?;
90        let conversion_chain = ConversionChain::from_config_embedded(&config.conversion_chain)?;
91
92        Ok(Self {
93            name: config.name,
94            segmentation: segmentation.into_segmenter(),
95            conversion_chain,
96        })
97    }
98
99    /// 根据加载的配置转换字符串
100    ///
101    /// # 参数
102    ///
103    /// * `input`: 需要转换的字符串
104    ///
105    /// # 返回
106    ///
107    /// 转换后的字符串
108    pub fn convert(&self, input: &str) -> String {
109        // 1. 使用分词器进行分词
110        let segments = self.segmentation.segment(input);
111        // 2. 使用转换链进行转换
112        self.conversion_chain.convert(&segments)
113    }
114
115    /// 返回当前加载的配置名称
116    pub fn name(&self) -> &str {
117        &self.name
118    }
119}