Closed sffc closed 2 years ago
Discussion:
Things we need to do with constructors:
Discussion with @sffc @Manishearth:
It appears that #1833 still has unresolved questions.
In light of that, let me be clear on what I am proposing for constructor signatures in ICU4X 1.0.
In Rust:
impl FooFormat {
pub fn try_new_any(p: &P, locale: &DataLocale, options: FooOptions)
-> Result<FooFormat, DataError>
where
P: AnyProvider
pub fn try_new_buffer(p: &P, locale: &DataLocale, options: FooOptions)
-> Result<FooFormat, DataError>
where
P: BufferProvider
pub fn try_new_unstable(p: &P, locale: &DataLocale, options: FooOptions)
-> Result<FooFormat, DataError>
where
P: ResourceProvider<Marker1> + ResourceProvider<Marker2>
}
#[non_exhaustive]
pub struct FooOptions {
pub option1: i32,
// ...
}
In FFI:
class ICU4XFooFormat {
public:
DiplomatResult<FooFormat, DataError> try_new_any(
const ICU4XAnyProvider& provider,
const ICU4XDataLocale& locale,
const ICU4XFooOptions& options
);
DiplomatResult<FooFormat, DataError> try_new_buffer(
const ICU4XBufferProvider& provider,
const ICU4XDataLocale& locale,
const ICU4XFooOptions& options
);
}
class ICU4XFooOptions; // opaque
I should also note a potential path for Rust constructors involving traits
trait TryNewBufferProvider<O> {
fn try_new(locale: DataLocale, p: &impl BufferProvider, options: O)
}
impl TryFromBufferProvider<FooOptions> for FooFormat { ... }
Into<DataLocale>
?.into()
from anything that implements it.Consensus: No objection to what I proposed in https://github.com/unicode-org/icu4x/issues/2136#issuecomment-1183797247.
I reviewed all component and property APIs. To-do list:
&provider
the first argumenticu_decimal::error
module should be private (the error type is re-exported)try_new_...
try_new_...
CustomTimeZone::try_set_metazone
does not return a Result so it is a misnomerQuestions:
icu_decimal::provider
: should all the types be labled "V1" or only the main one?icu_list::List
: should it be named FormattedList?icu_provider::serde::borrow_de_utils
be doc-hidden?For FFI purposes, it would make things a lot simpler if we had just one provider type. It would be an enum between a buffer provider and an any provider.
This doesn't solve Serde code size issues directly, but we can circumvent that problem by having a feature on the icu_capi
crate to enable or disable the BufferProvider version of it.
Hmmm. Not ideal but I guess it works.
None of our choices are ideal:
We have some precedent of using features to reduce code size (deserialize_json
). So I think it's fine.
We could even do the same thing on the Rust side to get from 3 constructors down to 2 constructors. But I'm not proposing that we do that in 1.0. We should consider it for 2.0 alongside the new Preferences stuff.
Proposal: Have a single ICU4XDataProvider with features to independently enable the AnyProvider and the BufferProvider versions.
LGTM: @robertbastian @Manishearth @sffc @nordzilla
This is finally fixed.
In #1833 we're starting to establish a pattern for constructor signatures in Rust. I want to establish how that extends to FFI.
There are some constraints that apply to FFI but not Rust:
* Diplomat itself could be extended to reduce duplication and improve code maintainability/readability on an as-needed basis.
I'm going to approach this question assuming that constructors typically take 3 parameters: locale/preferences, data provider, and configuration options.
I. Locale/Preferences
Options:
Locale
objectLocale
which may harm code size and/or type safetyDataLocale
object (#1995)II. Data Provider
Options:
AnyProvider
and one forBufferProvider
FixedDecimalFormatProvider
III. Configuration Options
Options:
Thoughts? @zbraniecki @Manishearth @robertbastian