swap selector category types for ints (#661)

Though enumerated as ints, the selector service
categories are stored and managed as strings. The
only time that we use the int is when passing their
iota const to and from functions.  Using a string
type instead of an int allows us to get rid of the
string builders and AtoI funcs (though not the
stringer requirement in the Iface, sadly).
This commit is contained in:
Keepers 2022-08-29 13:46:08 -06:00 committed by GitHub
parent 81cb76dd55
commit 56c7e0f85f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 43 additions and 152 deletions

View File

@ -292,7 +292,7 @@ func (s *exchange) Users(users []string) []ExchangeScope {
// If the input is empty or selectors.None, the scope will always fail comparisons.
func (sr *ExchangeRestore) MailReceivedAfter(timeStrings string) []ExchangeScope {
return []ExchangeScope{
makeFilterScope[ExchangeScope](ExchangeMail, ExchangeInfoMailReceivedAfter, []string{timeStrings}),
makeFilterScope[ExchangeScope](ExchangeMail, ExchangeFilterMailReceivedAfter, []string{timeStrings}),
}
}
@ -302,7 +302,7 @@ func (sr *ExchangeRestore) MailReceivedAfter(timeStrings string) []ExchangeScope
// If the input is empty or selectors.None, the scope will always fail comparisons.
func (sr *ExchangeRestore) MailReceivedBefore(timeStrings string) []ExchangeScope {
return []ExchangeScope{
makeFilterScope[ExchangeScope](ExchangeMail, ExchangeInfoMailReceivedBefore, []string{timeStrings}),
makeFilterScope[ExchangeScope](ExchangeMail, ExchangeFilterMailReceivedBefore, []string{timeStrings}),
}
}
@ -313,7 +313,7 @@ func (sr *ExchangeRestore) MailReceivedBefore(timeStrings string) []ExchangeScop
// If any slice is empty, it defaults to [selectors.None]
func (sr *ExchangeRestore) MailSender(senderIDs []string) []ExchangeScope {
return []ExchangeScope{
makeFilterScope[ExchangeScope](ExchangeMail, ExchangeInfoMailSender, senderIDs),
makeFilterScope[ExchangeScope](ExchangeMail, ExchangeFilterMailSender, senderIDs),
}
}
@ -324,7 +324,7 @@ func (sr *ExchangeRestore) MailSender(senderIDs []string) []ExchangeScope {
// If any slice is empty, it defaults to [selectors.None]
func (sr *ExchangeRestore) MailSubject(subjectSubstrings []string) []ExchangeScope {
return []ExchangeScope{
makeFilterScope[ExchangeScope](ExchangeMail, ExchangeInfoMailSubject, subjectSubstrings),
makeFilterScope[ExchangeScope](ExchangeMail, ExchangeFilterMailSubject, subjectSubstrings),
}
}
@ -372,57 +372,27 @@ func (d ExchangeDestination) Set(cat exchangeCategory, dest string) error {
// exchangeCategory enumerates the type of the lowest level
// of data specified by the scope.
type exchangeCategory int
type exchangeCategory string
// interface compliance checks
var _ categorizer = ExchangeCategoryUnknown
//go:generate stringer -type=exchangeCategory
const (
ExchangeCategoryUnknown exchangeCategory = iota
ExchangeCategoryUnknown exchangeCategory = ""
// types of data identified by exchange
ExchangeContact
ExchangeContactFolder
ExchangeEvent
ExchangeMail
ExchangeMailFolder
ExchangeUser
ExchangeContact exchangeCategory = "ExchangeContact"
ExchangeContactFolder exchangeCategory = "ExchangeContactFolder"
ExchangeEvent exchangeCategory = "ExchangeEvent"
ExchangeMail exchangeCategory = "ExchangeMail"
ExchangeMailFolder exchangeCategory = "ExchangeFolder"
ExchangeUser exchangeCategory = "ExchangeUser"
// filterable topics identified by exchange
ExchangeInfoMailSender exchangeCategory = iota + 100 // offset to pad out future data additions
ExchangeInfoMailSubject
ExchangeInfoMailReceivedAfter
ExchangeInfoMailReceivedBefore
ExchangeFilterMailSender exchangeCategory = "ExchangeFilterMailSender"
ExchangeFilterMailSubject exchangeCategory = "ExchangeFilterMailSubject"
ExchangeFilterMailReceivedAfter exchangeCategory = "ExchangeFilterMailReceivedAfter"
ExchangeFilterMailReceivedBefore exchangeCategory = "ExchangeFilterMailReceivedBefore"
)
func exchangeCatAtoI(s string) exchangeCategory {
switch s {
// data types
case ExchangeContact.String():
return ExchangeContact
case ExchangeContactFolder.String():
return ExchangeContactFolder
case ExchangeEvent.String():
return ExchangeEvent
case ExchangeMail.String():
return ExchangeMail
case ExchangeMailFolder.String():
return ExchangeMailFolder
case ExchangeUser.String():
return ExchangeUser
// filters
case ExchangeInfoMailSender.String():
return ExchangeInfoMailSender
case ExchangeInfoMailSubject.String():
return ExchangeInfoMailSubject
case ExchangeInfoMailReceivedAfter.String():
return ExchangeInfoMailReceivedAfter
case ExchangeInfoMailReceivedBefore.String():
return ExchangeInfoMailReceivedBefore
default:
return ExchangeCategoryUnknown
}
}
// exchangePathSet describes the category type keys used in Exchange paths.
// The order of each slice is important, and should match the order in which
// these types appear in the canonical Path for each type.
@ -433,6 +403,10 @@ var exchangePathSet = map[categorizer][]categorizer{
ExchangeUser: {ExchangeUser}, // the root category must be represented
}
func (ec exchangeCategory) String() string {
return string(ec)
}
// leafCat returns the leaf category of the receiver.
// If the receiver category has multiple leaves (ex: User) or no leaves,
// (ex: Unknown), the receiver itself is returned.
@ -530,7 +504,7 @@ var _ scoper = &ExchangeScope{}
// Category describes the type of the data in scope.
func (s ExchangeScope) Category() exchangeCategory {
return exchangeCatAtoI(s[scopeKeyCategory])
return exchangeCategory(s[scopeKeyCategory])
}
// categorizer type is a generic wrapper around Category.
@ -548,7 +522,7 @@ func (s ExchangeScope) Contains(cat exchangeCategory, target string) bool {
// FilterCategory returns the category enum of the scope filter.
// If the scope is not a filter type, returns ExchangeUnknownCategory.
func (s ExchangeScope) FilterCategory() exchangeCategory {
return exchangeCatAtoI(s[scopeKeyInfoFilter])
return exchangeCategory(s[scopeKeyInfoFilter])
}
// Granularity describes the granularity (directory || item)
@ -627,7 +601,7 @@ func (s ExchangeScope) matchesEntry(
return matchesPathValues(s, cat.(exchangeCategory), pathValues) || s.matchesInfo(entry.Exchange)
}
// matchesInfo handles the standard behavior when comparing a scope and an exchangeInfo
// matchesInfo handles the standard behavior when comparing a scope and an ExchangeFilter
// returns true if the scope and info match for the provided category.
func (s ExchangeScope) matchesInfo(info *details.ExchangeInfo) bool {
// we need values to match against
@ -654,19 +628,19 @@ func (s ExchangeScope) matchesInfo(info *details.ExchangeInfo) bool {
// any of the targets for a given info filter may succeed.
for _, target := range targets {
switch filterCat {
case ExchangeInfoMailSender:
case ExchangeFilterMailSender:
if target == info.Sender {
return true
}
case ExchangeInfoMailSubject:
case ExchangeFilterMailSubject:
if strings.Contains(info.Subject, target) {
return true
}
case ExchangeInfoMailReceivedAfter:
case ExchangeFilterMailReceivedAfter:
if target < common.FormatTime(info.Received) {
return true
}
case ExchangeInfoMailReceivedBefore:
case ExchangeFilterMailReceivedBefore:
if target > common.FormatTime(info.Received) {
return true
}

View File

@ -1034,7 +1034,7 @@ func (suite *ExchangeSelectorSuite) TestExchangeCategory_leafCat() {
cat exchangeCategory
expect exchangeCategory
}{
{exchangeCategory(-1), exchangeCategory(-1)},
{exchangeCategory("foo"), exchangeCategory("foo")},
{ExchangeCategoryUnknown, ExchangeCategoryUnknown},
{ExchangeUser, ExchangeUser},
{ExchangeMailFolder, ExchangeMail},

View File

@ -1,44 +0,0 @@
// Code generated by "stringer -type=exchangeCategory"; DO NOT EDIT.
package selectors
import "strconv"
func _() {
// An "invalid array index" compiler error signifies that the constant values have changed.
// Re-run the stringer command to generate them again.
var x [1]struct{}
_ = x[ExchangeCategoryUnknown-0]
_ = x[ExchangeContact-1]
_ = x[ExchangeContactFolder-2]
_ = x[ExchangeEvent-3]
_ = x[ExchangeMail-4]
_ = x[ExchangeMailFolder-5]
_ = x[ExchangeUser-6]
_ = x[ExchangeInfoMailSender-107]
_ = x[ExchangeInfoMailSubject-108]
_ = x[ExchangeInfoMailReceivedAfter-109]
_ = x[ExchangeInfoMailReceivedBefore-110]
}
const (
_exchangeCategory_name_0 = "ExchangeCategoryUnknownExchangeContactExchangeContactFolderExchangeEventExchangeMailExchangeMailFolderExchangeUser"
_exchangeCategory_name_1 = "ExchangeInfoMailSenderExchangeInfoMailSubjectExchangeInfoMailReceivedAfterExchangeInfoMailReceivedBefore"
)
var (
_exchangeCategory_index_0 = [...]uint8{0, 23, 38, 59, 72, 84, 102, 114}
_exchangeCategory_index_1 = [...]uint8{0, 22, 45, 74, 104}
)
func (i exchangeCategory) String() string {
switch {
case 0 <= i && i <= 6:
return _exchangeCategory_name_0[_exchangeCategory_index_0[i]:_exchangeCategory_index_0[i+1]]
case 107 <= i && i <= 110:
i -= 107
return _exchangeCategory_name_1[_exchangeCategory_index_1[i]:_exchangeCategory_index_1[i+1]]
default:
return "exchangeCategory(" + strconv.FormatInt(int64(i), 10) + ")"
}
}

View File

@ -7,25 +7,18 @@ import "github.com/alcionai/corso/pkg/backup/details"
// ---------------------------------------------------------------------------
// categorizer
type mockCategorizer int
type mockCategorizer string
const (
unknownCatStub mockCategorizer = iota
rootCatStub
leafCatStub
unknownCatStub mockCategorizer = ""
rootCatStub mockCategorizer = "rootCatStub"
leafCatStub mockCategorizer = "leafCatStub"
)
var _ categorizer = unknownCatStub
func (mc mockCategorizer) String() string {
switch mc {
case leafCatStub:
return "leaf"
case rootCatStub:
return "root"
}
return "unknown"
return string(mc)
}
func (mc mockCategorizer) leafCat() categorizer {

View File

@ -139,29 +139,17 @@ func (s *oneDrive) DiscreteScopes(userPNs []string) []OneDriveScope {
// oneDriveCategory enumerates the type of the lowest level
// of data () in a scope.
type oneDriveCategory int
type oneDriveCategory string
// interface compliance checks
var _ categorizer = OneDriveCategoryUnknown
//go:generate go run golang.org/x/tools/cmd/stringer -type=oneDriveCategory
const (
OneDriveCategoryUnknown oneDriveCategory = iota
OneDriveCategoryUnknown oneDriveCategory = ""
// types of data identified by OneDrive
OneDriveUser
OneDriveUser oneDriveCategory = "OneDriveUser"
)
func oneDriveCatAtoI(s string) oneDriveCategory {
switch s {
// data types
case OneDriveUser.String():
return OneDriveUser
// filters
default:
return OneDriveCategoryUnknown
}
}
// oneDrivePathSet describes the category type keys used in OneDrive paths.
// The order of each slice is important, and should match the order in which
// these types appear in the canonical Path for each type.
@ -169,6 +157,10 @@ var oneDrivePathSet = map[categorizer][]categorizer{
OneDriveUser: {OneDriveUser}, // the root category must be represented
}
func (c oneDriveCategory) String() string {
return string(c)
}
// leafCat returns the leaf category of the receiver.
// If the receiver category has multiple leaves (ex: User) or no leaves,
// (ex: Unknown), the receiver itself is returned.
@ -234,7 +226,7 @@ var _ scoper = &OneDriveScope{}
// Category describes the type of the data in scope.
func (s OneDriveScope) Category() oneDriveCategory {
return oneDriveCatAtoI(s[scopeKeyCategory])
return oneDriveCategory(s[scopeKeyCategory])
}
// categorizer type is a generic wrapper around Category.
@ -246,7 +238,7 @@ func (s OneDriveScope) categorizer() categorizer {
// FilterCategory returns the category enum of the scope filter.
// If the scope is not a filter type, returns OneDriveUnknownCategory.
func (s OneDriveScope) FilterCategory() oneDriveCategory {
return oneDriveCatAtoI(s[scopeKeyInfoFilter])
return oneDriveCategory(s[scopeKeyInfoFilter])
}
// Granularity describes the granularity (directory || item)

View File

@ -1,24 +0,0 @@
// Code generated by "stringer -type=oneDriveCategory"; DO NOT EDIT.
package selectors
import "strconv"
func _() {
// An "invalid array index" compiler error signifies that the constant values have changed.
// Re-run the stringer command to generate them again.
var x [1]struct{}
_ = x[OneDriveCategoryUnknown-0]
_ = x[OneDriveUser-1]
}
const _oneDriveCategory_name = "OneDriveCategoryUnknownOneDriveUser"
var _oneDriveCategory_index = [...]uint8{0, 23, 35}
func (i oneDriveCategory) String() string {
if i < 0 || i >= oneDriveCategory(len(_oneDriveCategory_index)-1) {
return "oneDriveCategory(" + strconv.FormatInt(int64(i), 10) + ")"
}
return _oneDriveCategory_name[_oneDriveCategory_index[i]:_oneDriveCategory_index[i+1]]
}

View File

@ -51,7 +51,7 @@ type (
}
// categoryT is the generic type interface of a categorizer
categoryT interface {
~int
~string
categorizer
}
)