diff --git a/Cargo.lock b/Cargo.lock index 32be453572c..3320eed67c6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1066,6 +1066,7 @@ dependencies = [ "icu_locid", "icu_locid_macros", "icu_plurals", + "icu_properties", "icu_provider", "icu_provider_blob", "icu_provider_fs", diff --git a/components/properties/src/maps.rs b/components/properties/src/maps.rs index 1fb51b7c854..cb677723931 100644 --- a/components/properties/src/maps.rs +++ b/components/properties/src/maps.rs @@ -18,7 +18,9 @@ use crate::*; use icu_codepointtrie::TrieValue; use icu_provider::prelude::*; -type CodePointMapResult = Result>, PropertiesError>; +/// TODO(#1239): Finalize this API. +pub type CodePointMapResult = + Result>, PropertiesError>; fn get_cp_map(provider: &D, resc_key: ResourceKey) -> CodePointMapResult where diff --git a/components/properties/src/sets.rs b/components/properties/src/sets.rs index d9bc9fccd44..9470b7b00fa 100644 --- a/components/properties/src/sets.rs +++ b/components/properties/src/sets.rs @@ -19,7 +19,8 @@ use crate::provider::*; use crate::*; use icu_provider::prelude::*; -type UnisetResult = Result, PropertiesError>; +/// TODO(#1239): Finalize this API. +pub type UnisetResult = Result, PropertiesError>; // helper fn fn get_uniset(provider: &D, resc_key: ResourceKey) -> UnisetResult diff --git a/ffi/diplomat/Cargo.toml b/ffi/diplomat/Cargo.toml index 09bfe6db362..6669a9c4184 100644 --- a/ffi/diplomat/Cargo.toml +++ b/ffi/diplomat/Cargo.toml @@ -64,6 +64,7 @@ icu_locale_canonicalizer = { path = "../../components/locale_canonicalizer" } icu_locid = { path = "../../components/locid" } icu_locid_macros = { path = "../../components/locid/macros" } icu_plurals = { path = "../../components/plurals/" } +icu_properties = { path = "../../components/properties/" } icu_provider = { path = "../../provider/core", features = ["provider_serde"] } icu_provider_blob = { path = "../../provider/blob" } tinystr = { version = "0.4.10", features = ["alloc"], default-features = false } diff --git a/ffi/diplomat/c/include/ICU4XCodePointMapData16.h b/ffi/diplomat/c/include/ICU4XCodePointMapData16.h new file mode 100644 index 00000000000..471611af21a --- /dev/null +++ b/ffi/diplomat/c/include/ICU4XCodePointMapData16.h @@ -0,0 +1,28 @@ +#ifndef ICU4XCodePointMapData16_H +#define ICU4XCodePointMapData16_H +#include +#include +#include +#include +#include "diplomat_runtime.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct ICU4XCodePointMapData16 ICU4XCodePointMapData16; +#include "ICU4XDataProvider.h" +#include "ICU4XCodePointMapData16Response.h" +#include "ICU4XStaticDataProvider.h" + +ICU4XCodePointMapData16Response ICU4XCodePointMapData16_try_get_script(const ICU4XDataProvider* provider); + +ICU4XCodePointMapData16Response ICU4XCodePointMapData16_try_get_script_from_static(const ICU4XStaticDataProvider* provider); + +uint16_t ICU4XCodePointMapData16_get(const ICU4XCodePointMapData16* self, char32_t cp); +void ICU4XCodePointMapData16_destroy(ICU4XCodePointMapData16* self); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/ffi/diplomat/c/include/ICU4XCodePointMapData16Response.h b/ffi/diplomat/c/include/ICU4XCodePointMapData16Response.h new file mode 100644 index 00000000000..8b494bc5bc2 --- /dev/null +++ b/ffi/diplomat/c/include/ICU4XCodePointMapData16Response.h @@ -0,0 +1,24 @@ +#ifndef ICU4XCodePointMapData16Response_H +#define ICU4XCodePointMapData16Response_H +#include +#include +#include +#include +#include "diplomat_runtime.h" + +#ifdef __cplusplus +extern "C" { +#endif +typedef struct ICU4XCodePointMapData16 ICU4XCodePointMapData16; + +typedef struct ICU4XCodePointMapData16Response { + ICU4XCodePointMapData16* data; + bool success; +} ICU4XCodePointMapData16Response; + +void ICU4XCodePointMapData16Response_destroy(ICU4XCodePointMapData16Response* self); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/ffi/diplomat/c/include/ICU4XCodePointSetData.h b/ffi/diplomat/c/include/ICU4XCodePointSetData.h new file mode 100644 index 00000000000..b2660ee1c11 --- /dev/null +++ b/ffi/diplomat/c/include/ICU4XCodePointSetData.h @@ -0,0 +1,28 @@ +#ifndef ICU4XCodePointSetData_H +#define ICU4XCodePointSetData_H +#include +#include +#include +#include +#include "diplomat_runtime.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct ICU4XCodePointSetData ICU4XCodePointSetData; +#include "ICU4XDataProvider.h" +#include "ICU4XCodePointSetDataResult.h" +#include "ICU4XStaticDataProvider.h" + +ICU4XCodePointSetDataResult ICU4XCodePointSetData_try_get_ascii_hex_digit(const ICU4XDataProvider* provider); + +ICU4XCodePointSetDataResult ICU4XCodePointSetData_try_get_ascii_hex_digit_from_static(const ICU4XStaticDataProvider* provider); + +bool ICU4XCodePointSetData_contains(const ICU4XCodePointSetData* self, char32_t cp); +void ICU4XCodePointSetData_destroy(ICU4XCodePointSetData* self); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/ffi/diplomat/c/include/ICU4XCodePointSetDataResult.h b/ffi/diplomat/c/include/ICU4XCodePointSetDataResult.h new file mode 100644 index 00000000000..c43112bc564 --- /dev/null +++ b/ffi/diplomat/c/include/ICU4XCodePointSetDataResult.h @@ -0,0 +1,24 @@ +#ifndef ICU4XCodePointSetDataResult_H +#define ICU4XCodePointSetDataResult_H +#include +#include +#include +#include +#include "diplomat_runtime.h" + +#ifdef __cplusplus +extern "C" { +#endif +typedef struct ICU4XCodePointSetData ICU4XCodePointSetData; + +typedef struct ICU4XCodePointSetDataResult { + ICU4XCodePointSetData* data; + bool success; +} ICU4XCodePointSetDataResult; + +void ICU4XCodePointSetDataResult_destroy(ICU4XCodePointSetDataResult* self); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/ffi/diplomat/cpp/docs/source/index.rst b/ffi/diplomat/cpp/docs/source/index.rst index dc6af180669..dfa36aa56ed 100644 --- a/ffi/diplomat/cpp/docs/source/index.rst +++ b/ffi/diplomat/cpp/docs/source/index.rst @@ -10,6 +10,8 @@ Documentation locale_canonicalizer_ffi locale_ffi pluralrules_ffi + properties_maps_ffi + properties_sets_ffi provider_ffi Indices and tables diff --git a/ffi/diplomat/cpp/docs/source/properties_maps_ffi.rst b/ffi/diplomat/cpp/docs/source/properties_maps_ffi.rst new file mode 100644 index 00000000000..3ed023b09b5 --- /dev/null +++ b/ffi/diplomat/cpp/docs/source/properties_maps_ffi.rst @@ -0,0 +1,28 @@ +``properties_maps::ffi`` +======================== + +.. cpp:class:: ICU4XCodePointMapData16 + + An ICU4X Unicode Set Property object, capable of querying whether a code point is contained in a set based on a Unicode property. For properties whose values fit into 16 bits. See `the Rust docs `__ for more information. + + .. cpp:function:: static ICU4XCodePointMapData16Response try_get_script(const ICU4XDataProvider& provider) + + Gets a map for Unicode property Script from a :cpp:class:`ICU4XDataProvider`. See `the Rust docs `__ for more information. + + .. cpp:function:: static ICU4XCodePointMapData16Response try_get_script_from_static(const ICU4XStaticDataProvider& provider) + + Gets a map for Unicode property Script from a :cpp:class:`ICU4XStaticDataProvider`. See `the Rust docs `__ for more information. + + .. cpp:function:: uint16_t get(char32_t cp) const + + Gets the value for a code point. See `the Rust docs `__ for more information. + +.. cpp:struct:: ICU4XCodePointMapData16Response + + .. cpp:member:: std::optional data + + The :cpp:class:`ICU4XCodePointMapData16`, if creation was successful. + + .. cpp:member:: bool success + + Whether creating the :cpp:class:`ICU4XCodePointMapData16` was successful. diff --git a/ffi/diplomat/cpp/docs/source/properties_sets_ffi.rst b/ffi/diplomat/cpp/docs/source/properties_sets_ffi.rst new file mode 100644 index 00000000000..e6721edb9d8 --- /dev/null +++ b/ffi/diplomat/cpp/docs/source/properties_sets_ffi.rst @@ -0,0 +1,28 @@ +``properties_sets::ffi`` +======================== + +.. cpp:class:: ICU4XCodePointSetData + + An ICU4X Unicode Set Property object, capable of querying whether a code point is contained in a set based on a Unicode property. See `the Rust docs `__ for more information. + + .. cpp:function:: static ICU4XCodePointSetDataResult try_get_ascii_hex_digit(const ICU4XDataProvider& provider) + + Gets a set for Unicode property ascii_hex_digit from a :cpp:class:`ICU4XDataProvider`. See `the Rust docs `__ for more information. + + .. cpp:function:: static ICU4XCodePointSetDataResult try_get_ascii_hex_digit_from_static(const ICU4XStaticDataProvider& provider) + + Gets a set for Unicode property ascii_hex_digit from a :cpp:class:`ICU4XStaticDataProvider`. See `the Rust docs `__ for more information. + + .. cpp:function:: bool contains(char32_t cp) const + + Checks whether the code point is in the set. See `the Rust docs `__ for more information. + +.. cpp:struct:: ICU4XCodePointSetDataResult + + .. cpp:member:: std::optional data + + The :cpp:class:`ICU4XCodePointSetData`, if creation was successful. + + .. cpp:member:: bool success + + Whether creating the :cpp:class:`ICU4XCodePointSetData` was successful. diff --git a/ffi/diplomat/cpp/examples/properties/.gitignore b/ffi/diplomat/cpp/examples/properties/.gitignore new file mode 100644 index 00000000000..cb34c546b3b --- /dev/null +++ b/ffi/diplomat/cpp/examples/properties/.gitignore @@ -0,0 +1,2 @@ +a.out +a.out.dSYM diff --git a/ffi/diplomat/cpp/examples/properties/Makefile b/ffi/diplomat/cpp/examples/properties/Makefile new file mode 100644 index 00000000000..864edeaa29c --- /dev/null +++ b/ffi/diplomat/cpp/examples/properties/Makefile @@ -0,0 +1,27 @@ +# This file is part of ICU4X. For terms of use, please see the file +# called LICENSE at the top level of the ICU4X source tree +# (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ). + +.DEFAULT_GOAL := test +.PHONY: build test + +ALL_HEADERS := $(wildcard ../../include/*.hpp) $(wildcard ../../../c/include/*.h) +ALL_RUST := $(wildcard ../../../src/*.rs) + +CXX?=g++ + +$(ALL_RUST): + +$(ALL_HEADERS): + + +../../../../../target/debug/libicu_capi.a: $(ALL_RUST) + cargo build -p icu_capi + +a.out: ../../../../../target/debug/libicu_capi.a $(ALL_HEADERS) test.cpp + $(CXX) -std=c++17 test.cpp ../../../../../target/debug/libicu_capi.a -ldl -lpthread -lm -g + +build: a.out + +test: build + ./a.out diff --git a/ffi/diplomat/cpp/examples/properties/test.cpp b/ffi/diplomat/cpp/examples/properties/test.cpp new file mode 100644 index 00000000000..964227b24b6 --- /dev/null +++ b/ffi/diplomat/cpp/examples/properties/test.cpp @@ -0,0 +1,69 @@ +// This file is part of ICU4X. For terms of use, please see the file +// called LICENSE at the top level of the ICU4X source tree +// (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ). + +#include "../../include/ICU4XCodePointSetData.hpp" +#include "../../include/ICU4XCodePointMapData16.hpp" +#include "../../include/ICU4XCodePointMapData16Response.hpp" + +#include + +const std::string_view path = "../../../../../provider/testdata/data/json/"; + +int test_set_property(ICU4XCodePointSetDataResult result, char32_t included, char32_t excluded) { + if (!result.success) { + std::cout << "Failed to create ICU4XCodePointSetData" << std::endl; + return 1; + } + bool contains1 = result.data.value().contains(included); + bool contains2 = result.data.value().contains(excluded); + std::cout << std::hex; // print hex for U+#### + if (contains1 && !contains2) { + std::cout << "Set correctly contains U+" << included << " and not U+" << excluded << std::endl; + } else { + std::cout << "Set returns wrong result on U+" << included << " or U+" << excluded << std::endl; + return 1; + } + return 0; +} + +int test_map_16_property(ICU4XCodePointMapData16Response result, char32_t sample, uint32_t expected) { + if (!result.success) { + std::cout << "Failed to create ICU4XCodePointMapData16" << std::endl; + return 1; + } + uint32_t actual = result.data.value().get(sample); + std::cout << std::hex; // print hex for U+#### + if (actual == expected) { + std::cout << "Code point U+" << sample << " correctly mapped to 0x" << actual << std::endl; + } else { + std::cout << "Code point U+" << sample << " incorrectly mapped to 0x" << actual << std::endl; + return 1; + } + return 0; +} + +int main() { + ICU4XDataProvider dp = ICU4XDataProvider::create_fs(path).provider.value(); + int result; + + result = test_set_property( + ICU4XCodePointSetData::try_get_ascii_hex_digit(dp), + u'3', + u'੩' + ); + if (result != 0) { + return result; + } + + result = test_map_16_property( + ICU4XCodePointMapData16::try_get_script(dp), + u'木', + 17 // Script::Han + ); + if (result != 0) { + return result; + } + + return 0; +} diff --git a/ffi/diplomat/cpp/include/ICU4XCodePointMapData16.h b/ffi/diplomat/cpp/include/ICU4XCodePointMapData16.h new file mode 100644 index 00000000000..471611af21a --- /dev/null +++ b/ffi/diplomat/cpp/include/ICU4XCodePointMapData16.h @@ -0,0 +1,28 @@ +#ifndef ICU4XCodePointMapData16_H +#define ICU4XCodePointMapData16_H +#include +#include +#include +#include +#include "diplomat_runtime.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct ICU4XCodePointMapData16 ICU4XCodePointMapData16; +#include "ICU4XDataProvider.h" +#include "ICU4XCodePointMapData16Response.h" +#include "ICU4XStaticDataProvider.h" + +ICU4XCodePointMapData16Response ICU4XCodePointMapData16_try_get_script(const ICU4XDataProvider* provider); + +ICU4XCodePointMapData16Response ICU4XCodePointMapData16_try_get_script_from_static(const ICU4XStaticDataProvider* provider); + +uint16_t ICU4XCodePointMapData16_get(const ICU4XCodePointMapData16* self, char32_t cp); +void ICU4XCodePointMapData16_destroy(ICU4XCodePointMapData16* self); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/ffi/diplomat/cpp/include/ICU4XCodePointMapData16.hpp b/ffi/diplomat/cpp/include/ICU4XCodePointMapData16.hpp new file mode 100644 index 00000000000..bed58fa9992 --- /dev/null +++ b/ffi/diplomat/cpp/include/ICU4XCodePointMapData16.hpp @@ -0,0 +1,85 @@ +#ifndef ICU4XCodePointMapData16_HPP +#define ICU4XCodePointMapData16_HPP +#include +#include +#include +#include +#include +#include +#include +#include +#include "diplomat_runtime.hpp" + +namespace capi { +#include "ICU4XCodePointMapData16.h" +} + +class ICU4XDataProvider; +struct ICU4XCodePointMapData16Response; +class ICU4XStaticDataProvider; + +/** + * A destruction policy for using ICU4XCodePointMapData16 with std::unique_ptr. + */ +struct ICU4XCodePointMapData16Deleter { + void operator()(capi::ICU4XCodePointMapData16* l) const noexcept { + capi::ICU4XCodePointMapData16_destroy(l); + } +}; +class ICU4XCodePointMapData16 { + public: + + /** + * Gets a map for Unicode property Script from a [`ICU4XDataProvider`]. + * See [the Rust docs](https://unicode-org.github.io/icu4x-docs/doc/icu_properties/maps/fn.get_script.html) for more information. + */ + static ICU4XCodePointMapData16Response try_get_script(const ICU4XDataProvider& provider); + + /** + * Gets a map for Unicode property Script from a [`ICU4XStaticDataProvider`]. + * See [the Rust docs](https://unicode-org.github.io/icu4x-docs/doc/icu_properties/maps/fn.get_script.html) for more information. + */ + static ICU4XCodePointMapData16Response try_get_script_from_static(const ICU4XStaticDataProvider& provider); + + /** + * Gets the value for a code point. + * See [the Rust docs](https://unicode-org.github.io/icu4x-docs/doc/icu_codepointtrie/codepointtrie/struct.CodePointTrie.html#method.get_u32) for more information. + */ + uint16_t get(char32_t cp) const; + inline const capi::ICU4XCodePointMapData16* AsFFI() const { return this->inner.get(); } + inline capi::ICU4XCodePointMapData16* AsFFIMut() { return this->inner.get(); } + inline ICU4XCodePointMapData16(capi::ICU4XCodePointMapData16* i) : inner(i) {} + private: + std::unique_ptr inner; +}; + +#include "ICU4XDataProvider.hpp" +#include "ICU4XCodePointMapData16Response.hpp" +#include "ICU4XStaticDataProvider.hpp" + +inline ICU4XCodePointMapData16Response ICU4XCodePointMapData16::try_get_script(const ICU4XDataProvider& provider) { + capi::ICU4XCodePointMapData16Response diplomat_raw_struct_out_value = capi::ICU4XCodePointMapData16_try_get_script(provider.AsFFI()); + auto diplomat_optional_raw_out_value_data = diplomat_raw_struct_out_value.data; + std::optional diplomat_optional_out_value_data; + if (diplomat_optional_raw_out_value_data != nullptr) { + diplomat_optional_out_value_data = ICU4XCodePointMapData16(diplomat_optional_raw_out_value_data); + } else { + diplomat_optional_out_value_data = std::nullopt; + } + return ICU4XCodePointMapData16Response{ .data = std::move(diplomat_optional_out_value_data), .success = std::move(diplomat_raw_struct_out_value.success) }; +} +inline ICU4XCodePointMapData16Response ICU4XCodePointMapData16::try_get_script_from_static(const ICU4XStaticDataProvider& provider) { + capi::ICU4XCodePointMapData16Response diplomat_raw_struct_out_value = capi::ICU4XCodePointMapData16_try_get_script_from_static(provider.AsFFI()); + auto diplomat_optional_raw_out_value_data = diplomat_raw_struct_out_value.data; + std::optional diplomat_optional_out_value_data; + if (diplomat_optional_raw_out_value_data != nullptr) { + diplomat_optional_out_value_data = ICU4XCodePointMapData16(diplomat_optional_raw_out_value_data); + } else { + diplomat_optional_out_value_data = std::nullopt; + } + return ICU4XCodePointMapData16Response{ .data = std::move(diplomat_optional_out_value_data), .success = std::move(diplomat_raw_struct_out_value.success) }; +} +inline uint16_t ICU4XCodePointMapData16::get(char32_t cp) const { + return capi::ICU4XCodePointMapData16_get(this->inner.get(), cp); +} +#endif diff --git a/ffi/diplomat/cpp/include/ICU4XCodePointMapData16Response.h b/ffi/diplomat/cpp/include/ICU4XCodePointMapData16Response.h new file mode 100644 index 00000000000..8b494bc5bc2 --- /dev/null +++ b/ffi/diplomat/cpp/include/ICU4XCodePointMapData16Response.h @@ -0,0 +1,24 @@ +#ifndef ICU4XCodePointMapData16Response_H +#define ICU4XCodePointMapData16Response_H +#include +#include +#include +#include +#include "diplomat_runtime.h" + +#ifdef __cplusplus +extern "C" { +#endif +typedef struct ICU4XCodePointMapData16 ICU4XCodePointMapData16; + +typedef struct ICU4XCodePointMapData16Response { + ICU4XCodePointMapData16* data; + bool success; +} ICU4XCodePointMapData16Response; + +void ICU4XCodePointMapData16Response_destroy(ICU4XCodePointMapData16Response* self); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/ffi/diplomat/cpp/include/ICU4XCodePointMapData16Response.hpp b/ffi/diplomat/cpp/include/ICU4XCodePointMapData16Response.hpp new file mode 100644 index 00000000000..cecd3ee3a65 --- /dev/null +++ b/ffi/diplomat/cpp/include/ICU4XCodePointMapData16Response.hpp @@ -0,0 +1,42 @@ +#ifndef ICU4XCodePointMapData16Response_HPP +#define ICU4XCodePointMapData16Response_HPP +#include +#include +#include +#include +#include +#include +#include +#include +#include "diplomat_runtime.hpp" + +namespace capi { +#include "ICU4XCodePointMapData16Response.h" +} + +class ICU4XCodePointMapData16; + +/** + * A destruction policy for using ICU4XCodePointMapData16Response with std::unique_ptr. + */ +struct ICU4XCodePointMapData16ResponseDeleter { + void operator()(capi::ICU4XCodePointMapData16Response* l) const noexcept { + capi::ICU4XCodePointMapData16Response_destroy(l); + } +}; +struct ICU4XCodePointMapData16Response { + public: + + /** + * The [`ICU4XCodePointMapData16`], if creation was successful. + */ + std::optional data; + + /** + * Whether creating the [`ICU4XCodePointMapData16`] was successful. + */ + bool success; +}; + + +#endif diff --git a/ffi/diplomat/cpp/include/ICU4XCodePointSetData.h b/ffi/diplomat/cpp/include/ICU4XCodePointSetData.h new file mode 100644 index 00000000000..b2660ee1c11 --- /dev/null +++ b/ffi/diplomat/cpp/include/ICU4XCodePointSetData.h @@ -0,0 +1,28 @@ +#ifndef ICU4XCodePointSetData_H +#define ICU4XCodePointSetData_H +#include +#include +#include +#include +#include "diplomat_runtime.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct ICU4XCodePointSetData ICU4XCodePointSetData; +#include "ICU4XDataProvider.h" +#include "ICU4XCodePointSetDataResult.h" +#include "ICU4XStaticDataProvider.h" + +ICU4XCodePointSetDataResult ICU4XCodePointSetData_try_get_ascii_hex_digit(const ICU4XDataProvider* provider); + +ICU4XCodePointSetDataResult ICU4XCodePointSetData_try_get_ascii_hex_digit_from_static(const ICU4XStaticDataProvider* provider); + +bool ICU4XCodePointSetData_contains(const ICU4XCodePointSetData* self, char32_t cp); +void ICU4XCodePointSetData_destroy(ICU4XCodePointSetData* self); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/ffi/diplomat/cpp/include/ICU4XCodePointSetData.hpp b/ffi/diplomat/cpp/include/ICU4XCodePointSetData.hpp new file mode 100644 index 00000000000..a6ba46a7ce4 --- /dev/null +++ b/ffi/diplomat/cpp/include/ICU4XCodePointSetData.hpp @@ -0,0 +1,85 @@ +#ifndef ICU4XCodePointSetData_HPP +#define ICU4XCodePointSetData_HPP +#include +#include +#include +#include +#include +#include +#include +#include +#include "diplomat_runtime.hpp" + +namespace capi { +#include "ICU4XCodePointSetData.h" +} + +class ICU4XDataProvider; +struct ICU4XCodePointSetDataResult; +class ICU4XStaticDataProvider; + +/** + * A destruction policy for using ICU4XCodePointSetData with std::unique_ptr. + */ +struct ICU4XCodePointSetDataDeleter { + void operator()(capi::ICU4XCodePointSetData* l) const noexcept { + capi::ICU4XCodePointSetData_destroy(l); + } +}; +class ICU4XCodePointSetData { + public: + + /** + * Gets a set for Unicode property ascii_hex_digit from a [`ICU4XDataProvider`]. + * See [the Rust docs](https://unicode-org.github.io/icu4x-docs/doc/icu_properties/sets/fn.get_ascii_hex_digit.html) for more information. + */ + static ICU4XCodePointSetDataResult try_get_ascii_hex_digit(const ICU4XDataProvider& provider); + + /** + * Gets a set for Unicode property ascii_hex_digit from a [`ICU4XStaticDataProvider`]. + * See [the Rust docs](https://unicode-org.github.io/icu4x-docs/doc/icu_properties/sets/fn.get_ascii_hex_digit.html) for more information. + */ + static ICU4XCodePointSetDataResult try_get_ascii_hex_digit_from_static(const ICU4XStaticDataProvider& provider); + + /** + * Checks whether the code point is in the set. + * See [the Rust docs](https://unicode-org.github.io/icu4x-docs/doc/icu_uniset/struct.UnicodeSet.html#method.contains) for more information. + */ + bool contains(char32_t cp) const; + inline const capi::ICU4XCodePointSetData* AsFFI() const { return this->inner.get(); } + inline capi::ICU4XCodePointSetData* AsFFIMut() { return this->inner.get(); } + inline ICU4XCodePointSetData(capi::ICU4XCodePointSetData* i) : inner(i) {} + private: + std::unique_ptr inner; +}; + +#include "ICU4XDataProvider.hpp" +#include "ICU4XCodePointSetDataResult.hpp" +#include "ICU4XStaticDataProvider.hpp" + +inline ICU4XCodePointSetDataResult ICU4XCodePointSetData::try_get_ascii_hex_digit(const ICU4XDataProvider& provider) { + capi::ICU4XCodePointSetDataResult diplomat_raw_struct_out_value = capi::ICU4XCodePointSetData_try_get_ascii_hex_digit(provider.AsFFI()); + auto diplomat_optional_raw_out_value_data = diplomat_raw_struct_out_value.data; + std::optional diplomat_optional_out_value_data; + if (diplomat_optional_raw_out_value_data != nullptr) { + diplomat_optional_out_value_data = ICU4XCodePointSetData(diplomat_optional_raw_out_value_data); + } else { + diplomat_optional_out_value_data = std::nullopt; + } + return ICU4XCodePointSetDataResult{ .data = std::move(diplomat_optional_out_value_data), .success = std::move(diplomat_raw_struct_out_value.success) }; +} +inline ICU4XCodePointSetDataResult ICU4XCodePointSetData::try_get_ascii_hex_digit_from_static(const ICU4XStaticDataProvider& provider) { + capi::ICU4XCodePointSetDataResult diplomat_raw_struct_out_value = capi::ICU4XCodePointSetData_try_get_ascii_hex_digit_from_static(provider.AsFFI()); + auto diplomat_optional_raw_out_value_data = diplomat_raw_struct_out_value.data; + std::optional diplomat_optional_out_value_data; + if (diplomat_optional_raw_out_value_data != nullptr) { + diplomat_optional_out_value_data = ICU4XCodePointSetData(diplomat_optional_raw_out_value_data); + } else { + diplomat_optional_out_value_data = std::nullopt; + } + return ICU4XCodePointSetDataResult{ .data = std::move(diplomat_optional_out_value_data), .success = std::move(diplomat_raw_struct_out_value.success) }; +} +inline bool ICU4XCodePointSetData::contains(char32_t cp) const { + return capi::ICU4XCodePointSetData_contains(this->inner.get(), cp); +} +#endif diff --git a/ffi/diplomat/cpp/include/ICU4XCodePointSetDataResult.h b/ffi/diplomat/cpp/include/ICU4XCodePointSetDataResult.h new file mode 100644 index 00000000000..c43112bc564 --- /dev/null +++ b/ffi/diplomat/cpp/include/ICU4XCodePointSetDataResult.h @@ -0,0 +1,24 @@ +#ifndef ICU4XCodePointSetDataResult_H +#define ICU4XCodePointSetDataResult_H +#include +#include +#include +#include +#include "diplomat_runtime.h" + +#ifdef __cplusplus +extern "C" { +#endif +typedef struct ICU4XCodePointSetData ICU4XCodePointSetData; + +typedef struct ICU4XCodePointSetDataResult { + ICU4XCodePointSetData* data; + bool success; +} ICU4XCodePointSetDataResult; + +void ICU4XCodePointSetDataResult_destroy(ICU4XCodePointSetDataResult* self); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/ffi/diplomat/cpp/include/ICU4XCodePointSetDataResult.hpp b/ffi/diplomat/cpp/include/ICU4XCodePointSetDataResult.hpp new file mode 100644 index 00000000000..419c6c344db --- /dev/null +++ b/ffi/diplomat/cpp/include/ICU4XCodePointSetDataResult.hpp @@ -0,0 +1,42 @@ +#ifndef ICU4XCodePointSetDataResult_HPP +#define ICU4XCodePointSetDataResult_HPP +#include +#include +#include +#include +#include +#include +#include +#include +#include "diplomat_runtime.hpp" + +namespace capi { +#include "ICU4XCodePointSetDataResult.h" +} + +class ICU4XCodePointSetData; + +/** + * A destruction policy for using ICU4XCodePointSetDataResult with std::unique_ptr. + */ +struct ICU4XCodePointSetDataResultDeleter { + void operator()(capi::ICU4XCodePointSetDataResult* l) const noexcept { + capi::ICU4XCodePointSetDataResult_destroy(l); + } +}; +struct ICU4XCodePointSetDataResult { + public: + + /** + * The [`ICU4XCodePointSetData`], if creation was successful. + */ + std::optional data; + + /** + * Whether creating the [`ICU4XCodePointSetData`] was successful. + */ + bool success; +}; + + +#endif diff --git a/ffi/diplomat/src/lib.rs b/ffi/diplomat/src/lib.rs index 9be88bea8a3..3995bd99944 100644 --- a/ffi/diplomat/src/lib.rs +++ b/ffi/diplomat/src/lib.rs @@ -38,6 +38,8 @@ pub mod fixed_decimal; pub mod locale; pub mod locale_canonicalizer; pub mod pluralrules; +pub mod properties_maps; +pub mod properties_sets; pub mod provider; #[cfg(target_arch = "wasm32")] diff --git a/ffi/diplomat/src/properties_maps.rs b/ffi/diplomat/src/properties_maps.rs new file mode 100644 index 00000000000..c6dc7029baf --- /dev/null +++ b/ffi/diplomat/src/properties_maps.rs @@ -0,0 +1,77 @@ +// This file is part of ICU4X. For terms of use, please see the file +// called LICENSE at the top level of the ICU4X source tree +// (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ). + +#[diplomat::bridge] +pub mod ffi { + use alloc::boxed::Box; + use icu_properties::{ + maps::{self, CodePointMapResult}, + provider::{UnicodePropertyMapV1, UnicodePropertyMapV1Marker}, + Script, + }; + use icu_provider::prelude::DataPayload; + + use crate::{provider::ffi::ICU4XDataProvider, provider::ffi::ICU4XStaticDataProvider}; + + #[diplomat::opaque] + /// An ICU4X Unicode Set Property object, capable of querying whether a code point is contained in a set based on a Unicode property. For properties whose values fit into 16 bits. + /// See [the Rust docs](https://unicode-org.github.io/icu4x-docs/doc/icu_properties/index.html) for more information. + pub struct ICU4XCodePointMapData16(DataPayload>); + + pub struct ICU4XCodePointMapData16Response { + /// The [`ICU4XCodePointMapData16`], if creation was successful. + pub data: Option>, + /// Whether creating the [`ICU4XCodePointMapData16`] was successful. + pub success: bool, + } + + impl ICU4XCodePointMapData16 { + /// Gets a map for Unicode property Script from a [`ICU4XDataProvider`]. + /// See [the Rust docs](https://unicode-org.github.io/icu4x-docs/doc/icu_properties/maps/fn.get_script.html) for more information. + pub fn try_get_script(provider: &ICU4XDataProvider) -> ICU4XCodePointMapData16Response { + let provider = provider.0.as_ref(); + Self::prepare_result_from_script(maps::get_script(provider)) + } + + /// Gets a map for Unicode property Script from a [`ICU4XStaticDataProvider`]. + /// See [the Rust docs](https://unicode-org.github.io/icu4x-docs/doc/icu_properties/maps/fn.get_script.html) for more information. + pub fn try_get_script_from_static( + provider: &ICU4XStaticDataProvider, + ) -> ICU4XCodePointMapData16Response { + let provider = provider.0.as_ref(); + Self::prepare_result_from_script(maps::get_script(provider)) + } + + fn prepare_result_from_script( + result: CodePointMapResult