SemVer.h 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. /*
  2. * Copyright (c) 2023, Gurkirat Singh <tbhaxor@gmail.com>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #pragma once
  7. #include <AK/Error.h>
  8. #include <AK/Format.h>
  9. #include <AK/String.h>
  10. #include <AK/StringView.h>
  11. #include <AK/Types.h>
  12. namespace SemVer {
  13. enum class BumpType {
  14. Major,
  15. Minor,
  16. Patch,
  17. Prerelease,
  18. };
  19. enum class CompareType {
  20. Exact,
  21. Major,
  22. Minor,
  23. Patch
  24. };
  25. class SemVer {
  26. public:
  27. SemVer(u64 major, u64 minor, u64 patch, char m_number_separator)
  28. : m_number_separator(m_number_separator)
  29. , m_major(major)
  30. , m_minor(minor)
  31. , m_patch(patch)
  32. {
  33. }
  34. SemVer(u64 major, u64 minor, u64 patch, char m_number_separator, Vector<String> const& prereleases, Vector<String> const& build_metadata)
  35. : m_number_separator(m_number_separator)
  36. , m_major(major)
  37. , m_minor(minor)
  38. , m_patch(patch)
  39. , m_prerelease_identifiers(prereleases)
  40. , m_build_metadata_identifiers(build_metadata)
  41. {
  42. }
  43. [[nodiscard]] u64 major() const { return m_major; }
  44. [[nodiscard]] u64 minor() const { return m_minor; }
  45. [[nodiscard]] u64 patch() const { return m_patch; }
  46. [[nodiscard]] ReadonlySpan<String> prerelease_identifiers() const { return m_prerelease_identifiers.span(); }
  47. [[nodiscard]] String prerelease() const
  48. {
  49. return String::join('.', m_prerelease_identifiers).release_value_but_fixme_should_propagate_errors();
  50. }
  51. [[nodiscard]] ReadonlySpan<String> build_metadata_identifiers() const { return m_build_metadata_identifiers.span(); }
  52. [[nodiscard]] String build_metadata() const { return String::join('.', m_build_metadata_identifiers).release_value_but_fixme_should_propagate_errors(); }
  53. [[nodiscard]] SemVer bump(BumpType) const;
  54. [[nodiscard]] bool is_same(SemVer const&, CompareType = CompareType::Exact) const;
  55. [[nodiscard]] bool is_greater_than(SemVer const&) const;
  56. [[nodiscard]] bool is_lesser_than(SemVer const& other) const { return !is_same(other) && !is_greater_than(other); }
  57. [[nodiscard]] bool operator==(SemVer const& other) const { return is_same(other); }
  58. [[nodiscard]] bool operator!=(SemVer const& other) const { return !is_same(other); }
  59. [[nodiscard]] bool operator>(SemVer const& other) const { return is_lesser_than(other); }
  60. [[nodiscard]] bool operator<(SemVer const& other) const { return is_greater_than(other); }
  61. [[nodiscard]] bool operator>=(SemVer const& other) const { return *this == other || *this > other; }
  62. [[nodiscard]] bool operator<=(SemVer const& other) const { return *this == other || *this < other; }
  63. [[nodiscard]] bool satisfies(StringView const& semver_spec) const;
  64. [[nodiscard]] String suffix() const;
  65. [[nodiscard]] String to_string() const;
  66. private:
  67. char m_number_separator;
  68. u64 m_major;
  69. u64 m_minor;
  70. u64 m_patch;
  71. Vector<String> m_prerelease_identifiers;
  72. Vector<String> m_build_metadata_identifiers;
  73. };
  74. ErrorOr<SemVer> from_string_view(StringView const&, char normal_version_separator = '.');
  75. bool is_valid(StringView const&, char normal_version_separator = '.');
  76. }
  77. template<>
  78. struct AK::Formatter<SemVer::SemVer> : Formatter<String> {
  79. ErrorOr<void> format(FormatBuilder& builder, SemVer::SemVer const& value)
  80. {
  81. return Formatter<String>::format(builder, value.to_string());
  82. }
  83. };