1 /* 2 * SPDX-FileCopyrightText: 2021~2021 CSSlayer <wengxt@gmail.com> 3 * 4 * SPDX-License-Identifier: LGPL-2.1-or-later 5 * 6 */ 7 #ifndef _FCITX_UTILS_SEMVER_H_ 8 #define _FCITX_UTILS_SEMVER_H_ 9 10 #include <cstdint> 11 #include <optional> 12 #include <string> 13 #include <variant> 14 #include <vector> 15 #include "fcitxutils_export.h" 16 #include "log.h" 17 #include "macros.h" 18 19 #ifdef __DragonFly__ 20 #undef major 21 #undef minor 22 #endif 23 24 namespace fcitx { 25 26 class FCITXUTILS_EXPORT PreReleaseId { 27 public: 28 explicit PreReleaseId(uint32_t id); 29 explicit PreReleaseId(std::string id); 30 31 FCITX_INLINE_DEFINE_DEFAULT_DTOR_COPY_AND_MOVE(PreReleaseId); 32 33 std::string toString() const; 34 35 bool isNumeric() const; 36 uint32_t numericId() const; 37 const std::string &id() const; 38 39 int compare(const PreReleaseId &other) const; 40 41 private: 42 std::variant<std::string, uint32_t> value_; 43 }; 44 45 /** 46 * @brief Provide a Semantic version 2.0 implementation 47 * 48 * @since 5.0.6 49 */ 50 class FCITXUTILS_EXPORT SemanticVersion { 51 public: 52 SemanticVersion() = default; 53 FCITX_INLINE_DEFINE_DEFAULT_DTOR_COPY_AND_MOVE(SemanticVersion); 54 55 static std::optional<SemanticVersion> parse(std::string_view data); 56 57 std::string toString() const; 58 59 FCITX_DECLARE_PROPERTY(uint32_t, major, setMajor); 60 FCITX_DECLARE_PROPERTY(uint32_t, minor, setMinor); 61 FCITX_DECLARE_PROPERTY(uint32_t, patch, setPatch); 62 FCITX_DECLARE_PROPERTY(std::vector<PreReleaseId>, preReleaseIds, 63 setPreReleaseIds); 64 FCITX_DECLARE_PROPERTY(std::vector<std::string>, buildIds, setBuildIds); 65 bool isPreRelease() const; 66 67 int compare(const SemanticVersion &version) const noexcept; 68 69 private: 70 uint32_t major_ = 0; 71 uint32_t minor_ = 1; 72 uint32_t patch_ = 0; 73 std::vector<PreReleaseId> preReleaseIds_; 74 std::vector<std::string> buildIds_; 75 }; 76 77 inline bool operator<(const PreReleaseId &lhs, 78 const PreReleaseId &rhs) noexcept { 79 return lhs.compare(rhs) < 0; 80 } 81 82 inline bool operator>(const PreReleaseId &lhs, 83 const PreReleaseId &rhs) noexcept { 84 return rhs < lhs; 85 } 86 87 inline bool operator==(const PreReleaseId &lhs, 88 const PreReleaseId &rhs) noexcept { 89 return lhs.compare(rhs) == 0; 90 } 91 92 inline bool operator!=(const PreReleaseId &lhs, 93 const PreReleaseId &rhs) noexcept { 94 return !(lhs == rhs); 95 } 96 97 inline bool operator<=(const PreReleaseId &lhs, 98 const PreReleaseId &rhs) noexcept { 99 return !(lhs > rhs); 100 } 101 102 inline bool operator>=(const PreReleaseId &lhs, 103 const PreReleaseId &rhs) noexcept { 104 return !(lhs < rhs); 105 } 106 107 inline bool operator<(const SemanticVersion &lhs, 108 const SemanticVersion &rhs) noexcept { 109 return lhs.compare(rhs) < 0; 110 } 111 112 inline bool operator>(const SemanticVersion &lhs, 113 const SemanticVersion &rhs) noexcept { 114 return rhs < lhs; 115 } 116 117 inline bool operator==(const SemanticVersion &lhs, 118 const SemanticVersion &rhs) noexcept { 119 return lhs.compare(rhs) == 0; 120 } 121 122 inline bool operator!=(const SemanticVersion &lhs, 123 const SemanticVersion &rhs) noexcept { 124 return !(lhs == rhs); 125 } 126 127 inline bool operator<=(const SemanticVersion &lhs, 128 const SemanticVersion &rhs) noexcept { 129 return !(lhs > rhs); 130 } 131 132 inline bool operator>=(const SemanticVersion &lhs, 133 const SemanticVersion &rhs) noexcept { 134 return !(lhs < rhs); 135 } 136 137 inline LogMessageBuilder &operator<<(LogMessageBuilder &builder, 138 const SemanticVersion &version) { 139 builder << "SemanticVersion(" << version.toString() << ")"; 140 return builder; 141 } 142 143 } // namespace fcitx 144 145 #endif // _FCITX_UTILS_SEMVER_H_ 146