]>
git.proxmox.com Git - rustc.git/blob - vendor/unicase/src/unicode/mod.rs
1 #[cfg(__unicase__iter_cmp)]
2 use core
::cmp
::Ordering
;
3 use core
::hash
::{Hash, Hasher}
;
8 #[derive(Clone, Copy, Debug, Default)]
9 pub struct Unicode
<S
>(pub S
);
11 impl<S1
: AsRef
<str>, S2
: AsRef
<str>> PartialEq
<Unicode
<S2
>> for Unicode
<S1
> {
13 fn eq(&self, other
: &Unicode
<S2
>) -> bool
{
14 let mut left
= self.0.as_ref().chars().flat_map(lookup
);
15 let mut right
= other
.0.as_ref().chars().flat_map(lookup
);
17 // inline Iterator::eq since not added until Rust 1.5
19 let x
= match left
.next() {
20 None
=> return right
.next().is_none(),
24 let y
= match right
.next() {
36 impl<S
: AsRef
<str>> Eq
for Unicode
<S
> {}
38 #[cfg(__unicase__iter_cmp)]
39 impl<T
: AsRef
<str>> PartialOrd
for Unicode
<T
> {
41 fn partial_cmp(&self, other
: &Self) -> Option
<Ordering
> {
46 #[cfg(__unicase__iter_cmp)]
47 impl<T
: AsRef
<str>> Ord
for Unicode
<T
> {
49 fn cmp(&self, other
: &Self) -> Ordering
{
50 let self_chars
= self.0.as_ref().chars().flat_map(lookup
);
51 let other_chars
= other
.0.as_ref().chars().flat_map(lookup
);
52 self_chars
.cmp(other_chars
)
56 impl<S
: AsRef
<str>> Hash
for Unicode
<S
> {
58 fn hash
<H
: Hasher
>(&self, hasher
: &mut H
) {
60 for c
in self.0.as_ref().chars().flat_map(|c
| lookup(c
)) {
61 let len
= char_to_utf8(c
, &mut buf
);
62 hasher
.write(&buf
[..len
])
68 fn char_to_utf8(c
: char, dst
: &mut [u8; 4]) -> usize {
69 const TAG_CONT
: u8 = 0b1000_0000;
70 const TAG_TWO_B
: u8 = 0b1100_0000;
71 const TAG_THREE_B
: u8 = 0b1110_0000;
72 const TAG_FOUR_B
: u8 = 0b1111_0000;
78 } else if code
<= 0x7FF {
79 dst
[0] = (code
>> 6 & 0x1F) as u8 | TAG_TWO_B
;
80 dst
[1] = (code
& 0x3F) as u8 | TAG_CONT
;
82 } else if code
<= 0xFFFF {
83 dst
[0] = (code
>> 12 & 0x0F) as u8 | TAG_THREE_B
;
84 dst
[1] = (code
>> 6 & 0x3F) as u8 | TAG_CONT
;
85 dst
[2] = (code
& 0x3F) as u8 | TAG_CONT
;
88 dst
[0] = (code
>> 18 & 0x07) as u8 | TAG_FOUR_B
;
89 dst
[1] = (code
>> 12 & 0x3F) as u8 | TAG_CONT
;
90 dst
[2] = (code
>> 6 & 0x3F) as u8 | TAG_CONT
;
91 dst
[3] = (code
& 0x3F) as u8 | TAG_CONT
;
96 // internal mod so that the enum can be 'pub'
97 // thanks privacy-checker :___(
99 #[derive(Clone, Copy)]
104 Three(char, char, char),
107 impl Iterator
for Fold
{
110 fn next(&mut self) -> Option
<char> {
117 Fold
::Two(one
, two
) => {
118 *self = Fold
::One(two
);
121 Fold
::Three(one
, two
, three
) => {
122 *self = Fold
::Two(one
, two
);
129 fn size_hint(&self) -> (usize, Option
<usize>) {
131 Fold
::Zero
=> (0, Some(0)),
132 Fold
::One(..) => (1, Some(1)),
133 Fold
::Two(..) => (2, Some(2)),
134 Fold
::Three(..) => (3, Some(3))
139 impl From
<(char,)> for Fold
{
141 fn from((one
,): (char,)) -> Fold
{
146 impl From
<(char, char)> for Fold
{
148 fn from((one
, two
): (char, char)) -> Fold
{
153 impl From
<(char, char, char)> for Fold
{
155 fn from((one
, two
, three
): (char, char, char)) -> Fold
{
156 Fold
::Three(one
, two
, three
)
166 ($left
:expr
, $right
:expr
) => ({
167 assert_eq
!(Unicode($left
), Unicode($right
));
172 fn test_ascii_folding() {
173 eq
!("foo bar", "FoO BAR");
177 fn test_simple_case_folding() {
178 eq
!("στιγμας", "στιγμασ");
182 fn test_full_case_folding() {
183 eq
!("flour", "flour");
184 eq
!("Maße", "MASSE");
185 eq
!("ᾲ στο διάολο", "ὰι στο διάολο");
188 #[cfg(feature = "nightly")]
190 fn bench_ascii_folding(b
: &mut ::test
::Bencher
) {
191 b
.bytes
= b
"foo bar".len() as u64;
192 b
.iter(|| eq
!("foo bar", "FoO BAR"));
195 #[cfg(feature = "nightly")]
197 fn bench_simple_case_folding(b
: &mut ::test
::Bencher
) {
198 b
.bytes
= "στιγμας".len() as u64;
199 b
.iter(|| eq
!("στιγμας", "στιγμασ"));