Repository: cloudflare/cloudflare-go
Pull request #1325 (2023-07-05 02:24:19)

resource_container: add explicit `Type` field for `ResourceContainer`
Extend the resource container object to have an explicit `Type` instead of inferring/manipulating from the `Level`.

codecov-commenter: ## [Codecov](https://app.codecov.io/gh/cloudflare/cloudflare-go/pull/1325?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=cloudflare) Report
> Merging [#1325](https://app.codecov.io/gh/cloudflare/cloudflare-go/pull/1325?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=cloudflare) (23e65c0) into [master](https://app.codecov.io/gh/cloudflare/cloudflare-go/commit/74e0b34cc19a48b158d6996d94fa21b0612854aa?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=cloudflare) (74e0b34) will **decrease** coverage by `0.62%`.
> The diff coverage is `68.75%`.

```diff
@@            Coverage Diff             @@
##           master    #1325      +/-   ##
==========================================
- Coverage   48.95%   48.33%   -0.62%     
==========================================
  Files         135      133       -2     
  Lines       13180    13023     -157     
==========================================
- Hits         6452     6295     -157     
+ Misses       5212     5201      -11     
- Partials     1516     1527      +11     
```


| [Impacted Files](https://app.codecov.io/gh/cloudflare/cloudflare-go/pull/1325?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=cloudflare) | Coverage Δ | |
|---|---|---|
| [access\_audit\_log.go](https://app.codecov.io/gh/cloudflare/cloudflare-go/pull/1325?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=cloudflare#diff-YWNjZXNzX2F1ZGl0X2xvZy5nbw==) | `79.31% <0.00%> (ø)` | |
| [device\_posture\_rule.go](https://app.codecov.io/gh/cloudflare/cloudflare-go/pull/1325?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=cloudflare#diff-ZGV2aWNlX3Bvc3R1cmVfcnVsZS5nbw==) | `61.80% <ø> (ø)` | |
| [options.go](https://app.codecov.io/gh/cloudflare/cloudflare-go/pull/1325?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=cloudflare#diff-b3B0aW9ucy5nbw==) | `61.01% <ø> (-3.05%)` | :arrow_down: |
| [teams\_devices.go](https://app.codecov.io/gh/cloudflare/cloudflare-go/pull/1325?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=cloudflare#diff-dGVhbXNfZGV2aWNlcy5nbw==) | `52.63% <ø> (ø)` | |
| [dns\_firewall.go](https://app.codecov.io/gh/cloudflare/cloudflare-go/pull/1325?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=cloudflare#diff-ZG5zX2ZpcmV3YWxsLmdv) | `7.69% <10.00%> (-13.74%)` | :arrow_down: |
| [images.go](https://app.codecov.io/gh/cloudflare/cloudflare-go/pull/1325?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=cloudflare#diff-aW1hZ2VzLmdv) | `44.81% <46.06%> (-5.54%)` | :arrow_down: |
| [tunnel.go](https://app.codecov.io/gh/cloudflare/cloudflare-go/pull/1325?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=cloudflare#diff-dHVubmVsLmdv) | `42.41% <66.66%> (+1.01%)` | :arrow_up: |
| [access\_policy.go](https://app.codecov.io/gh/cloudflare/cloudflare-go/pull/1325?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=cloudflare#diff-YWNjZXNzX3BvbGljeS5nbw==) | `70.27% <73.33%> (-6.05%)` | :arrow_down: |
| [access\_application.go](https://app.codecov.io/gh/cloudflare/cloudflare-go/pull/1325?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=cloudflare#diff-YWNjZXNzX2FwcGxpY2F0aW9uLmdv) | `72.72% <75.47%> (-3.80%)` | :arrow_down: |
| [access\_mutual\_tls\_certificates.go](https://app.codecov.io/gh/cloudflare/cloudflare-go/pull/1325?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=cloudflare#diff-YWNjZXNzX211dHVhbF90bHNfY2VydGlmaWNhdGVzLmdv) | `68.86% <75.51%> (-3.36%)` | :arrow_down: |
| ... and [9 more](https://app.codecov.io/gh/cloudflare/cloudflare-go/pull/1325?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=cloudflare) | |

... and [1 file with indirect coverage changes](https://app.codecov.io/gh/cloudflare/cloudflare-go/pull/1325/indirect-changes?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=cloudflare)


github-actions[bot]: Oops! It looks like no changelog entry is attached to this PR. Please include a release note as described in https://github.com/cloudflare/cloudflare-go/blob/master/docs/changelog-process.md.

Example: 

~~~
```release-note:TYPE
Release note
```
~~~

If you do not require a release note to be included, please add the `workflow/skip-changelog-entry` label.

Patch:
diff --git a/.changelog/1325.txt b/.changelog/1325.txt
new file mode 100644
index 000000000..0742b1f7f
--- /dev/null
+++ b/.changelog/1325.txt
@@ -0,0 +1,3 @@
+```release-note:enhancement
+resource_container: expose `Type` on `*ResourceContainer` to explicitly denote what type of resource it is instead of inferring from `Level`.
+```
diff --git a/resource.go b/resource.go
index 481eae25a..d78197593 100644
--- a/resource.go
+++ b/resource.go
@@ -2,13 +2,30 @@ package cloudflare
 
 import "fmt"
 
-// RouteLevel holds the "level" where the resource resides.
+// RouteLevel holds the "level" where the resource resides. Commonly used in
+// routing configurations or builders.
 type RouteLevel string
 
+// ResourceType holds the type of the resource. This is similar to `RouteLevel`
+// however this is the singular version of `RouteLevel` and isn't suitable for
+// use in routing.
+type ResourceType string
+
 const (
-	AccountRouteLevel RouteLevel = "accounts"
-	ZoneRouteLevel    RouteLevel = "zones"
-	UserRouteLevel    RouteLevel = "user"
+	user    = "user"
+	zone    = "zone"
+	account = "account"
+
+	zones    = zone + "s"
+	accounts = account + "s"
+
+	AccountRouteLevel RouteLevel = accounts
+	ZoneRouteLevel    RouteLevel = zones
+	UserRouteLevel    RouteLevel = user
+
+	AccountType ResourceType = account
+	ZoneType    ResourceType = zone
+	UserType    ResourceType = user
 )
 
 // ResourceContainer defines an API resource you wish to target. Should not be
@@ -17,6 +34,33 @@ const (
 type ResourceContainer struct {
 	Level      RouteLevel
 	Identifier string
+	Type       ResourceType
+}
+
+func (r RouteLevel) String() string {
+	switch r {
+	case AccountRouteLevel:
+		return accounts
+	case ZoneRouteLevel:
+		return zones
+	case UserRouteLevel:
+		return user
+	default:
+		return "unknown"
+	}
+}
+
+func (r ResourceType) String() string {
+	switch r {
+	case AccountType:
+		return account
+	case ZoneType:
+		return zone
+	case UserType:
+		return user
+	default:
+		return "unknown"
+	}
 }
 
 // Returns a URL fragment of the endpoint scoped by the container.
@@ -29,7 +73,7 @@ func (rc *ResourceContainer) URLFragment() string {
 	}
 
 	if rc.Level == UserRouteLevel {
-		return "user"
+		return user
 	}
 
 	return fmt.Sprintf("%s/%s", rc.Level, rc.Identifier)
@@ -47,6 +91,7 @@ func UserIdentifier(id string) *ResourceContainer {
 	return &ResourceContainer{
 		Level:      UserRouteLevel,
 		Identifier: id,
+		Type:       UserType,
 	}
 }
 
@@ -55,6 +100,7 @@ func ZoneIdentifier(id string) *ResourceContainer {
 	return &ResourceContainer{
 		Level:      ZoneRouteLevel,
 		Identifier: id,
+		Type:       ZoneType,
 	}
 }
 
@@ -63,5 +109,6 @@ func AccountIdentifier(id string) *ResourceContainer {
 	return &ResourceContainer{
 		Level:      AccountRouteLevel,
 		Identifier: id,
+		Type:       AccountType,
 	}
 }


Test patch:
diff --git a/resource_test.go b/resource_test.go
index 0a9e82caa..ad2e7295a 100644
--- a/resource_test.go
+++ b/resource_test.go
@@ -6,6 +6,44 @@ import (
 	"github.com/stretchr/testify/assert"
 )
 
+func TestResourceProperties(t *testing.T) {
+	testCases := map[string]struct {
+		container          *ResourceContainer
+		expectedRoute      string
+		expectedType       string
+		expectedIdentifier string
+	}{
+		account: {
+			container:          AccountIdentifier("abcd1234"),
+			expectedRoute:      accounts,
+			expectedType:       account,
+			expectedIdentifier: "abcd1234",
+		},
+		zone: {
+			container:          ZoneIdentifier("abcd1234"),
+			expectedRoute:      zones,
+			expectedType:       zone,
+			expectedIdentifier: "abcd1234",
+		},
+		user: {
+			container:          UserIdentifier("abcd1234"),
+			expectedRoute:      user,
+			expectedType:       user,
+			expectedIdentifier: "abcd1234",
+		},
+	}
+
+	for name, tc := range testCases {
+		t.Run(name, func(t *testing.T) {
+			setup()
+			defer teardown()
+
+			assert.Equal(t, tc.container.Level.String(), tc.expectedRoute)
+			assert.Equal(t, tc.container.Type.String(), tc.expectedType)
+			assert.Equal(t, tc.container.Identifier, tc.expectedIdentifier)
+		})
+	}
+}
 func TestResourcURLFragment(t *testing.T) {
 	tests := map[string]struct {
 		container *ResourceContainer