/* * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #include #include #include #include #include #include namespace facebook::yoga { using namespace nlohmann; static inline bool isAuto(json& j) { return j.is_string() && j == "auto"; } static inline bool isUndefined(json& j) { return j.is_string() && j == "undefined"; } static inline std::string invalidArgumentMessage( const std::string& arg, const std::string& enumName) { return arg + " does not represent any " + enumName + " values"; } static inline float floatFromJson(json& j) { float result = YGUndefined; if (!j.is_null()) { result = j; } return result; } YGFlexDirection flexDirectionFromString(const std::string& str) { if (str == "row") { return YGFlexDirectionRow; } else if (str == "row-reverse") { return YGFlexDirectionRowReverse; } else if (str == "column") { return YGFlexDirectionColumn; } else if (str == "column-reverse") { return YGFlexDirectionColumnReverse; } else { throw std::invalid_argument(invalidArgumentMessage(str, "YGFlexDirection")); } } YGJustify justifyContentFromString(const std::string& str) { if (str == "flex-start") { return YGJustifyFlexStart; } else if (str == "center") { return YGJustifyCenter; } else if (str == "flex-end") { return YGJustifyFlexEnd; } else if (str == "space-between") { return YGJustifySpaceBetween; } else if (str == "space-around") { return YGJustifySpaceAround; } else if (str == "space-evenly") { return YGJustifySpaceEvenly; } else { throw std::invalid_argument(invalidArgumentMessage(str, "YGJustify")); } } YGAlign alignFromString(const std::string& str) { if (str == "auto") { return YGAlignAuto; } else if (str == "flex-start") { return YGAlignFlexStart; } else if (str == "center") { return YGAlignCenter; } else if (str == "flex-end") { return YGAlignFlexEnd; } else if (str == "stretch") { return YGAlignStretch; } else if (str == "baseline") { return YGAlignBaseline; } else if (str == "space-between") { return YGAlignSpaceBetween; } else if (str == "space-around") { return YGAlignSpaceAround; } else if (str == "space-evenly") { return YGAlignSpaceEvenly; } else { throw std::invalid_argument(invalidArgumentMessage(str, "YGAlign")); } } YGWrap wrapFromString(const std::string& str) { if (str == "no-wrap") { return YGWrapNoWrap; } else if (str == "wrap") { return YGWrapWrap; } else if (str == "wrap-reverse") { return YGWrapWrapReverse; } else { throw std::invalid_argument(invalidArgumentMessage(str, "YGAlign")); } } YGOverflow overflowFromString(const std::string& str) { if (str == "visible") { return YGOverflowVisible; } else if (str == "hidden") { return YGOverflowHidden; } else if (str == "scroll") { return YGOverflowScroll; } else { throw std::invalid_argument(invalidArgumentMessage(str, "YGAlign")); } } YGDisplay displayFromString(const std::string& str) { if (str == "flex") { return YGDisplayFlex; } else if (str == "none") { return YGDisplayNone; } else { throw std::invalid_argument(invalidArgumentMessage(str, "YGAlign")); } } YGPositionType positionTypeFromString(const std::string& str) { if (str == "static") { return YGPositionTypeStatic; } else if (str == "relative") { return YGPositionTypeRelative; } else if (str == "absolute") { return YGPositionTypeAbsolute; } else { throw std::invalid_argument(invalidArgumentMessage(str, "YGAlign")); } } YGUnit unitFromJson(json& j) { if (isAuto(j)) { return YGUnitAuto; } if (isUndefined(j)) { return YGUnitUndefined; } std::string unit = j["unit"]; if (unit == "px") { return YGUnitPoint; } else if (unit == "pct") { return YGUnitPercent; } else { throw std::invalid_argument(invalidArgumentMessage(unit, "YGUnit")); } } YGEdge edgeFromString(const std::string& str) { if (str == "left") { return YGEdgeLeft; } else if (str == "top") { return YGEdgeTop; } else if (str == "right") { return YGEdgeRight; } else if (str == "bottom") { return YGEdgeBottom; } else if (str == "start") { return YGEdgeStart; } else if (str == "end") { return YGEdgeEnd; } else if (str == "horizontal") { return YGEdgeHorizontal; } else if (str == "vertical") { return YGEdgeVertical; } else if (str == "all") { return YGEdgeAll; } else { throw std::invalid_argument(invalidArgumentMessage(str, "YGEdge")); } } YGErrata errataFromString(const std::string& str) { if (str == "none") { return YGErrataNone; } else if (str == "all") { return YGErrataAll; } else if (str == "classic") { return YGErrataClassic; } else { throw std::invalid_argument(invalidArgumentMessage(str, "YGErrata")); } } YGExperimentalFeature experimentalFeatureFromString(const std::string& str) { if (str == "web-flex-basis") { return YGExperimentalFeatureWebFlexBasis; } else { throw std::invalid_argument( invalidArgumentMessage(str, "YGExperimentalFeature")); } } std::string edgeStringFromPropertyName( const json::iterator& it, const std::string& propertyName) { return it.key().substr(propertyName.length() + 1); } YGDirection directionFromString(const std::string& str) { if (str == "ltr") { return YGDirectionLTR; } else if (str == "rtl") { return YGDirectionRTL; } else if (str == "inherit") { return YGDirectionInherit; } else { throw std::invalid_argument(invalidArgumentMessage(str, "YGDirection")); } } YGMeasureMode measureModeFromString(const std::string& str) { if (str == "at-most") { return YGMeasureModeAtMost; } else if (str == "exactly") { return YGMeasureModeExactly; } else if (str == "undefined") { return YGMeasureModeUndefined; } else { throw std::invalid_argument(invalidArgumentMessage(str, "YGMeasureMode")); } } SerializedMeasureFunc serializedMeasureFuncFromJson(json& j) { return SerializedMeasureFunc{ floatFromJson(j["width"]), measureModeFromString(j["width-mode"]), floatFromJson(j["height"]), measureModeFromString(j["height-mode"]), floatFromJson(j["output-width"]), floatFromJson(j["output-height"]), j["duration-ns"]}; } } // namespace facebook::yoga