|
21 | 21 | //! ## Examples
|
22 | 22 | //!
|
23 | 23 | //! Sample code use is given below.
|
24 |
| -//! |
| 24 | +//! |
25 | 25 | //! ```rust
|
26 | 26 | //! use rust_icu_sys as sys;
|
27 | 27 | //! use rust_icu_ubrk as ubrk;
|
|
41 | 41 | //! assert_eq!(iter.current(), 13);
|
42 | 42 | //! assert_eq!(iter.previous(), Some(12));
|
43 | 43 | //! assert_eq!(iter.current(), 12);
|
44 |
| -//! |
| 44 | +//! |
45 | 45 | //! // Reset to first boundary and consume `iter`.
|
46 | 46 | //! assert_eq!(iter.first(), 0);
|
47 | 47 | //! let breaks: Vec<i32> = iter.collect();
|
|
56 | 56 | use {
|
57 | 57 | rust_icu_common::{self as common, simple_drop_impl},
|
58 | 58 | rust_icu_sys::{self as sys, *},
|
| 59 | + rust_icu_uloc as uloc, |
59 | 60 | rust_icu_ustring as ustring,
|
60 | 61 | std::{convert::TryFrom, ffi, os::raw, ptr, rc::Rc},
|
61 | 62 | };
|
@@ -129,29 +130,14 @@ impl Iterator for UBreakIterator {
|
129 | 130 | }
|
130 | 131 |
|
131 | 132 | impl UBreakIterator {
|
132 |
| - /// Reports the number of locales for which text breaking information is |
133 |
| - /// available. |
| 133 | + /// Returns an iterator over the locales for which text breaking information |
| 134 | + /// is available. |
134 | 135 | ///
|
135 | 136 | /// Implements `ubrk_countAvailable`.
|
136 |
| - pub fn count_available_locales() -> i32 { |
137 |
| - unsafe { versioned_function!(ubrk_countAvailable)() } |
138 |
| - } |
139 |
| - |
140 |
| - /// Returns the locale for which line breaking information is available |
141 |
| - /// at the specified index. |
142 |
| - /// |
143 |
| - /// Implements `ubrk_getAvailable`. |
144 |
| - pub fn get_available_locale_at( |
145 |
| - index: i32, |
146 |
| - ) -> Result<Option<String>, common::Error> { |
147 |
| - let locale_ptr = |
148 |
| - unsafe { versioned_function!(ubrk_getAvailable)(index) }; |
149 |
| - if locale_ptr == 0 as *const raw::c_char { |
150 |
| - Ok(None) |
151 |
| - } else { |
152 |
| - let c_str = unsafe { ffi::CStr::from_ptr(locale_ptr) }; |
153 |
| - let s = c_str.to_str().map(|s| s.to_owned())?; |
154 |
| - Ok(Some(s)) |
| 137 | + pub fn available_locales() -> Locales { |
| 138 | + Locales { |
| 139 | + cur: 0, |
| 140 | + max: unsafe { versioned_function!(ubrk_countAvailable)() }, |
155 | 141 | }
|
156 | 142 | }
|
157 | 143 |
|
@@ -531,6 +517,47 @@ impl UBreakIterator {
|
531 | 517 | }
|
532 | 518 | }
|
533 | 519 |
|
| 520 | +/// Iterator over the locales for which text breaking information is available. |
| 521 | +pub struct Locales { |
| 522 | + // The index that will be |
| 523 | + cur: i32, |
| 524 | + max: i32, |
| 525 | +} |
| 526 | + |
| 527 | +impl Iterator for Locales { |
| 528 | + type Item = uloc::ULoc; |
| 529 | + |
| 530 | + /// Returns the next locale for which text breaking information is available. |
| 531 | + /// |
| 532 | + /// Implements `ubrk_getAvailable`. |
| 533 | + fn next(&mut self) -> Option<Self::Item> { |
| 534 | + if self.cur >= self.max { |
| 535 | + return None; |
| 536 | + } |
| 537 | + let loc_ptr = |
| 538 | + unsafe { versioned_function!(ubrk_getAvailable)(self.cur) }; |
| 539 | + assert_ne!(loc_ptr, 0 as *const raw::c_char); |
| 540 | + let c_str = unsafe { ffi::CStr::from_ptr(loc_ptr) }; |
| 541 | + let loc = uloc::ULoc::try_from(c_str); |
| 542 | + match loc { |
| 543 | + Ok(loc) => { |
| 544 | + self.cur += 1; |
| 545 | + Some(loc) |
| 546 | + } |
| 547 | + _ => None, |
| 548 | + } |
| 549 | + } |
| 550 | +} |
| 551 | + |
| 552 | +impl ExactSizeIterator for Locales { |
| 553 | + /// Reports the number of locales for which text breaking information is available. |
| 554 | + /// |
| 555 | + /// Implements `ubrk_countAvailable`. |
| 556 | + fn len(&self) -> usize { |
| 557 | + self.max as usize |
| 558 | + } |
| 559 | +} |
| 560 | + |
534 | 561 | #[cfg(test)]
|
535 | 562 | mod tests {
|
536 | 563 | use super::UBreakIterator;
|
@@ -723,13 +750,8 @@ $w+ {99}; # Break on `w`s with custom rule status of `99`.
|
723 | 750 | #[test]
|
724 | 751 | fn test_available_locales() {
|
725 | 752 | trace!("Available locales");
|
726 |
| - let count = UBreakIterator::count_available_locales(); |
727 |
| - for i in 0..count { |
728 |
| - let locale = UBreakIterator::get_available_locale_at(i).unwrap(); |
729 |
| - match locale { |
730 |
| - Some(loc) => trace!(" {}", loc), |
731 |
| - None => (), |
732 |
| - } |
| 753 | + for loc in UBreakIterator::available_locales() { |
| 754 | + trace!(" {}", loc); |
733 | 755 | }
|
734 | 756 | }
|
735 | 757 | }
|
0 commit comments