Rust字符串精确处理库precis-profiles的使用:支持PRECIS框架的Unicode标准化和验证功能

Rust字符串精确处理库precis-profiles的使用:支持PRECIS框架的Unicode标准化和验证功能

precis-profiles是一个实现PRECIS框架的Rust库,用于国际化字符串的预处理、强制和比较。它遵循RFC8264规范,并实现了以下PRECIS配置文件:

  1. RFC8265:用于表示用户名和密码的国际化字符串的预处理、强制和比较
  2. RFC8266:用于表示昵称的国际化字符串的预处理、强制和比较

示例代码

assert_eq!(Nickname::prepare("Guybrush Threepwood"),
  Ok(Cow::from("Guybrush Threepwood")));
assert_eq!(Nickname::enforce("   Guybrush     Threepwood  "),
  Ok(Cow::from("Guybrush Threepwood")));
assert_eq!(Nickname::compare("Guybrush   Threepwood  ",
  "guybrush threepwood"), Ok(true));

完整示例demo

use precis_profiles::Nickname;
use std::borrow::Cow;

fn main() {
    // 示例1:准备昵称字符串
    let prepared = Nickname::prepare("Guybrush Threepwood");
    assert_eq!(prepared, Ok(Cow::from("Guybrush Threepwood")));
    
    // 示例2:强制执行昵称规则(去除多余空格)
    let enforced = Nickname::enforce("   Guybrush     Threepwood  ");
    assert_eq!(enforced, Ok(Cow::from("Guybrush Threepwood")));
    
    // 示例3:比较两个昵称(不区分大小写和空格)
    let compared = Nickname::compare("Guybrush   Threepwood  ", "guybrush threepwood");
    assert_eq!(compared, Ok(true));
    
    // 示例4:处理包含特殊字符的昵称
    let special_chars = Nickname::prepare("ユーザー名123");
    println!("处理后的昵称: {:?}", special_chars);
    
    // 示例5:处理无效昵称
    let invalid_nick = Nickname::enforce("Invalid\nNick");
    println!("无效昵称处理结果: {:?}", invalid_nick);
}

功能说明

  1. prepare(): 准备字符串,进行基本的Unicode标准化处理
  2. enforce(): 强制执行PRECIS规则,包括去除多余空格等
  3. compare(): 比较两个字符串,不区分大小写和空格差异

安装

在Cargo.toml中添加依赖:

precis-profiles = "0.1.12"

或者运行命令:

cargo add precis-profiles

许可证

该项目采用以下许可证之一:

  • Apache License, Version 2.0
  • MIT license

1 回复

Rust字符串精确处理库precis-profiles的使用

precis-profiles是一个实现PRECIS框架(Preparedness and Comparison of Internationalized Strings)的Rust库,用于Unicode字符串的标准化处理和验证。

功能概述

precis-profiles提供以下主要功能:

  • 实现RFC 8264/8265/8266定义的PRECIS框架
  • Unicode字符串的标准化处理
  • 字符串验证和比较
  • 支持多种PRECIS profile(IdentifierClass, FreeFormClass等)

安装方法

在Cargo.toml中添加依赖:

[dependencies]
precis-profiles = "0.5"

基本使用方法

1. 字符串标准化

use precis_profiles::{IdentifierClass, Profile};

fn main() {
    let input = "Hello_World123"; // 全角字符
    
    // 使用IdentifierClass profile处理字符串
    let result = IdentifierClass::prepare(input).unwrap();
    
    println!("{}", result); // 输出: "hello_world123"
}

2. 字符串验证

use precis_profiles::{FreeFormClass, Profile};

fn main() {
    let username = "user@name";
    
    match FreeFormClass::validate(username) {
        Ok(_) => println!("Valid username"),
        Err(e) => println!("Invalid username: {}", e),
    }
}

3. 字符串比较

use precis_profiles::{IdentifierClass, Profile};

fn main() {
    let str1 = "User";
    let str2 = "user";
    
    let comparable1 = IdentifierClass::prepare(str1).unwrap();
    let comparable2 = IdentifierClass::prepare(str2).unwrap();
    
    assert_eq!(comparable1, comparable2);
}

支持的PRECIS Profiles

precis-profiles实现了以下几种标准profile:

  1. IdentifierClass - 用于标识符(如用户名)
  2. FreeFormClass - 用于自由格式字符串(如聊天消息)
  3. OpaqueString - 用于不透明的字符串(如密码)
  4. Nickname - 用于昵称处理

高级用法

自定义profile

use precis_profiles::{Profile, BaseProfile, DerivedPropertyValue};

struct MyCustomProfile;

impl Profile for MyCustomProfile {
    fn prepare(&self, s: &str) -> Result<String, precis_core::Error> {
        BaseProfile::new()
            .width(true)          // 全角转半角
            .case_map(true)       // 大小写转换
            .additional_mapping(|c| if c == '!' { Some('_') } else { None })
            .derived_property_value(DerivedPropertyValue::FreeForm)
            .prepare(s)
    }
}

fn main() {
    let input = "Hello!World";
    let result = MyCustomProfile.prepare(input).unwrap();
    println!("{}", result); // 输出: "hello_world"
}

实际应用场景

  1. 用户名处理
use precis_profiles::IdentifierClass;

fn normalize_username(username: &str) -> Result<String, String> {
    IdentifierClass::prepare(username)
        .map_err(|e| format!("Invalid username: {}", e))
}
  1. 密码规范化
use precis_profiles::OpaqueString;

fn normalize_password(password: &str) -> Result<String, String> {
    OpaqueString::prepare(password)
        .map_err(|e| format!("Invalid password: {}", e))
}
  1. 国际化域名处理
use precis_profiles::IdentifierClass;

fn normalize_domain_label(label: &str) -> Result<String, String> {
    IdentifierClass::prepare(label)
        .map_err(|e| format!("Invalid domain label: {}", e))
}

完整示例代码

use precis_profiles::{Profile, IdentifierClass, FreeFormClass, OpaqueString};

fn main() {
    // 字符串标准化示例
    let input = "Abc123"; // 全角字符
    let normalized = IdentifierClass::prepare(input).unwrap();
    println!("标准化结果: {}", normalized); // 输出: "abc123"

    // 用户名验证示例
    let username = "user@test";
    match IdentifierClass::validate(username) {
        Ok(_) => println!("用户名有效"),
        Err(e) => println!("用户名无效: {}", e),
    }

    // 密码处理示例
    let password = "P@ssw0rd";
    let safe_pwd = OpaqueString::prepare(password).unwrap();
    println!("标准化密码: {}", safe_pwd);

    // 字符串比较示例
    let str1 = "Hello";
    let str2 = "hello";
    let comp1 = FreeFormClass::prepare(str1).unwrap();
    let comp2 = FreeFormClass::prepare(str2).unwrap();
    println!("比较结果: {}", comp1 == comp2); // 输出: true

    // 自定义profile使用示例
    struct MyProfile;
    impl Profile for MyProfile {
        fn prepare(&self, s: &str) -> Result<String, precis_core::Error> {
            BaseProfile::new()
                .width(true)
                .case_map(true)
                .prepare(s)
        }
    }
    
    let custom_input = "TEST";
    let custom_result = MyProfile.prepare(custom_input).unwrap();
    println!("自定义处理结果: {}", custom_result); // 输出: "test"
}

注意事项

  1. PRECIS处理是不可逆的,原始字符串信息可能会丢失
  2. 不同profile的严格程度不同,应根据具体场景选择
  3. 密码等敏感信息建议使用OpaqueString profile
  4. 处理结果可能会因Unicode版本不同而略有差异

precis-profiles为处理国际化字符串提供了标准化的方法,特别适合需要严格字符串处理的应用程序,如身份验证系统、网络协议实现等。

回到顶部