summary refs log tree commit diff
path: root/vendor/maunium.net/go/mautrix/versions.go
diff options
context:
space:
mode:
authorEmile <git@emile.space>2024-10-25 15:55:50 +0200
committerEmile <git@emile.space>2024-10-25 15:55:50 +0200
commitc90f36e3dd179d2de96f4f5fe38d8dc9a9de6dfe (patch)
tree89e9afb41c5bf76f48cfb09305a2d3db8d302b06 /vendor/maunium.net/go/mautrix/versions.go
parent98bbb0f559a8883bc47bae80607dbe326a448e61 (diff)
vendor HEAD main
Diffstat (limited to 'vendor/maunium.net/go/mautrix/versions.go')
-rw-r--r--vendor/maunium.net/go/mautrix/versions.go196
1 files changed, 196 insertions, 0 deletions
diff --git a/vendor/maunium.net/go/mautrix/versions.go b/vendor/maunium.net/go/mautrix/versions.go
new file mode 100644
index 0000000..672018f
--- /dev/null
+++ b/vendor/maunium.net/go/mautrix/versions.go
@@ -0,0 +1,196 @@
+// Copyright (c) 2022 Tulir Asokan
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+package mautrix
+
+import (
+	"fmt"
+	"regexp"
+	"strconv"
+)
+
+// RespVersions is the JSON response for https://spec.matrix.org/v1.2/client-server-api/#get_matrixclientversions
+type RespVersions struct {
+	Versions         []SpecVersion   `json:"versions"`
+	UnstableFeatures map[string]bool `json:"unstable_features"`
+}
+
+func (versions *RespVersions) ContainsFunc(match func(found SpecVersion) bool) bool {
+	if versions == nil {
+		return false
+	}
+	for _, found := range versions.Versions {
+		if match(found) {
+			return true
+		}
+	}
+	return false
+}
+
+func (versions *RespVersions) Contains(version SpecVersion) bool {
+	return versions.ContainsFunc(func(found SpecVersion) bool {
+		return found == version
+	})
+}
+
+func (versions *RespVersions) ContainsGreaterOrEqual(version SpecVersion) bool {
+	return versions.ContainsFunc(func(found SpecVersion) bool {
+		return found.GreaterThan(version) || found == version
+	})
+}
+
+func (versions *RespVersions) GetLatest() (latest SpecVersion) {
+	if versions == nil {
+		return
+	}
+	for _, ver := range versions.Versions {
+		if ver.GreaterThan(latest) {
+			latest = ver
+		}
+	}
+	return
+}
+
+type UnstableFeature struct {
+	UnstableFlag string
+	SpecVersion  SpecVersion
+}
+
+var (
+	FeatureAsyncUploads       = UnstableFeature{UnstableFlag: "fi.mau.msc2246.stable", SpecVersion: SpecV17}
+	FeatureAppservicePing     = UnstableFeature{UnstableFlag: "fi.mau.msc2659.stable", SpecVersion: SpecV17}
+	FeatureAuthenticatedMedia = UnstableFeature{UnstableFlag: "org.matrix.msc3916.stable", SpecVersion: SpecV111}
+
+	BeeperFeatureHungry               = UnstableFeature{UnstableFlag: "com.beeper.hungry"}
+	BeeperFeatureBatchSending         = UnstableFeature{UnstableFlag: "com.beeper.batch_sending"}
+	BeeperFeatureRoomYeeting          = UnstableFeature{UnstableFlag: "com.beeper.room_yeeting"}
+	BeeperFeatureAutojoinInvites      = UnstableFeature{UnstableFlag: "com.beeper.room_create_autojoin_invites"}
+	BeeperFeatureArbitraryProfileMeta = UnstableFeature{UnstableFlag: "com.beeper.arbitrary_profile_meta"}
+	BeeperFeatureAccountDataMute      = UnstableFeature{UnstableFlag: "com.beeper.account_data_mute"}
+	BeeperFeatureInboxState           = UnstableFeature{UnstableFlag: "com.beeper.inbox_state"}
+)
+
+func (versions *RespVersions) Supports(feature UnstableFeature) bool {
+	if versions == nil {
+		return false
+	}
+	return versions.UnstableFeatures[feature.UnstableFlag] ||
+		(!feature.SpecVersion.IsEmpty() && versions.ContainsGreaterOrEqual(feature.SpecVersion))
+}
+
+type SpecVersionFormat int
+
+const (
+	SpecVersionFormatUnknown SpecVersionFormat = iota
+	SpecVersionFormatR
+	SpecVersionFormatV
+)
+
+var (
+	SpecR000 = MustParseSpecVersion("r0.0.0")
+	SpecR001 = MustParseSpecVersion("r0.0.1")
+	SpecR010 = MustParseSpecVersion("r0.1.0")
+	SpecR020 = MustParseSpecVersion("r0.2.0")
+	SpecR030 = MustParseSpecVersion("r0.3.0")
+	SpecR040 = MustParseSpecVersion("r0.4.0")
+	SpecR050 = MustParseSpecVersion("r0.5.0")
+	SpecR060 = MustParseSpecVersion("r0.6.0")
+	SpecR061 = MustParseSpecVersion("r0.6.1")
+	SpecV11  = MustParseSpecVersion("v1.1")
+	SpecV12  = MustParseSpecVersion("v1.2")
+	SpecV13  = MustParseSpecVersion("v1.3")
+	SpecV14  = MustParseSpecVersion("v1.4")
+	SpecV15  = MustParseSpecVersion("v1.5")
+	SpecV16  = MustParseSpecVersion("v1.6")
+	SpecV17  = MustParseSpecVersion("v1.7")
+	SpecV18  = MustParseSpecVersion("v1.8")
+	SpecV19  = MustParseSpecVersion("v1.9")
+	SpecV110 = MustParseSpecVersion("v1.10")
+	SpecV111 = MustParseSpecVersion("v1.11")
+)
+
+func (svf SpecVersionFormat) String() string {
+	switch svf {
+	case SpecVersionFormatR:
+		return "r"
+	case SpecVersionFormatV:
+		return "v"
+	default:
+		return ""
+	}
+}
+
+type SpecVersion struct {
+	Format SpecVersionFormat
+	Major  int
+	Minor  int
+	Patch  int
+
+	Raw string
+}
+
+var legacyVersionRegex = regexp.MustCompile(`^r(\d+)\.(\d+)\.(\d+)$`)
+var modernVersionRegex = regexp.MustCompile(`^v(\d+)\.(\d+)$`)
+
+func MustParseSpecVersion(version string) SpecVersion {
+	sv, err := ParseSpecVersion(version)
+	if err != nil {
+		panic(err)
+	}
+	return sv
+}
+
+func ParseSpecVersion(version string) (sv SpecVersion, err error) {
+	sv.Raw = version
+	if parts := modernVersionRegex.FindStringSubmatch(version); parts != nil {
+		sv.Major, _ = strconv.Atoi(parts[1])
+		sv.Minor, _ = strconv.Atoi(parts[2])
+		sv.Format = SpecVersionFormatV
+	} else if parts = legacyVersionRegex.FindStringSubmatch(version); parts != nil {
+		sv.Major, _ = strconv.Atoi(parts[1])
+		sv.Minor, _ = strconv.Atoi(parts[2])
+		sv.Patch, _ = strconv.Atoi(parts[3])
+		sv.Format = SpecVersionFormatR
+	} else {
+		err = fmt.Errorf("version '%s' doesn't match either known syntax", version)
+	}
+	return
+}
+
+func (sv *SpecVersion) UnmarshalText(version []byte) error {
+	*sv, _ = ParseSpecVersion(string(version))
+	return nil
+}
+
+func (sv *SpecVersion) MarshalText() ([]byte, error) {
+	return []byte(sv.String()), nil
+}
+
+func (sv SpecVersion) String() string {
+	switch sv.Format {
+	case SpecVersionFormatR:
+		return fmt.Sprintf("r%d.%d.%d", sv.Major, sv.Minor, sv.Patch)
+	case SpecVersionFormatV:
+		return fmt.Sprintf("v%d.%d", sv.Major, sv.Minor)
+	default:
+		return sv.Raw
+	}
+}
+
+func (sv SpecVersion) IsEmpty() bool {
+	return sv.Format == SpecVersionFormatUnknown && sv.Raw == ""
+}
+
+func (sv SpecVersion) LessThan(other SpecVersion) bool {
+	return sv != other && !sv.GreaterThan(other)
+}
+
+func (sv SpecVersion) GreaterThan(other SpecVersion) bool {
+	return sv.Format > other.Format ||
+		(sv.Format == other.Format && sv.Major > other.Major) ||
+		(sv.Format == other.Format && sv.Major == other.Major && sv.Minor > other.Minor) ||
+		(sv.Format == other.Format && sv.Major == other.Major && sv.Minor == other.Minor && sv.Patch > other.Patch)
+}