mirror of
				https://codeberg.org/forgejo/forgejo.git
				synced 2025-11-04 08:21:11 +00:00 
			
		
		
		
	* update github.com/blevesearch/bleve v2.0.2 -> v2.0.3 * github.com/denisenkom/go-mssqldb v0.9.0 -> v0.10.0 * github.com/editorconfig/editorconfig-core-go v2.4.1 -> v2.4.2 * github.com/go-chi/cors v1.1.1 -> v1.2.0 * github.com/go-git/go-billy v5.0.0 -> v5.1.0 * github.com/go-git/go-git v5.2.0 -> v5.3.0 * github.com/go-ldap/ldap v3.2.4 -> v3.3.0 * github.com/go-redis/redis v8.6.0 -> v8.8.2 * github.com/go-sql-driver/mysql v1.5.0 -> v1.6.0 * github.com/go-swagger/go-swagger v0.26.1 -> v0.27.0 * github.com/lib/pq v1.9.0 -> v1.10.1 * github.com/mattn/go-sqlite3 v1.14.6 -> v1.14.7 * github.com/go-testfixtures/testfixtures v3.5.0 -> v3.6.0 * github.com/issue9/identicon v1.0.1 -> v1.2.0 * github.com/klauspost/compress v1.11.8 -> v1.12.1 * github.com/mgechev/revive v1.0.3 -> v1.0.6 * github.com/microcosm-cc/bluemonday v1.0.7 -> v1.0.8 * github.com/niklasfasching/go-org v1.4.0 -> v1.5.0 * github.com/olivere/elastic v7.0.22 -> v7.0.24 * github.com/pelletier/go-toml v1.8.1 -> v1.9.0 * github.com/prometheus/client_golang v1.9.0 -> v1.10.0 * github.com/xanzy/go-gitlab v0.44.0 -> v0.48.0 * github.com/yuin/goldmark v1.3.3 -> v1.3.5 * github.com/6543/go-version v1.2.4 -> v1.3.1 * do github.com/lib/pq v1.10.0 -> v1.10.1 again ...
		
			
				
	
	
		
			320 lines
		
	
	
	
		
			8 KiB
		
	
	
	
		
			Go
		
	
	
	
		
			Vendored
		
	
	
	
			
		
		
	
	
			320 lines
		
	
	
	
		
			8 KiB
		
	
	
	
		
			Go
		
	
	
	
		
			Vendored
		
	
	
	
// Copyright 2015 go-swagger maintainers
 | 
						|
//
 | 
						|
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
						|
// you may not use this file except in compliance with the License.
 | 
						|
// You may obtain a copy of the License at
 | 
						|
//
 | 
						|
//    http://www.apache.org/licenses/LICENSE-2.0
 | 
						|
//
 | 
						|
// Unless required by applicable law or agreed to in writing, software
 | 
						|
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
						|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
						|
// See the License for the specific language governing permissions and
 | 
						|
// limitations under the License.
 | 
						|
 | 
						|
package strfmt
 | 
						|
 | 
						|
import (
 | 
						|
	"encoding"
 | 
						|
	"fmt"
 | 
						|
	"reflect"
 | 
						|
	"strings"
 | 
						|
	"sync"
 | 
						|
	"time"
 | 
						|
 | 
						|
	"github.com/go-openapi/errors"
 | 
						|
	"github.com/mitchellh/mapstructure"
 | 
						|
)
 | 
						|
 | 
						|
// Default is the default formats registry
 | 
						|
var Default = NewSeededFormats(nil, nil)
 | 
						|
 | 
						|
// Validator represents a validator for a string format.
 | 
						|
type Validator func(string) bool
 | 
						|
 | 
						|
// Format represents a string format.
 | 
						|
//
 | 
						|
// All implementations of Format provide a string representation and text
 | 
						|
// marshaling/unmarshaling interface to be used by encoders (e.g. encoding/json).
 | 
						|
type Format interface {
 | 
						|
	String() string
 | 
						|
	encoding.TextMarshaler
 | 
						|
	encoding.TextUnmarshaler
 | 
						|
}
 | 
						|
 | 
						|
// Registry is a registry of string formats, with a validation method.
 | 
						|
type Registry interface {
 | 
						|
	Add(string, Format, Validator) bool
 | 
						|
	DelByName(string) bool
 | 
						|
	GetType(string) (reflect.Type, bool)
 | 
						|
	ContainsName(string) bool
 | 
						|
	Validates(string, string) bool
 | 
						|
	Parse(string, string) (interface{}, error)
 | 
						|
	MapStructureHookFunc() mapstructure.DecodeHookFunc
 | 
						|
}
 | 
						|
 | 
						|
type knownFormat struct {
 | 
						|
	Name      string
 | 
						|
	OrigName  string
 | 
						|
	Type      reflect.Type
 | 
						|
	Validator Validator
 | 
						|
}
 | 
						|
 | 
						|
// NameNormalizer is a function that normalizes a format name.
 | 
						|
type NameNormalizer func(string) string
 | 
						|
 | 
						|
// DefaultNameNormalizer removes all dashes
 | 
						|
func DefaultNameNormalizer(name string) string {
 | 
						|
	return strings.ReplaceAll(name, "-", "")
 | 
						|
}
 | 
						|
 | 
						|
type defaultFormats struct {
 | 
						|
	sync.Mutex
 | 
						|
	data          []knownFormat
 | 
						|
	normalizeName NameNormalizer
 | 
						|
}
 | 
						|
 | 
						|
// NewFormats creates a new formats registry seeded with the values from the default
 | 
						|
func NewFormats() Registry {
 | 
						|
	return NewSeededFormats(Default.(*defaultFormats).data, nil)
 | 
						|
}
 | 
						|
 | 
						|
// NewSeededFormats creates a new formats registry
 | 
						|
func NewSeededFormats(seeds []knownFormat, normalizer NameNormalizer) Registry {
 | 
						|
	if normalizer == nil {
 | 
						|
		normalizer = DefaultNameNormalizer
 | 
						|
	}
 | 
						|
	// copy here, don't modify original
 | 
						|
	d := append([]knownFormat(nil), seeds...)
 | 
						|
	return &defaultFormats{
 | 
						|
		data:          d,
 | 
						|
		normalizeName: normalizer,
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// MapStructureHookFunc is a decode hook function for mapstructure
 | 
						|
func (f *defaultFormats) MapStructureHookFunc() mapstructure.DecodeHookFunc {
 | 
						|
	return func(from reflect.Type, to reflect.Type, data interface{}) (interface{}, error) {
 | 
						|
		if from.Kind() != reflect.String {
 | 
						|
			return data, nil
 | 
						|
		}
 | 
						|
		for _, v := range f.data {
 | 
						|
			tpe, _ := f.GetType(v.Name)
 | 
						|
			if to == tpe {
 | 
						|
				switch v.Name {
 | 
						|
				case "date":
 | 
						|
					d, err := time.Parse(RFC3339FullDate, data.(string))
 | 
						|
					if err != nil {
 | 
						|
						return nil, err
 | 
						|
					}
 | 
						|
					return Date(d), nil
 | 
						|
				case "datetime":
 | 
						|
					input := data.(string)
 | 
						|
					if len(input) == 0 {
 | 
						|
						return nil, fmt.Errorf("empty string is an invalid datetime format")
 | 
						|
					}
 | 
						|
					return ParseDateTime(input)
 | 
						|
				case "duration":
 | 
						|
					dur, err := ParseDuration(data.(string))
 | 
						|
					if err != nil {
 | 
						|
						return nil, err
 | 
						|
					}
 | 
						|
					return Duration(dur), nil
 | 
						|
				case "uri":
 | 
						|
					return URI(data.(string)), nil
 | 
						|
				case "email":
 | 
						|
					return Email(data.(string)), nil
 | 
						|
				case "uuid":
 | 
						|
					return UUID(data.(string)), nil
 | 
						|
				case "uuid3":
 | 
						|
					return UUID3(data.(string)), nil
 | 
						|
				case "uuid4":
 | 
						|
					return UUID4(data.(string)), nil
 | 
						|
				case "uuid5":
 | 
						|
					return UUID5(data.(string)), nil
 | 
						|
				case "hostname":
 | 
						|
					return Hostname(data.(string)), nil
 | 
						|
				case "ipv4":
 | 
						|
					return IPv4(data.(string)), nil
 | 
						|
				case "ipv6":
 | 
						|
					return IPv6(data.(string)), nil
 | 
						|
				case "cidr":
 | 
						|
					return CIDR(data.(string)), nil
 | 
						|
				case "mac":
 | 
						|
					return MAC(data.(string)), nil
 | 
						|
				case "isbn":
 | 
						|
					return ISBN(data.(string)), nil
 | 
						|
				case "isbn10":
 | 
						|
					return ISBN10(data.(string)), nil
 | 
						|
				case "isbn13":
 | 
						|
					return ISBN13(data.(string)), nil
 | 
						|
				case "creditcard":
 | 
						|
					return CreditCard(data.(string)), nil
 | 
						|
				case "ssn":
 | 
						|
					return SSN(data.(string)), nil
 | 
						|
				case "hexcolor":
 | 
						|
					return HexColor(data.(string)), nil
 | 
						|
				case "rgbcolor":
 | 
						|
					return RGBColor(data.(string)), nil
 | 
						|
				case "byte":
 | 
						|
					return Base64(data.(string)), nil
 | 
						|
				case "password":
 | 
						|
					return Password(data.(string)), nil
 | 
						|
				case "ulid":
 | 
						|
					ulid, err := ParseULID(data.(string))
 | 
						|
					if err != nil {
 | 
						|
						return nil, err
 | 
						|
					}
 | 
						|
					return ulid, nil
 | 
						|
				default:
 | 
						|
					return nil, errors.InvalidTypeName(v.Name)
 | 
						|
				}
 | 
						|
			}
 | 
						|
		}
 | 
						|
		return data, nil
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// Add adds a new format, return true if this was a new item instead of a replacement
 | 
						|
func (f *defaultFormats) Add(name string, strfmt Format, validator Validator) bool {
 | 
						|
	f.Lock()
 | 
						|
	defer f.Unlock()
 | 
						|
 | 
						|
	nme := f.normalizeName(name)
 | 
						|
 | 
						|
	tpe := reflect.TypeOf(strfmt)
 | 
						|
	if tpe.Kind() == reflect.Ptr {
 | 
						|
		tpe = tpe.Elem()
 | 
						|
	}
 | 
						|
 | 
						|
	for i := range f.data {
 | 
						|
		v := &f.data[i]
 | 
						|
		if v.Name == nme {
 | 
						|
			v.Type = tpe
 | 
						|
			v.Validator = validator
 | 
						|
			return false
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	// turns out it's new after all
 | 
						|
	f.data = append(f.data, knownFormat{Name: nme, OrigName: name, Type: tpe, Validator: validator})
 | 
						|
	return true
 | 
						|
}
 | 
						|
 | 
						|
// GetType gets the type for the specified name
 | 
						|
func (f *defaultFormats) GetType(name string) (reflect.Type, bool) {
 | 
						|
	f.Lock()
 | 
						|
	defer f.Unlock()
 | 
						|
	nme := f.normalizeName(name)
 | 
						|
	for _, v := range f.data {
 | 
						|
		if v.Name == nme {
 | 
						|
			return v.Type, true
 | 
						|
		}
 | 
						|
	}
 | 
						|
	return nil, false
 | 
						|
}
 | 
						|
 | 
						|
// DelByName removes the format by the specified name, returns true when an item was actually removed
 | 
						|
func (f *defaultFormats) DelByName(name string) bool {
 | 
						|
	f.Lock()
 | 
						|
	defer f.Unlock()
 | 
						|
 | 
						|
	nme := f.normalizeName(name)
 | 
						|
 | 
						|
	for i, v := range f.data {
 | 
						|
		if v.Name == nme {
 | 
						|
			f.data[i] = knownFormat{} // release
 | 
						|
			f.data = append(f.data[:i], f.data[i+1:]...)
 | 
						|
			return true
 | 
						|
		}
 | 
						|
	}
 | 
						|
	return false
 | 
						|
}
 | 
						|
 | 
						|
// DelByFormat removes the specified format, returns true when an item was actually removed
 | 
						|
func (f *defaultFormats) DelByFormat(strfmt Format) bool {
 | 
						|
	f.Lock()
 | 
						|
	defer f.Unlock()
 | 
						|
 | 
						|
	tpe := reflect.TypeOf(strfmt)
 | 
						|
	if tpe.Kind() == reflect.Ptr {
 | 
						|
		tpe = tpe.Elem()
 | 
						|
	}
 | 
						|
 | 
						|
	for i, v := range f.data {
 | 
						|
		if v.Type == tpe {
 | 
						|
			f.data[i] = knownFormat{} // release
 | 
						|
			f.data = append(f.data[:i], f.data[i+1:]...)
 | 
						|
			return true
 | 
						|
		}
 | 
						|
	}
 | 
						|
	return false
 | 
						|
}
 | 
						|
 | 
						|
// ContainsName returns true if this registry contains the specified name
 | 
						|
func (f *defaultFormats) ContainsName(name string) bool {
 | 
						|
	f.Lock()
 | 
						|
	defer f.Unlock()
 | 
						|
	nme := f.normalizeName(name)
 | 
						|
	for _, v := range f.data {
 | 
						|
		if v.Name == nme {
 | 
						|
			return true
 | 
						|
		}
 | 
						|
	}
 | 
						|
	return false
 | 
						|
}
 | 
						|
 | 
						|
// ContainsFormat returns true if this registry contains the specified format
 | 
						|
func (f *defaultFormats) ContainsFormat(strfmt Format) bool {
 | 
						|
	f.Lock()
 | 
						|
	defer f.Unlock()
 | 
						|
	tpe := reflect.TypeOf(strfmt)
 | 
						|
	if tpe.Kind() == reflect.Ptr {
 | 
						|
		tpe = tpe.Elem()
 | 
						|
	}
 | 
						|
 | 
						|
	for _, v := range f.data {
 | 
						|
		if v.Type == tpe {
 | 
						|
			return true
 | 
						|
		}
 | 
						|
	}
 | 
						|
	return false
 | 
						|
}
 | 
						|
 | 
						|
// Validates passed data against format.
 | 
						|
//
 | 
						|
// Note that the format name is automatically normalized, e.g. one may
 | 
						|
// use "date-time" to use the "datetime" format validator.
 | 
						|
func (f *defaultFormats) Validates(name, data string) bool {
 | 
						|
	f.Lock()
 | 
						|
	defer f.Unlock()
 | 
						|
	nme := f.normalizeName(name)
 | 
						|
	for _, v := range f.data {
 | 
						|
		if v.Name == nme {
 | 
						|
			return v.Validator(data)
 | 
						|
		}
 | 
						|
	}
 | 
						|
	return false
 | 
						|
}
 | 
						|
 | 
						|
// Parse a string into the appropriate format representation type.
 | 
						|
//
 | 
						|
// E.g. parsing a string a "date" will return a Date type.
 | 
						|
func (f *defaultFormats) Parse(name, data string) (interface{}, error) {
 | 
						|
	f.Lock()
 | 
						|
	defer f.Unlock()
 | 
						|
	nme := f.normalizeName(name)
 | 
						|
	for _, v := range f.data {
 | 
						|
		if v.Name == nme {
 | 
						|
			nw := reflect.New(v.Type).Interface()
 | 
						|
			if dec, ok := nw.(encoding.TextUnmarshaler); ok {
 | 
						|
				if err := dec.UnmarshalText([]byte(data)); err != nil {
 | 
						|
					return nil, err
 | 
						|
				}
 | 
						|
				return nw, nil
 | 
						|
			}
 | 
						|
			return nil, errors.InvalidTypeName(name)
 | 
						|
		}
 | 
						|
	}
 | 
						|
	return nil, errors.InvalidTypeName(name)
 | 
						|
}
 |