Rust国际化组件库icu_capi的使用:Unicode文本处理、日期格式化和区域敏感操作的C语言绑定
Rust国际化组件库icu_capi的使用:Unicode文本处理、日期格式化和区域敏感操作的C语言绑定
概述
icu_capi是ICU4X项目的C语言绑定,提供了Unicode文本处理、日期格式化和区域敏感操作等国际化功能。这个crate包含了extern "C"
FFI接口以及通过Diplomat生成的C、C++、Dart、JavaScript和TypeScript绑定。
特性
- 兼容
no_std
环境,但需要分配器支持 - 提供稳定的C API接口(在同一个主要semver版本中保持稳定)
- 支持多种编程语言的绑定
安装
在Cargo.toml中添加依赖:
icu_capi = "2.0.2"
或者运行命令:
cargo add icu_capi
使用示例
Unicode文本处理示例
use icu_capi::data_provider::StaticDataProvider;
use icu_capi::normalizer::UCharNormalizer;
// 创建静态数据提供者
let provider = StaticDataProvider::try_new_default().unwrap();
// 创建Unicode规范化器(NFC形式)
let normalizer = UCharNormalizer::try_new_nfc(&provider).unwrap();
// 输入文本
let input = "Café".as_bytes();
// 规范化文本
let mut output = Vec::new();
normalizer.normalize_utf8(input, &mut output).unwrap();
println!("Normalized: {}", String::from_utf8(output).unwrap());
日期格式化示例
use icu_capi::calendar::Gregorian;
use icu_capi::datetime::DateTimeFormat;
use icu_capi::data_provider::StaticDataProvider;
use icu_capi::locale::Locale;
// 创建静态数据提供者
let provider = StaticDataProvider::try_new_default().unwrap();
// 设置区域(美国英语)
let locale = Locale::try_from_bytes(b"en-US").unwrap();
// 创建日期格式化器
let options = DateTimeFormat::try_new_default_date(&provider, &locale).unwrap();
// 创建日期(2023年6月15日)
let date = Gregorian::try_new_date(2023, 6, 15).unwrap();
// 格式化日期
let mut output = Vec::new();
options.format_to_write(&mut output, &date).unwrap();
println!("Formatted date: {}", String::from_utf8(output).unwrap());
区域敏感操作示例
use icu_capi::collator::Collator;
use icu_capi::data_provider::StaticDataProvider;
use icu_capi::locale::Locale;
// 创建静态数据提供者
let provider = StaticDataProvider::try_new_default().unwrap();
// 设置区域(德语-德国)
let locale = Locale::try_from_bytes(b"de-DE").unwrap();
// 创建排序器
let collator = Collator::try_new(&provider, &locale).unwrap();
// 比较字符串(德语特殊字符ä与z比较)
let result = collator.compare(b"ä", b"z").unwrap();
println!("Comparison result: {}", result);
注意事项
- 虽然这个crate的类型是公开的,但其API不打算直接从Rust使用
- C API接口在同一主要semver版本中是稳定的
- 在
no_std
环境下使用时,需要启用looping_panic_handler
和libc_alloc
特性,或者自定义分配器/panic处理程序
完整示例
以下是一个完整的示例,展示如何使用icu_capi进行Unicode文本规范化、日期格式化和区域敏感排序:
use icu_capi::{
calendar::Gregorian,
collator::Collator,
data_provider::StaticDataProvider,
datetime::DateTimeFormat,
locale::Locale,
normalizer::UCharNormalizer,
};
fn main() {
// 初始化数据提供者
let provider = StaticDataProvider::try_new_default().unwrap();
// 示例1: Unicode文本规范化
let normalizer = UCharNormalizer::try_new_nfc(&provider).unwrap();
let input = "Café".as_bytes();
let mut normalized = Vec::new();
normalizer.normalize_utf8(input, &mut normalized).unwrap();
println!("Normalized text: {}", String::from_utf8(normalized).unwrap());
// 示例2: 日期格式化
let locale = Locale::try_from_bytes(b"en-US").unwrap();
let date_format = DateTimeFormat::try_new_default_date(&provider, &locale).unwrap();
let date = Gregorian::try_new_date(2023, 6, 15).unwrap();
let mut formatted_date = Vec::new();
date_format.format_to_write(&mut formatted_date, &date).unwrap();
println!("Formatted date: {}", String::from_utf8(formatted_date).unwrap());
// 示例3: 区域敏感排序
let german_locale = Locale::try_from_bytes(b"de-DE").unwrap();
let collator = Collator::try_new(&provider, &german_locale).unwrap();
let comparison = collator.compare(b"ä", b"z").unwrap();
println!("German comparison (ä vs z): {}", comparison);
}
这个示例展示了icu_capi的主要功能:
- Unicode文本规范化(NFC形式)
- 按照美国英语格式格式化日期
- 按照德语规则比较字符串
注意在实际使用时,需要根据具体需求调整区域设置和选项参数。
1 回复
Rust国际化组件库icu_capi的使用指南
概述
icu_capi
是Rust中用于国际化和本地化操作的C语言绑定库,它基于ICU(International Components for Unicode)库,提供了强大的Unicode文本处理、日期格式化和区域敏感操作功能。
主要功能
- Unicode文本处理
- 日期和时间格式化
- 区域敏感操作(排序、数字格式化等)
- 字符集转换
- 复数规则处理
安装
在Cargo.toml中添加依赖:
[dependencies]
icu_capi = "0.7"
基本使用方法
1. Unicode文本处理
use icu_capi::normalizer::*;
use std::ffi::CString;
fn main() {
// 创建规范化器
let normalizer = unsafe { unorm2_getNFCInstance(std::ptr::null_mut()) };
// 要规范化的字符串
let input = CString::new("Café").unwrap();
let mut output = [0u8; 32];
// 执行规范化
let status = unsafe {
unorm2_normalize(
normalizer,
input.as_ptr() as *const u16,
input.as_bytes().len() as i32,
output.as_mut_ptr() as *mut u16,
32,
std::ptr::null_mut(),
)
};
if status.is_ok() {
println!("Normalization successful");
}
}
2. 日期格式化
use icu_capi::udat::*;
use icu_capi::uloc::*;
use std::ffi::CString;
fn main() {
// 设置区域
let locale = CString::new("en-US").unwrap();
let loc = unsafe { uloc_open(locale.as_ptr(), std::ptr::null(), std::ptr::null_mut()) };
// 创建日期格式化器
let pattern = CString::new("yyyy-MM-dd").unwrap();
let df = unsafe {
udat_open(
UDAT_PATTERN,
UDAT_PATTERN,
loc,
std::ptr::null(),
-1,
pattern.as_ptr() as *const u16,
pattern.as_bytes().len() as i32,
std::ptr::null_mut(),
)
};
// 格式化当前时间
let mut buffer = [0u16; 64];
let now = unsafe { udat_getNow() };
let len = unsafe {
udat_format(
df,
now,
buffer.as_mut_ptr(),
64,
std::ptr::null(),
std::ptr::null_mut(),
)
};
if len > 0 {
let formatted = String::from_utf16_lossy(&buffer[..len as usize]);
println!("Formatted date: {}", formatted);
}
// 清理资源
unsafe {
udat_close(df);
uloc_close(loc);
}
}
3. 区域敏感操作(数字格式化)
use icu_capi::unum::*;
use icu_capi::uloc::*;
use std::ffi::CString;
fn main() {
// 设置区域
let locale = CString::new("fr-FR").unwrap();
let loc = unsafe { uloc_open(locale.as_ptr(), std::ptr::null(), std::ptr::null_mut()) };
// 创建数字格式化器
let nf = unsafe { unum_open(UNUM_DECIMAL, std::ptr::null(), -1, loc, std::ptr::null(), std::ptr::null_mut()) };
// 格式化数字
let number = 1234567.89;
let mut buffer = [0u16; 64];
let len = unsafe {
unum_formatDouble(
nf,
number,
buffer.as_mut_ptr(),
64,
std::ptr::null(),
std::ptr::null_mut(),
)
};
if len > 0 {
let formatted = String::from_utf16_lossy(&buffer[..len as usize]);
println!("Formatted number (French): {}", formatted); // 输出 "1 234 567,89"
}
// 清理资源
unsafe {
unum_close(nf);
uloc_close(loc);
}
}
完整示例demo
下面是一个综合使用icu_capi的完整示例,展示了文本规范化、日期格式化和数字格式化的组合使用:
use icu_capi::{normalizer::*, udat::*, unum::*, uloc::*};
use std::ffi::CString;
fn main() {
// ==== 第一部分:Unicode文本规范化 ====
println!("=== Unicode文本规范化 ===");
// 创建NFC规范化器
let normalizer = unsafe { unorm2_getNFCInstance(std::ptr::null_mut()) };
let input = CString::new("Café").unwrap();
let mut output = [0u8; 32];
// 执行规范化
let status = unsafe {
unorm2_normalize(
normalizer,
input.as_ptr() as *const u16,
input.as_bytes().len() as i32,
output.as_mut_ptr() as *mut u16,
32,
std::ptr::null_mut(),
)
};
if status.is_ok() {
println!("文本规范化成功");
}
// ==== 第二部分:日期格式化 ====
println!("\n=== 日期格式化 ===");
// 设置英文(美国)区域
let locale_en = CString::new("en-US").unwrap();
let loc_en = unsafe { uloc_open(locale_en.as_ptr(), std::ptr::null(), std::ptr::null_mut()) };
// 创建日期格式化器
let pattern = CString::new("yyyy-MM-dd HH:mm:ss").unwrap();
let df = unsafe {
udat_open(
UDAT_PATTERN,
UDAT_PATTERN,
loc_en,
std::ptr::null(),
-1,
pattern.as_ptr() as *const u16,
pattern.as_bytes().len() as i32,
std::ptr::null_mut(),
)
};
// 格式化当前时间
let mut date_buffer = [0u16; 64];
let now = unsafe { udat_getNow() };
let len = unsafe {
udat_format(
df,
now,
date_buffer.as_mut_ptr(),
64,
std::ptr::null(),
std::ptr::null_mut(),
)
};
if len > 0 {
let formatted = String::from_utf16_lossy(&date_buffer[..len as usize]);
println!("英文日期格式: {}", formatted);
}
// ==== 第三部分:数字格式化 ====
println!("\n=== 数字格式化 ===");
// 设置法语(法国)区域
let locale_fr = CString::new("fr-FR").unwrap();
let loc_fr = unsafe { uloc_open(locale_fr.as_ptr(), std::ptr::null(), std::ptr::null_mut()) };
// 创建数字格式化器
let nf = unsafe { unum_open(UNUM_DECIMAL, std::ptr::null(), -1, loc_fr, std::ptr::null(), std::ptr::null_mut()) };
// 格式化数字
let number = 1234567.89;
let mut num_buffer = [0u16; 64];
let len = unsafe {
unum_formatDouble(
nf,
number,
num_buffer.as_mut_ptr(),
64,
std::ptr::null(),
std::ptr::null_mut(),
)
};
if len > 0 {
let formatted = String::from_utf16_lossy(&num_buffer[..len as usize]);
println!("法文数字格式: {}", formatted); // 输出 "1 234 567,89"
}
// ==== 清理资源 ====
unsafe {
// 释放文本规范化相关资源
// (注意:unorm2_getNFCInstance返回的是共享实例,不需要关闭)
// 释放日期格式化相关资源
udat_close(df);
uloc_close(loc_en);
// 释放数字格式化相关资源
unum_close(nf);
uloc_close(loc_fr);
}
}
注意事项
- 大多数ICU C API函数需要手动管理内存,确保正确释放资源
- 错误处理通过返回的UErrorCode进行
- 字符串通常以UTF-16格式处理
- 在多线程环境中使用时需要注意线程安全性
高级功能
icu_capi
还支持更高级的功能,如:
- 双向文本处理(阿拉伯语、希伯来语等)
- 断词和断行
- 转换器(字符编码转换)
- 复数规则和消息格式化
性能建议
- 重用格式化器实例,避免频繁创建和销毁
- 对于固定模式,考虑预编译模式
- 使用缓冲区重用技术减少内存分配
通过icu_capi
,Rust开发者可以方便地利用ICU库的强大国际化功能,同时保持与C语言生态系统的互操作性。