func (im *IdentityMapping) String() string {
	return fmt.Sprintf("IdentityMapping <IP:%s Port:%d Protocol:%s>",
		im.IP.String(), im.Port, im.Protocol.String())
}
String converts identity mapping into a human-readable string.
package natplugin
import (
	"fmt"
	"net"
	"github.com/contiv/vpp/plugins/service/renderer"
)
type IdentityMappings struct {
	list []*IdentityMapping
}
type IdentityMapping struct {
	IP       net.IP
	Port     uint16
	Protocol renderer.ProtocolType
	VrfID    uint32
}
func (ims *IdentityMappings) String() string {
	mappings := ""
	for idx, mapping := range ims.list {
		mappings += mapping.String()
		if idx < len(ims.list)-1 {
			mappings += ", "
		}
	}
	return fmt.Sprintf("IdentityMappings [%s]", mappings)
}
func (ims *IdentityMappings) Count() int {
	return len(ims.list)
}
func (ims *IdentityMappings) Has(im *IdentityMapping) bool {
	for _, mapping := range ims.list {
		if mapping.Equals(im) {
			return true
		}
	}
	return false
}
func (ims *IdentityMappings) Add(im *IdentityMapping) bool {
	if ims.Has(im) {
		return false
	}
	ims.list = append(ims.list, im)
	return true
}
func (ims *IdentityMappings) Join(ims2 *IdentityMappings) bool {
	allAdded := true
	for _, im2 := range ims2.list {
		if !ims.Add(im2) {
			allAdded = false
		}
	}
	return allAdded
}
func (ims *IdentityMappings) Subtract(ims2 *IdentityMappings) bool {
	allRemoved := true
	for _, im2 := range ims2.list {
		removed := false
		filtered := []*IdentityMapping{}
		for _, im := range ims.list {
			if im.Equals(im2) {
				removed = true
			} else {
				filtered = append(filtered, im)
			}
		}
		if !removed {
			allRemoved = false
		} else {
			ims.list = filtered
		}
	}
	return allRemoved
}