Skip to content

Commit 2d78f8b

Browse files
committed
Expose an iterator over available locales for text boundary analysis
1 parent 3167821 commit 2d78f8b

File tree

2 files changed

+59
-30
lines changed

2 files changed

+59
-30
lines changed

rust_icu_ubrk/Cargo.toml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ log = "0.4.6"
2020
paste = "1.0"
2121
rust_icu_common = { path = "../rust_icu_common", version = "0.3.2", default-features = false }
2222
rust_icu_sys = { path = "../rust_icu_sys", version = "0.3.2", default-features = false }
23+
rust_icu_uloc = { path = "../rust_icu_uloc", version = "0.3.2", default-features = false }
2324
rust_icu_ustring = { path = "../rust_icu_ustring", version = "0.3.2", default-features = false }
2425

2526
[dev-dependencies]
@@ -32,31 +33,37 @@ default = ["use-bindgen", "renaming", "icu_config"]
3233
icu_config = [
3334
"rust_icu_common/icu_config",
3435
"rust_icu_sys/icu_config",
36+
"rust_icu_uloc/icu_config",
3537
"rust_icu_ustring/icu_config",
3638
]
3739
icu_version_64_plus = [
3840
"rust_icu_common/icu_version_64_plus",
3941
"rust_icu_sys/icu_version_64_plus",
42+
"rust_icu_uloc/icu_version_64_plus",
4043
"rust_icu_ustring/icu_version_64_plus",
4144
]
4245
icu_version_67_plus = [
4346
"rust_icu_common/icu_version_67_plus",
4447
"rust_icu_sys/icu_version_67_plus",
48+
"rust_icu_uloc/icu_version_67_plus",
4549
"rust_icu_ustring/icu_version_67_plus",
4650
]
4751
icu_version_in_env = [
4852
"rust_icu_common/icu_version_in_env",
4953
"rust_icu_sys/icu_version_in_env",
54+
"rust_icu_uloc/icu_version_in_env",
5055
"rust_icu_ustring/icu_version_in_env",
5156
]
5257
renaming = [
5358
"rust_icu_common/renaming",
5459
"rust_icu_sys/renaming",
60+
"rust_icu_uloc/renaming",
5561
"rust_icu_ustring/renaming",
5662
]
5763
use-bindgen = [
5864
"rust_icu_common/use-bindgen",
5965
"rust_icu_sys/use-bindgen",
66+
"rust_icu_uloc/use-bindgen",
6067
"rust_icu_ustring/use-bindgen",
6168
]
6269

rust_icu_ubrk/src/lib.rs

Lines changed: 52 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
//! ## Examples
2222
//!
2323
//! Sample code use is given below.
24-
//!
24+
//!
2525
//! ```rust
2626
//! use rust_icu_sys as sys;
2727
//! use rust_icu_ubrk as ubrk;
@@ -41,7 +41,7 @@
4141
//! assert_eq!(iter.current(), 13);
4242
//! assert_eq!(iter.previous(), Some(12));
4343
//! assert_eq!(iter.current(), 12);
44-
//!
44+
//!
4545
//! // Reset to first boundary and consume `iter`.
4646
//! assert_eq!(iter.first(), 0);
4747
//! let breaks: Vec<i32> = iter.collect();
@@ -56,6 +56,7 @@
5656
use {
5757
rust_icu_common::{self as common, simple_drop_impl},
5858
rust_icu_sys::{self as sys, *},
59+
rust_icu_uloc as uloc,
5960
rust_icu_ustring as ustring,
6061
std::{convert::TryFrom, ffi, os::raw, ptr, rc::Rc},
6162
};
@@ -129,29 +130,14 @@ impl Iterator for UBreakIterator {
129130
}
130131

131132
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.
134135
///
135136
/// 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)() },
155141
}
156142
}
157143

@@ -531,6 +517,47 @@ impl UBreakIterator {
531517
}
532518
}
533519

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+
534561
#[cfg(test)]
535562
mod tests {
536563
use super::UBreakIterator;
@@ -723,13 +750,8 @@ $w+ {99}; # Break on `w`s with custom rule status of `99`.
723750
#[test]
724751
fn test_available_locales() {
725752
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);
733755
}
734756
}
735757
}

0 commit comments

Comments
 (0)