#unicode #block #unicode-text #text

unic-ucd-block

UNIC — Unicode字符数据库 — Unicode区块

2个不稳定版本

0.9.0 2019年3月3日
0.8.0 2019年1月2日

1827文本处理 中排名

Download history 183/week @ 2024-03-13 251/week @ 2024-03-20 240/week @ 2024-03-27 237/week @ 2024-04-03 273/week @ 2024-04-10 198/week @ 2024-04-17 228/week @ 2024-04-24 217/week @ 2024-05-01 238/week @ 2024-05-08 206/week @ 2024-05-15 228/week @ 2024-05-22 278/week @ 2024-05-29 179/week @ 2024-06-05 219/week @ 2024-06-12 194/week @ 2024-06-19 181/week @ 2024-06-26

每月下载量 804
22 个仓库中使用 (直接使用 3 个)

MIT/Apache

58KB
786

UNIC:为Rust语言提供Unicode和国际化的组件

UNIC-logo

Travis Rust-1.45+ Unicode-10.0.0 Release Crates.io Documentation Gitter

https://github.com/open-i18n/rust-unic

UNIC 是一个旨在为Rust编程语言开发组件的项目,以提供高质量的、易于使用的Unicode和国际化和算法的crates。换句话说,它就像是Rust版的 ICU,完全用Rust编写,主要在 safe 模式下,但在可能的情况下也会受益于 unsafe 模式的性能提升。

请参阅 UNIC 更新日志 了解最新版本详情。

项目目标

UNIC的目标是为Unicode和国际化的所有级别提供访问权限,从Unicode字符属性开始,到处理文本的Unicode算法,再到基于Unicode通用区域数据仓库(CLDR)的更高级(基于区域的)过程。

根据需要,还实现了其他标准和最佳实践,如IETF RFCs。

项目状态

目前,UNIC正在经历快速开发:API经常在 master 分支上更新,并且每个 0.x 版本之间都可能发生API破坏。请参阅 开放问题 了解计划变更。

我们预计将在2018年发布 1.0 版本,之后将维护稳定的API,前几年可能每年更新一到两次API。

设计目标

  1. UNIC的主要目标是提供易于使用的API,以实现可靠的函数。因此,新添加的组件可能不会对性能进行很好的优化,但将会有足够的测试来展示符合标准,以及示例来展示用户如何使用它们来满足常见需求。

  2. UNIC组件的下一个主要目标是性能和低二进制和内存占用。特别地,优化ASCII和其他常见情况下的运行时将鼓励适应性,而不用担心减慢常规开发过程。

  3. 组件将在可能范围内保证提供一致的数据和算法。使用跨组件测试来捕获实现之间的任何不一致,而不会减慢开发过程。

组件及其组织

UNIC 组件具有层次结构,从根节点 unic 开始,包含主要组件。每个主要组件反过来可以包含一些次要组件。

主要组件的API是为库的最终用户设计的,并期望有广泛的文档,并附带代码示例。

与主要组件相比,次要组件充当更高层的数据和算法提供者,其API预计性能更高,并且可能提供多种访问数据的方式。

UNIC 超级包

unic 超级包是所有 UNIC(主要)组件的集合,提供了一个访问所有功能的简便方式,当需要所有或大多数组件时,无需逐个导入组件。此包确保所有导入的组件在算法和数据方面都是兼容的。

主要的代码示例和跨组件集成测试都在这个包下实现。

主要组件

应用

代码组织:组合存储库

以下是一些将组件组合成一个存储库的原因

  • 更快地开发。实现新的 Unicode/i18n 组件通常需要依赖其他(较低级别)组件,而这些组件反过来可能需要进行调整——暴露新的 API、修复错误等,这些都可以在更少的周期和更短的时间内进行开发、测试和审查。

  • 实现完整性。多个组件对其他组件的依赖意味着组件在某种程度上需要相互一致。许多由较小部分组成的Unicode算法假设算法的所有部分都在使用相同的Unicode数据版本。违反这个假设可能会导致不一致和难以捕捉的bug。在联合仓库中,在开发过程中以及在跨组件(集成)测试中,都有可能达到更好的完整性。

  • 按需付费。小型组件(基本crate),仅依赖于它们需要的部分,使用户只需在其项目中引入他们消耗的部分。

  • 共享引导。大量扩展Unicode/i18n功能依赖于将源Unicode/地区数据转换为目的地编程语言的格式化格式。在联合仓库中,更容易维护这些引导工具,扩大覆盖范围,并使用更高效的数据结构。

文档

如何使用UNIC

Cargo.toml

[dependencies]
unic = "0.9.0"  # This has Unicode 10.0.0 data and algorithms

和在main.rs

extern crate unic;

use unic::ucd::common::is_alphanumeric;
use unic::bidi::BidiInfo;
use unic::normal::StrNormalForm;
use unic::segment::{GraphemeIndices, Graphemes, WordBoundIndices, WordBounds, Words};
use unic::ucd::normal::compose;
use unic::ucd::{is_cased, Age, BidiClass, CharAge, CharBidiClass, StrBidiClass, UnicodeVersion};

fn main() {

    // Age

    assert_eq!(Age::of('A').unwrap().actual(), UnicodeVersion { major: 1, minor: 1, micro: 0 });
    assert_eq!(Age::of('\u{A0000}'), None);
    assert_eq!(
        Age::of('\u{10FFFF}').unwrap().actual(),
        UnicodeVersion { major: 2, minor: 0, micro: 0 }
    );

    if let Some(age) = '🦊'.age() {
        assert_eq!(age.actual().major, 9);
        assert_eq!(age.actual().minor, 0);
        assert_eq!(age.actual().micro, 0);
    }

    // Bidi

    let text = concat![
        "א",
        "ב",
        "ג",
        "a",
        "b",
        "c",
    ];

    assert!(!text.has_bidi_explicit());
    assert!(text.has_rtl());
    assert!(text.has_ltr());

    assert_eq!(text.chars().nth(0).unwrap().bidi_class(), BidiClass::RightToLeft);
    assert!(!text.chars().nth(0).unwrap().is_ltr());
    assert!(text.chars().nth(0).unwrap().is_rtl());

    assert_eq!(text.chars().nth(3).unwrap().bidi_class(), BidiClass::LeftToRight);
    assert!(text.chars().nth(3).unwrap().is_ltr());
    assert!(!text.chars().nth(3).unwrap().is_rtl());

    let bidi_info = BidiInfo::new(text, None);
    assert_eq!(bidi_info.paragraphs.len(), 1);

    let para = &bidi_info.paragraphs[0];
    assert_eq!(para.level.number(), 1);
    assert_eq!(para.level.is_rtl(), true);

    let line = para.range.clone();
    let display = bidi_info.reorder_line(para, line);
    assert_eq!(
        display,
        concat![
            "a",
            "b",
            "c",
            "ג",
            "ב",
            "א",
        ]
    );

    // Case

    assert_eq!(is_cased('A'), true);
    assert_eq!(is_cased('א'), false);

    // Normalization

    assert_eq!(compose('A', '\u{030A}'), Some('Å'));

    let s = "ÅΩ";
    let c = s.nfc().collect::<String>();
    assert_eq!(c, "ÅΩ");

    // Segmentation

    assert_eq!(
        Graphemes::new("a\u{310}e\u{301}o\u{308}\u{332}").collect::<Vec<&str>>(),
        &["a\u{310}", "e\u{301}", "o\u{308}\u{332}"]
    );

    assert_eq!(
        Graphemes::new("a\r\nb🇺🇳🇮🇨").collect::<Vec<&str>>(),
        &["a", "\r\n", "b", "🇺🇳", "🇮🇨"]
    );

    assert_eq!(
        GraphemeIndices::new("a̐éö̲\r\n").collect::<Vec<(usize, &str)>>(),
        &[(0, ""), (3, ""), (6, "ö̲"), (11, "\r\n")]
    );

    assert_eq!(
        Words::new(
            "The quick (\"brown\") fox can't jump 32.3 feet, right?",
            |s: &&str| s.chars().any(is_alphanumeric),
        ).collect::<Vec<&str>>(),
        &["The", "quick", "brown", "fox", "can't", "jump", "32.3", "feet", "right"]
    );

    assert_eq!(
        WordBounds::new("The quick (\"brown\")  fox").collect::<Vec<&str>>(),
        &["The", " ", "quick", " ", "(", "\"", "brown", "\"", ")", " ", " ", "fox"]
    );

    assert_eq!(
        WordBoundIndices::new("Brr, it's 29.3°F!").collect::<Vec<(usize, &str)>>(),
        &[
            (0, "Brr"),
            (3, ","),
            (4, " "),
            (5, "it's"),
            (9, " "),
            (10, "29.3"),
            (14, "°"),
            (16, "F"),
            (17, "!")
        ]
    );
}

您可以在examplestests目录下找到更多示例。(随着UNIC的扩展还将添加更多...)

许可证

许可方式如下

由您选择。

贡献

除非您明确声明,否则根据Apache-2.0许可证定义,您提交的任何旨在包含在作品中的贡献,都应按上述方式双许可,没有任何附加条款或条件。

行为准则

UNIC项目遵循《Rust行为准则》。您可以在CODE_OF_CONDUCT.md中或在线https://www.rust-lang.net.cn/conduct.html找到其副本。


lib.rs:

UNIC - UCD - 区块

unic的一部分:Rust的Unicode和国际化crate。

Unicode字符数据库(UCD)代码块的访问器

依赖