1use core::cmp;
12
13use unic_char_property::{CharProperty, CustomCharProperty, PartialCharProperty};
14pub use unic_ucd_version::UnicodeVersion;
15
16#[derive(Clone, Copy, Eq, PartialEq, Ord, Debug, Hash)]
39pub struct Age(UnicodeVersion);
40
41impl CharProperty for Age {
42 fn prop_abbr_name() -> &'static str {
43 "age"
44 }
45
46 fn prop_long_name() -> &'static str {
47 "Age"
48 }
49
50 fn prop_human_name() -> &'static str {
51 "Age"
52 }
53}
54
55impl PartialCharProperty for Age {
56 fn of(ch: char) -> Option<Self> {
57 Self::of(ch)
58 }
59}
60
61impl CustomCharProperty<UnicodeVersion> for Age {
62 fn actual(&self) -> UnicodeVersion {
64 Self::actual(self)
65 }
66}
67
68mod data {
69 use super::UnicodeVersion;
70 use unic_char_property::tables::CharDataTable;
71 pub const AGE_TABLE: CharDataTable<UnicodeVersion> = include!("../tables/age_values.rsv");
72}
73
74impl Age {
75 pub fn of(ch: char) -> Option<Age> {
77 data::AGE_TABLE.find(ch).map(Age)
78 }
79
80 pub fn actual(&self) -> UnicodeVersion {
82 self.0
83 }
84}
85
86impl cmp::PartialOrd for Age {
87 fn partial_cmp(&self, other: &Age) -> Option<cmp::Ordering> {
88 match self.0.cmp(&other.0) {
89 cmp::Ordering::Greater => Some(cmp::Ordering::Less),
90 cmp::Ordering::Less => Some(cmp::Ordering::Greater),
91 cmp::Ordering::Equal => Some(cmp::Ordering::Equal),
92 }
93 }
94}
95
96pub trait CharAge {
98 fn age(self) -> Option<Age>;
100}
101
102impl CharAge for char {
103 #[inline]
104 fn age(self) -> Option<Age> {
105 Age::of(self)
106 }
107}
108
109#[cfg(test)]
110mod tests {
111 use super::Age;
112 use unic_ucd_version::UnicodeVersion;
113
114 #[test]
115 fn test_values() {
116 assert_eq!(
118 Age::of('\u{0000}'),
119 Some(Age(UnicodeVersion {
120 major: 1,
121 minor: 1,
122 micro: 0,
123 }))
124 );
125 assert_eq!(
126 Age::of('\u{0021}'),
127 Some(Age(UnicodeVersion {
128 major: 1,
129 minor: 1,
130 micro: 0,
131 }))
132 );
133 assert_eq!(
134 Age::of('\u{0041}'),
135 Some(Age(UnicodeVersion {
136 major: 1,
137 minor: 1,
138 micro: 0,
139 }))
140 );
141 assert_eq!(
142 Age::of('\u{007f}'),
143 Some(Age(UnicodeVersion {
144 major: 1,
145 minor: 1,
146 micro: 0,
147 }))
148 );
149
150 assert_eq!(
151 Age::of('\u{0100}'),
152 Some(Age(UnicodeVersion {
153 major: 1,
154 minor: 1,
155 micro: 0,
156 }))
157 );
158 assert_eq!(
159 Age::of('\u{01f5}'),
160 Some(Age(UnicodeVersion {
161 major: 1,
162 minor: 1,
163 micro: 0,
164 }))
165 );
166 assert_eq!(
167 Age::of('\u{037e}'),
168 Some(Age(UnicodeVersion {
169 major: 1,
170 minor: 1,
171 micro: 0,
172 }))
173 );
174 assert_eq!(
175 Age::of('\u{200c}'),
176 Some(Age(UnicodeVersion {
177 major: 1,
178 minor: 1,
179 micro: 0,
180 }))
181 );
182
183 assert_eq!(
184 Age::of('\u{01f6}'),
185 Some(Age(UnicodeVersion {
186 major: 3,
187 minor: 0,
188 micro: 0,
189 }))
190 );
191 assert_eq!(
192 Age::of('\u{01f7}'),
193 Some(Age(UnicodeVersion {
194 major: 3,
195 minor: 0,
196 micro: 0,
197 }))
198 );
199 assert_eq!(
200 Age::of('\u{01f9}'),
201 Some(Age(UnicodeVersion {
202 major: 3,
203 minor: 0,
204 micro: 0,
205 }))
206 );
207
208 assert_eq!(
209 Age::of('\u{0860}'),
210 Some(Age(UnicodeVersion {
211 major: 10,
212 minor: 0,
213 micro: 0,
214 }))
215 );
216 assert_eq!(
217 Age::of('\u{0866}'),
218 Some(Age(UnicodeVersion {
219 major: 10,
220 minor: 0,
221 micro: 0,
222 }))
223 );
224 assert_eq!(
225 Age::of('\u{086a}'),
226 Some(Age(UnicodeVersion {
227 major: 10,
228 minor: 0,
229 micro: 0,
230 }))
231 );
232
233 assert_eq!(
234 Age::of('\u{fffe}'),
235 Some(Age(UnicodeVersion {
236 major: 1,
237 minor: 1,
238 micro: 0,
239 }))
240 );
241 assert_eq!(
242 Age::of('\u{ffff}'),
243 Some(Age(UnicodeVersion {
244 major: 1,
245 minor: 1,
246 micro: 0,
247 }))
248 );
249
250 assert_eq!(
251 Age::of('\u{10000}'),
252 Some(Age(UnicodeVersion {
253 major: 4,
254 minor: 0,
255 micro: 0,
256 }))
257 );
258 assert_eq!(
259 Age::of('\u{10001}'),
260 Some(Age(UnicodeVersion {
261 major: 4,
262 minor: 0,
263 micro: 0,
264 }))
265 );
266
267 assert_eq!(
268 Age::of('\u{e0100}'),
269 Some(Age(UnicodeVersion {
270 major: 4,
271 minor: 0,
272 micro: 0,
273 }))
274 );
275 assert_eq!(
276 Age::of('\u{e0101}'),
277 Some(Age(UnicodeVersion {
278 major: 4,
279 minor: 0,
280 micro: 0,
281 }))
282 );
283 assert_eq!(
284 Age::of('\u{e0170}'),
285 Some(Age(UnicodeVersion {
286 major: 4,
287 minor: 0,
288 micro: 0,
289 }))
290 );
291 assert_eq!(
292 Age::of('\u{e01ee}'),
293 Some(Age(UnicodeVersion {
294 major: 4,
295 minor: 0,
296 micro: 0,
297 }))
298 );
299 assert_eq!(
300 Age::of('\u{e01ef}'),
301 Some(Age(UnicodeVersion {
302 major: 4,
303 minor: 0,
304 micro: 0,
305 }))
306 );
307
308 assert_eq!(
309 Age::of('\u{10000}'),
310 Some(Age(UnicodeVersion {
311 major: 4,
312 minor: 0,
313 micro: 0,
314 }))
315 );
316
317 assert_eq!(
318 Age::of('\u{20000}'),
319 Some(Age(UnicodeVersion {
320 major: 3,
321 minor: 1,
322 micro: 0,
323 }))
324 );
325
326 assert_eq!(Age::of('\u{30000}'), None);
327 assert_eq!(Age::of('\u{40000}'), None);
328 assert_eq!(Age::of('\u{50000}'), None);
329 assert_eq!(Age::of('\u{60000}'), None);
330 assert_eq!(Age::of('\u{70000}'), None);
331 assert_eq!(Age::of('\u{80000}'), None);
332 assert_eq!(Age::of('\u{90000}'), None);
333 assert_eq!(Age::of('\u{a0000}'), None);
334 assert_eq!(Age::of('\u{b0000}'), None);
335 assert_eq!(Age::of('\u{c0000}'), None);
336 assert_eq!(Age::of('\u{d0000}'), None);
337 assert_eq!(Age::of('\u{e0000}'), None);
338 assert_eq!(Age::of('\u{efffd}'), None);
339
340 assert_eq!(
341 Age::of('\u{efffe}'),
342 Some(Age(UnicodeVersion {
343 major: 2,
344 minor: 0,
345 micro: 0,
346 }))
347 );
348 assert_eq!(
349 Age::of('\u{effff}'),
350 Some(Age(UnicodeVersion {
351 major: 2,
352 minor: 0,
353 micro: 0,
354 }))
355 );
356
357 assert_eq!(
359 Age::of('\u{f0000}'),
360 Some(Age(UnicodeVersion {
361 major: 2,
362 minor: 0,
363 micro: 0,
364 }))
365 );
366 assert_eq!(
367 Age::of('\u{f0001}'),
368 Some(Age(UnicodeVersion {
369 major: 2,
370 minor: 0,
371 micro: 0,
372 }))
373 );
374 assert_eq!(
375 Age::of('\u{ffffe}'),
376 Some(Age(UnicodeVersion {
377 major: 2,
378 minor: 0,
379 micro: 0,
380 }))
381 );
382 assert_eq!(
383 Age::of('\u{fffff}'),
384 Some(Age(UnicodeVersion {
385 major: 2,
386 minor: 0,
387 micro: 0,
388 }))
389 );
390 assert_eq!(
391 Age::of('\u{100000}'),
392 Some(Age(UnicodeVersion {
393 major: 2,
394 minor: 0,
395 micro: 0,
396 }))
397 );
398 assert_eq!(
399 Age::of('\u{100001}'),
400 Some(Age(UnicodeVersion {
401 major: 2,
402 minor: 0,
403 micro: 0,
404 }))
405 );
406 assert_eq!(
407 Age::of('\u{10fffe}'),
408 Some(Age(UnicodeVersion {
409 major: 2,
410 minor: 0,
411 micro: 0,
412 }))
413 );
414 assert_eq!(
415 Age::of('\u{10ffff}'),
416 Some(Age(UnicodeVersion {
417 major: 2,
418 minor: 0,
419 micro: 0,
420 }))
421 );
422 }
423
424 #[test]
425 fn test_cmp() {
426 assert!(Age::of('A') == Age::of('a'));
427 assert!(Age::of('A') > Age::of('Ɐ'));
428 assert!(Age::of('A') > Age::of('\u{10000}'));
429 assert!(Age::of('A') > Age::of('\u{D0000}'));
430
431 assert!(
432 Some(Age(UnicodeVersion {
433 major: 1,
434 minor: 1,
435 micro: 0,
436 })) == Some(Age(UnicodeVersion {
437 major: 1,
438 minor: 1,
439 micro: 0,
440 }))
441 );
442 assert!(
443 Some(Age(UnicodeVersion {
444 major: 1,
445 minor: 1,
446 micro: 0,
447 })) > Some(Age(UnicodeVersion {
448 major: 2,
449 minor: 0,
450 micro: 0,
451 }))
452 );
453 assert!(
454 Some(Age(UnicodeVersion {
455 major: 1,
456 minor: 1,
457 micro: 0,
458 })) > Some(Age(UnicodeVersion {
459 major: 3,
460 minor: 0,
461 micro: 0,
462 }))
463 );
464 assert!(
465 Some(Age(UnicodeVersion {
466 major: 1,
467 minor: 1,
468 micro: 0,
469 })) > Some(Age(UnicodeVersion {
470 major: 10,
471 minor: 0,
472 micro: 0,
473 }))
474 );
475 assert!(
476 Some(Age(UnicodeVersion {
477 major: 1,
478 minor: 1,
479 micro: 0,
480 })) > None
481 );
482
483 assert!(
484 Some(Age(UnicodeVersion {
485 major: 2,
486 minor: 0,
487 micro: 0,
488 })) < Some(Age(UnicodeVersion {
489 major: 1,
490 minor: 1,
491 micro: 0,
492 }))
493 );
494 assert!(
495 Some(Age(UnicodeVersion {
496 major: 2,
497 minor: 0,
498 micro: 0,
499 })) == Some(Age(UnicodeVersion {
500 major: 2,
501 minor: 0,
502 micro: 0,
503 }))
504 );
505 assert!(
506 Some(Age(UnicodeVersion {
507 major: 2,
508 minor: 0,
509 micro: 0,
510 })) > Some(Age(UnicodeVersion {
511 major: 3,
512 minor: 0,
513 micro: 0,
514 }))
515 );
516 assert!(
517 Some(Age(UnicodeVersion {
518 major: 2,
519 minor: 0,
520 micro: 0,
521 })) > Some(Age(UnicodeVersion {
522 major: 10,
523 minor: 0,
524 micro: 0,
525 }))
526 );
527 assert!(
528 Some(Age(UnicodeVersion {
529 major: 2,
530 minor: 0,
531 micro: 0,
532 })) > None
533 );
534
535 assert!(
536 Some(Age(UnicodeVersion {
537 major: 3,
538 minor: 0,
539 micro: 0,
540 })) < Some(Age(UnicodeVersion {
541 major: 1,
542 minor: 1,
543 micro: 0,
544 }))
545 );
546 assert!(
547 Some(Age(UnicodeVersion {
548 major: 3,
549 minor: 0,
550 micro: 0,
551 })) < Some(Age(UnicodeVersion {
552 major: 2,
553 minor: 0,
554 micro: 0,
555 }))
556 );
557 assert!(
558 Some(Age(UnicodeVersion {
559 major: 3,
560 minor: 0,
561 micro: 0,
562 })) == Some(Age(UnicodeVersion {
563 major: 3,
564 minor: 0,
565 micro: 0,
566 }))
567 );
568 assert!(
569 Some(Age(UnicodeVersion {
570 major: 3,
571 minor: 0,
572 micro: 0,
573 })) > Some(Age(UnicodeVersion {
574 major: 10,
575 minor: 0,
576 micro: 0,
577 }))
578 );
579 assert!(
580 Some(Age(UnicodeVersion {
581 major: 3,
582 minor: 0,
583 micro: 0,
584 })) > None
585 );
586
587 assert!(
588 Some(Age(UnicodeVersion {
589 major: 10,
590 minor: 0,
591 micro: 0,
592 })) < Some(Age(UnicodeVersion {
593 major: 1,
594 minor: 1,
595 micro: 0,
596 }))
597 );
598 assert!(
599 Some(Age(UnicodeVersion {
600 major: 10,
601 minor: 0,
602 micro: 0,
603 })) < Some(Age(UnicodeVersion {
604 major: 2,
605 minor: 0,
606 micro: 0,
607 }))
608 );
609 assert!(
610 Some(Age(UnicodeVersion {
611 major: 10,
612 minor: 0,
613 micro: 0,
614 })) < Some(Age(UnicodeVersion {
615 major: 3,
616 minor: 0,
617 micro: 0,
618 }))
619 );
620 assert!(
621 Some(Age(UnicodeVersion {
622 major: 10,
623 minor: 0,
624 micro: 0,
625 })) == Some(Age(UnicodeVersion {
626 major: 10,
627 minor: 0,
628 micro: 0,
629 }))
630 );
631 assert!(
632 Some(Age(UnicodeVersion {
633 major: 10,
634 minor: 0,
635 micro: 0,
636 })) > None
637 );
638
639 assert!(
640 None < Some(Age(UnicodeVersion {
641 major: 1,
642 minor: 1,
643 micro: 0,
644 }))
645 );
646 assert!(
647 None < Some(Age(UnicodeVersion {
648 major: 2,
649 minor: 0,
650 micro: 0,
651 }))
652 );
653 assert!(
654 None < Some(Age(UnicodeVersion {
655 major: 3,
656 minor: 0,
657 micro: 0,
658 }))
659 );
660 assert!(
661 None < Some(Age(UnicodeVersion {
662 major: 10,
663 minor: 0,
664 micro: 0,
665 }))
666 );
667 }
668
669 #[test]
670 fn test_char_trait() {
671 use super::CharAge;
672
673 assert_eq!(
674 '\u{0000}'.age().unwrap().actual(),
675 UnicodeVersion {
676 major: 1,
677 minor: 1,
678 micro: 0,
679 }
680 );
681 assert_eq!(
682 '\u{0041}'.age().unwrap().actual(),
683 UnicodeVersion {
684 major: 1,
685 minor: 1,
686 micro: 0,
687 }
688 );
689 assert_eq!(
690 '\u{10ffff}'.age().unwrap().actual(),
691 UnicodeVersion {
692 major: 2,
693 minor: 0,
694 micro: 0,
695 }
696 );
697 }
698}