func (b *buneary) setupChannel() error {
	if b.channel != nil {
		if err := b.channel.Close(); err != nil {
			return fmt.Errorf("closing AMQP channel: %w", err)
		}
	}
	conn, err := amqp.Dial(b.config.URI())
	if err != nil {
		return fmt.Errorf("dialling RabbitMQ server: %w", err)
	}
	if b.channel, err = conn.Channel(); err != nil {
		return fmt.Errorf("establishing AMQP channel: %w", err)
	}
	return nil
}
setupChannel dials the configured RabbitMQ server, sets up a connection and opens a
channel from that connection, which should be closed once buneary has finished.
package main
import (
	"bytes"
	"encoding/json"
	"fmt"
	"net/http"
	"strconv"
	"strings"
	"time"
	rabbithole "github.com/michaelklishin/rabbit-hole/v2"
	"github.com/streadway/amqp"
)
const (
	amqpDefaultPort = 5672
	apiDefaultPort  = 15672
)
type (
	ExchangeType string
	QueueType string
	BindingType string
)
const (
	Direct ExchangeType = "direct"
	Headers = "headers"
	Fanout = "fanout"
	Topic = "topic"
	Classic QueueType = "classic"
	Quorum = "quorum"
	ToQueue BindingType = "queue"
	ToExchange = "exchange"
)
type Provider interface {
	CreateExchange(exchange Exchange) error
	CreateQueue(queue Queue) (string, error)
	CreateBinding(binding Binding) error
	GetExchanges(filter func(exchange Exchange) bool) ([]Exchange, error)
	GetQueues(filter func(queue Queue) bool) ([]Queue, error)
	GetBindings(filter func(binding Binding) bool) ([]Binding, error)
	GetMessages(queue Queue, max int, requeue bool) ([]Message, error)
	PublishMessage(message Message) error
	DeleteExchange(exchange Exchange) error
	DeleteQueue(queue Queue) error
}
type RabbitMQConfig struct {
	Address string
	User string
	Password string
}
func (a *RabbitMQConfig) URI() string {
	tokens := strings.Split(a.Address, ":")
	var port string
	if len(tokens) == 2 {
		port = tokens[1]
	} else {
		port = strconv.Itoa(amqpDefaultPort)
	}
	uri := fmt.Sprintf("amqp://%s:%s@%s:%s", a.User, a.Password, tokens[0], port)
	return uri
}
func (a *RabbitMQConfig) apiURI() string {
	tokens := strings.Split(a.Address, ":")
	var port string
	if len(tokens) == 2 {
		port = tokens[1]
	} else {
		port = strconv.Itoa(apiDefaultPort)
	}
	uri := fmt.Sprintf("http://%s:%s", tokens[0], port)
	return uri
}
type Exchange struct {
	Name string
	Type ExchangeType
	Durable bool
	AutoDelete bool
	Internal bool
	NoWait bool
}
type Queue struct {
	Name string
	Type QueueType
	Durable bool
	AutoDelete bool
}
type Binding struct {
	Type BindingType
	From Exchange
	TargetName string
	Key string
}
type Message struct {
	Target Exchange
	Headers map[string]interface{}
	RoutingKey string
	Body []byte
}
func NewProvider(config *RabbitMQConfig) Provider {
	b := buneary{
		config: config,
	}
	return &b
}
type buneary struct {
	config  *RabbitMQConfig
	channel *amqp.Channel
	client  *rabbithole.Client
}