Assert type from a generic

Viewed 51

I have a relatively small app that reads from an AWS SQS queue. I have no control over these and the message structures and I need to handle at minimum two different message structures.

In an attempt to keep the codebase clean I opted to go down the route of using generic types for my queue handling functions as each strategy requires a different value passed to the handler function. I've slimmed this example down but it holds the pertanent data.

My question: Given that the generic type M could be one of two values how can I use that type when I know for sure I have one and only one of the contained types?

type MessageType interface {
    types.Message | []types.Message
}

const (
    CONCURRENT uint8 = 1 << iota
    AGGREGATE
)

func SubscribeTo[M MessageType](queueName string, handler func(msg M, del chan *string), strategy uint8) {
    go func() {
        switch true {
        case strategy&CONCURRENT != 0:
            useConcurrentPoller(queueName, handler)
            break
        case strategy&AGGREGATE != 0:
        default:
            useAggregatePoller(queueName, handler)
            break
        }
    }
}

func useConcurrentPoller[M MessageType](queueName string, concurrency int, handler func(msg M, del chan *string) {
   // Queue connection and message retrieval logic removed for brevity
   var deleteChannel = make(chan *string, 100)

   for _, sqsMessage := range msgResult.Messages {
       // sqsMessage is of type `types.Message` but errors as
       // Cannot use 'sqsMessage' (type types.Message) as the type M

       handler(sqsMessage, deleteChannel)
   }
}

func useAggregatePoller[M MessageType](queueName string, handler func(msg M, del chan *string) {
   // Queue connection and message retrieval logic removed for brevity
   var deleteChannel = make(chan *string, 100)
   handler(msgResult.Messages, deleteChannel)
}

I'm sure the solution is probably staring me in the face but somehow I can't see it. Type asserting on sqsMessage won't work as it's a non interface type (at least from what I gather).

Can anyone see how I can get this working?

0 Answers
Related