mirror of
				https://github.com/superseriousbusiness/gotosocial.git
				synced 2025-11-03 16:32:24 -06:00 
			
		
		
		
	* Add Swagger spec test script * Fix Swagger spec errors not related to statuses with polls * Add API tests that post a status with a poll * Fix creating a status with a poll from form params * Fix Swagger spec errors related to statuses with polls (this is the last error) * Fix Swagger spec warnings not related to unused definitions * Suppress a duplicate list update params definition that was somehow causing wrong param names * Add Swagger test to CI - updates Drone config - vendorizes go-swagger - fixes a file extension issue that caused the test script to generate JSON instead of YAML with the vendorized version * Put `Sample: ` on its own line everywhere * Remove unused id param from emojiCategoriesGet * Add 5 more pairs of profile fields to account update API Swagger * Remove Swagger prefix from dummy fields It makes the generated code look weird * Manually annotate params for statusCreate operation * Fix all remaining Swagger spec warnings - Change some models into operation parameters - Ignore models that already correspond to manually documented operation parameters but can't be trivially changed (those with file fields) * Documented that creating a status with scheduled_at isn't implemented yet * sign drone.yml * Fix filter API Swagger errors * fixup! Fix filter API Swagger errors --------- Co-authored-by: tobi <tobi.smethurst@protonmail.com>
		
			
				
	
	
		
			262 lines
		
	
	
	
		
			6.2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			262 lines
		
	
	
	
		
			6.2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
// 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 swag
 | 
						|
 | 
						|
import (
 | 
						|
	"unicode"
 | 
						|
)
 | 
						|
 | 
						|
var nameReplaceTable = map[rune]string{
 | 
						|
	'@': "At ",
 | 
						|
	'&': "And ",
 | 
						|
	'|': "Pipe ",
 | 
						|
	'$': "Dollar ",
 | 
						|
	'!': "Bang ",
 | 
						|
	'-': "",
 | 
						|
	'_': "",
 | 
						|
}
 | 
						|
 | 
						|
type (
 | 
						|
	splitter struct {
 | 
						|
		postSplitInitialismCheck bool
 | 
						|
		initialisms              []string
 | 
						|
	}
 | 
						|
 | 
						|
	splitterOption func(*splitter) *splitter
 | 
						|
)
 | 
						|
 | 
						|
// split calls the splitter; splitter provides more control and post options
 | 
						|
func split(str string) []string {
 | 
						|
	lexems := newSplitter().split(str)
 | 
						|
	result := make([]string, 0, len(lexems))
 | 
						|
 | 
						|
	for _, lexem := range lexems {
 | 
						|
		result = append(result, lexem.GetOriginal())
 | 
						|
	}
 | 
						|
 | 
						|
	return result
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
func (s *splitter) split(str string) []nameLexem {
 | 
						|
	return s.toNameLexems(str)
 | 
						|
}
 | 
						|
 | 
						|
func newSplitter(options ...splitterOption) *splitter {
 | 
						|
	splitter := &splitter{
 | 
						|
		postSplitInitialismCheck: false,
 | 
						|
		initialisms:              initialisms,
 | 
						|
	}
 | 
						|
 | 
						|
	for _, option := range options {
 | 
						|
		splitter = option(splitter)
 | 
						|
	}
 | 
						|
 | 
						|
	return splitter
 | 
						|
}
 | 
						|
 | 
						|
// withPostSplitInitialismCheck allows to catch initialisms after main split process
 | 
						|
func withPostSplitInitialismCheck(s *splitter) *splitter {
 | 
						|
	s.postSplitInitialismCheck = true
 | 
						|
	return s
 | 
						|
}
 | 
						|
 | 
						|
type (
 | 
						|
	initialismMatch struct {
 | 
						|
		start, end int
 | 
						|
		body       []rune
 | 
						|
		complete   bool
 | 
						|
	}
 | 
						|
	initialismMatches []*initialismMatch
 | 
						|
)
 | 
						|
 | 
						|
func (s *splitter) toNameLexems(name string) []nameLexem {
 | 
						|
	nameRunes := []rune(name)
 | 
						|
	matches := s.gatherInitialismMatches(nameRunes)
 | 
						|
	return s.mapMatchesToNameLexems(nameRunes, matches)
 | 
						|
}
 | 
						|
 | 
						|
func (s *splitter) gatherInitialismMatches(nameRunes []rune) initialismMatches {
 | 
						|
	matches := make(initialismMatches, 0)
 | 
						|
 | 
						|
	for currentRunePosition, currentRune := range nameRunes {
 | 
						|
		newMatches := make(initialismMatches, 0, len(matches))
 | 
						|
 | 
						|
		// check current initialism matches
 | 
						|
		for _, match := range matches {
 | 
						|
			if keepCompleteMatch := match.complete; keepCompleteMatch {
 | 
						|
				newMatches = append(newMatches, match)
 | 
						|
				continue
 | 
						|
			}
 | 
						|
 | 
						|
			// drop failed match
 | 
						|
			currentMatchRune := match.body[currentRunePosition-match.start]
 | 
						|
			if !s.initialismRuneEqual(currentMatchRune, currentRune) {
 | 
						|
				continue
 | 
						|
			}
 | 
						|
 | 
						|
			// try to complete ongoing match
 | 
						|
			if currentRunePosition-match.start == len(match.body)-1 {
 | 
						|
				// we are close; the next step is to check the symbol ahead
 | 
						|
				// if it is a small letter, then it is not the end of match
 | 
						|
				// but beginning of the next word
 | 
						|
 | 
						|
				if currentRunePosition < len(nameRunes)-1 {
 | 
						|
					nextRune := nameRunes[currentRunePosition+1]
 | 
						|
					if newWord := unicode.IsLower(nextRune); newWord {
 | 
						|
						// oh ok, it was the start of a new word
 | 
						|
						continue
 | 
						|
					}
 | 
						|
				}
 | 
						|
 | 
						|
				match.complete = true
 | 
						|
				match.end = currentRunePosition
 | 
						|
			}
 | 
						|
 | 
						|
			newMatches = append(newMatches, match)
 | 
						|
		}
 | 
						|
 | 
						|
		// check for new initialism matches
 | 
						|
		for _, initialism := range s.initialisms {
 | 
						|
			initialismRunes := []rune(initialism)
 | 
						|
			if s.initialismRuneEqual(initialismRunes[0], currentRune) {
 | 
						|
				newMatches = append(newMatches, &initialismMatch{
 | 
						|
					start:    currentRunePosition,
 | 
						|
					body:     initialismRunes,
 | 
						|
					complete: false,
 | 
						|
				})
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		matches = newMatches
 | 
						|
	}
 | 
						|
 | 
						|
	return matches
 | 
						|
}
 | 
						|
 | 
						|
func (s *splitter) mapMatchesToNameLexems(nameRunes []rune, matches initialismMatches) []nameLexem {
 | 
						|
	nameLexems := make([]nameLexem, 0)
 | 
						|
 | 
						|
	var lastAcceptedMatch *initialismMatch
 | 
						|
	for _, match := range matches {
 | 
						|
		if !match.complete {
 | 
						|
			continue
 | 
						|
		}
 | 
						|
 | 
						|
		if firstMatch := lastAcceptedMatch == nil; firstMatch {
 | 
						|
			nameLexems = append(nameLexems, s.breakCasualString(nameRunes[:match.start])...)
 | 
						|
			nameLexems = append(nameLexems, s.breakInitialism(string(match.body)))
 | 
						|
 | 
						|
			lastAcceptedMatch = match
 | 
						|
 | 
						|
			continue
 | 
						|
		}
 | 
						|
 | 
						|
		if overlappedMatch := match.start <= lastAcceptedMatch.end; overlappedMatch {
 | 
						|
			continue
 | 
						|
		}
 | 
						|
 | 
						|
		middle := nameRunes[lastAcceptedMatch.end+1 : match.start]
 | 
						|
		nameLexems = append(nameLexems, s.breakCasualString(middle)...)
 | 
						|
		nameLexems = append(nameLexems, s.breakInitialism(string(match.body)))
 | 
						|
 | 
						|
		lastAcceptedMatch = match
 | 
						|
	}
 | 
						|
 | 
						|
	// we have not found any accepted matches
 | 
						|
	if lastAcceptedMatch == nil {
 | 
						|
		return s.breakCasualString(nameRunes)
 | 
						|
	}
 | 
						|
 | 
						|
	if lastAcceptedMatch.end+1 != len(nameRunes) {
 | 
						|
		rest := nameRunes[lastAcceptedMatch.end+1:]
 | 
						|
		nameLexems = append(nameLexems, s.breakCasualString(rest)...)
 | 
						|
	}
 | 
						|
 | 
						|
	return nameLexems
 | 
						|
}
 | 
						|
 | 
						|
func (s *splitter) initialismRuneEqual(a, b rune) bool {
 | 
						|
	return a == b
 | 
						|
}
 | 
						|
 | 
						|
func (s *splitter) breakInitialism(original string) nameLexem {
 | 
						|
	return newInitialismNameLexem(original, original)
 | 
						|
}
 | 
						|
 | 
						|
func (s *splitter) breakCasualString(str []rune) []nameLexem {
 | 
						|
	segments := make([]nameLexem, 0)
 | 
						|
	currentSegment := ""
 | 
						|
 | 
						|
	addCasualNameLexem := func(original string) {
 | 
						|
		segments = append(segments, newCasualNameLexem(original))
 | 
						|
	}
 | 
						|
 | 
						|
	addInitialismNameLexem := func(original, match string) {
 | 
						|
		segments = append(segments, newInitialismNameLexem(original, match))
 | 
						|
	}
 | 
						|
 | 
						|
	addNameLexem := func(original string) {
 | 
						|
		if s.postSplitInitialismCheck {
 | 
						|
			for _, initialism := range s.initialisms {
 | 
						|
				if upper(initialism) == upper(original) {
 | 
						|
					addInitialismNameLexem(original, initialism)
 | 
						|
					return
 | 
						|
				}
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		addCasualNameLexem(original)
 | 
						|
	}
 | 
						|
 | 
						|
	for _, rn := range string(str) {
 | 
						|
		if replace, found := nameReplaceTable[rn]; found {
 | 
						|
			if currentSegment != "" {
 | 
						|
				addNameLexem(currentSegment)
 | 
						|
				currentSegment = ""
 | 
						|
			}
 | 
						|
 | 
						|
			if replace != "" {
 | 
						|
				addNameLexem(replace)
 | 
						|
			}
 | 
						|
 | 
						|
			continue
 | 
						|
		}
 | 
						|
 | 
						|
		if !unicode.In(rn, unicode.L, unicode.M, unicode.N, unicode.Pc) {
 | 
						|
			if currentSegment != "" {
 | 
						|
				addNameLexem(currentSegment)
 | 
						|
				currentSegment = ""
 | 
						|
			}
 | 
						|
 | 
						|
			continue
 | 
						|
		}
 | 
						|
 | 
						|
		if unicode.IsUpper(rn) {
 | 
						|
			if currentSegment != "" {
 | 
						|
				addNameLexem(currentSegment)
 | 
						|
			}
 | 
						|
			currentSegment = ""
 | 
						|
		}
 | 
						|
 | 
						|
		currentSegment += string(rn)
 | 
						|
	}
 | 
						|
 | 
						|
	if currentSegment != "" {
 | 
						|
		addNameLexem(currentSegment)
 | 
						|
	}
 | 
						|
 | 
						|
	return segments
 | 
						|
}
 |