mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Allow parsing lists of compound data types (#49188)
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/49188 This allows creating lists of a compound data type, storing each element as a variant of the possible types, instead of as the specified type. Changelog: [Internal] Reviewed By: lenaic Differential Revision: D69142157 fbshipit-source-id: d742d81a6517b24f24827727cd777550f2ad274f
This commit is contained in:
committed by
Facebook GitHub Bot
parent
62ea6e891c
commit
1def9fdbc9
@@ -21,13 +21,17 @@ struct CSSCompoundDataTypeMarker {};
|
||||
template <CSSDataType... AllowedTypesT>
|
||||
struct CSSCompoundDataType : public detail::CSSCompoundDataTypeMarker {};
|
||||
|
||||
template <typename T>
|
||||
concept CSSValidCompoundDataType =
|
||||
std::is_base_of_v<detail::CSSCompoundDataTypeMarker, T>;
|
||||
|
||||
/**
|
||||
* A concrete data type, or a compound data type which represents multiple other
|
||||
* data types.
|
||||
*/
|
||||
template <typename T>
|
||||
concept CSSMaybeCompoundDataType =
|
||||
CSSDataType<T> || std::is_base_of_v<detail::CSSCompoundDataTypeMarker, T>;
|
||||
CSSDataType<T> || CSSValidCompoundDataType<T>;
|
||||
|
||||
namespace detail {
|
||||
|
||||
|
||||
@@ -8,17 +8,26 @@
|
||||
#pragma once
|
||||
|
||||
#include <optional>
|
||||
#include <type_traits>
|
||||
#include <variant>
|
||||
|
||||
#include <react/renderer/css/CSSCompoundDataType.h>
|
||||
#include <react/renderer/css/CSSDataType.h>
|
||||
#include <react/renderer/css/CSSValueParser.h>
|
||||
|
||||
namespace facebook::react {
|
||||
|
||||
template <CSSDataType AllowedTypeT, CSSDelimiter Delim>
|
||||
struct CSSList : public std::vector<AllowedTypeT> {};
|
||||
template <CSSMaybeCompoundDataType T, CSSDelimiter Delim>
|
||||
struct CSSList;
|
||||
|
||||
template <CSSDataType AllowedTypeT, CSSDelimiter Delim>
|
||||
struct CSSList<AllowedTypeT, Delim> : public std::vector<AllowedTypeT> {};
|
||||
|
||||
template <CSSValidCompoundDataType AllowedTypesT, CSSDelimiter Delim>
|
||||
struct CSSList<AllowedTypesT, Delim>
|
||||
: public std::vector<CSSVariantWithTypes<AllowedTypesT>> {};
|
||||
|
||||
template <CSSMaybeCompoundDataType AllowedTypeT, CSSDelimiter Delim>
|
||||
struct CSSDataTypeParser<CSSList<AllowedTypeT, Delim>> {
|
||||
static inline auto consume(CSSSyntaxParser& parser)
|
||||
-> std::optional<CSSList<AllowedTypeT, Delim>> {
|
||||
@@ -26,7 +35,18 @@ struct CSSDataTypeParser<CSSList<AllowedTypeT, Delim>> {
|
||||
for (auto nextValue = parseNextCSSValue<AllowedTypeT>(parser);
|
||||
!std::holds_alternative<std::monostate>(nextValue);
|
||||
nextValue = parseNextCSSValue<AllowedTypeT>(parser, Delim)) {
|
||||
result.push_back(std::move(std::get<AllowedTypeT>(nextValue)));
|
||||
// Copy from the variant of possible values to the element (either the
|
||||
// concrete type, or a variant of compound types which exlcudes the
|
||||
// possibility of std::monostate for parse error)
|
||||
std::visit(
|
||||
[&](auto&& v) {
|
||||
if constexpr (!std::is_same_v<
|
||||
std::remove_cvref_t<decltype(v)>,
|
||||
std::monostate>) {
|
||||
result.push_back(std::forward<decltype(v)>(v));
|
||||
}
|
||||
},
|
||||
nextValue);
|
||||
}
|
||||
|
||||
if (result.empty()) {
|
||||
@@ -38,17 +58,19 @@ struct CSSDataTypeParser<CSSList<AllowedTypeT, Delim>> {
|
||||
};
|
||||
|
||||
/**
|
||||
* Represents a comma-separated repetition of a given single type.
|
||||
* Represents a comma-separated repetition of a single type, or compound type
|
||||
* (represented as a variant of possible types).
|
||||
* https://www.w3.org/TR/css-values-4/#mult-comma
|
||||
*/
|
||||
template <CSSDataType AllowedTypeT>
|
||||
template <CSSMaybeCompoundDataType AllowedTypeT>
|
||||
using CSSCommaSeparatedList = CSSList<AllowedTypeT, CSSDelimiter::Comma>;
|
||||
|
||||
/**
|
||||
* Represents a whitespace-separated repetition of a given single type.
|
||||
* Represents a whitespace-separated repetition of a single type, or compound
|
||||
* type (represented as a variant of possible types).
|
||||
* https://www.w3.org/TR/css-values-4/#component-combinators
|
||||
*/
|
||||
template <CSSDataType AllowedTypeT>
|
||||
template <CSSMaybeCompoundDataType AllowedTypeT>
|
||||
using CSSWhitespaceSeparatedList =
|
||||
CSSList<AllowedTypeT, CSSDelimiter::Whitespace>;
|
||||
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
*/
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <react/renderer/css/CSSCompoundDataType.h>
|
||||
#include <react/renderer/css/CSSLength.h>
|
||||
#include <react/renderer/css/CSSList.h>
|
||||
#include <react/renderer/css/CSSNumber.h>
|
||||
#include <react/renderer/css/CSSValueParser.h>
|
||||
@@ -130,4 +132,22 @@ TEST(CSSList, extra_commas) {
|
||||
EXPECT_TRUE(std::holds_alternative<std::monostate>(suffixCommaValue));
|
||||
}
|
||||
|
||||
TEST(CSSList, compound_data_type) {
|
||||
using NumberLengthList =
|
||||
CSSCommaSeparatedList<CSSCompoundDataType<CSSNumber, CSSLength>>;
|
||||
|
||||
auto compoundType = parseCSSProperty<NumberLengthList>("10px,20");
|
||||
|
||||
EXPECT_TRUE(std::holds_alternative<NumberLengthList>(compoundType));
|
||||
auto& list = std::get<NumberLengthList>(compoundType);
|
||||
|
||||
EXPECT_EQ(list.size(), 2);
|
||||
EXPECT_TRUE(std::holds_alternative<CSSLength>(list[0]));
|
||||
EXPECT_EQ(std::get<CSSLength>(list[0]).value, 10);
|
||||
EXPECT_EQ(std::get<CSSLength>(list[0]).unit, CSSLengthUnit::Px);
|
||||
|
||||
EXPECT_TRUE(std::holds_alternative<CSSNumber>(list[1]));
|
||||
EXPECT_EQ(std::get<CSSNumber>(list[1]).value, 20);
|
||||
}
|
||||
|
||||
} // namespace facebook::react
|
||||
|
||||
Reference in New Issue
Block a user