func (u *StringList) Contains(p string) bool {
	for _, t := range *u {
		if t == p {
			return true
		}
	}
	return false
}
Contains returns true if the list contains the string
package jwt
import (
	"encoding/json"
	"fmt"
	"net"
	"strings"
	"time"
)
type ExportType int
const (
	Unknown ExportType = iota
	Stream
	Service
)
func (t ExportType) String() string {
	switch t {
	case Stream:
		return "stream"
	case Service:
		return "service"
	}
	return "unknown"
}
func (t *ExportType) MarshalJSON() ([]byte, error) {
	switch *t {
	case Stream:
		return []byte("\"stream\""), nil
	case Service:
		return []byte("\"service\""), nil
	}
	return nil, fmt.Errorf("unknown export type")
}
func (t *ExportType) UnmarshalJSON(b []byte) error {
	var j string
	err := json.Unmarshal(b, &j)
	if err != nil {
		return err
	}
	switch j {
	case "stream":
		*t = Stream
		return nil
	case "service":
		*t = Service
		return nil
	}
	return fmt.Errorf("unknown export type")
}
type Subject string
func (s Subject) Validate(vr *ValidationResults) {
	v := string(s)
	if v == "" {
		vr.AddError("subject cannot be empty")
	}
	if strings.Contains(v, " ") {
		vr.AddError("subject %q cannot have spaces", v)
	}
}
func (s Subject) HasWildCards() bool {
	v := string(s)
	return strings.HasSuffix(v, ".>") ||
		strings.Contains(v, ".*.") ||
		strings.HasSuffix(v, ".*") ||
		strings.HasPrefix(v, "*.") ||
		v == "*" ||
		v == ">"
}
func (s Subject) IsContainedIn(other Subject) bool {
	otherArray := strings.Split(string(other), ".")
	myArray := strings.Split(string(s), ".")
	if len(myArray) > len(otherArray) && otherArray[len(otherArray)-1] != ">" {
		return false
	}
	if len(myArray) < len(otherArray) {
		return false
	}
	for ind, tok := range otherArray {
		myTok := myArray[ind]
		if ind == len(otherArray)-1 && tok == ">" {
			return true
		}
		if tok != myTok && tok != "*" {
			return false
		}
	}
	return true
}
type NamedSubject struct {
	Name    string  `json:"name,omitempty"`
	Subject Subject `json:"subject,omitempty"`
}
func (ns *NamedSubject) Validate(vr *ValidationResults) {
	ns.Subject.Validate(vr)
}
type TimeRange struct {
	Start string `json:"start,omitempty"`
	End   string `json:"end,omitempty"`
}
func (tr *TimeRange) Validate(vr *ValidationResults) {
	format := "15:04:05"
	if tr.Start == "" {
		vr.AddError("time ranges start must contain a start")
	} else {
		_, err := time.Parse(format, tr.Start)
		if err != nil {
			vr.AddError("start in time range is invalid %q", tr.Start)
		}
	}
	if tr.End == "" {
		vr.AddError("time ranges end must contain an end")
	} else {
		_, err := time.Parse(format, tr.End)
		if err != nil {
			vr.AddError("end in time range is invalid %q", tr.End)
		}
	}
}
type Limits struct {
	Max     int64       `json:"max,omitempty"`
	Payload int64       `json:"payload,omitempty"`
	Src     string      `json:"src,omitempty"`
	Times   []TimeRange `json:"times,omitempty"`
}
func (l *Limits) Validate(vr *ValidationResults) {
	if l.Max < 0 {
		vr.AddError("limits cannot contain a negative maximum, %d", l.Max)
	}
	if l.Payload < 0 {
		vr.AddError("limits cannot contain a negative payload, %d", l.Payload)
	}
	if l.Src != "" {
		elements := strings.Split(l.Src, ",")
		for _, cidr := range elements {
			cidr = strings.TrimSpace(cidr)
			_, ipNet, err := net.ParseCIDR(cidr)
			if err != nil || ipNet == nil {
				vr.AddError("invalid cidr %q in user src limits", cidr)
			}
		}
	}
	if l.Times != nil && len(l.Times) > 0 {
		for _, t := range l.Times {
			t.Validate(vr)
		}
	}
}
type Permission struct {
	Allow StringList `json:"allow,omitempty"`
	Deny  StringList `json:"deny,omitempty"`
}
func (p *Permission) Validate(vr *ValidationResults) {
	for _, subj := range p.Allow {
		Subject(subj).Validate(vr)
	}
	for _, subj := range p.Deny {
		Subject(subj).Validate(vr)
	}
}
type ResponsePermission struct {
	MaxMsgs int           `json:"max"`
	Expires time.Duration `json:"ttl"`
}
func (p *ResponsePermission) Validate(vr *ValidationResults) {
}
type Permissions struct {
	Pub  Permission          `json:"pub,omitempty"`
	Sub  Permission          `json:"sub,omitempty"`
	Resp *ResponsePermission `json:"resp,omitempty"`
}
func (p *Permissions) Validate(vr *ValidationResults) {
	p.Pub.Validate(vr)
	p.Sub.Validate(vr)
	if p.Resp != nil {
		p.Resp.Validate(vr)
	}
}
type StringList []string