| 54 | } |
| 55 | |
| 56 | static Result<Ref<TextAttributeValue>> doParse(const ColorPalette* colorPalette, |
| 57 | const Value& value, |
| 58 | ILogger* logger, |
| 59 | bool strict) { |
| 60 | const auto* components = value.getArray(); |
| 61 | if (components == nullptr) { |
| 62 | return invalidTextAttributeValueError(value, "Expecting array"); |
| 63 | } |
| 64 | |
| 65 | if (components->empty()) { |
| 66 | return invalidTextAttributeValueError(value, "Empty components"); |
| 67 | } |
| 68 | |
| 69 | std::optional<Error> error; |
| 70 | TextAttributeValue::Parts parts; |
| 71 | StylesStack stylesStack; |
| 72 | |
| 73 | size_t index = 0; |
| 74 | auto size = components->size(); |
| 75 | |
| 76 | while (index < size) { |
| 77 | auto type = static_cast<TextAttributeValueEntryType>((*components)[index].toInt()); |
| 78 | auto entrySize = (type == TextAttributeValueEntryTypePop) ? 1 : 2; |
| 79 | if (index + entrySize > size) { |
| 80 | error = {invalidTextAttributeValueError(value, "Missing entries")}; |
| 81 | if (strict) { |
| 82 | return error.value(); |
| 83 | } else { |
| 84 | logParseError(logger, error); |
| 85 | break; |
| 86 | } |
| 87 | } |
| 88 | const auto& entryValue = (*components)[index + entrySize - 1]; |
| 89 | |
| 90 | switch (type) { |
| 91 | case TextAttributeValueEntryTypeContent: { |
| 92 | auto content = entryValue.toStringBox(); |
| 93 | auto& part = parts.emplace_back(); |
| 94 | part.content = entryValue.toStringBox(); |
| 95 | |
| 96 | if (!stylesStack.empty()) { |
| 97 | part.style = stylesStack[stylesStack.size() - 1]; |
| 98 | } |
| 99 | } break; |
| 100 | case TextAttributeValueEntryTypePop: |
| 101 | if (stylesStack.empty()) { |
| 102 | error = {invalidTextAttributeValueError(value, "Unbalanced styles stack")}; |
| 103 | if (strict) { |
| 104 | return error.value(); |
| 105 | } else { |
| 106 | logParseError(logger, error); |
| 107 | } |
| 108 | } else { |
| 109 | stylesStack.pop_back(); |
| 110 | } |
| 111 | break; |
| 112 | case TextAttributeValueEntryTypePushFont: |
| 113 | pushStyle(stylesStack).font = entryValue.toStringBox(); |
no test coverage detected