From d845fb6507f32820644f24ebaa52af43be276689 Mon Sep 17 00:00:00 2001 From: "Shane F. Carr" Date: Mon, 16 Dec 2024 13:39:38 -0800 Subject: [PATCH 1/9] Add trim_end_if_integer to FixedDecimal (#5903) Fixes https://github.com/unicode-org/icu4x/issues/5902 --- ffi/capi/bindings/c/SignedFixedDecimal.h | 2 + .../cpp/icu4x/SignedFixedDecimal.d.hpp | 2 + .../bindings/cpp/icu4x/SignedFixedDecimal.hpp | 6 ++ .../bindings/dart/SignedFixedDecimal.g.dart | 10 ++++ ffi/capi/bindings/js/SignedFixedDecimal.d.ts | 2 + ffi/capi/bindings/js/SignedFixedDecimal.mjs | 7 +++ ffi/capi/src/fixed_decimal.rs | 10 ++++ utils/fixed_decimal/src/decimal.rs | 60 +++++++++++++++++++ 8 files changed, 99 insertions(+) diff --git a/ffi/capi/bindings/c/SignedFixedDecimal.h b/ffi/capi/bindings/c/SignedFixedDecimal.h index d703e1cc38e..21fb5c8a8f6 100644 --- a/ffi/capi/bindings/c/SignedFixedDecimal.h +++ b/ffi/capi/bindings/c/SignedFixedDecimal.h @@ -67,6 +67,8 @@ void icu4x_SignedFixedDecimal_trim_start_mv1(SignedFixedDecimal* self); void icu4x_SignedFixedDecimal_trim_end_mv1(SignedFixedDecimal* self); +void icu4x_SignedFixedDecimal_trim_end_if_integer_mv1(SignedFixedDecimal* self); + void icu4x_SignedFixedDecimal_pad_start_mv1(SignedFixedDecimal* self, int16_t position); void icu4x_SignedFixedDecimal_pad_end_mv1(SignedFixedDecimal* self, int16_t position); diff --git a/ffi/capi/bindings/cpp/icu4x/SignedFixedDecimal.d.hpp b/ffi/capi/bindings/cpp/icu4x/SignedFixedDecimal.d.hpp index 8b4adb670a0..22f17fd63f0 100644 --- a/ffi/capi/bindings/cpp/icu4x/SignedFixedDecimal.d.hpp +++ b/ffi/capi/bindings/cpp/icu4x/SignedFixedDecimal.d.hpp @@ -73,6 +73,8 @@ class SignedFixedDecimal { inline void trim_end(); + inline void trim_end_if_integer(); + inline void pad_start(int16_t position); inline void pad_end(int16_t position); diff --git a/ffi/capi/bindings/cpp/icu4x/SignedFixedDecimal.hpp b/ffi/capi/bindings/cpp/icu4x/SignedFixedDecimal.hpp index 524b5569bd5..e47ea847d62 100644 --- a/ffi/capi/bindings/cpp/icu4x/SignedFixedDecimal.hpp +++ b/ffi/capi/bindings/cpp/icu4x/SignedFixedDecimal.hpp @@ -69,6 +69,8 @@ namespace capi { void icu4x_SignedFixedDecimal_trim_end_mv1(icu4x::capi::SignedFixedDecimal* self); + void icu4x_SignedFixedDecimal_trim_end_if_integer_mv1(icu4x::capi::SignedFixedDecimal* self); + void icu4x_SignedFixedDecimal_pad_start_mv1(icu4x::capi::SignedFixedDecimal* self, int16_t position); void icu4x_SignedFixedDecimal_pad_end_mv1(icu4x::capi::SignedFixedDecimal* self, int16_t position); @@ -207,6 +209,10 @@ inline void icu4x::SignedFixedDecimal::trim_end() { icu4x::capi::icu4x_SignedFixedDecimal_trim_end_mv1(this->AsFFI()); } +inline void icu4x::SignedFixedDecimal::trim_end_if_integer() { + icu4x::capi::icu4x_SignedFixedDecimal_trim_end_if_integer_mv1(this->AsFFI()); +} + inline void icu4x::SignedFixedDecimal::pad_start(int16_t position) { icu4x::capi::icu4x_SignedFixedDecimal_pad_start_mv1(this->AsFFI(), position); diff --git a/ffi/capi/bindings/dart/SignedFixedDecimal.g.dart b/ffi/capi/bindings/dart/SignedFixedDecimal.g.dart index ef5017554b0..d1054ee04c4 100644 --- a/ffi/capi/bindings/dart/SignedFixedDecimal.g.dart +++ b/ffi/capi/bindings/dart/SignedFixedDecimal.g.dart @@ -161,6 +161,11 @@ final class SignedFixedDecimal implements ffi.Finalizable { _icu4x_SignedFixedDecimal_trim_end_mv1(_ffi); } + /// See the [Rust documentation for `trim_end_if_integer`](https://docs.rs/fixed_decimal/latest/fixed_decimal/struct.UnsignedFixedDecimal.html#method.trim_end_if_integer) for more information. + void trimEndIfInteger() { + _icu4x_SignedFixedDecimal_trim_end_if_integer_mv1(_ffi); + } + /// Zero-pad the [`SignedFixedDecimal`] on the left to a particular position /// /// See the [Rust documentation for `pad_start`](https://docs.rs/fixed_decimal/latest/fixed_decimal/struct.FixedDecimal.html#method.pad_start) for more information. @@ -336,6 +341,11 @@ external void _icu4x_SignedFixedDecimal_trim_start_mv1(ffi.Pointer s // ignore: non_constant_identifier_names external void _icu4x_SignedFixedDecimal_trim_end_mv1(ffi.Pointer self); +@meta.RecordUse() +@ffi.Native)>(isLeaf: true, symbol: 'icu4x_SignedFixedDecimal_trim_end_if_integer_mv1') +// ignore: non_constant_identifier_names +external void _icu4x_SignedFixedDecimal_trim_end_if_integer_mv1(ffi.Pointer self); + @meta.RecordUse() @ffi.Native, ffi.Int16)>(isLeaf: true, symbol: 'icu4x_SignedFixedDecimal_pad_start_mv1') // ignore: non_constant_identifier_names diff --git a/ffi/capi/bindings/js/SignedFixedDecimal.d.ts b/ffi/capi/bindings/js/SignedFixedDecimal.d.ts index 1b48a4e4bb1..c47f50f422d 100644 --- a/ffi/capi/bindings/js/SignedFixedDecimal.d.ts +++ b/ffi/capi/bindings/js/SignedFixedDecimal.d.ts @@ -51,6 +51,8 @@ export class SignedFixedDecimal { trimEnd(): void; + trimEndIfInteger(): void; + padStart(position: number): void; padEnd(position: number): void; diff --git a/ffi/capi/bindings/js/SignedFixedDecimal.mjs b/ffi/capi/bindings/js/SignedFixedDecimal.mjs index 0e5d069e6d9..40f4dc95d2b 100644 --- a/ffi/capi/bindings/js/SignedFixedDecimal.mjs +++ b/ffi/capi/bindings/js/SignedFixedDecimal.mjs @@ -245,6 +245,13 @@ export class SignedFixedDecimal { finally {} } + trimEndIfInteger() {wasm.icu4x_SignedFixedDecimal_trim_end_if_integer_mv1(this.ffiValue); + + try {} + + finally {} + } + padStart(position) {wasm.icu4x_SignedFixedDecimal_pad_start_mv1(this.ffiValue, position); try {} diff --git a/ffi/capi/src/fixed_decimal.rs b/ffi/capi/src/fixed_decimal.rs index 58b3d7bc409..33dcd2c0c1d 100644 --- a/ffi/capi/src/fixed_decimal.rs +++ b/ffi/capi/src/fixed_decimal.rs @@ -278,6 +278,16 @@ pub mod ffi { self.0.absolute.trim_end() } + #[diplomat::rust_link(fixed_decimal::UnsignedFixedDecimal::trim_end_if_integer, FnInStruct)] + #[diplomat::rust_link( + fixed_decimal::UnsignedFixedDecimal::trimmed_end_if_integer, + FnInStruct, + hidden + )] + pub fn trim_end_if_integer(&mut self) { + self.0.absolute.trim_end_if_integer() + } + /// Zero-pad the [`SignedFixedDecimal`] on the left to a particular position #[diplomat::rust_link(fixed_decimal::FixedDecimal::pad_start, FnInStruct)] #[diplomat::rust_link(fixed_decimal::FixedDecimal::padded_start, FnInStruct, hidden)] diff --git a/utils/fixed_decimal/src/decimal.rs b/utils/fixed_decimal/src/decimal.rs index cdb9877c431..baa28f028fc 100644 --- a/utils/fixed_decimal/src/decimal.rs +++ b/utils/fixed_decimal/src/decimal.rs @@ -680,6 +680,66 @@ impl UnsignedFixedDecimal { self.check_invariants(); } + /// Returns this number with its trailing zeros removed, + /// but only if the number is an integer + /// + /// # Examples + /// + /// ``` + /// use fixed_decimal::UnsignedFixedDecimal; + /// + /// let dec = UnsignedFixedDecimal::from(12340000u32) + /// .multiplied_pow10(-2); + /// assert_eq!("123400.00", dec.to_string()); + /// assert_eq!("123400", dec.trimmed_end_if_integer().to_string()); + /// + /// // No effect if there are nonzero fractional digits: + /// let dec = UnsignedFixedDecimal::from(123400u32) + /// .multiplied_pow10(-4) + /// .padded_start(4); + /// assert_eq!("0012.3400", dec.to_string()); + /// assert_eq!("0012.3400", dec.trimmed_end_if_integer().to_string()); + /// ``` + pub fn trimmed_end_if_integer(mut self) -> Self { + self.trim_end_if_integer(); + self + } + + /// Removes the trailing zeros of this number, + /// but only if the number is an integer + /// + /// # Examples + /// + /// ``` + /// use fixed_decimal::UnsignedFixedDecimal; + /// + /// let mut dec = UnsignedFixedDecimal::from(12340000u32) + /// .multiplied_pow10(-2); + /// assert_eq!("123400.00", dec.to_string()); + /// + /// dec.trim_end_if_integer(); + /// assert_eq!("123400", dec.to_string()); + /// + /// // No effect on trailing zeros in the integer: + /// dec.trim_end_if_integer(); + /// assert_eq!("123400", dec.to_string()); + /// + /// // No effect if there are nonzero fractional digits: + /// dec.multiply_pow10(-4); + /// dec.pad_start(4); + /// assert_eq!("0012.3400", dec.to_string()); + /// + /// dec.trim_end_if_integer(); + /// assert_eq!("0012.3400", dec.to_string()); + /// ``` + pub fn trim_end_if_integer(&mut self) { + if self.nonzero_magnitude_end() >= 0 { + self.lower_magnitude = 0; + } + #[cfg(debug_assertions)] + self.check_invariants(); + } + /// Returns this number padded with leading zeros on a particular position. /// /// Negative position numbers have no effect. From 7e5dcecaa88e579fdc6ac4b4115080780b86a710 Mon Sep 17 00:00:00 2001 From: "Shane F. Carr" Date: Mon, 16 Dec 2024 14:41:46 -0800 Subject: [PATCH 2/9] Add numbering_system getter to FixedDecimalFormatter (#5904) Part of #5900 --- components/decimal/src/lib.rs | 44 +++++++++++++++++++ .../src/extensions/unicode/value.rs | 13 ++++++ ffi/capi/bindings/c/FixedDecimalFormatter.h | 2 + .../cpp/icu4x/FixedDecimalFormatter.d.hpp | 2 + .../cpp/icu4x/FixedDecimalFormatter.hpp | 10 +++++ .../dart/FixedDecimalFormatter.g.dart | 12 +++++ .../demo_gen/FixedDecimalFormatter.d.ts | 1 + .../demo_gen/FixedDecimalFormatter.mjs | 19 ++++++++ ffi/capi/bindings/demo_gen/index.mjs | 21 +++++++++ .../bindings/js/FixedDecimalFormatter.d.ts | 2 + .../bindings/js/FixedDecimalFormatter.mjs | 13 ++++++ ffi/capi/src/decimal.rs | 5 +++ 12 files changed, 144 insertions(+) diff --git a/components/decimal/src/lib.rs b/components/decimal/src/lib.rs index 49f706aa8d8..b1cdce69120 100644 --- a/components/decimal/src/lib.rs +++ b/components/decimal/src/lib.rs @@ -104,6 +104,7 @@ pub use format::FormattedFixedDecimal; use alloc::string::String; use fixed_decimal::SignedFixedDecimal; +use icu_locale_core::extensions::unicode::Value; use icu_locale_core::locale; use icu_locale_core::preferences::{ define_preferences, extensions::unicode::keywords::NumberingSystem, @@ -214,4 +215,47 @@ impl FixedDecimalFormatter { pub fn format_to_string(&self, value: &SignedFixedDecimal) -> String { self.format(value).write_to_string().into_owned() } + + /// Gets the resolved numbering system identifier of this formatter. + /// + /// # Examples + /// + /// ``` + /// use icu::decimal::FixedDecimalFormatter; + /// use icu::locale::locale; + /// + /// let fmt_en = FixedDecimalFormatter::try_new( + /// locale!("en").into(), + /// Default::default() + /// ) + /// .unwrap(); + /// + /// let fmt_bn = FixedDecimalFormatter::try_new( + /// locale!("bn").into(), + /// Default::default() + /// ) + /// .unwrap(); + /// + /// let fmt_zh_nu = FixedDecimalFormatter::try_new( + /// locale!("zh-u-nu-hanidec").into(), + /// Default::default() + /// ) + /// .unwrap(); + /// + /// assert_eq!(fmt_en.numbering_system(), "latn"); + /// assert_eq!(fmt_bn.numbering_system(), "beng"); + /// assert_eq!(fmt_zh_nu.numbering_system(), "hanidec"); + /// ``` + pub fn numbering_system(&self) -> Value { + match Value::try_from_str(self.symbols.get().numsys()) { + Ok(v) => v, + Err(e) => { + debug_assert!( + false, + "Problem converting numbering system ID to Value: {e}" + ); + Value::new_empty() + } + } + } } diff --git a/components/locale_core/src/extensions/unicode/value.rs b/components/locale_core/src/extensions/unicode/value.rs index 02c2e9df21b..818659909a3 100644 --- a/components/locale_core/src/extensions/unicode/value.rs +++ b/components/locale_core/src/extensions/unicode/value.rs @@ -142,6 +142,19 @@ impl Value { self.0.len() } + /// Creates an empty [`Value`], which corresponds to a "true" value. + /// + /// # Examples + /// + /// ``` + /// use icu::locale::extensions::unicode::{value, Value}; + /// + /// assert_eq!(value!("true"), Value::new_empty()); + /// ``` + pub const fn new_empty() -> Self { + Self(ShortBoxSlice::new()) + } + /// Returns `true` if the Value has no subtags. /// /// # Examples diff --git a/ffi/capi/bindings/c/FixedDecimalFormatter.h b/ffi/capi/bindings/c/FixedDecimalFormatter.h index c7e4468b73d..644a66bdff5 100644 --- a/ffi/capi/bindings/c/FixedDecimalFormatter.h +++ b/ffi/capi/bindings/c/FixedDecimalFormatter.h @@ -31,6 +31,8 @@ icu4x_FixedDecimalFormatter_create_with_manual_data_mv1_result icu4x_FixedDecima void icu4x_FixedDecimalFormatter_format_mv1(const FixedDecimalFormatter* self, const SignedFixedDecimal* value, DiplomatWrite* write); +void icu4x_FixedDecimalFormatter_numbering_system_mv1(const FixedDecimalFormatter* self, DiplomatWrite* write); + void icu4x_FixedDecimalFormatter_destroy_mv1(FixedDecimalFormatter* self); diff --git a/ffi/capi/bindings/cpp/icu4x/FixedDecimalFormatter.d.hpp b/ffi/capi/bindings/cpp/icu4x/FixedDecimalFormatter.d.hpp index c9661b3b11d..1db040fed4b 100644 --- a/ffi/capi/bindings/cpp/icu4x/FixedDecimalFormatter.d.hpp +++ b/ffi/capi/bindings/cpp/icu4x/FixedDecimalFormatter.d.hpp @@ -41,6 +41,8 @@ class FixedDecimalFormatter { inline std::string format(const icu4x::SignedFixedDecimal& value) const; + inline std::string numbering_system() const; + inline const icu4x::capi::FixedDecimalFormatter* AsFFI() const; inline icu4x::capi::FixedDecimalFormatter* AsFFI(); inline static const icu4x::FixedDecimalFormatter* FromFFI(const icu4x::capi::FixedDecimalFormatter* ptr); diff --git a/ffi/capi/bindings/cpp/icu4x/FixedDecimalFormatter.hpp b/ffi/capi/bindings/cpp/icu4x/FixedDecimalFormatter.hpp index cfd8b63b972..64d7c7c7a35 100644 --- a/ffi/capi/bindings/cpp/icu4x/FixedDecimalFormatter.hpp +++ b/ffi/capi/bindings/cpp/icu4x/FixedDecimalFormatter.hpp @@ -32,6 +32,8 @@ namespace capi { void icu4x_FixedDecimalFormatter_format_mv1(const icu4x::capi::FixedDecimalFormatter* self, const icu4x::capi::SignedFixedDecimal* value, diplomat::capi::DiplomatWrite* write); + void icu4x_FixedDecimalFormatter_numbering_system_mv1(const icu4x::capi::FixedDecimalFormatter* self, diplomat::capi::DiplomatWrite* write); + void icu4x_FixedDecimalFormatter_destroy_mv1(FixedDecimalFormatter* self); @@ -76,6 +78,14 @@ inline std::string icu4x::FixedDecimalFormatter::format(const icu4x::SignedFixed return output; } +inline std::string icu4x::FixedDecimalFormatter::numbering_system() const { + std::string output; + diplomat::capi::DiplomatWrite write = diplomat::WriteFromString(output); + icu4x::capi::icu4x_FixedDecimalFormatter_numbering_system_mv1(this->AsFFI(), + &write); + return output; +} + inline const icu4x::capi::FixedDecimalFormatter* icu4x::FixedDecimalFormatter::AsFFI() const { return reinterpret_cast(this); } diff --git a/ffi/capi/bindings/dart/FixedDecimalFormatter.g.dart b/ffi/capi/bindings/dart/FixedDecimalFormatter.g.dart index 6ef3a34bfa4..c97fc5299da 100644 --- a/ffi/capi/bindings/dart/FixedDecimalFormatter.g.dart +++ b/ffi/capi/bindings/dart/FixedDecimalFormatter.g.dart @@ -72,6 +72,13 @@ final class FixedDecimalFormatter implements ffi.Finalizable { _icu4x_FixedDecimalFormatter_format_mv1(_ffi, value._ffi, write._ffi); return write.finalize(); } + + /// See the [Rust documentation for `numbering_system`](https://docs.rs/icu/latest/icu/decimal/struct.FixedDecimalFormatter.html#method.numbering_system) for more information. + String numberingSystem() { + final write = _Write(); + _icu4x_FixedDecimalFormatter_numbering_system_mv1(_ffi, write._ffi); + return write.finalize(); + } } @meta.RecordUse() @@ -98,3 +105,8 @@ external _ResultOpaqueInt32 _icu4x_FixedDecimalFormatter_create_with_manual_data @ffi.Native, ffi.Pointer, ffi.Pointer)>(isLeaf: true, symbol: 'icu4x_FixedDecimalFormatter_format_mv1') // ignore: non_constant_identifier_names external void _icu4x_FixedDecimalFormatter_format_mv1(ffi.Pointer self, ffi.Pointer value, ffi.Pointer write); + +@meta.RecordUse() +@ffi.Native, ffi.Pointer)>(isLeaf: true, symbol: 'icu4x_FixedDecimalFormatter_numbering_system_mv1') +// ignore: non_constant_identifier_names +external void _icu4x_FixedDecimalFormatter_numbering_system_mv1(ffi.Pointer self, ffi.Pointer write); diff --git a/ffi/capi/bindings/demo_gen/FixedDecimalFormatter.d.ts b/ffi/capi/bindings/demo_gen/FixedDecimalFormatter.d.ts index 0742354294a..867900b6360 100644 --- a/ffi/capi/bindings/demo_gen/FixedDecimalFormatter.d.ts +++ b/ffi/capi/bindings/demo_gen/FixedDecimalFormatter.d.ts @@ -2,3 +2,4 @@ import { FixedDecimalFormatter } from "icu4x" import { Locale } from "icu4x" import { SignedFixedDecimal } from "icu4x" export function format(name: string, groupingStrategy: FixedDecimalGroupingStrategy, f: number, magnitude: number); +export function numberingSystem(name: string, groupingStrategy: FixedDecimalGroupingStrategy); diff --git a/ffi/capi/bindings/demo_gen/FixedDecimalFormatter.mjs b/ffi/capi/bindings/demo_gen/FixedDecimalFormatter.mjs index fd0f6062631..74ce26c81f1 100644 --- a/ffi/capi/bindings/demo_gen/FixedDecimalFormatter.mjs +++ b/ffi/capi/bindings/demo_gen/FixedDecimalFormatter.mjs @@ -27,3 +27,22 @@ export function format(name, groupingStrategy, f, magnitude) { ] ); } +export function numberingSystem(name, groupingStrategy) { + return (function (...args) { return args[0].numberingSystem(...args.slice(1)) }).apply( + null, + [ + FixedDecimalFormatter.createWithGroupingStrategy.apply( + null, + [ + Locale.fromString.apply( + null, + [ + name + ] + ), + groupingStrategy + ] + ) + ] + ); +} diff --git a/ffi/capi/bindings/demo_gen/index.mjs b/ffi/capi/bindings/demo_gen/index.mjs index 29ea392dd0a..e3053f423ac 100644 --- a/ffi/capi/bindings/demo_gen/index.mjs +++ b/ffi/capi/bindings/demo_gen/index.mjs @@ -1087,6 +1087,27 @@ let termini = Object.assign({ ] }, + "FixedDecimalFormatter.numberingSystem": { + func: FixedDecimalFormatterDemo.numberingSystem, + // For avoiding webpacking minifying issues: + funcName: "FixedDecimalFormatter.numberingSystem", + parameters: [ + + { + name: "Self:Locale:Name", + type: "string", + typeUse: "string" + }, + + { + name: "Self:GroupingStrategy", + type: "FixedDecimalGroupingStrategy", + typeUse: "enumerator" + } + + ] + }, + "SignedFixedDecimal.toString": { func: SignedFixedDecimalDemo.toString, // For avoiding webpacking minifying issues: diff --git a/ffi/capi/bindings/js/FixedDecimalFormatter.d.ts b/ffi/capi/bindings/js/FixedDecimalFormatter.d.ts index 396e47dead8..12d54cd908c 100644 --- a/ffi/capi/bindings/js/FixedDecimalFormatter.d.ts +++ b/ffi/capi/bindings/js/FixedDecimalFormatter.d.ts @@ -23,4 +23,6 @@ export class FixedDecimalFormatter { static createWithManualData(plusSignPrefix: string, plusSignSuffix: string, minusSignPrefix: string, minusSignSuffix: string, decimalSeparator: string, groupingSeparator: string, primaryGroupSize: number, secondaryGroupSize: number, minGroupSize: number, digits: Array, groupingStrategy: FixedDecimalGroupingStrategy | null): FixedDecimalFormatter; format(value: SignedFixedDecimal): string; + + numberingSystem(): string; } \ No newline at end of file diff --git a/ffi/capi/bindings/js/FixedDecimalFormatter.mjs b/ffi/capi/bindings/js/FixedDecimalFormatter.mjs index 20547087ee0..e83d1edd461 100644 --- a/ffi/capi/bindings/js/FixedDecimalFormatter.mjs +++ b/ffi/capi/bindings/js/FixedDecimalFormatter.mjs @@ -127,4 +127,17 @@ export class FixedDecimalFormatter { write.free(); } } + + numberingSystem() { + const write = new diplomatRuntime.DiplomatWriteBuf(wasm); + wasm.icu4x_FixedDecimalFormatter_numbering_system_mv1(this.ffiValue, write.buffer); + + try { + return write.readString8(); + } + + finally { + write.free(); + } + } } \ No newline at end of file diff --git a/ffi/capi/src/decimal.rs b/ffi/capi/src/decimal.rs index 79f0610f565..c4ae961d4ee 100644 --- a/ffi/capi/src/decimal.rs +++ b/ffi/capi/src/decimal.rs @@ -176,5 +176,10 @@ pub mod ffi { ) { let _infallible = self.0.format(&value.0).write_to(write); } + + #[diplomat::rust_link(icu::decimal::FixedDecimalFormatter::numbering_system, FnInStruct)] + pub fn numbering_system(&self, write: &mut diplomat_runtime::DiplomatWrite) { + let _infallible = self.0.numbering_system().write_to(write); + } } } From a2a006029220684340cf2adf6c764bb7f8b19b37 Mon Sep 17 00:00:00 2001 From: "Shane F. Carr" Date: Mon, 16 Dec 2024 19:05:35 -0800 Subject: [PATCH 3/9] Change icu_pattern PlaceholderValueProvider and parts behavior (#5908) See discussion in #5897 --- components/pattern/src/common.rs | 141 +++++++++++++++++++------ components/pattern/src/double.rs | 47 +++++---- components/pattern/src/frontend/mod.rs | 42 +++----- components/pattern/src/lib.rs | 2 - components/pattern/src/multi_named.rs | 50 +++++---- components/pattern/src/single.rs | 46 ++++---- ffi/capi/tests/missing_apis.txt | 6 +- 7 files changed, 213 insertions(+), 121 deletions(-) diff --git a/components/pattern/src/common.rs b/components/pattern/src/common.rs index a2e328e4baa..951cea986ff 100644 --- a/components/pattern/src/common.rs +++ b/components/pattern/src/common.rs @@ -3,7 +3,7 @@ // (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ). use crate::Error; -use writeable::{Part, TryWriteable}; +use writeable::{TryWriteable, Writeable}; #[cfg(feature = "alloc")] use alloc::{borrow::Cow, boxed::Box}; @@ -110,30 +110,97 @@ pub trait PatternBackend: crate::private::Sealed + 'static + core::fmt::Debug { fn empty() -> &'static Self::Store; } -/// Default annotation for the literal portion of a pattern. +/// Trait implemented on collections that can produce [`TryWriteable`]s for interpolation. /// -/// For more information, see [`PlaceholderValueProvider`]. For an example, see [`Pattern`]. +/// This trait can add [`Part`]s for individual literals or placeholders. The implementations +/// of this trait on standard types do not add any [`Part`]s. /// -/// [`Pattern`]: crate::Pattern -pub const PATTERN_LITERAL_PART: Part = Part { - category: "pattern", - value: "literal", -}; - -/// Default annotation for the placeholder portion of a pattern. +/// # Examples /// -/// For more information, see [`PlaceholderValueProvider`]. For an example, see [`Pattern`]. +/// A custom implementation that adds parts: /// -/// [`Pattern`]: crate::Pattern -pub const PATTERN_PLACEHOLDER_PART: Part = Part { - category: "pattern", - value: "placeholder", -}; - -/// Trait implemented on collections that can produce [`TryWriteable`]s for interpolation. +/// ``` +/// use core::str::FromStr; +/// use icu_pattern::Pattern; +/// use icu_pattern::DoublePlaceholder; +/// use icu_pattern::DoublePlaceholderKey; +/// use icu_pattern::PlaceholderValueProvider; +/// use writeable::adapters::WithPart; +/// use writeable::adapters::WriteableAsTryWriteableInfallible; +/// use writeable::assert_writeable_parts_eq; +/// use writeable::Part; +/// use writeable::Writeable; +/// +/// let pattern = Pattern::::try_from_str( +/// "Hello, {0} and {1}!", +/// Default::default(), +/// ) +/// .unwrap(); +/// +/// struct ValuesWithParts<'a>(&'a str, &'a str); +/// +/// const PART_PLACEHOLDER_0: Part = Part { +/// category: "custom", +/// value: "placeholder0", +/// }; +/// const PART_PLACEHOLDER_1: Part = Part { +/// category: "custom", +/// value: "placeholder1", +/// }; +/// const PART_LITERAL: Part = Part { +/// category: "custom", +/// value: "literal", +/// }; +/// +/// impl PlaceholderValueProvider for ValuesWithParts<'_> { +/// type Error = core::convert::Infallible; +/// +/// type W<'a> = WriteableAsTryWriteableInfallible> +/// where +/// Self: 'a; +/// +/// type L<'a, 'l> = WithPart<&'l str> +/// where +/// Self: 'a; +/// +/// #[inline] +/// fn value_for(&self, key: DoublePlaceholderKey) -> Self::W<'_> { +/// let writeable = match key { +/// DoublePlaceholderKey::Place0 => WithPart { +/// writeable: self.0, +/// part: PART_PLACEHOLDER_0, +/// }, +/// DoublePlaceholderKey::Place1 => WithPart { +/// writeable: self.1, +/// part: PART_PLACEHOLDER_1, +/// }, +/// }; +/// WriteableAsTryWriteableInfallible(writeable) +/// } +/// +/// #[inline] +/// fn map_literal<'a, 'l>(&'a self, literal: &'l str) -> Self::L<'a, 'l> { +/// WithPart { +/// writeable: literal, +/// part: PART_LITERAL, +/// } +/// } +/// } /// -/// This trait determines the [`Part`]s produced by the writeable. In this crate, implementations -/// of this trait default to using [`PATTERN_LITERAL_PART`] and [`PATTERN_PLACEHOLDER_PART`]. +/// assert_writeable_parts_eq!( +/// pattern.interpolate(ValuesWithParts("Alice", "Bob")), +/// "Hello, Alice and Bob!", +/// [ +/// (0, 7, PART_LITERAL), +/// (7, 12, PART_PLACEHOLDER_0), +/// (12, 17, PART_LITERAL), +/// (17, 20, PART_PLACEHOLDER_1), +/// (20, 21, PART_LITERAL), +/// ] +/// ); +/// ``` +/// +/// [`Part`]: writeable::Part pub trait PlaceholderValueProvider { type Error; @@ -141,11 +208,19 @@ pub trait PlaceholderValueProvider { where Self: 'a; - const LITERAL_PART: Part; + type L<'a, 'l>: Writeable + where + Self: 'a; - /// Returns the [`TryWriteable`] to substitute for the given placeholder - /// and the [`Part`] representing it. - fn value_for(&self, key: K) -> (Self::W<'_>, Part); + /// Returns the [`TryWriteable`] to substitute for the given placeholder. + /// + /// See [`PatternItem::Placeholder`] + fn value_for(&self, key: K) -> Self::W<'_>; + + /// Maps a literal string to a [`Writeable`] that could contain parts. + /// + /// See [`PatternItem::Literal`] + fn map_literal<'a, 'l>(&'a self, literal: &'l str) -> Self::L<'a, 'l>; } impl<'b, K, T> PlaceholderValueProvider for &'b T @@ -153,13 +228,19 @@ where T: PlaceholderValueProvider + ?Sized, { type Error = T::Error; - type W<'a> - = T::W<'a> + + type W<'a> = T::W<'a> where - T: 'a, - 'b: 'a; - const LITERAL_PART: Part = T::LITERAL_PART; - fn value_for(&self, key: K) -> (Self::W<'_>, Part) { + Self: 'a; + + type L<'a, 'l> = T::L<'a, 'l> + where + Self: 'a; + + fn value_for(&self, key: K) -> Self::W<'_> { (*self).value_for(key) } + fn map_literal<'a, 'l>(&'a self, literal: &'l str) -> Self::L<'a, 'l> { + (*self).map_literal(literal) + } } diff --git a/components/pattern/src/double.rs b/components/pattern/src/double.rs index e5129e490fc..d8314974f47 100644 --- a/components/pattern/src/double.rs +++ b/components/pattern/src/double.rs @@ -75,22 +75,26 @@ where W1: Writeable, { type Error = Infallible; - type W<'a> - = WriteableAsTryWriteableInfallible> + + type W<'a> = WriteableAsTryWriteableInfallible> + where + Self: 'a; + + type L<'a, 'l> = &'l str where - W0: 'a, - W1: 'a; - const LITERAL_PART: writeable::Part = crate::PATTERN_LITERAL_PART; + Self: 'a; + #[inline] - fn value_for(&self, key: DoublePlaceholderKey) -> (Self::W<'_>, writeable::Part) { + fn value_for(&self, key: DoublePlaceholderKey) -> Self::W<'_> { let writeable = match key { DoublePlaceholderKey::Place0 => Either::Left(&self.0), DoublePlaceholderKey::Place1 => Either::Right(&self.1), }; - ( - WriteableAsTryWriteableInfallible(writeable), - crate::PATTERN_PLACEHOLDER_PART, - ) + WriteableAsTryWriteableInfallible(writeable) + } + #[inline] + fn map_literal<'a, 'l>(&'a self, literal: &'l str) -> Self::L<'a, 'l> { + literal } } @@ -99,22 +103,27 @@ where W: Writeable, { type Error = Infallible; - type W<'a> - = WriteableAsTryWriteableInfallible<&'a W> + + type W<'a> = WriteableAsTryWriteableInfallible<&'a W> + where + Self: 'a; + + type L<'a, 'l> = &'l str where - W: 'a; - const LITERAL_PART: writeable::Part = crate::PATTERN_LITERAL_PART; + Self: 'a; + #[inline] - fn value_for(&self, key: DoublePlaceholderKey) -> (Self::W<'_>, writeable::Part) { + fn value_for(&self, key: DoublePlaceholderKey) -> Self::W<'_> { let [item0, item1] = self; let writeable = match key { DoublePlaceholderKey::Place0 => item0, DoublePlaceholderKey::Place1 => item1, }; - ( - WriteableAsTryWriteableInfallible(writeable), - crate::PATTERN_PLACEHOLDER_PART, - ) + WriteableAsTryWriteableInfallible(writeable) + } + #[inline] + fn map_literal<'a, 'l>(&'a self, literal: &'l str) -> Self::L<'a, 'l> { + literal } } diff --git a/components/pattern/src/frontend/mod.rs b/components/pattern/src/frontend/mod.rs index 39a22c6a31f..a8cf38dad85 100644 --- a/components/pattern/src/frontend/mod.rs +++ b/components/pattern/src/frontend/mod.rs @@ -15,11 +15,7 @@ use crate::Parser; use crate::ParserOptions; #[cfg(feature = "alloc")] use alloc::{borrow::ToOwned, boxed::Box, str::FromStr, string::String}; -use core::{ - convert::Infallible, - fmt::{self, Write}, - marker::PhantomData, -}; +use core::{convert::Infallible, fmt, marker::PhantomData}; use writeable::{adapters::TryWriteableInfallibleAsWriteable, PartsWrite, TryWriteable, Writeable}; /// A string pattern with placeholders. @@ -38,21 +34,18 @@ use writeable::{adapters::TryWriteableInfallibleAsWriteable, PartsWrite, TryWrit /// /// # Format to Parts /// -/// [`Pattern`] supports interpolating with [writeable::Part]s, annotations for whether the -/// substring was a placeholder or a literal. -/// -/// By default, the substrings are annotated with [`PATTERN_LITERAL_PART`] and -/// [`PATTERN_PLACEHOLDER_PART`]. This can be customized with [`PlaceholderValueProvider`]. +/// [`Pattern`] propagates [`Part`]s from inner writeables. In addition, it supports annotating +/// [`Part`]s for individual literals or placeholders via the [`PlaceholderValueProvider`] trait. /// /// # Examples /// -/// Interpolating a [`SinglePlaceholder`] pattern with parts: +/// Interpolating a [`SinglePlaceholder`] pattern: /// /// ``` /// use core::str::FromStr; /// use icu_pattern::Pattern; /// use icu_pattern::SinglePlaceholder; -/// use writeable::assert_writeable_parts_eq; +/// use writeable::assert_writeable_eq; /// /// let pattern = Pattern::::try_from_str( /// "Hello, {0}!", @@ -60,20 +53,16 @@ use writeable::{adapters::TryWriteableInfallibleAsWriteable, PartsWrite, TryWrit /// ) /// .unwrap(); /// -/// assert_writeable_parts_eq!( +/// assert_writeable_eq!( /// pattern.interpolate(["Alice"]), -/// "Hello, Alice!", -/// [ -/// (0, 7, icu_pattern::PATTERN_LITERAL_PART), -/// (7, 12, icu_pattern::PATTERN_PLACEHOLDER_PART), -/// (12, 13, icu_pattern::PATTERN_LITERAL_PART), -/// ] +/// "Hello, Alice!" /// ); /// ``` /// /// [`SinglePlaceholder`]: crate::SinglePlaceholder /// [`DoublePlaceholder`]: crate::DoublePlaceholder /// [`MultiNamedPlaceholder`]: crate::MultiNamedPlaceholder +/// [`Part`]: writeable::Part #[cfg_attr(feature = "yoke", derive(yoke::Yokeable))] #[repr(transparent)] pub struct Pattern { @@ -344,17 +333,14 @@ where for item in it { match item { PatternItem::Literal(s) => { - sink.with_part(P::LITERAL_PART, |sink| sink.write_str(s))?; + self.value_provider.map_literal(s).write_to_parts(sink)?; } PatternItem::Placeholder(key) => { - let (element_writeable, part) = self.value_provider.value_for(key); - sink.with_part(part, |sink| { - if let Err(e) = element_writeable.try_write_to_parts(sink)? { - // Keep the first error if there was one - error.get_or_insert(e); - } - Ok(()) - })?; + let element_writeable = self.value_provider.value_for(key); + if let Err(e) = element_writeable.try_write_to_parts(sink)? { + // Keep the first error if there was one + error.get_or_insert(e); + } } } #[cfg(debug_assertions)] diff --git a/components/pattern/src/lib.rs b/components/pattern/src/lib.rs index 78b9cad560b..192427adbb1 100644 --- a/components/pattern/src/lib.rs +++ b/components/pattern/src/lib.rs @@ -66,8 +66,6 @@ pub use common::PatternItem; #[cfg(feature = "alloc")] pub use common::PatternItemCow; pub use common::PlaceholderValueProvider; -pub use common::PATTERN_LITERAL_PART; -pub use common::PATTERN_PLACEHOLDER_PART; pub use double::DoublePlaceholder; pub use double::DoublePlaceholderKey; pub use error::PatternError; diff --git a/components/pattern/src/multi_named.rs b/components/pattern/src/multi_named.rs index ace5e3b2474..62a5faa1ae3 100644 --- a/components/pattern/src/multi_named.rs +++ b/components/pattern/src/multi_named.rs @@ -94,22 +94,25 @@ where W: Writeable, { type Error = MissingNamedPlaceholderError<'k>; - type W<'a> - = Result<&'a W, Self::Error> + + type W<'a> = Result<&'a W, Self::Error> + where + Self: 'a; + + type L<'a, 'l> = &'l str where - W: 'a, Self: 'a; - const LITERAL_PART: writeable::Part = crate::PATTERN_LITERAL_PART; + #[inline] - fn value_for<'a>( - &'a self, - key: MultiNamedPlaceholderKey<'k>, - ) -> (Self::W<'a>, writeable::Part) { - let writeable = match self.get(key.0) { + fn value_for<'a>(&'a self, key: MultiNamedPlaceholderKey<'k>) -> Self::W<'a> { + match self.get(key.0) { Some(value) => Ok(value), None => Err(MissingNamedPlaceholderError { name: key.0 }), - }; - (writeable, crate::PATTERN_PLACEHOLDER_PART) + } + } + #[inline] + fn map_literal<'a, 'l>(&'a self, literal: &'l str) -> Self::L<'a, 'l> { + literal } } @@ -121,22 +124,25 @@ where S: litemap::store::Store, { type Error = MissingNamedPlaceholderError<'k>; - type W<'a> - = Result<&'a W, Self::Error> + + type W<'a> = Result<&'a W, Self::Error> + where + Self: 'a; + + type L<'a, 'l> = &'l str where - W: 'a, Self: 'a; - const LITERAL_PART: writeable::Part = crate::PATTERN_LITERAL_PART; + #[inline] - fn value_for<'a>( - &'a self, - key: MultiNamedPlaceholderKey<'k>, - ) -> (Self::W<'a>, writeable::Part) { - let writeable = match self.get(key.0) { + fn value_for<'a>(&'a self, key: MultiNamedPlaceholderKey<'k>) -> Self::W<'a> { + match self.get(key.0) { Some(value) => Ok(value), None => Err(MissingNamedPlaceholderError { name: key.0 }), - }; - (writeable, crate::PATTERN_PLACEHOLDER_PART) + } + } + #[inline] + fn map_literal<'a, 'l>(&'a self, literal: &'l str) -> Self::L<'a, 'l> { + literal } } diff --git a/components/pattern/src/single.rs b/components/pattern/src/single.rs index 9f74913b317..70464f00fdd 100644 --- a/components/pattern/src/single.rs +++ b/components/pattern/src/single.rs @@ -65,16 +65,21 @@ where W: Writeable, { type Error = Infallible; - type W<'a> - = WriteableAsTryWriteableInfallible<&'a W> + + type W<'a> = WriteableAsTryWriteableInfallible<&'a W> + where + Self: 'a; + + type L<'a, 'l> = &'l str where - W: 'a; - const LITERAL_PART: writeable::Part = crate::PATTERN_LITERAL_PART; - fn value_for(&self, _key: SinglePlaceholderKey) -> (Self::W<'_>, writeable::Part) { - ( - WriteableAsTryWriteableInfallible(&self.0), - crate::PATTERN_PLACEHOLDER_PART, - ) + Self: 'a; + + fn value_for(&self, _key: SinglePlaceholderKey) -> Self::W<'_> { + WriteableAsTryWriteableInfallible(&self.0) + } + #[inline] + fn map_literal<'a, 'l>(&'a self, literal: &'l str) -> Self::L<'a, 'l> { + literal } } @@ -83,17 +88,22 @@ where W: Writeable, { type Error = Infallible; - type W<'a> - = WriteableAsTryWriteableInfallible<&'a W> + + type W<'a> = WriteableAsTryWriteableInfallible<&'a W> + where + Self: 'a; + + type L<'a, 'l> = &'l str where - W: 'a; - const LITERAL_PART: writeable::Part = crate::PATTERN_LITERAL_PART; - fn value_for(&self, _key: SinglePlaceholderKey) -> (Self::W<'_>, writeable::Part) { + Self: 'a; + + fn value_for(&self, _key: SinglePlaceholderKey) -> Self::W<'_> { let [value] = self; - ( - WriteableAsTryWriteableInfallible(value), - crate::PATTERN_PLACEHOLDER_PART, - ) + WriteableAsTryWriteableInfallible(value) + } + #[inline] + fn map_literal<'a, 'l>(&'a self, literal: &'l str) -> Self::L<'a, 'l> { + literal } } diff --git a/ffi/capi/tests/missing_apis.txt b/ffi/capi/tests/missing_apis.txt index 8e82c849e7c..8dcc9a06093 100644 --- a/ffi/capi/tests/missing_apis.txt +++ b/ffi/capi/tests/missing_apis.txt @@ -487,6 +487,7 @@ icu::normalizer::uts46::Uts46MapperBorrowed::normalize_validate#FnInStruct icu::pattern::DoublePlaceholder#Enum icu::pattern::DoublePlaceholderKey#Enum icu::pattern::DoublePlaceholderKey::from_str#FnInEnum +icu::pattern::DoublePlaceholderKey::map_literal#FnInEnum icu::pattern::DoublePlaceholderKey::value_for#FnInEnum icu::pattern::DoublePlaceholderPattern#Typedef icu::pattern::Error#Enum @@ -494,10 +495,9 @@ icu::pattern::MissingNamedPlaceholderError#Struct icu::pattern::MissingNamedPlaceholderError::write_to#FnInStruct icu::pattern::MultiNamedPlaceholder#Enum icu::pattern::MultiNamedPlaceholderKey#Struct +icu::pattern::MultiNamedPlaceholderKey::map_literal#FnInStruct icu::pattern::MultiNamedPlaceholderKey::value_for#FnInStruct icu::pattern::MultiNamedPlaceholderPattern#Typedef -icu::pattern::PATTERN_LITERAL_PART#Constant -icu::pattern::PATTERN_PLACEHOLDER_PART#Constant icu::pattern::ParsedPatternItem#Enum icu::pattern::Parser#Struct icu::pattern::Parser::new#FnInStruct @@ -518,11 +518,13 @@ icu::pattern::PatternError#Enum icu::pattern::PatternItem#Enum icu::pattern::PatternItemCow#Enum icu::pattern::PatternString#Struct +icu::pattern::PlaceholderValueProvider::map_literal#FnInTrait icu::pattern::PlaceholderValueProvider::value_for#FnInTrait icu::pattern::QuoteMode#Enum icu::pattern::SinglePlaceholder#Enum icu::pattern::SinglePlaceholderKey#Enum icu::pattern::SinglePlaceholderKey::from_str#FnInEnum +icu::pattern::SinglePlaceholderKey::map_literal#FnInEnum icu::pattern::SinglePlaceholderKey::value_for#FnInEnum icu::pattern::SinglePlaceholderPattern#Typedef icu::plurals::PluralElements#Struct From 756afb600a625784dc5600fe8b7108593c24ecb1 Mon Sep 17 00:00:00 2001 From: "Shane F. Carr" Date: Mon, 16 Dec 2024 19:29:16 -0800 Subject: [PATCH 4/9] DateTimeFormatter AnyCalendarKind getter (#5907) Another part of #5900 --- components/datetime/src/neo.rs | 32 ++++++++++++++++++- ffi/capi/bindings/c/DateFormatter.h | 3 ++ ffi/capi/bindings/c/DateTimeFormatter.h | 3 ++ .../bindings/cpp/icu4x/DateFormatter.d.hpp | 3 ++ ffi/capi/bindings/cpp/icu4x/DateFormatter.hpp | 8 +++++ .../cpp/icu4x/DateTimeFormatter.d.hpp | 3 ++ .../bindings/cpp/icu4x/DateTimeFormatter.hpp | 8 +++++ ffi/capi/bindings/dart/DateFormatter.g.dart | 13 ++++++++ .../bindings/dart/DateTimeFormatter.g.dart | 13 ++++++++ ffi/capi/bindings/js/DateFormatter.d.ts | 3 ++ ffi/capi/bindings/js/DateFormatter.mjs | 11 +++++++ ffi/capi/bindings/js/DateTimeFormatter.d.ts | 3 ++ ffi/capi/bindings/js/DateTimeFormatter.mjs | 11 +++++++ ffi/capi/src/datetime_formatter.rs | 13 ++++++++ 14 files changed, 126 insertions(+), 1 deletion(-) diff --git a/components/datetime/src/neo.rs b/components/datetime/src/neo.rs index 988877f82a0..9a1c1599658 100644 --- a/components/datetime/src/neo.rs +++ b/components/datetime/src/neo.rs @@ -21,7 +21,7 @@ use crate::MismatchedCalendarError; use core::fmt; use core::marker::PhantomData; use icu_calendar::any_calendar::IntoAnyCalendar; -use icu_calendar::{AnyCalendar, AnyCalendarPreferences}; +use icu_calendar::{AnyCalendar, AnyCalendarKind, AnyCalendarPreferences}; use icu_decimal::FixedDecimalFormatterPreferences; use icu_locale_core::preferences::extensions::unicode::keywords::{ CalendarAlgorithm, HourCycle, NumberingSystem, @@ -765,6 +765,36 @@ impl DateTimeFormatter { _calendar: PhantomData, }) } + + /// Returns the calendar system used in this formatter. + /// + /// # Examples + /// + /// ``` + /// use icu::calendar::AnyCalendarKind; + /// use icu::calendar::Date; + /// use icu::datetime::fieldsets::YMD; + /// use icu::datetime::DateTimeFormatter; + /// use icu::locale::locale; + /// use writeable::assert_writeable_eq; + /// + /// let formatter = DateTimeFormatter::try_new( + /// locale!("th").into(), + /// YMD::long(), + /// ) + /// .unwrap(); + /// + /// assert_writeable_eq!( + /// formatter.format_any_calendar(&Date::try_new_iso(2024, 12, 16).unwrap()), + /// "16 ธันวาคม 2567" + /// ); + /// + /// assert_eq!(formatter.calendar_kind(), AnyCalendarKind::Buddhist); + /// assert_eq!(formatter.calendar_kind().as_bcp47_string(), "buddhist"); + /// ``` + pub fn calendar_kind(&self) -> AnyCalendarKind { + self.calendar.kind() + } } /// A formatter optimized for time and time zone formatting. diff --git a/ffi/capi/bindings/c/DateFormatter.h b/ffi/capi/bindings/c/DateFormatter.h index d872bd3f509..3b5532aceb3 100644 --- a/ffi/capi/bindings/c/DateFormatter.h +++ b/ffi/capi/bindings/c/DateFormatter.h @@ -7,6 +7,7 @@ #include #include "diplomat_runtime.h" +#include "AnyCalendarKind.d.h" #include "DataProvider.d.h" #include "Date.d.h" #include "DateTime.d.h" @@ -42,6 +43,8 @@ icu4x_DateFormatter_format_datetime_mv1_result icu4x_DateFormatter_format_dateti typedef struct icu4x_DateFormatter_format_iso_datetime_mv1_result {union { DateTimeFormatError err;}; bool is_ok;} icu4x_DateFormatter_format_iso_datetime_mv1_result; icu4x_DateFormatter_format_iso_datetime_mv1_result icu4x_DateFormatter_format_iso_datetime_mv1(const DateFormatter* self, const IsoDateTime* value, DiplomatWrite* write); +AnyCalendarKind icu4x_DateFormatter_calendar_kind_mv1(const DateFormatter* self); + void icu4x_DateFormatter_destroy_mv1(DateFormatter* self); diff --git a/ffi/capi/bindings/c/DateTimeFormatter.h b/ffi/capi/bindings/c/DateTimeFormatter.h index 045724563e2..306caee11ca 100644 --- a/ffi/capi/bindings/c/DateTimeFormatter.h +++ b/ffi/capi/bindings/c/DateTimeFormatter.h @@ -7,6 +7,7 @@ #include #include "diplomat_runtime.h" +#include "AnyCalendarKind.d.h" #include "DataProvider.d.h" #include "DateTime.d.h" #include "DateTimeFormatError.d.h" @@ -34,6 +35,8 @@ icu4x_DateTimeFormatter_format_datetime_mv1_result icu4x_DateTimeFormatter_forma typedef struct icu4x_DateTimeFormatter_format_iso_datetime_mv1_result {union { DateTimeFormatError err;}; bool is_ok;} icu4x_DateTimeFormatter_format_iso_datetime_mv1_result; icu4x_DateTimeFormatter_format_iso_datetime_mv1_result icu4x_DateTimeFormatter_format_iso_datetime_mv1(const DateTimeFormatter* self, const IsoDateTime* value, DiplomatWrite* write); +AnyCalendarKind icu4x_DateTimeFormatter_calendar_kind_mv1(const DateTimeFormatter* self); + void icu4x_DateTimeFormatter_destroy_mv1(DateTimeFormatter* self); diff --git a/ffi/capi/bindings/cpp/icu4x/DateFormatter.d.hpp b/ffi/capi/bindings/cpp/icu4x/DateFormatter.d.hpp index 708f49b74fa..dc8b56c4bb5 100644 --- a/ffi/capi/bindings/cpp/icu4x/DateFormatter.d.hpp +++ b/ffi/capi/bindings/cpp/icu4x/DateFormatter.d.hpp @@ -24,6 +24,7 @@ namespace capi { struct IsoDateTime; } class IsoDateTime; namespace capi { struct Locale; } class Locale; +class AnyCalendarKind; class DateTimeFormatError; class DateTimeFormatterLoadError; class DateTimeLength; @@ -52,6 +53,8 @@ class DateFormatter { inline diplomat::result format_iso_datetime(const icu4x::IsoDateTime& value) const; + inline icu4x::AnyCalendarKind calendar_kind() const; + inline const icu4x::capi::DateFormatter* AsFFI() const; inline icu4x::capi::DateFormatter* AsFFI(); inline static const icu4x::DateFormatter* FromFFI(const icu4x::capi::DateFormatter* ptr); diff --git a/ffi/capi/bindings/cpp/icu4x/DateFormatter.hpp b/ffi/capi/bindings/cpp/icu4x/DateFormatter.hpp index 7879bf7fa5c..aad249f7e98 100644 --- a/ffi/capi/bindings/cpp/icu4x/DateFormatter.hpp +++ b/ffi/capi/bindings/cpp/icu4x/DateFormatter.hpp @@ -10,6 +10,7 @@ #include #include #include "../diplomat_runtime.hpp" +#include "AnyCalendarKind.hpp" #include "DataProvider.hpp" #include "Date.hpp" #include "DateTime.hpp" @@ -43,6 +44,8 @@ namespace capi { typedef struct icu4x_DateFormatter_format_iso_datetime_mv1_result {union { icu4x::capi::DateTimeFormatError err;}; bool is_ok;} icu4x_DateFormatter_format_iso_datetime_mv1_result; icu4x_DateFormatter_format_iso_datetime_mv1_result icu4x_DateFormatter_format_iso_datetime_mv1(const icu4x::capi::DateFormatter* self, const icu4x::capi::IsoDateTime* value, diplomat::capi::DiplomatWrite* write); + icu4x::capi::AnyCalendarKind icu4x_DateFormatter_calendar_kind_mv1(const icu4x::capi::DateFormatter* self); + void icu4x_DateFormatter_destroy_mv1(DateFormatter* self); @@ -99,6 +102,11 @@ inline diplomat::result icu4x::DateForm return result.is_ok ? diplomat::result(diplomat::Ok(std::move(output))) : diplomat::result(diplomat::Err(icu4x::DateTimeFormatError::FromFFI(result.err))); } +inline icu4x::AnyCalendarKind icu4x::DateFormatter::calendar_kind() const { + auto result = icu4x::capi::icu4x_DateFormatter_calendar_kind_mv1(this->AsFFI()); + return icu4x::AnyCalendarKind::FromFFI(result); +} + inline const icu4x::capi::DateFormatter* icu4x::DateFormatter::AsFFI() const { return reinterpret_cast(this); } diff --git a/ffi/capi/bindings/cpp/icu4x/DateTimeFormatter.d.hpp b/ffi/capi/bindings/cpp/icu4x/DateTimeFormatter.d.hpp index be7dcdd276e..56c4d5eb5f9 100644 --- a/ffi/capi/bindings/cpp/icu4x/DateTimeFormatter.d.hpp +++ b/ffi/capi/bindings/cpp/icu4x/DateTimeFormatter.d.hpp @@ -20,6 +20,7 @@ namespace capi { struct IsoDateTime; } class IsoDateTime; namespace capi { struct Locale; } class Locale; +class AnyCalendarKind; class DateTimeFormatError; class DateTimeFormatterLoadError; class DateTimeLength; @@ -44,6 +45,8 @@ class DateTimeFormatter { inline diplomat::result format_iso_datetime(const icu4x::IsoDateTime& value) const; + inline icu4x::AnyCalendarKind calendar_kind() const; + inline const icu4x::capi::DateTimeFormatter* AsFFI() const; inline icu4x::capi::DateTimeFormatter* AsFFI(); inline static const icu4x::DateTimeFormatter* FromFFI(const icu4x::capi::DateTimeFormatter* ptr); diff --git a/ffi/capi/bindings/cpp/icu4x/DateTimeFormatter.hpp b/ffi/capi/bindings/cpp/icu4x/DateTimeFormatter.hpp index e33aa20b0ce..65246177659 100644 --- a/ffi/capi/bindings/cpp/icu4x/DateTimeFormatter.hpp +++ b/ffi/capi/bindings/cpp/icu4x/DateTimeFormatter.hpp @@ -10,6 +10,7 @@ #include #include #include "../diplomat_runtime.hpp" +#include "AnyCalendarKind.hpp" #include "DataProvider.hpp" #include "DateTime.hpp" #include "DateTimeFormatError.hpp" @@ -35,6 +36,8 @@ namespace capi { typedef struct icu4x_DateTimeFormatter_format_iso_datetime_mv1_result {union { icu4x::capi::DateTimeFormatError err;}; bool is_ok;} icu4x_DateTimeFormatter_format_iso_datetime_mv1_result; icu4x_DateTimeFormatter_format_iso_datetime_mv1_result icu4x_DateTimeFormatter_format_iso_datetime_mv1(const icu4x::capi::DateTimeFormatter* self, const icu4x::capi::IsoDateTime* value, diplomat::capi::DiplomatWrite* write); + icu4x::capi::AnyCalendarKind icu4x_DateTimeFormatter_calendar_kind_mv1(const icu4x::capi::DateTimeFormatter* self); + void icu4x_DateTimeFormatter_destroy_mv1(DateTimeFormatter* self); @@ -73,6 +76,11 @@ inline diplomat::result icu4x::DateTime return result.is_ok ? diplomat::result(diplomat::Ok(std::move(output))) : diplomat::result(diplomat::Err(icu4x::DateTimeFormatError::FromFFI(result.err))); } +inline icu4x::AnyCalendarKind icu4x::DateTimeFormatter::calendar_kind() const { + auto result = icu4x::capi::icu4x_DateTimeFormatter_calendar_kind_mv1(this->AsFFI()); + return icu4x::AnyCalendarKind::FromFFI(result); +} + inline const icu4x::capi::DateTimeFormatter* icu4x::DateTimeFormatter::AsFFI() const { return reinterpret_cast(this); } diff --git a/ffi/capi/bindings/dart/DateFormatter.g.dart b/ffi/capi/bindings/dart/DateFormatter.g.dart index 27ffae6a5f5..3635269998e 100644 --- a/ffi/capi/bindings/dart/DateFormatter.g.dart +++ b/ffi/capi/bindings/dart/DateFormatter.g.dart @@ -98,6 +98,14 @@ final class DateFormatter implements ffi.Finalizable { } return write.finalize(); } + + /// Returns the calendar system used in this formatter. + /// + /// See the [Rust documentation for `calendar_kind`](https://docs.rs/icu/latest/icu/datetime/struct.DateTimeFormatter.html#method.calendar_kind) for more information. + AnyCalendarKind calendarKind() { + final result = _icu4x_DateFormatter_calendar_kind_mv1(_ffi); + return AnyCalendarKind.values[result]; + } } @meta.RecordUse() @@ -134,3 +142,8 @@ external _ResultVoidInt32 _icu4x_DateFormatter_format_datetime_mv1(ffi.Pointer, ffi.Pointer, ffi.Pointer)>(isLeaf: true, symbol: 'icu4x_DateFormatter_format_iso_datetime_mv1') // ignore: non_constant_identifier_names external _ResultVoidInt32 _icu4x_DateFormatter_format_iso_datetime_mv1(ffi.Pointer self, ffi.Pointer value, ffi.Pointer write); + +@meta.RecordUse() +@ffi.Native)>(isLeaf: true, symbol: 'icu4x_DateFormatter_calendar_kind_mv1') +// ignore: non_constant_identifier_names +external int _icu4x_DateFormatter_calendar_kind_mv1(ffi.Pointer self); diff --git a/ffi/capi/bindings/dart/DateTimeFormatter.g.dart b/ffi/capi/bindings/dart/DateTimeFormatter.g.dart index e803c83b190..fb2bc1c92f4 100644 --- a/ffi/capi/bindings/dart/DateTimeFormatter.g.dart +++ b/ffi/capi/bindings/dart/DateTimeFormatter.g.dart @@ -72,6 +72,14 @@ final class DateTimeFormatter implements ffi.Finalizable { } return write.finalize(); } + + /// Returns the calendar system used in this formatter. + /// + /// See the [Rust documentation for `calendar_kind`](https://docs.rs/icu/latest/icu/datetime/struct.DateTimeFormatter.html#method.calendar_kind) for more information. + AnyCalendarKind calendarKind() { + final result = _icu4x_DateTimeFormatter_calendar_kind_mv1(_ffi); + return AnyCalendarKind.values[result]; + } } @meta.RecordUse() @@ -98,3 +106,8 @@ external _ResultVoidInt32 _icu4x_DateTimeFormatter_format_datetime_mv1(ffi.Point @ffi.Native<_ResultVoidInt32 Function(ffi.Pointer, ffi.Pointer, ffi.Pointer)>(isLeaf: true, symbol: 'icu4x_DateTimeFormatter_format_iso_datetime_mv1') // ignore: non_constant_identifier_names external _ResultVoidInt32 _icu4x_DateTimeFormatter_format_iso_datetime_mv1(ffi.Pointer self, ffi.Pointer value, ffi.Pointer write); + +@meta.RecordUse() +@ffi.Native)>(isLeaf: true, symbol: 'icu4x_DateTimeFormatter_calendar_kind_mv1') +// ignore: non_constant_identifier_names +external int _icu4x_DateTimeFormatter_calendar_kind_mv1(ffi.Pointer self); diff --git a/ffi/capi/bindings/js/DateFormatter.d.ts b/ffi/capi/bindings/js/DateFormatter.d.ts index 97ca1f354c9..7a8c8880897 100644 --- a/ffi/capi/bindings/js/DateFormatter.d.ts +++ b/ffi/capi/bindings/js/DateFormatter.d.ts @@ -1,4 +1,5 @@ // generated by diplomat-tool +import type { AnyCalendarKind } from "./AnyCalendarKind" import type { DataProvider } from "./DataProvider" import type { Date } from "./Date" import type { DateTime } from "./DateTime" @@ -32,4 +33,6 @@ export class DateFormatter { formatDatetime(value: DateTime): string; formatIsoDatetime(value: IsoDateTime): string; + + calendarKind(): AnyCalendarKind; } \ No newline at end of file diff --git a/ffi/capi/bindings/js/DateFormatter.mjs b/ffi/capi/bindings/js/DateFormatter.mjs index 8d721c3e78a..4e1e7639161 100644 --- a/ffi/capi/bindings/js/DateFormatter.mjs +++ b/ffi/capi/bindings/js/DateFormatter.mjs @@ -1,4 +1,5 @@ // generated by diplomat-tool +import { AnyCalendarKind } from "./AnyCalendarKind.mjs" import { DataProvider } from "./DataProvider.mjs" import { Date } from "./Date.mjs" import { DateTime } from "./DateTime.mjs" @@ -171,4 +172,14 @@ export class DateFormatter { write.free(); } } + + calendarKind() { + const result = wasm.icu4x_DateFormatter_calendar_kind_mv1(this.ffiValue); + + try { + return new AnyCalendarKind(diplomatRuntime.internalConstructor, result); + } + + finally {} + } } \ No newline at end of file diff --git a/ffi/capi/bindings/js/DateTimeFormatter.d.ts b/ffi/capi/bindings/js/DateTimeFormatter.d.ts index 7658b058e76..78fbb2fbb16 100644 --- a/ffi/capi/bindings/js/DateTimeFormatter.d.ts +++ b/ffi/capi/bindings/js/DateTimeFormatter.d.ts @@ -1,4 +1,5 @@ // generated by diplomat-tool +import type { AnyCalendarKind } from "./AnyCalendarKind" import type { DataProvider } from "./DataProvider" import type { DateTime } from "./DateTime" import type { DateTimeFormatError } from "./DateTimeFormatError" @@ -26,4 +27,6 @@ export class DateTimeFormatter { formatDatetime(value: DateTime): string; formatIsoDatetime(value: IsoDateTime): string; + + calendarKind(): AnyCalendarKind; } \ No newline at end of file diff --git a/ffi/capi/bindings/js/DateTimeFormatter.mjs b/ffi/capi/bindings/js/DateTimeFormatter.mjs index 5d6e1359ac1..524e6bfad15 100644 --- a/ffi/capi/bindings/js/DateTimeFormatter.mjs +++ b/ffi/capi/bindings/js/DateTimeFormatter.mjs @@ -1,4 +1,5 @@ // generated by diplomat-tool +import { AnyCalendarKind } from "./AnyCalendarKind.mjs" import { DataProvider } from "./DataProvider.mjs" import { DateTime } from "./DateTime.mjs" import { DateTimeFormatError } from "./DateTimeFormatError.mjs" @@ -125,4 +126,14 @@ export class DateTimeFormatter { write.free(); } } + + calendarKind() { + const result = wasm.icu4x_DateTimeFormatter_calendar_kind_mv1(this.ffiValue); + + try { + return new AnyCalendarKind(diplomatRuntime.internalConstructor, result); + } + + finally {} + } } \ No newline at end of file diff --git a/ffi/capi/src/datetime_formatter.rs b/ffi/capi/src/datetime_formatter.rs index 98bb427d1a4..b4eeba75df7 100644 --- a/ffi/capi/src/datetime_formatter.rs +++ b/ffi/capi/src/datetime_formatter.rs @@ -13,6 +13,7 @@ pub mod ffi { }; use crate::{ + calendar::ffi::AnyCalendarKind, date::ffi::{Date, IsoDate}, datetime::ffi::{DateTime, IsoDateTime}, errors::ffi::{DateTimeFormatError, DateTimeFormatterLoadError}, @@ -306,6 +307,12 @@ pub mod ffi { let _infallible = self.0.format_any_calendar(&any).write_to(write); Ok(()) } + + /// Returns the calendar system used in this formatter. + #[diplomat::rust_link(icu::datetime::DateTimeFormatter::calendar_kind, FnInStruct)] + pub fn calendar_kind(&self) -> AnyCalendarKind { + self.0.calendar_kind().into() + } } #[diplomat::opaque] @@ -372,5 +379,11 @@ pub mod ffi { let _infallible = self.0.format_any_calendar(&any).write_to(write); Ok(()) } + + /// Returns the calendar system used in this formatter. + #[diplomat::rust_link(icu::datetime::DateTimeFormatter::calendar_kind, FnInStruct)] + pub fn calendar_kind(&self) -> AnyCalendarKind { + self.0.calendar_kind().into() + } } } From 4bad0305f4b98b7dc25410a8006bb45591d96ea6 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Mon, 16 Dec 2024 21:04:02 -0800 Subject: [PATCH 5/9] Make FFI DataProvider only support BufferProvider (#5895) Fixes #4639 --- components/datetime/src/error.rs | 6 + ffi/capi/bindings/c/DataProvider.h | 4 - .../bindings/cpp/icu4x/DataProvider.d.hpp | 4 - ffi/capi/bindings/cpp/icu4x/DataProvider.hpp | 14 -- ffi/capi/bindings/dart/DataProvider.g.dart | 29 --- ffi/capi/bindings/js/DataProvider.d.ts | 4 - ffi/capi/bindings/js/DataProvider.mjs | 20 -- ffi/capi/src/bidi.rs | 6 +- ffi/capi/src/calendar.rs | 25 +-- ffi/capi/src/casemap.rs | 24 ++- ffi/capi/src/collator.rs | 22 ++- ffi/capi/src/datetime_formatter.rs | 99 +++++----- ffi/capi/src/decimal.rs | 29 +-- ffi/capi/src/displaynames.rs | 25 +-- ffi/capi/src/exemplar_chars.rs | 15 +- ffi/capi/src/fallbacker.rs | 10 +- ffi/capi/src/list.rs | 48 ++--- ffi/capi/src/locale.rs | 44 ++--- ffi/capi/src/locale_directionality.rs | 33 ++-- ffi/capi/src/normalizer.rs | 45 +++-- ffi/capi/src/normalizer_properties.rs | 29 ++- ffi/capi/src/pluralrules.rs | 25 +-- ffi/capi/src/properties_maps.rs | 30 +-- ffi/capi/src/properties_names.rs | 58 +++--- ffi/capi/src/properties_sets.rs | 151 +++++++-------- ffi/capi/src/properties_unisets.rs | 7 +- ffi/capi/src/provider.rs | 172 ++++-------------- ffi/capi/src/script.rs | 16 +- ffi/capi/src/segmenter_grapheme.rs | 16 +- ffi/capi/src/segmenter_line.rs | 70 ++++--- ffi/capi/src/segmenter_sentence.rs | 25 +-- ffi/capi/src/segmenter_word.rs | 72 ++++---- ffi/capi/src/timezone_mapper.rs | 18 +- ffi/capi/src/units_converter.rs | 13 +- ffi/capi/src/week.rs | 18 +- ffi/capi/src/zoned_formatter.rs | 47 ++--- tutorials/cpp/segmenter.cpp | 1 - 37 files changed, 560 insertions(+), 714 deletions(-) diff --git a/components/datetime/src/error.rs b/components/datetime/src/error.rs index dde16a054e9..7363d79072d 100644 --- a/components/datetime/src/error.rs +++ b/components/datetime/src/error.rs @@ -30,6 +30,12 @@ pub enum DateTimeFormatterLoadError { Data(DataError), } +impl From for DateTimeFormatterLoadError { + fn from(error: DataError) -> Self { + Self::Data(error) + } +} + /// An error from mixing calendar types in a formatter. #[derive(Display, Debug, Copy, Clone, PartialEq)] #[displaydoc("DateTimeFormatter for {this_kind} calendar was given a {date_kind:?} calendar")] diff --git a/ffi/capi/bindings/c/DataProvider.h b/ffi/capi/bindings/c/DataProvider.h index b05b5839bd3..a27390b0c2d 100644 --- a/ffi/capi/bindings/c/DataProvider.h +++ b/ffi/capi/bindings/c/DataProvider.h @@ -17,16 +17,12 @@ -DataProvider* icu4x_DataProvider_compiled_mv1(void); - typedef struct icu4x_DataProvider_from_fs_mv1_result {union {DataProvider* ok; DataError err;}; bool is_ok;} icu4x_DataProvider_from_fs_mv1_result; icu4x_DataProvider_from_fs_mv1_result icu4x_DataProvider_from_fs_mv1(DiplomatStringView path); typedef struct icu4x_DataProvider_from_byte_slice_mv1_result {union {DataProvider* ok; DataError err;}; bool is_ok;} icu4x_DataProvider_from_byte_slice_mv1_result; icu4x_DataProvider_from_byte_slice_mv1_result icu4x_DataProvider_from_byte_slice_mv1(DiplomatU8View blob); -DataProvider* icu4x_DataProvider_empty_mv1(void); - typedef struct icu4x_DataProvider_fork_by_key_mv1_result {union { DataError err;}; bool is_ok;} icu4x_DataProvider_fork_by_key_mv1_result; icu4x_DataProvider_fork_by_key_mv1_result icu4x_DataProvider_fork_by_key_mv1(DataProvider* self, DataProvider* other); diff --git a/ffi/capi/bindings/cpp/icu4x/DataProvider.d.hpp b/ffi/capi/bindings/cpp/icu4x/DataProvider.d.hpp index 9bca1b49c01..54915fb1b45 100644 --- a/ffi/capi/bindings/cpp/icu4x/DataProvider.d.hpp +++ b/ffi/capi/bindings/cpp/icu4x/DataProvider.d.hpp @@ -28,14 +28,10 @@ namespace icu4x { class DataProvider { public: - inline static std::unique_ptr compiled(); - inline static diplomat::result, icu4x::DataError> from_fs(std::string_view path); inline static diplomat::result, icu4x::DataError> from_byte_slice(diplomat::span blob); - inline static std::unique_ptr empty(); - inline diplomat::result fork_by_key(icu4x::DataProvider& other); inline diplomat::result fork_by_locale(icu4x::DataProvider& other); diff --git a/ffi/capi/bindings/cpp/icu4x/DataProvider.hpp b/ffi/capi/bindings/cpp/icu4x/DataProvider.hpp index 3eff3554fa1..1c63cbd76c5 100644 --- a/ffi/capi/bindings/cpp/icu4x/DataProvider.hpp +++ b/ffi/capi/bindings/cpp/icu4x/DataProvider.hpp @@ -18,16 +18,12 @@ namespace icu4x { namespace capi { extern "C" { - icu4x::capi::DataProvider* icu4x_DataProvider_compiled_mv1(void); - typedef struct icu4x_DataProvider_from_fs_mv1_result {union {icu4x::capi::DataProvider* ok; icu4x::capi::DataError err;}; bool is_ok;} icu4x_DataProvider_from_fs_mv1_result; icu4x_DataProvider_from_fs_mv1_result icu4x_DataProvider_from_fs_mv1(diplomat::capi::DiplomatStringView path); typedef struct icu4x_DataProvider_from_byte_slice_mv1_result {union {icu4x::capi::DataProvider* ok; icu4x::capi::DataError err;}; bool is_ok;} icu4x_DataProvider_from_byte_slice_mv1_result; icu4x_DataProvider_from_byte_slice_mv1_result icu4x_DataProvider_from_byte_slice_mv1(diplomat::capi::DiplomatU8View blob); - icu4x::capi::DataProvider* icu4x_DataProvider_empty_mv1(void); - typedef struct icu4x_DataProvider_fork_by_key_mv1_result {union { icu4x::capi::DataError err;}; bool is_ok;} icu4x_DataProvider_fork_by_key_mv1_result; icu4x_DataProvider_fork_by_key_mv1_result icu4x_DataProvider_fork_by_key_mv1(icu4x::capi::DataProvider* self, icu4x::capi::DataProvider* other); @@ -44,11 +40,6 @@ namespace capi { } // namespace capi } // namespace -inline std::unique_ptr icu4x::DataProvider::compiled() { - auto result = icu4x::capi::icu4x_DataProvider_compiled_mv1(); - return std::unique_ptr(icu4x::DataProvider::FromFFI(result)); -} - inline diplomat::result, icu4x::DataError> icu4x::DataProvider::from_fs(std::string_view path) { auto result = icu4x::capi::icu4x_DataProvider_from_fs_mv1({path.data(), path.size()}); return result.is_ok ? diplomat::result, icu4x::DataError>(diplomat::Ok>(std::unique_ptr(icu4x::DataProvider::FromFFI(result.ok)))) : diplomat::result, icu4x::DataError>(diplomat::Err(icu4x::DataError::FromFFI(result.err))); @@ -59,11 +50,6 @@ inline diplomat::result, icu4x::DataError> return result.is_ok ? diplomat::result, icu4x::DataError>(diplomat::Ok>(std::unique_ptr(icu4x::DataProvider::FromFFI(result.ok)))) : diplomat::result, icu4x::DataError>(diplomat::Err(icu4x::DataError::FromFFI(result.err))); } -inline std::unique_ptr icu4x::DataProvider::empty() { - auto result = icu4x::capi::icu4x_DataProvider_empty_mv1(); - return std::unique_ptr(icu4x::DataProvider::FromFFI(result)); -} - inline diplomat::result icu4x::DataProvider::fork_by_key(icu4x::DataProvider& other) { auto result = icu4x::capi::icu4x_DataProvider_fork_by_key_mv1(this->AsFFI(), other.AsFFI()); diff --git a/ffi/capi/bindings/dart/DataProvider.g.dart b/ffi/capi/bindings/dart/DataProvider.g.dart index 22ef963d3ae..69990cac6fc 100644 --- a/ffi/capi/bindings/dart/DataProvider.g.dart +++ b/ffi/capi/bindings/dart/DataProvider.g.dart @@ -24,25 +24,6 @@ final class DataProvider implements ffi.Finalizable { static final _finalizer = ffi.NativeFinalizer(ffi.Native.addressOf(_icu4x_DataProvider_destroy_mv1)); - /// Constructs an [`DataProvider`] that uses compiled data. - /// - /// Requires the `compiled_data` feature. - /// - /// This provider cannot be modified or combined with other providers, so `enable_fallback`, - /// `enabled_fallback_with`, `fork_by_locale`, and `fork_by_key` will return `Err`s. - factory DataProvider.compiled() { - final result = _icu4x_DataProvider_compiled_mv1(); - return DataProvider._fromFfi(result, []); - } - - /// Constructs an empty [`DataProvider`]. - /// - /// See the [Rust documentation for `EmptyDataProvider`](https://docs.rs/icu_provider_adapters/latest/icu_provider_adapters/empty/struct.EmptyDataProvider.html) for more information. - factory DataProvider.empty() { - final result = _icu4x_DataProvider_empty_mv1(); - return DataProvider._fromFfi(result, []); - } - /// Creates a provider that tries the current provider and then, if the current provider /// doesn't support the data key, another provider `other`. /// @@ -95,16 +76,6 @@ final class DataProvider implements ffi.Finalizable { // ignore: non_constant_identifier_names external void _icu4x_DataProvider_destroy_mv1(ffi.Pointer self); -@meta.RecordUse() -@ffi.Native Function()>(isLeaf: true, symbol: 'icu4x_DataProvider_compiled_mv1') -// ignore: non_constant_identifier_names -external ffi.Pointer _icu4x_DataProvider_compiled_mv1(); - -@meta.RecordUse() -@ffi.Native Function()>(isLeaf: true, symbol: 'icu4x_DataProvider_empty_mv1') -// ignore: non_constant_identifier_names -external ffi.Pointer _icu4x_DataProvider_empty_mv1(); - @meta.RecordUse() @ffi.Native<_ResultVoidInt32 Function(ffi.Pointer, ffi.Pointer)>(isLeaf: true, symbol: 'icu4x_DataProvider_fork_by_key_mv1') // ignore: non_constant_identifier_names diff --git a/ffi/capi/bindings/js/DataProvider.d.ts b/ffi/capi/bindings/js/DataProvider.d.ts index 0c5823c7b75..fc8cd56c830 100644 --- a/ffi/capi/bindings/js/DataProvider.d.ts +++ b/ffi/capi/bindings/js/DataProvider.d.ts @@ -13,10 +13,6 @@ export class DataProvider { get ffiValue(): pointer; - static compiled(): DataProvider; - - static empty(): DataProvider; - forkByKey(other: DataProvider): void; forkByLocale(other: DataProvider): void; diff --git a/ffi/capi/bindings/js/DataProvider.mjs b/ffi/capi/bindings/js/DataProvider.mjs index fdedf0364b4..b7116e95bd9 100644 --- a/ffi/capi/bindings/js/DataProvider.mjs +++ b/ffi/capi/bindings/js/DataProvider.mjs @@ -40,26 +40,6 @@ export class DataProvider { return this.#ptr; } - static compiled() { - const result = wasm.icu4x_DataProvider_compiled_mv1(); - - try { - return new DataProvider(diplomatRuntime.internalConstructor, result, []); - } - - finally {} - } - - static empty() { - const result = wasm.icu4x_DataProvider_empty_mv1(); - - try { - return new DataProvider(diplomatRuntime.internalConstructor, result, []); - } - - finally {} - } - forkByKey(other) { const diplomatReceive = new diplomatRuntime.DiplomatReceiveBuf(wasm, 5, 4, true); diff --git a/ffi/capi/src/bidi.rs b/ffi/capi/src/bidi.rs index bd1432a435e..5dfdebb7027 100644 --- a/ffi/capi/src/bidi.rs +++ b/ffi/capi/src/bidi.rs @@ -10,8 +10,8 @@ pub mod ffi { use alloc::vec::Vec; use core::fmt::Write; - use crate::errors::ffi::DataError; - use crate::provider::ffi::DataProvider; + #[cfg(feature = "buffer_provider")] + use crate::{errors::ffi::DataError, provider::ffi::DataProvider}; pub enum BidiDirection { Ltr, @@ -39,9 +39,9 @@ pub mod ffi { /// Creates a new [`Bidi`] from locale data, and a particular data source. #[diplomat::rust_link(icu::properties::bidi::BidiClassAdapter::new, FnInStruct)] #[diplomat::attr(supports = fallible_constructors, named_constructor = "with_provider")] + #[cfg(feature = "buffer_provider")] pub fn create_with_provider(provider: &DataProvider) -> Result, DataError> { Ok(Box::new(Bidi(call_constructor_unstable!( - icu_properties::CodePointMapData::new [m => Ok(m.static_to_owned())], icu_properties::CodePointMapData::try_new_unstable, provider, )?))) diff --git a/ffi/capi/src/calendar.rs b/ffi/capi/src/calendar.rs index eb382fc354b..549946a19de 100644 --- a/ffi/capi/src/calendar.rs +++ b/ffi/capi/src/calendar.rs @@ -10,8 +10,10 @@ pub mod ffi { use alloc::sync::Arc; use core::fmt::Write; + #[cfg(any(feature = "compiled_data", feature = "buffer_provider"))] use crate::errors::ffi::DataError; use crate::locale_core::ffi::Locale; + #[cfg(feature = "buffer_provider")] use crate::provider::ffi::DataProvider; /// The various calendar types currently supported by [`Calendar`] @@ -126,34 +128,33 @@ pub mod ffi { #[diplomat::rust_link(icu::calendar::AnyCalendar::try_new, FnInEnum)] #[diplomat::attr(supports = fallible_constructors, named_constructor = "for_locale_with_provider")] #[diplomat::demo(default_constructor)] + #[cfg(feature = "buffer_provider")] pub fn create_for_locale_with_provider( provider: &DataProvider, locale: &Locale, ) -> Result, DataError> { let prefs = (&locale.0).into(); - Ok(Box::new(Calendar(Arc::new(call_constructor!( - icu_calendar::AnyCalendar::try_new, - icu_calendar::AnyCalendar::try_new_with_any_provider, - icu_calendar::AnyCalendar::try_new_with_buffer_provider, - provider, - prefs + Ok(Box::new(Calendar(Arc::new(provider.call_constructor( + |provider| icu_calendar::AnyCalendar::try_new_with_buffer_provider(provider, prefs), )?)))) } /// Creates a new [`Calendar`] from the specified date and time, using a particular data source. #[diplomat::rust_link(icu::calendar::AnyCalendar::new_for_kind, FnInEnum)] #[diplomat::attr(supports = fallible_constructors, named_constructor = "for_kind_with_provider")] + #[cfg(feature = "buffer_provider")] pub fn create_for_kind_with_provider( provider: &DataProvider, kind: AnyCalendarKind, ) -> Result, DataError> { - Ok(Box::new(Calendar(Arc::new(call_constructor!( - icu_calendar::AnyCalendar::new_for_kind [r => Ok(r)], - icu_calendar::AnyCalendar::try_new_for_kind_with_any_provider, - icu_calendar::AnyCalendar::try_new_for_kind_with_buffer_provider, - provider, - kind.into() + Ok(Box::new(Calendar(Arc::new(provider.call_constructor( + |provider| { + icu_calendar::AnyCalendar::try_new_for_kind_with_buffer_provider( + provider, + kind.into(), + ) + }, )?)))) } diff --git a/ffi/capi/src/casemap.rs b/ffi/capi/src/casemap.rs index 7b45e68245f..5eadd0b336c 100644 --- a/ffi/capi/src/casemap.rs +++ b/ffi/capi/src/casemap.rs @@ -10,7 +10,11 @@ use icu_casemap::titlecase::TitlecaseOptions; pub mod ffi { use alloc::boxed::Box; - use crate::{errors::ffi::DataError, locale_core::ffi::Locale, provider::ffi::DataProvider}; + #[cfg(any(feature = "compiled_data", feature = "buffer_provider"))] + use crate::errors::ffi::DataError; + use crate::locale_core::ffi::Locale; + #[cfg(feature = "buffer_provider")] + use crate::provider::ffi::DataProvider; use diplomat_runtime::DiplomatOption; use writeable::Writeable; @@ -65,12 +69,10 @@ pub mod ffi { /// Construct a new CaseMapper instance using a particular data source. #[diplomat::rust_link(icu::casemap::CaseMapper::new, FnInStruct)] #[diplomat::attr(supports = fallible_constructors, named_constructor = "with_provider")] + #[cfg(feature = "buffer_provider")] pub fn create_with_provider(provider: &DataProvider) -> Result, DataError> { - Ok(Box::new(CaseMapper(call_constructor!( - icu_casemap::CaseMapper::new [r => Ok(r)], - icu_casemap::CaseMapper::try_new_with_any_provider, + Ok(Box::new(CaseMapper(provider.call_constructor( icu_casemap::CaseMapper::try_new_with_buffer_provider, - provider, )?))) } /// Returns the full lowercase mapping of the given string @@ -230,14 +232,12 @@ pub mod ffi { #[diplomat::rust_link(icu::casemap::CaseMapCloser::new, FnInStruct)] #[diplomat::rust_link(icu::casemap::CaseMapCloser::new_with_mapper, FnInStruct, hidden)] #[diplomat::attr(supports = fallible_constructors, named_constructor = "with_provider")] + #[cfg(feature = "buffer_provider")] pub fn create_with_provider( provider: &DataProvider, ) -> Result, DataError> { - Ok(Box::new(CaseMapCloser(call_constructor!( - icu_casemap::CaseMapCloser::new [r => Ok(r)], - icu_casemap::CaseMapCloser::try_new_with_any_provider, + Ok(Box::new(CaseMapCloser(provider.call_constructor( icu_casemap::CaseMapCloser::try_new_with_buffer_provider, - provider, )?))) } /// Adds all simple case mappings and the full case folding for `c` to `builder`. @@ -289,14 +289,12 @@ pub mod ffi { #[diplomat::rust_link(icu::casemap::TitlecaseMapper::new, FnInStruct)] #[diplomat::rust_link(icu::casemap::TitlecaseMapper::new_with_mapper, FnInStruct, hidden)] #[diplomat::attr(supports = fallible_constructors, named_constructor = "with_provider")] + #[cfg(feature = "buffer_provider")] pub fn create_with_provider( provider: &DataProvider, ) -> Result, DataError> { - Ok(Box::new(TitlecaseMapper(call_constructor!( - icu_casemap::TitlecaseMapper::new [r => Ok(r)], - icu_casemap::TitlecaseMapper::try_new_with_any_provider, + Ok(Box::new(TitlecaseMapper(provider.call_constructor( icu_casemap::TitlecaseMapper::try_new_with_buffer_provider, - provider, )?))) } /// Returns the full titlecase mapping of the given string diff --git a/ffi/capi/src/collator.rs b/ffi/capi/src/collator.rs index b6e43cb5c7f..46e45ae25fc 100644 --- a/ffi/capi/src/collator.rs +++ b/ffi/capi/src/collator.rs @@ -8,7 +8,10 @@ pub mod ffi { use alloc::boxed::Box; - use crate::{errors::ffi::DataError, locale_core::ffi::Locale, provider::ffi::DataProvider}; + #[cfg(feature = "buffer_provider")] + use crate::provider::ffi::DataProvider; + #[cfg(any(feature = "compiled_data", feature = "buffer_provider"))] + use crate::{errors::ffi::DataError, locale_core::ffi::Locale}; use diplomat_runtime::DiplomatOption; #[diplomat::opaque] @@ -131,18 +134,21 @@ pub mod ffi { #[diplomat::rust_link(icu::collator::CollatorPreferences, Struct, hidden)] #[diplomat::attr(supports = fallible_constructors, constructor)] #[diplomat::attr(supports = non_exhaustive_structs, rename = "create_with_provider")] + #[cfg(feature = "buffer_provider")] pub fn create_v1_with_provider( provider: &DataProvider, locale: &Locale, options: CollatorOptionsV1, ) -> Result, DataError> { - Ok(Box::new(Collator(call_constructor!( - icu_collator::Collator::try_new [r => Ok(r?.static_to_owned())], - icu_collator::Collator::try_new_with_any_provider, - icu_collator::Collator::try_new_with_buffer_provider, - provider, - icu_collator::CollatorPreferences::from(&locale.0), - icu_collator::CollatorOptions::from(options), + let options = options.into(); + Ok(Box::new(Collator(provider.call_constructor( + |provider| { + icu_collator::Collator::try_new_with_buffer_provider( + provider, + (&locale.0).into(), + options, + ) + }, )?))) } /// Compare two strings. diff --git a/ffi/capi/src/datetime_formatter.rs b/ffi/capi/src/datetime_formatter.rs index b4eeba75df7..1ec9de85cec 100644 --- a/ffi/capi/src/datetime_formatter.rs +++ b/ffi/capi/src/datetime_formatter.rs @@ -7,18 +7,21 @@ #[diplomat::attr(auto, namespace = "icu4x")] pub mod ffi { use alloc::boxed::Box; - use icu_datetime::{ - fieldsets::{T, YMD, YMDT}, - options::Length, - }; - + use icu_datetime::fieldsets::{T, YMD, YMDT}; + #[cfg(any(feature = "compiled_data", feature = "buffer_provider"))] + use icu_datetime::options::Length; + + #[cfg(any(feature = "compiled_data", feature = "buffer_provider"))] + use crate::errors::ffi::DateTimeFormatterLoadError; + #[cfg(any(feature = "compiled_data", feature = "buffer_provider"))] + use crate::locale_core::ffi::Locale; + #[cfg(feature = "buffer_provider")] + use crate::provider::ffi::DataProvider; use crate::{ calendar::ffi::AnyCalendarKind, date::ffi::{Date, IsoDate}, datetime::ffi::{DateTime, IsoDateTime}, - errors::ffi::{DateTimeFormatError, DateTimeFormatterLoadError}, - locale_core::ffi::Locale, - provider::ffi::DataProvider, + errors::ffi::DateTimeFormatError, time::ffi::Time, }; @@ -56,6 +59,7 @@ pub mod ffi { /// Creates a new [`TimeFormatter`] using a particular data source. #[diplomat::attr(supports = fallible_constructors, named_constructor = "with_length_and_provider")] + #[cfg(feature = "buffer_provider")] pub fn create_with_length_and_provider( provider: &DataProvider, locale: &Locale, @@ -64,14 +68,13 @@ pub mod ffi { let prefs = (&locale.0).into(); let options = T::with_length(Length::from(length)).hm(); - Ok(Box::new(TimeFormatter(call_constructor!( - icu_datetime::FixedCalendarDateTimeFormatter::try_new, - icu_datetime::FixedCalendarDateTimeFormatter::try_new_with_any_provider, - icu_datetime::FixedCalendarDateTimeFormatter::try_new_with_buffer_provider, - provider, - prefs, - options - )?))) + Ok(Box::new(TimeFormatter( + provider.call_constructor_custom_err(move |provider| { + icu_datetime::FixedCalendarDateTimeFormatter::try_new_with_buffer_provider( + provider, prefs, options, + ) + })?, + ))) } /// Formats a [`Time`] to a string. @@ -125,6 +128,7 @@ pub mod ffi { /// Creates a new [`GregorianDateFormatter`] using a particular data source. #[diplomat::attr(supports = fallible_constructors, named_constructor = "with_length_and_provider")] + #[cfg(feature = "buffer_provider")] pub fn create_with_length_and_provider( provider: &DataProvider, locale: &Locale, @@ -133,14 +137,13 @@ pub mod ffi { let prefs = (&locale.0).into(); let options = YMD::with_length(Length::from(length)); - Ok(Box::new(GregorianDateFormatter(call_constructor!( - icu_datetime::FixedCalendarDateTimeFormatter::try_new, - icu_datetime::FixedCalendarDateTimeFormatter::try_new_with_any_provider, - icu_datetime::FixedCalendarDateTimeFormatter::try_new_with_buffer_provider, - provider, - prefs, - options - )?))) + Ok(Box::new(GregorianDateFormatter( + provider.call_constructor_custom_err(move |provider| { + icu_datetime::FixedCalendarDateTimeFormatter::try_new_with_buffer_provider( + provider, prefs, options, + ) + })?, + ))) } /// Formats a [`IsoDate`] to a string. @@ -190,6 +193,7 @@ pub mod ffi { /// Creates a new [`GregorianDateTimeFormatter`] using a particular data source. #[diplomat::attr(supports = fallible_constructors, named_constructor = "with_length_and_provider")] + #[cfg(feature = "buffer_provider")] pub fn create_with_length_and_provider( provider: &DataProvider, locale: &Locale, @@ -198,14 +202,13 @@ pub mod ffi { let prefs = (&locale.0).into(); let options = YMDT::with_length(Length::from(length)).hm(); - Ok(Box::new(GregorianDateTimeFormatter(call_constructor!( - icu_datetime::FixedCalendarDateTimeFormatter::try_new, - icu_datetime::FixedCalendarDateTimeFormatter::try_new_with_any_provider, - icu_datetime::FixedCalendarDateTimeFormatter::try_new_with_buffer_provider, - provider, - prefs, - options - )?))) + Ok(Box::new(GregorianDateTimeFormatter( + provider.call_constructor_custom_err(move |provider| { + icu_datetime::FixedCalendarDateTimeFormatter::try_new_with_buffer_provider( + provider, prefs, options, + ) + })?, + ))) } /// Formats a [`IsoDateTime`] to a string. @@ -244,6 +247,7 @@ pub mod ffi { /// Creates a new [`DateFormatter`] using a particular data source. #[diplomat::attr(supports = fallible_constructors, named_constructor = "with_length_and_provider")] + #[cfg(feature = "buffer_provider")] pub fn create_with_length_and_provider( provider: &DataProvider, locale: &Locale, @@ -252,14 +256,13 @@ pub mod ffi { let prefs = (&locale.0).into(); let options = YMD::with_length(Length::from(length)); - Ok(Box::new(DateFormatter(call_constructor!( - icu_datetime::DateTimeFormatter::try_new, - icu_datetime::DateTimeFormatter::try_new_with_any_provider, - icu_datetime::DateTimeFormatter::try_new_with_buffer_provider, - provider, - prefs, - options - )?))) + Ok(Box::new(DateFormatter( + provider.call_constructor_custom_err(move |provider| { + icu_datetime::DateTimeFormatter::try_new_with_buffer_provider( + provider, prefs, options, + ) + })?, + ))) } /// Formats a [`Date`] to a string. @@ -340,6 +343,7 @@ pub mod ffi { /// Creates a new [`DateTimeFormatter`] using a particular data source. #[diplomat::attr(supports = fallible_constructors, named_constructor = "with_length_and_provider")] + #[cfg(feature = "buffer_provider")] pub fn create_with_length_and_provider( provider: &DataProvider, locale: &Locale, @@ -348,14 +352,13 @@ pub mod ffi { let prefs = (&locale.0).into(); let options = YMDT::with_length(Length::from(length)).hm(); - Ok(Box::new(DateTimeFormatter(call_constructor!( - icu_datetime::DateTimeFormatter::try_new, - icu_datetime::DateTimeFormatter::try_new_with_any_provider, - icu_datetime::DateTimeFormatter::try_new_with_buffer_provider, - provider, - prefs, - options - )?))) + Ok(Box::new(DateTimeFormatter( + provider.call_constructor_custom_err(move |provider| { + icu_datetime::DateTimeFormatter::try_new_with_buffer_provider( + provider, prefs, options, + ) + })?, + ))) } /// Formats a [`DateTime`] to a string. pub fn format_datetime( diff --git a/ffi/capi/src/decimal.rs b/ffi/capi/src/decimal.rs index c4ae961d4ee..eaeb2a9e3f1 100644 --- a/ffi/capi/src/decimal.rs +++ b/ffi/capi/src/decimal.rs @@ -8,11 +8,14 @@ pub mod ffi { use alloc::boxed::Box; - use crate::{ - errors::ffi::DataError, fixed_decimal::ffi::SignedFixedDecimal, locale_core::ffi::Locale, - provider::ffi::DataProvider, - }; - use icu_decimal::{options::FixedDecimalFormatterOptions, FixedDecimalFormatterPreferences}; + #[cfg(any(feature = "compiled_data", feature = "buffer_provider"))] + use crate::locale_core::ffi::Locale; + #[cfg(feature = "buffer_provider")] + use crate::provider::ffi::DataProvider; + use crate::{errors::ffi::DataError, fixed_decimal::ffi::SignedFixedDecimal}; + use icu_decimal::options::FixedDecimalFormatterOptions; + #[cfg(any(feature = "compiled_data", feature = "buffer_provider"))] + use icu_decimal::FixedDecimalFormatterPreferences; use writeable::Writeable; @@ -56,6 +59,7 @@ pub mod ffi { #[diplomat::rust_link(icu::decimal::FixedDecimalFormatter::try_new, FnInStruct)] #[diplomat::attr(supports = fallible_constructors, named_constructor = "with_grouping_strategy_and_provider")] #[diplomat::demo(default_constructor)] + #[cfg(feature = "buffer_provider")] pub fn create_with_grouping_strategy_and_provider( provider: &DataProvider, locale: &Locale, @@ -67,14 +71,13 @@ pub mod ffi { options.grouping_strategy = grouping_strategy .map(Into::into) .unwrap_or(options.grouping_strategy); - Ok(Box::new(FixedDecimalFormatter(call_constructor!( - icu_decimal::FixedDecimalFormatter::try_new, - icu_decimal::FixedDecimalFormatter::try_new_with_any_provider, - icu_decimal::FixedDecimalFormatter::try_new_with_buffer_provider, - provider, - prefs, - options, - )?))) + Ok(Box::new(FixedDecimalFormatter( + provider.call_constructor_custom_err(move |provider| { + icu_decimal::FixedDecimalFormatter::try_new_with_buffer_provider( + provider, prefs, options, + ) + })?, + ))) } /// Creates a new [`FixedDecimalFormatter`] from preconstructed locale data. diff --git a/ffi/capi/src/displaynames.rs b/ffi/capi/src/displaynames.rs index 28db7b258f8..18e89babbd5 100644 --- a/ffi/capi/src/displaynames.rs +++ b/ffi/capi/src/displaynames.rs @@ -8,8 +8,11 @@ pub mod ffi { use alloc::boxed::Box; - use crate::errors::ffi::{DataError, LocaleParseError}; + #[cfg(any(feature = "compiled_data", feature = "buffer_provider"))] + use crate::errors::ffi::DataError; + use crate::errors::ffi::LocaleParseError; use crate::locale_core::ffi::Locale; + #[cfg(feature = "buffer_provider")] use crate::provider::ffi::DataProvider; use diplomat_runtime::DiplomatOption; @@ -86,6 +89,7 @@ pub mod ffi { #[diplomat::attr(supports = non_exhaustive_structs, rename = "create_with_provider")] #[diplomat::attr(all(supports = fallible_constructors, supports = non_exhaustive_structs), named_constructor = "with_provider")] #[diplomat::attr(all(supports = fallible_constructors, not(supports = non_exhaustive_structs)), named_constructor = "v1_with_provider")] + #[cfg(feature = "buffer_provider")] pub fn create_v1_with_provider( provider: &DataProvider, locale: &Locale, @@ -95,14 +99,9 @@ pub mod ffi { let options = icu_experimental::displaynames::DisplayNamesOptions::from(options); Ok(Box::new(LocaleDisplayNamesFormatter( - call_constructor!( - icu_experimental::displaynames::LocaleDisplayNamesFormatter::try_new, - icu_experimental::displaynames::LocaleDisplayNamesFormatter::try_new_with_any_provider, - icu_experimental::displaynames::LocaleDisplayNamesFormatter::try_new_with_buffer_provider, - provider, - prefs, + provider.call_constructor_custom_err(move |provider| icu_experimental::displaynames::LocaleDisplayNamesFormatter::try_new_with_buffer_provider(provider, prefs, options, - )?, + ))?, ))) } @@ -138,6 +137,7 @@ pub mod ffi { #[diplomat::attr(supports = non_exhaustive_structs, rename = "create_with_provider")] #[diplomat::attr(all(supports = fallible_constructors, supports = non_exhaustive_structs), named_constructor = "with_provider")] #[diplomat::attr(all(supports = fallible_constructors, not(supports = non_exhaustive_structs)), named_constructor = "v1_with_provider")] + #[cfg(feature = "buffer_provider")] pub fn create_v1_with_provider( provider: &DataProvider, locale: &Locale, @@ -145,14 +145,9 @@ pub mod ffi { ) -> Result, DataError> { let prefs = (&locale.0).into(); let options = icu_experimental::displaynames::DisplayNamesOptions::from(options); - Ok(Box::new(RegionDisplayNames(call_constructor!( - icu_experimental::displaynames::RegionDisplayNames::try_new, - icu_experimental::displaynames::RegionDisplayNames::try_new_with_any_provider, - icu_experimental::displaynames::RegionDisplayNames::try_new_with_buffer_provider, - provider, - prefs, + Ok(Box::new(RegionDisplayNames(provider.call_constructor_custom_err(move |provider| icu_experimental::displaynames::RegionDisplayNames::try_new_with_buffer_provider(provider, prefs, options - )?))) + ))?))) } /// Returns the locale specific display name of a region. diff --git a/ffi/capi/src/exemplar_chars.rs b/ffi/capi/src/exemplar_chars.rs index 6fa23bec364..6514964e39b 100644 --- a/ffi/capi/src/exemplar_chars.rs +++ b/ffi/capi/src/exemplar_chars.rs @@ -8,9 +8,10 @@ pub mod ffi { use alloc::boxed::Box; - use crate::errors::ffi::DataError; - use crate::locale_core::ffi::Locale; + #[cfg(feature = "buffer_provider")] use crate::provider::ffi::DataProvider; + #[cfg(any(feature = "compiled_data", feature = "buffer_provider"))] + use crate::{errors::ffi::DataError, locale_core::ffi::Locale}; #[diplomat::opaque] /// A set of "exemplar characters" for a given locale. @@ -67,13 +68,13 @@ pub mod ffi { FnInStruct )] #[diplomat::attr(supports = fallible_constructors, named_constructor = "main_with_provider")] + #[cfg(feature = "buffer_provider")] pub fn create_main_with_provider( provider: &DataProvider, locale: &Locale, ) -> Result, DataError> { let locale = locale.to_datalocale(); Ok(Box::new(ExemplarCharacters(call_constructor_unstable!( - icu_locale::exemplar_chars::ExemplarCharacters::try_new_main [r => r.map(|r| r.static_to_owned())], icu_locale::exemplar_chars::ExemplarCharacters::try_new_main_unstable, provider, &locale @@ -100,13 +101,13 @@ pub mod ffi { FnInStruct )] #[diplomat::attr(supports = fallible_constructors, named_constructor = "auxiliary_with_provider")] + #[cfg(feature = "buffer_provider")] pub fn create_auxiliary_with_provider( provider: &DataProvider, locale: &Locale, ) -> Result, DataError> { let locale = locale.to_datalocale(); Ok(Box::new(ExemplarCharacters(call_constructor_unstable!( - icu_locale::exemplar_chars::ExemplarCharacters::try_new_auxiliary [r => r.map(|r| r.static_to_owned())], icu_locale::exemplar_chars::ExemplarCharacters::try_new_auxiliary_unstable, provider, &locale @@ -133,13 +134,13 @@ pub mod ffi { FnInStruct )] #[diplomat::attr(supports = fallible_constructors, named_constructor = "punctuation_with_provider")] + #[cfg(feature = "buffer_provider")] pub fn create_punctuation_with_provider( provider: &DataProvider, locale: &Locale, ) -> Result, DataError> { let locale = locale.to_datalocale(); Ok(Box::new(ExemplarCharacters(call_constructor_unstable!( - icu_locale::exemplar_chars::ExemplarCharacters::try_new_punctuation [r => r.map(|r| r.static_to_owned())], icu_locale::exemplar_chars::ExemplarCharacters::try_new_punctuation_unstable, provider, &locale @@ -167,13 +168,13 @@ pub mod ffi { FnInStruct )] #[diplomat::attr(supports = fallible_constructors, named_constructor = "numbers_with_provider")] + #[cfg(feature = "buffer_provider")] pub fn create_numbers_with_provider( provider: &DataProvider, locale: &Locale, ) -> Result, DataError> { let locale = locale.to_datalocale(); Ok(Box::new(ExemplarCharacters(call_constructor_unstable!( - icu_locale::exemplar_chars::ExemplarCharacters::try_new_numbers [r => r.map(|r| r.static_to_owned())], icu_locale::exemplar_chars::ExemplarCharacters::try_new_numbers_unstable, provider, &locale @@ -201,13 +202,13 @@ pub mod ffi { FnInStruct )] #[diplomat::attr(supports = fallible_constructors, named_constructor = "index_with_provider")] + #[cfg(feature = "buffer_provider")] pub fn create_index_with_provider( provider: &DataProvider, locale: &Locale, ) -> Result, DataError> { let locale = locale.to_datalocale(); Ok(Box::new(ExemplarCharacters(call_constructor_unstable!( - icu_locale::exemplar_chars::ExemplarCharacters::try_new_index [r => r.map(|r| r.static_to_owned())], icu_locale::exemplar_chars::ExemplarCharacters::try_new_index_unstable, provider, &locale diff --git a/ffi/capi/src/fallbacker.rs b/ffi/capi/src/fallbacker.rs index fa5435b7004..ea6310d395a 100644 --- a/ffi/capi/src/fallbacker.rs +++ b/ffi/capi/src/fallbacker.rs @@ -8,7 +8,9 @@ pub mod ffi { use alloc::boxed::Box; - use crate::{errors::ffi::DataError, locale_core::ffi::Locale, provider::ffi::DataProvider}; + use crate::locale_core::ffi::Locale; + #[cfg(feature = "buffer_provider")] + use crate::{errors::ffi::DataError, provider::ffi::DataProvider}; /// An object that runs the ICU4X locale fallback algorithm. #[diplomat::opaque] @@ -78,14 +80,12 @@ pub mod ffi { hidden )] #[diplomat::attr(supports = fallible_constructors, named_constructor = "with_provider")] + #[cfg(feature = "buffer_provider")] pub fn create_with_provider( provider: &DataProvider, ) -> Result, DataError> { - Ok(Box::new(LocaleFallbacker(call_constructor!( - icu_locale::LocaleFallbacker::new [r => Ok(r.static_to_owned())], - icu_locale::LocaleFallbacker::try_new_with_any_provider, + Ok(Box::new(LocaleFallbacker(provider.call_constructor( icu_locale::LocaleFallbacker::try_new_with_buffer_provider, - provider, )?))) } diff --git a/ffi/capi/src/list.rs b/ffi/capi/src/list.rs index d7e40368e82..fcf5c0ff006 100644 --- a/ffi/capi/src/list.rs +++ b/ffi/capi/src/list.rs @@ -8,9 +8,13 @@ pub mod ffi { use alloc::boxed::Box; use diplomat_runtime::{DiplomatStr16Slice, DiplomatStrSlice}; + #[cfg(any(feature = "compiled_data", feature = "buffer_provider"))] use icu_list::{ListFormatterOptions, ListFormatterPreferences}; - use crate::{errors::ffi::DataError, locale_core::ffi::Locale, provider::ffi::DataProvider}; + #[cfg(feature = "buffer_provider")] + use crate::provider::ffi::DataProvider; + #[cfg(any(feature = "compiled_data", feature = "buffer_provider"))] + use crate::{errors::ffi::DataError, locale_core::ffi::Locale}; use writeable::Writeable; @@ -45,6 +49,7 @@ pub mod ffi { /// Construct a new ListFormatter instance for And patterns #[diplomat::rust_link(icu::list::ListFormatter::try_new_and, FnInStruct)] #[diplomat::attr(supports = fallible_constructors, named_constructor = "and_with_length_and_provider")] + #[cfg(feature = "buffer_provider")] pub fn create_and_with_length_and_provider( provider: &DataProvider, locale: &Locale, @@ -52,13 +57,12 @@ pub mod ffi { ) -> Result, DataError> { let prefs = ListFormatterPreferences::from(&locale.0); let options = ListFormatterOptions::default().with_length(length.into()); - Ok(Box::new(ListFormatter(call_constructor!( - icu_list::ListFormatter::try_new_and, - icu_list::ListFormatter::try_new_and_with_any_provider, - icu_list::ListFormatter::try_new_and_with_buffer_provider, - provider, - prefs, - options, + Ok(Box::new(ListFormatter(provider.call_constructor( + move |provider| { + icu_list::ListFormatter::try_new_and_with_buffer_provider( + provider, prefs, options, + ) + }, )?))) } @@ -80,6 +84,7 @@ pub mod ffi { /// Construct a new ListFormatter instance for And patterns #[diplomat::rust_link(icu::list::ListFormatter::try_new_or, FnInStruct)] #[diplomat::attr(supports = fallible_constructors, named_constructor = "or_with_length_and_provider")] + #[cfg(feature = "buffer_provider")] pub fn create_or_with_length_and_provider( provider: &DataProvider, locale: &Locale, @@ -87,13 +92,12 @@ pub mod ffi { ) -> Result, DataError> { let prefs = ListFormatterPreferences::from(&locale.0); let options = ListFormatterOptions::default().with_length(length.into()); - Ok(Box::new(ListFormatter(call_constructor!( - icu_list::ListFormatter::try_new_or, - icu_list::ListFormatter::try_new_or_with_any_provider, - icu_list::ListFormatter::try_new_or_with_buffer_provider, - provider, - prefs, - options + Ok(Box::new(ListFormatter(provider.call_constructor( + move |provider| { + icu_list::ListFormatter::try_new_or_with_buffer_provider( + provider, prefs, options, + ) + }, )?))) } @@ -115,6 +119,7 @@ pub mod ffi { /// Construct a new ListFormatter instance for And patterns #[diplomat::rust_link(icu::list::ListFormatter::try_new_unit, FnInStruct)] #[diplomat::attr(supports = fallible_constructors, named_constructor = "unit_with_length_and_provider")] + #[cfg(feature = "buffer_provider")] pub fn create_unit_with_length_and_provider( provider: &DataProvider, locale: &Locale, @@ -122,13 +127,12 @@ pub mod ffi { ) -> Result, DataError> { let prefs = ListFormatterPreferences::from(&locale.0); let options = ListFormatterOptions::default().with_length(length.into()); - Ok(Box::new(ListFormatter(call_constructor!( - icu_list::ListFormatter::try_new_unit, - icu_list::ListFormatter::try_new_unit_with_any_provider, - icu_list::ListFormatter::try_new_unit_with_buffer_provider, - provider, - prefs, - options + Ok(Box::new(ListFormatter(provider.call_constructor( + move |provider| { + icu_list::ListFormatter::try_new_unit_with_buffer_provider( + provider, prefs, options, + ) + }, )?))) } diff --git a/ffi/capi/src/locale.rs b/ffi/capi/src/locale.rs index 4408cdc5721..d63aa63d978 100644 --- a/ffi/capi/src/locale.rs +++ b/ffi/capi/src/locale.rs @@ -8,9 +8,9 @@ pub mod ffi { use alloc::boxed::Box; - use crate::errors::ffi::DataError; use crate::locale_core::ffi::Locale; - use crate::provider::ffi::DataProvider; + #[cfg(feature = "buffer_provider")] + use crate::{errors::ffi::DataError, provider::ffi::DataProvider}; #[diplomat::rust_link(icu::locale::TransformResult, Enum)] #[diplomat::enum_convert(icu_locale::TransformResult)] @@ -35,14 +35,12 @@ pub mod ffi { /// Create a new [`LocaleCanonicalizer`]. #[diplomat::rust_link(icu::locale::LocaleCanonicalizer::new, FnInStruct)] #[diplomat::attr(supports = fallible_constructors, named_constructor = "with_provider")] + #[cfg(feature = "buffer_provider")] pub fn create_with_provider( provider: &DataProvider, ) -> Result, DataError> { - Ok(Box::new(LocaleCanonicalizer(call_constructor!( - icu_locale::LocaleCanonicalizer::new [r => Ok(r)], - icu_locale::LocaleCanonicalizer::try_new_with_any_provider, + Ok(Box::new(LocaleCanonicalizer(provider.call_constructor( icu_locale::LocaleCanonicalizer::try_new_with_buffer_provider, - provider, )?))) } /// Create a new [`LocaleCanonicalizer`] with extended data using compiled data. @@ -59,21 +57,19 @@ pub mod ffi { /// Create a new [`LocaleCanonicalizer`] with extended data. #[diplomat::rust_link(icu::locale::LocaleCanonicalizer::new_with_expander, FnInStruct)] #[diplomat::attr(supports = fallible_constructors, named_constructor = "extended_with_provider")] + #[cfg(feature = "buffer_provider")] pub fn create_extended_with_provider( provider: &DataProvider, ) -> Result, DataError> { - let expander = call_constructor!( - icu_locale::LocaleExpander::new_extended [r => Ok(r)], - icu_locale::LocaleExpander::try_new_with_any_provider, - icu_locale::LocaleExpander::try_new_with_buffer_provider, - provider, - )?; - Ok(Box::new(LocaleCanonicalizer(call_constructor!( - icu_locale::LocaleCanonicalizer::new_with_expander [r => Ok(r)], - icu_locale::LocaleCanonicalizer::try_new_with_expander_with_any_provider, - icu_locale::LocaleCanonicalizer::try_new_with_expander_with_buffer_provider, - provider, - expander + let expander = provider.call_constructor(|provider| { + icu_locale::LocaleExpander::try_new_with_buffer_provider(provider) + })?; + Ok(Box::new(LocaleCanonicalizer(provider.call_constructor( + move |provider| { + icu_locale::LocaleCanonicalizer::try_new_with_expander_with_buffer_provider( + provider, expander, + ) + }, )?))) } #[diplomat::rust_link(icu::locale::LocaleCanonicalizer::canonicalize, FnInStruct)] @@ -98,14 +94,12 @@ pub mod ffi { /// Create a new [`LocaleExpander`] using a particular data source. #[diplomat::rust_link(icu::locale::LocaleExpander::new, FnInStruct)] #[diplomat::attr(supports = fallible_constructors, named_constructor = "with_provider")] + #[cfg(feature = "buffer_provider")] pub fn create_with_provider( provider: &DataProvider, ) -> Result, DataError> { - Ok(Box::new(LocaleExpander(call_constructor!( - icu_locale::LocaleExpander::new [r => Ok(r)], - icu_locale::LocaleExpander::try_new_with_any_provider, + Ok(Box::new(LocaleExpander(provider.call_constructor( icu_locale::LocaleExpander::try_new_with_buffer_provider, - provider, )?))) } /// Create a new [`LocaleExpander`] with extended data using compiled data. @@ -118,14 +112,12 @@ pub mod ffi { /// Create a new [`LocaleExpander`] with extended data using a particular data source. #[diplomat::rust_link(icu::locale::LocaleExpander::new_extended, FnInStruct)] #[diplomat::attr(supports = fallible_constructors, named_constructor = "extended_with_provider")] + #[cfg(feature = "buffer_provider")] pub fn create_extended_with_provider( provider: &DataProvider, ) -> Result, DataError> { - Ok(Box::new(LocaleExpander(call_constructor!( - icu_locale::LocaleExpander::new_extended [r => Ok(r)], - icu_locale::LocaleExpander::try_new_with_any_provider, + Ok(Box::new(LocaleExpander(provider.call_constructor( icu_locale::LocaleExpander::try_new_with_buffer_provider, - provider, )?))) } #[diplomat::rust_link(icu::locale::LocaleExpander::maximize, FnInStruct)] diff --git a/ffi/capi/src/locale_directionality.rs b/ffi/capi/src/locale_directionality.rs index ccf5a316b3e..3a1765281da 100644 --- a/ffi/capi/src/locale_directionality.rs +++ b/ffi/capi/src/locale_directionality.rs @@ -8,12 +8,14 @@ pub mod ffi { use alloc::boxed::Box; - use crate::{ - errors::ffi::DataError, - locale::ffi::LocaleExpander, - locale_core::ffi::Locale, - provider::{ffi::DataProvider, DataProviderInner}, - }; + #[cfg(feature = "buffer_provider")] + use crate::errors::ffi::DataError; + #[cfg(feature = "buffer_provider")] + use crate::provider::{ffi::DataProvider, DataProviderInner}; + + #[cfg(any(feature = "compiled_data", feature = "buffer_provider"))] + use crate::locale::ffi::LocaleExpander; + use crate::locale_core::ffi::Locale; #[diplomat::rust_link(icu::locale::Direction, Enum)] pub enum LocaleDirection { @@ -38,14 +40,12 @@ pub mod ffi { /// Construct a new LocaleDirectionality instance using a particular data source. #[diplomat::rust_link(icu::locale::LocaleDirectionality::new, FnInStruct)] #[diplomat::attr(supports = fallible_constructors, named_constructor = "with_provider")] + #[cfg(feature = "buffer_provider")] pub fn create_with_provider( provider: &DataProvider, ) -> Result, DataError> { - Ok(Box::new(LocaleDirectionality(call_constructor!( - icu_locale::LocaleDirectionality::new [r => Ok(r)], - icu_locale::LocaleDirectionality::try_new_with_any_provider, + Ok(Box::new(LocaleDirectionality(provider.call_constructor( icu_locale::LocaleDirectionality::try_new_with_buffer_provider, - provider, )?))) } @@ -62,6 +62,7 @@ pub mod ffi { /// Construct a new LocaleDirectionality instance with a custom expander and a particular data source. #[diplomat::rust_link(icu::locale::LocaleDirectionality::new_with_expander, FnInStruct)] #[diplomat::attr(supports = fallible_constructors, named_constructor = "with_expander_and_provider")] + #[cfg(feature = "buffer_provider")] pub fn create_with_expander_and_provider( provider: &DataProvider, expander: &LocaleExpander, @@ -72,23 +73,13 @@ pub mod ffi { DataProviderInner::Destroyed => Err(icu_provider::DataError::custom( "This provider has been destroyed", ))?, - DataProviderInner::Empty => { - icu_locale::LocaleDirectionality::try_new_with_expander_unstable( - &icu_provider_adapters::empty::EmptyDataProvider::new(), - expander.0.clone(), - )? - } - #[cfg(feature = "buffer_provider")] + DataProviderInner::Buffer(buffer_provider) => { icu_locale::LocaleDirectionality::try_new_with_expander_unstable( &buffer_provider.as_deserializing(), expander.0.clone(), )? } - #[cfg(feature = "compiled_data")] - DataProviderInner::Compiled => { - icu_locale::LocaleDirectionality::new_with_expander(expander.0.clone()) - } }))) } diff --git a/ffi/capi/src/normalizer.rs b/ffi/capi/src/normalizer.rs index 4653318babb..9b1da84e757 100644 --- a/ffi/capi/src/normalizer.rs +++ b/ffi/capi/src/normalizer.rs @@ -8,6 +8,7 @@ pub mod ffi { use alloc::boxed::Box; + #[cfg(feature = "buffer_provider")] use crate::{errors::ffi::DataError, provider::ffi::DataProvider}; #[diplomat::opaque] @@ -39,14 +40,14 @@ pub mod ffi { hidden )] #[diplomat::attr(supports = fallible_constructors, named_constructor = "nfc_with_provider")] + #[cfg(feature = "buffer_provider")] pub fn create_nfc_with_provider( provider: &DataProvider, ) -> Result, DataError> { - Ok(Box::new(ComposingNormalizer(call_constructor!( - icu_normalizer::ComposingNormalizer::new_nfc [r => Ok(r.static_to_owned())], - icu_normalizer::ComposingNormalizer::try_new_nfc_with_any_provider, - icu_normalizer::ComposingNormalizer::try_new_nfc_with_buffer_provider, - provider, + Ok(Box::new(ComposingNormalizer(provider.call_constructor( + |provider| { + icu_normalizer::ComposingNormalizer::try_new_nfc_with_buffer_provider(provider) + }, )?))) } /// Construct a new ComposingNormalizer instance for NFKC using compiled data. @@ -71,14 +72,14 @@ pub mod ffi { hidden )] #[diplomat::attr(supports = fallible_constructors, named_constructor = "nfkc_with_provider")] + #[cfg(feature = "buffer_provider")] pub fn create_nfkc_with_provider( provider: &DataProvider, ) -> Result, DataError> { - Ok(Box::new(ComposingNormalizer(call_constructor!( - icu_normalizer::ComposingNormalizer::new_nfkc [r => Ok(r.static_to_owned())], - icu_normalizer::ComposingNormalizer::try_new_nfkc_with_any_provider, - icu_normalizer::ComposingNormalizer::try_new_nfkc_with_buffer_provider, - provider, + Ok(Box::new(ComposingNormalizer(provider.call_constructor( + |provider| { + icu_normalizer::ComposingNormalizer::try_new_nfkc_with_buffer_provider(provider) + }, )?))) } /// Normalize a string @@ -199,14 +200,16 @@ pub mod ffi { hidden )] #[diplomat::attr(supports = fallible_constructors, named_constructor = "nfd_with_provider")] + #[cfg(feature = "buffer_provider")] pub fn create_nfd_with_provider( provider: &DataProvider, ) -> Result, DataError> { - Ok(Box::new(DecomposingNormalizer(call_constructor!( - icu_normalizer::DecomposingNormalizer::new_nfd [r => Ok(r.static_to_owned())], - icu_normalizer::DecomposingNormalizer::try_new_nfd_with_any_provider, - icu_normalizer::DecomposingNormalizer::try_new_nfd_with_buffer_provider, - provider, + Ok(Box::new(DecomposingNormalizer(provider.call_constructor( + |provider| { + icu_normalizer::DecomposingNormalizer::try_new_nfd_with_buffer_provider( + provider, + ) + }, )?))) } @@ -233,14 +236,16 @@ pub mod ffi { hidden )] #[diplomat::attr(supports = fallible_constructors, named_constructor = "nfkd_with_provider")] + #[cfg(feature = "buffer_provider")] pub fn create_nfkd_with_provider( provider: &DataProvider, ) -> Result, DataError> { - Ok(Box::new(DecomposingNormalizer(call_constructor!( - icu_normalizer::DecomposingNormalizer::new_nfkd [r => Ok(r.static_to_owned())], - icu_normalizer::DecomposingNormalizer::try_new_nfkd_with_any_provider, - icu_normalizer::DecomposingNormalizer::try_new_nfkd_with_buffer_provider, - provider, + Ok(Box::new(DecomposingNormalizer(provider.call_constructor( + |provider| { + icu_normalizer::DecomposingNormalizer::try_new_nfkd_with_buffer_provider( + provider, + ) + }, )?))) } diff --git a/ffi/capi/src/normalizer_properties.rs b/ffi/capi/src/normalizer_properties.rs index 12e5f39edbc..046fbb89a63 100644 --- a/ffi/capi/src/normalizer_properties.rs +++ b/ffi/capi/src/normalizer_properties.rs @@ -8,6 +8,7 @@ pub mod ffi { use alloc::boxed::Box; + #[cfg(feature = "buffer_provider")] use crate::{errors::ffi::DataError, provider::ffi::DataProvider}; /// Lookup of the Canonical_Combining_Class Unicode property @@ -52,15 +53,11 @@ pub mod ffi { hidden )] #[diplomat::attr(supports = fallible_constructors, named_constructor = "with_provider")] + #[cfg(feature = "buffer_provider")] pub fn create_with_provider( provider: &DataProvider, ) -> Result, DataError> { - Ok(Box::new(CanonicalCombiningClassMap(call_constructor!( - icu_normalizer::properties::CanonicalCombiningClassMap::new [r => Ok(r.static_to_owned())], - icu_normalizer::properties::CanonicalCombiningClassMap::try_new_with_any_provider, - icu_normalizer::properties::CanonicalCombiningClassMap::try_new_with_buffer_provider, - provider - )?))) + Ok(Box::new(CanonicalCombiningClassMap(provider.call_constructor(icu_normalizer::properties::CanonicalCombiningClassMap::try_new_with_buffer_provider)?))) } #[diplomat::rust_link( @@ -129,14 +126,16 @@ pub mod ffi { hidden )] #[diplomat::attr(supports = fallible_constructors, named_constructor = "with_provider")] + #[cfg(feature = "buffer_provider")] pub fn create_with_provider( provider: &DataProvider, ) -> Result, DataError> { - Ok(Box::new(CanonicalComposition(call_constructor!( - icu_normalizer::properties::CanonicalComposition::new [r => Ok(r.static_to_owned())], - icu_normalizer::properties::CanonicalComposition::try_new_with_any_provider, - icu_normalizer::properties::CanonicalComposition::try_new_with_buffer_provider, - provider, + Ok(Box::new(CanonicalComposition(provider.call_constructor( + |provider| { + icu_normalizer::properties::CanonicalComposition::try_new_with_buffer_provider( + provider, + ) + }, )?))) } @@ -201,15 +200,11 @@ pub mod ffi { hidden )] #[diplomat::attr(supports = fallible_constructors, named_constructor = "with_provider")] + #[cfg(feature = "buffer_provider")] pub fn create_with_provider( provider: &DataProvider, ) -> Result, DataError> { - Ok(Box::new(CanonicalDecomposition(call_constructor!( - icu_normalizer::properties::CanonicalDecomposition::new [r => Ok(r.static_to_owned())], - icu_normalizer::properties::CanonicalDecomposition::try_new_with_any_provider, - icu_normalizer::properties::CanonicalDecomposition::try_new_with_buffer_provider, - provider, - )?))) + Ok(Box::new(CanonicalDecomposition(provider.call_constructor(icu_normalizer::properties::CanonicalDecomposition::try_new_with_buffer_provider)?))) } /// Performs non-recursive canonical decomposition (including for Hangul). diff --git a/ffi/capi/src/pluralrules.rs b/ffi/capi/src/pluralrules.rs index f0fe7801abb..6086c7e33a9 100644 --- a/ffi/capi/src/pluralrules.rs +++ b/ffi/capi/src/pluralrules.rs @@ -8,9 +8,12 @@ pub mod ffi { use alloc::boxed::Box; + #[cfg(any(feature = "compiled_data", feature = "buffer_provider"))] use crate::errors::ffi::DataError; use crate::errors::ffi::FixedDecimalParseError; + #[cfg(any(feature = "compiled_data", feature = "buffer_provider"))] use crate::locale_core::ffi::Locale; + #[cfg(feature = "buffer_provider")] use crate::provider::ffi::DataProvider; #[diplomat::rust_link(icu::plurals::PluralCategory, Enum)] @@ -56,17 +59,16 @@ pub mod ffi { #[diplomat::rust_link(icu::plurals::PluralRules::try_new, FnInStruct, hidden)] #[diplomat::rust_link(icu::plurals::PluralRuleType, Enum, hidden)] #[diplomat::attr(supports = fallible_constructors, named_constructor = "cardinal_with_provider")] + #[cfg(feature = "buffer_provider")] pub fn create_cardinal_with_provider( provider: &DataProvider, locale: &Locale, ) -> Result, DataError> { let prefs = icu_plurals::PluralRulesPreferences::from(&locale.0); - Ok(Box::new(PluralRules(call_constructor!( - icu_plurals::PluralRules::try_new_cardinal, - icu_plurals::PluralRules::try_new_cardinal_with_any_provider, - icu_plurals::PluralRules::try_new_cardinal_with_buffer_provider, - provider, - prefs + Ok(Box::new(PluralRules(provider.call_constructor( + |provider| { + icu_plurals::PluralRules::try_new_cardinal_with_buffer_provider(provider, prefs) + }, )?))) } /// Construct an [`PluralRules`] for the given locale, for ordinal numbers, using compiled data. @@ -86,17 +88,16 @@ pub mod ffi { #[diplomat::rust_link(icu::plurals::PluralRules::try_new, FnInStruct, hidden)] #[diplomat::rust_link(icu::plurals::PluralRuleType, Enum, hidden)] #[diplomat::attr(supports = fallible_constructors, named_constructor = "ordinal_with_provider")] + #[cfg(feature = "buffer_provider")] pub fn create_ordinal_with_provider( provider: &DataProvider, locale: &Locale, ) -> Result, DataError> { let prefs = icu_plurals::PluralRulesPreferences::from(&locale.0); - Ok(Box::new(PluralRules(call_constructor!( - icu_plurals::PluralRules::try_new_ordinal, - icu_plurals::PluralRules::try_new_ordinal_with_any_provider, - icu_plurals::PluralRules::try_new_ordinal_with_buffer_provider, - provider, - prefs + Ok(Box::new(PluralRules(provider.call_constructor( + |provider| { + icu_plurals::PluralRules::try_new_ordinal_with_buffer_provider(provider, prefs) + }, )?))) } /// Get the category for a given number represented as operands diff --git a/ffi/capi/src/properties_maps.rs b/ffi/capi/src/properties_maps.rs index f1fea94fe51..16f632fb7da 100644 --- a/ffi/capi/src/properties_maps.rs +++ b/ffi/capi/src/properties_maps.rs @@ -7,16 +7,17 @@ #[diplomat::attr(auto, namespace = "icu4x")] pub mod ffi { use alloc::boxed::Box; + #[cfg(any(feature = "compiled_data", feature = "buffer_provider"))] use icu_properties::props::{ BidiClass, CanonicalCombiningClass, EastAsianWidth, GeneralCategory, GraphemeClusterBreak, HangulSyllableType, IndicSyllabicCategory, JoiningType, LineBreak, Script, SentenceBreak, WordBreak, }; - use crate::errors::ffi::DataError; use crate::properties_iter::ffi::CodePointRangeIterator; use crate::properties_sets::ffi::CodePointSetData; - use crate::provider::ffi::DataProvider; + #[cfg(feature = "buffer_provider")] + use crate::{errors::ffi::DataError, provider::ffi::DataProvider}; #[diplomat::opaque] /// An ICU4X Unicode Map Property object, capable of querying whether a code point (key) to obtain the Unicode property value, for a specific Unicode property. @@ -34,6 +35,7 @@ pub mod ffi { )] pub struct CodePointMapData8(icu_properties::CodePointMapData); + #[cfg(any(feature = "compiled_data", feature = "buffer_provider"))] fn convert_8( data: icu_properties::CodePointMapData

, ) -> Box { @@ -139,11 +141,11 @@ pub mod ffi { /// Create a map for the `General_Category` property, using a particular data source #[diplomat::rust_link(icu::properties::props::GeneralCategory, Enum)] #[diplomat::attr(supports = fallible_constructors, named_constructor = "general_category_with_provider")] + #[cfg(feature = "buffer_provider")] pub fn create_general_category_with_provider( provider: &DataProvider, ) -> Result, DataError> { Ok(convert_8(call_constructor_unstable!( - icu_properties::CodePointMapData::::new [r => Ok(r.static_to_owned())], icu_properties::CodePointMapData::::try_new_unstable, provider, )?)) @@ -160,11 +162,11 @@ pub mod ffi { /// Create a map for the `Bidi_Class` property, using a particular data source. #[diplomat::rust_link(icu::properties::props::BidiClass, Struct)] #[diplomat::attr(supports = fallible_constructors, named_constructor = "bidi_class_with_provider")] + #[cfg(feature = "buffer_provider")] pub fn create_bidi_class_with_provider( provider: &DataProvider, ) -> Result, DataError> { Ok(convert_8(call_constructor_unstable!( - icu_properties::CodePointMapData::::new [r => Ok(r.static_to_owned())], icu_properties::CodePointMapData::::try_new_unstable, provider, )?)) @@ -180,11 +182,11 @@ pub mod ffi { /// Create a map for the `East_Asian_Width` property, using a particular data source. #[diplomat::rust_link(icu::properties::props::EastAsianWidth, Struct)] #[diplomat::attr(supports = fallible_constructors, named_constructor = "east_asian_width_with_provider")] + #[cfg(feature = "buffer_provider")] pub fn create_east_asian_width_with_provider( provider: &DataProvider, ) -> Result, DataError> { Ok(convert_8(call_constructor_unstable!( - icu_properties::CodePointMapData::::new [r => Ok(r.static_to_owned())], icu_properties::CodePointMapData::::try_new_unstable, provider, )?)) @@ -201,11 +203,11 @@ pub mod ffi { /// Create a map for the `Hangul_Syllable_Type` property, using a particular data source. #[diplomat::rust_link(icu::properties::props::HangulSyllableType, Struct)] #[diplomat::attr(supports = fallible_constructors, named_constructor = "hangul_syllable_type_with_provider")] + #[cfg(feature = "buffer_provider")] pub fn create_hangul_syllable_type_with_provider( provider: &DataProvider, ) -> Result, DataError> { Ok(convert_8(call_constructor_unstable!( - icu_properties::CodePointMapData::::new [r => Ok(r.static_to_owned())], icu_properties::CodePointMapData::::try_new_unstable, provider, )?)) @@ -222,11 +224,11 @@ pub mod ffi { /// Create a map for the `Indic_Syllabic_Property` property, using a particular data source. #[diplomat::rust_link(icu::properties::props::IndicSyllabicCategory, Struct)] #[diplomat::attr(supports = fallible_constructors, named_constructor = "indic_syllabic_category_with_provider")] + #[cfg(feature = "buffer_provider")] pub fn create_indic_syllabic_category_with_provider( provider: &DataProvider, ) -> Result, DataError> { Ok(convert_8(call_constructor_unstable!( - icu_properties::CodePointMapData::::new [r => Ok(r.static_to_owned())], icu_properties::CodePointMapData::::try_new_unstable, provider, )?)) @@ -241,11 +243,11 @@ pub mod ffi { /// Create a map for the `Line_Break` property, using a particular data source. #[diplomat::rust_link(icu::properties::props::LineBreak, Struct)] #[diplomat::attr(supports = fallible_constructors, named_constructor = "line_break_with_provider")] + #[cfg(feature = "buffer_provider")] pub fn create_line_break_with_provider( provider: &DataProvider, ) -> Result, DataError> { Ok(convert_8(call_constructor_unstable!( - icu_properties::CodePointMapData::::new [r => Ok(r.static_to_owned())], icu_properties::CodePointMapData::::try_new_unstable, provider, )?)) @@ -262,11 +264,11 @@ pub mod ffi { /// Create a map for the `Grapheme_Cluster_Break` property, using a particular data source. #[diplomat::rust_link(icu::properties::props::GraphemeClusterBreak, Struct)] #[diplomat::attr(supports = fallible_constructors, named_constructor = "grapheme_cluster_break_with_provider")] + #[cfg(feature = "buffer_provider")] pub fn create_grapheme_cluster_break_with_provider( provider: &DataProvider, ) -> Result, DataError> { Ok(convert_8(call_constructor_unstable!( - icu_properties::CodePointMapData::::new [r => Ok(r.static_to_owned())], icu_properties::CodePointMapData::::try_new_unstable, provider, )?)) @@ -281,11 +283,11 @@ pub mod ffi { /// Create a map for the `Word_Break` property, using a particular data source. #[diplomat::rust_link(icu::properties::props::WordBreak, Struct)] #[diplomat::attr(supports = fallible_constructors, named_constructor = "word_break_with_provider")] + #[cfg(feature = "buffer_provider")] pub fn create_word_break_with_provider( provider: &DataProvider, ) -> Result, DataError> { Ok(convert_8(call_constructor_unstable!( - icu_properties::CodePointMapData::::new [r => Ok(r.static_to_owned())], icu_properties::CodePointMapData::::try_new_unstable, provider, )?)) @@ -300,11 +302,11 @@ pub mod ffi { /// Create a map for the `Sentence_Break` property, using a particular data source. #[diplomat::rust_link(icu::properties::props::SentenceBreak, Struct)] #[diplomat::attr(supports = fallible_constructors, named_constructor = "sentence_break_with_provider")] + #[cfg(feature = "buffer_provider")] pub fn create_sentence_break_with_provider( provider: &DataProvider, ) -> Result, DataError> { Ok(convert_8(call_constructor_unstable!( - icu_properties::CodePointMapData::::new [r => Ok(r.static_to_owned())], icu_properties::CodePointMapData::::try_new_unstable, provider, )?)) @@ -320,11 +322,11 @@ pub mod ffi { /// Create a map for the `Joining_Type` property, using a particular data source. #[diplomat::rust_link(icu::properties::props::JoiningType, Struct)] #[diplomat::attr(supports = fallible_constructors, named_constructor = "joining_type_with_provider")] + #[cfg(feature = "buffer_provider")] pub fn create_joining_type_with_provider( provider: &DataProvider, ) -> Result, DataError> { Ok(convert_8(call_constructor_unstable!( - icu_properties::CodePointMapData::::new [r => Ok(r.static_to_owned())], icu_properties::CodePointMapData::::try_new_unstable, provider, )?)) @@ -342,11 +344,11 @@ pub mod ffi { /// Create a map for the `Canonical_Combining_Class` property, using a particular data source. #[diplomat::rust_link(icu::properties::props::CanonicalCombiningClass, Struct)] #[diplomat::attr(supports = fallible_constructors, named_constructor = "canonical_combining_class_with_provider")] + #[cfg(feature = "buffer_provider")] pub fn create_canonical_combining_class_with_provider( provider: &DataProvider, ) -> Result, DataError> { Ok(convert_8(call_constructor_unstable!( - icu_properties::CodePointMapData::::new [r => Ok(r.static_to_owned())], icu_properties::CodePointMapData::::try_new_unstable, provider, )?)) @@ -426,13 +428,13 @@ pub mod ffi { /// Create a map for the `Script` property, using a particular data source. #[diplomat::rust_link(icu::properties::props::Script, Struct)] #[diplomat::attr(supports = fallible_constructors, named_constructor = "script_with_provider")] + #[cfg(feature = "buffer_provider")] pub fn create_script_with_provider( provider: &DataProvider, ) -> Result, DataError> { #[allow(clippy::unwrap_used)] // script is a 16-bit property Ok(Box::new(CodePointMapData16( call_constructor_unstable!( - icu_properties::CodePointMapData::