File size: 3,039 Bytes
1c4c66b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
package service

import (
	"fmt"
	"slices"

	"github.com/openmeterio/openmeter/openmeter/subscription"
	"github.com/openmeterio/openmeter/pkg/models"
)

type SubscriptionReferenceType string

const (
	SubscriptionReferenceTypeID   SubscriptionReferenceType = "id"
	SubscriptionReferenceTypeView SubscriptionReferenceType = "view"
)

var SubscriptionReferenceTypes = []SubscriptionReferenceType{
	SubscriptionReferenceTypeID,
	SubscriptionReferenceTypeView,
}

func (t SubscriptionReferenceType) Validate() error {
	if slices.Contains(SubscriptionReferenceTypes, t) {
		return nil
	}

	return fmt.Errorf("invalid subscription reference type: %s", t)
}

type subscriptionReferenceOrView struct {
	t    SubscriptionReferenceType
	id   *models.NamespacedID
	view *subscription.SubscriptionView
}

func newSubscriptionReferenceOrView[T models.NamespacedID | subscription.SubscriptionView | subscription.Subscription](refOrView T) subscriptionReferenceOrView {
	switch v := any(refOrView).(type) {
	case models.NamespacedID:
		return subscriptionReferenceOrView{
			t:  SubscriptionReferenceTypeID,
			id: &v,
		}
	case subscription.SubscriptionView:
		return subscriptionReferenceOrView{
			t:    SubscriptionReferenceTypeView,
			view: &v,
		}
	case subscription.Subscription:
		return subscriptionReferenceOrView{
			t:  SubscriptionReferenceTypeID,
			id: &v.NamespacedID,
		}
	default:
		return subscriptionReferenceOrView{}
	}
}

func (r subscriptionReferenceOrView) Validate() error {
	switch r.t {
	case SubscriptionReferenceTypeID:
		if r.id == nil {
			return fmt.Errorf("subscription ID is required")
		}

		return nil
	case SubscriptionReferenceTypeView:
		if r.view == nil {
			return fmt.Errorf("subscription view is required")
		}

		return r.view.Validate(true)
	default:
		return fmt.Errorf("invalid subscription reference type: %s", r.t)
	}
}

func (r subscriptionReferenceOrView) Type() SubscriptionReferenceType {
	return r.t
}

func (r subscriptionReferenceOrView) AsNamespacedID() (models.NamespacedID, error) {
	if r.t != SubscriptionReferenceTypeID {
		return models.NamespacedID{}, fmt.Errorf("subscription reference type is not ID: %s", r.t)
	}

	if r.id == nil {
		return models.NamespacedID{}, fmt.Errorf("subscription ID is required")
	}

	return *r.id, nil
}

func (r subscriptionReferenceOrView) AsSubscriptionView() (subscription.SubscriptionView, error) {
	if r.t != SubscriptionReferenceTypeView {
		return subscription.SubscriptionView{}, fmt.Errorf("subscription reference type is not view: %s", r.t)
	}

	if r.view == nil {
		return subscription.SubscriptionView{}, fmt.Errorf("subscription view is required")
	}

	return *r.view, nil
}

func (r subscriptionReferenceOrView) GetID() models.NamespacedID {
	switch r.t {
	case SubscriptionReferenceTypeID:
		if r.id == nil {
			return models.NamespacedID{}
		}

		return *r.id
	case SubscriptionReferenceTypeView:
		if r.view == nil {
			return models.NamespacedID{}
		}

		return r.view.Subscription.NamespacedID
	default:
		return models.NamespacedID{}
	}
}