Help us shape the future of Go! Take the 2026 Go Developer Survey

rules

package
v2.5.64 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 22, 2026 License: MIT Imports: 9 Imported by: 30

Documentation

Index

Constants

This section is empty.

Variables

View Source
var FieldsOnCorrectTypeRule = Rule{
	Name: "FieldsOnCorrectType",
	RuleFunc: func(observers *Events, addError AddErrFunc) {
		ruleFuncFieldsOnCorrectType(observers, addError, false)
	},
}
View Source
var FieldsOnCorrectTypeRuleWithoutSuggestions = Rule{
	Name: "FieldsOnCorrectTypeWithoutSuggestions",
	RuleFunc: func(observers *Events, addError AddErrFunc) {
		ruleFuncFieldsOnCorrectType(observers, addError, true)
	},
}
View Source
var FragmentsOnCompositeTypesRule = Rule{
	Name: "FragmentsOnCompositeTypes",
	RuleFunc: func(observers *Events, addError AddErrFunc) {
		observers.OnInlineFragment(func(walker *Walker, inlineFragment *ast.InlineFragment) {
			fragmentType := walker.Schema.Types[inlineFragment.TypeCondition]
			if fragmentType == nil || fragmentType.IsCompositeType() {
				return
			}

			message := fmt.Sprintf(
				`Fragment cannot condition on non composite type "%s".`,
				inlineFragment.TypeCondition,
			)

			addError(
				Message("%s", message),
				At(inlineFragment.Position),
			)
		})

		observers.OnFragment(func(walker *Walker, fragment *ast.FragmentDefinition) {
			if fragment.Definition == nil || fragment.TypeCondition == "" ||
				fragment.Definition.IsCompositeType() {
				return
			}

			message := fmt.Sprintf(
				`Fragment "%s" cannot condition on non composite type "%s".`,
				fragment.Name,
				fragment.TypeCondition,
			)

			addError(
				Message("%s", message),
				At(fragment.Position),
			)
		})
	},
}
View Source
var KnownArgumentNamesRule = Rule{
	Name: "KnownArgumentNames",
	RuleFunc: func(observers *Events, addError AddErrFunc) {
		ruleFuncKnownArgumentNames(observers, addError, false)
	},
}
View Source
var KnownArgumentNamesRuleWithoutSuggestions = Rule{
	Name: "KnownArgumentNamesWithoutSuggestions",
	RuleFunc: func(observers *Events, addError AddErrFunc) {
		ruleFuncKnownArgumentNames(observers, addError, true)
	},
}
View Source
var KnownDirectivesRule = Rule{
	Name: "KnownDirectives",
	RuleFunc: func(observers *Events, addError AddErrFunc) {
		type mayNotBeUsedDirective struct {
			Name   string
			Line   int
			Column int
		}
		seen := map[mayNotBeUsedDirective]bool{}
		observers.OnDirective(func(walker *Walker, directive *ast.Directive) {
			if directive.Definition == nil {
				addError(
					Message(`Unknown directive "@%s".`, directive.Name),
					At(directive.Position),
				)
				return
			}

			if slices.Contains(directive.Definition.Locations, directive.Location) {
				return
			}

			tmp := mayNotBeUsedDirective{
				Name:   directive.Name,
				Line:   directive.Position.Line,
				Column: directive.Position.Column,
			}

			if !seen[tmp] {
				addError(
					Message(
						`Directive "@%s" may not be used on %s.`,
						directive.Name,
						directive.Location,
					),
					At(directive.Position),
				)
				seen[tmp] = true
			}
		})
	},
}
View Source
var KnownFragmentNamesRule = Rule{
	Name: "KnownFragmentNames",
	RuleFunc: func(observers *Events, addError AddErrFunc) {
		observers.OnFragmentSpread(func(walker *Walker, fragmentSpread *ast.FragmentSpread) {
			if fragmentSpread.Definition == nil {
				addError(
					Message(`Unknown fragment "%s".`, fragmentSpread.Name),
					At(fragmentSpread.Position),
				)
			}
		})
	},
}
View Source
var KnownRootTypeRule = Rule{
	Name: "KnownRootType",
	RuleFunc: func(observers *Events, addError AddErrFunc) {

		observers.OnOperation(func(walker *Walker, operation *ast.OperationDefinition) {
			var def *ast.Definition
			switch operation.Operation {
			case ast.Query, "":
				def = walker.Schema.Query
			case ast.Mutation:
				def = walker.Schema.Mutation
			case ast.Subscription:
				def = walker.Schema.Subscription
			default:

				panic(fmt.Sprintf(`got unknown operation type "%s"`, operation.Operation))
			}
			if def == nil {
				addError(
					Message(`Schema does not support operation type "%s"`, operation.Operation),
					At(operation.Position))
			}
		})
	},
}
View Source
var KnownTypeNamesRule = Rule{
	Name: "KnownTypeNames",
	RuleFunc: func(observers *Events, addError AddErrFunc) {
		ruleFuncKnownTypeNames(observers, addError, false)
	},
}
View Source
var KnownTypeNamesRuleWithoutSuggestions = Rule{
	Name: "KnownTypeNamesWithoutSuggestions",
	RuleFunc: func(observers *Events, addError AddErrFunc) {
		ruleFuncKnownTypeNames(observers, addError, true)
	},
}
View Source
var LoneAnonymousOperationRule = Rule{
	Name: "LoneAnonymousOperation",
	RuleFunc: func(observers *Events, addError AddErrFunc) {
		observers.OnOperation(func(walker *Walker, operation *ast.OperationDefinition) {
			if operation.Name == "" && len(walker.Document.Operations) > 1 {
				addError(
					Message(`This anonymous operation must be the only defined operation.`),
					At(operation.Position),
				)
			}
		})
	},
}
View Source
var MaxIntrospectionDepth = Rule{
	Name: "MaxIntrospectionDepth",
	RuleFunc: func(observers *Events, addError AddErrFunc) {

		c := &depthChecker{
			visitedFragments: make(map[string]int),
			memo:             make(map[fragmentAtDepth]bool),
		}

		observers.OnField(func(walker *Walker, field *ast.Field) {
			if field.Name == "__schema" || field.Name == "__type" {
				if c.checkDepthField(field, 0) {
					addError(
						Message(`Maximum introspection depth exceeded`),
						At(field.Position),
					)
				}
				return
			}
		})
	},
}

MaxIntrospectionDepth reports an introspection selection that nests __Type's list fields past a fixed depth.

A fragment cycle whose lap gains depth nests past any limit, so the rule reports it without needing NoFragmentCyclesRule to run alongside. A cycle whose lap gains none reaches no new depth and is cut, as it is in graphql-js.

View Source
var NoFragmentCyclesRule = Rule{
	Name: "NoFragmentCycles",
	RuleFunc: func(observers *Events, addError AddErrFunc) {
		visitedFrags := make(map[string]bool)

		observers.OnFragment(func(walker *Walker, fragment *ast.FragmentDefinition) {
			var spreadPath []*ast.FragmentSpread
			spreadPathIndexByName := make(map[string]int)

			var recursive func(fragment *ast.FragmentDefinition)
			recursive = func(fragment *ast.FragmentDefinition) {
				if visitedFrags[fragment.Name] {
					return
				}

				visitedFrags[fragment.Name] = true

				spreadNodes := getFragmentSpreads(fragment.SelectionSet)
				if len(spreadNodes) == 0 {
					return
				}
				spreadPathIndexByName[fragment.Name] = len(spreadPath)

				for _, spreadNode := range spreadNodes {
					spreadName := spreadNode.Name

					cycleIndex, ok := spreadPathIndexByName[spreadName]

					spreadPath = append(spreadPath, spreadNode)
					if !ok {
						spreadFragment := walker.Document.Fragments.ForName(spreadName)
						if spreadFragment != nil {
							recursive(spreadFragment)
						}
					} else {
						cyclePath := spreadPath[cycleIndex : len(spreadPath)-1]
						var fragmentNames []string
						for _, fs := range cyclePath {
							fragmentNames = append(fragmentNames, fmt.Sprintf(`"%s"`, fs.Name))
						}
						var via string
						if len(fragmentNames) != 0 {
							via = fmt.Sprintf(" via %s", strings.Join(fragmentNames, ", "))
						}
						addError(
							Message(
								`Cannot spread fragment "%s" within itself%s.`,
								spreadName,
								via,
							),
							At(spreadNode.Position),
						)
					}

					spreadPath = spreadPath[:len(spreadPath)-1]
				}

				delete(spreadPathIndexByName, fragment.Name)
			}

			recursive(fragment)
		})
	},
}
View Source
var NoUndefinedVariablesRule = Rule{
	Name: "NoUndefinedVariables",
	RuleFunc: func(observers *Events, addError AddErrFunc) {
		observers.OnValue(func(walker *Walker, value *ast.Value) {
			if walker.CurrentOperation == nil || value.Kind != ast.Variable ||
				value.VariableDefinition != nil {
				return
			}

			if walker.CurrentOperation.Name != "" {
				addError(
					Message(
						`Variable "%s" is not defined by operation "%s".`,
						value,
						walker.CurrentOperation.Name,
					),
					At(value.Position),
				)
			} else {
				addError(
					Message(`Variable "%s" is not defined.`, value),
					At(value.Position),
				)
			}
		})
	},
}
View Source
var NoUnusedFragmentsRule = Rule{
	Name: "NoUnusedFragments",
	RuleFunc: func(observers *Events, addError AddErrFunc) {
		inFragmentDefinition := false
		fragmentNameUsed := make(map[string]bool)

		observers.OnFragmentSpread(func(walker *Walker, fragmentSpread *ast.FragmentSpread) {
			if !inFragmentDefinition {
				fragmentNameUsed[fragmentSpread.Name] = true
			}
		})

		observers.OnFragment(func(walker *Walker, fragment *ast.FragmentDefinition) {
			inFragmentDefinition = true
			if !fragmentNameUsed[fragment.Name] {
				addError(
					Message(`Fragment "%s" is never used.`, fragment.Name),
					At(fragment.Position),
				)
			}
		})
	},
}
View Source
var NoUnusedVariablesRule = Rule{
	Name: "NoUnusedVariables",
	RuleFunc: func(observers *Events, addError AddErrFunc) {
		observers.OnOperation(func(walker *Walker, operation *ast.OperationDefinition) {
			for _, varDef := range operation.VariableDefinitions {
				if varDef.Used {
					continue
				}

				if operation.Name != "" {
					addError(
						Message(
							`Variable "$%s" is never used in operation "%s".`,
							varDef.Variable,
							operation.Name,
						),
						At(varDef.Position),
					)
				} else {
					addError(
						Message(`Variable "$%s" is never used.`, varDef.Variable),
						At(varDef.Position),
					)
				}
			}
		})
	},
}
View Source
var OverlappingFieldsCanBeMergedRule = Rule{
	Name: "OverlappingFieldsCanBeMerged",
	RuleFunc: func(observers *Events, addError AddErrFunc) {

		m := &overlappingFieldsCanBeMergedManager{
			comparedFieldsAndFragmentPairs: newOrderedPairSet[*sequentialFieldsMap, string](),
			comparedFragmentPairs:          pairSet{pairs: newOrderedPairSet[string, string]()},
			cachedFieldsAndFragmentNames: make(
				map[selectionSetKey]*fieldsAndFragmentNames,
			),
		}

		observers.OnOperation(func(walker *Walker, operation *ast.OperationDefinition) {
			m.walker = walker
			conflicts := m.findConflictsWithinSelectionSet(operation.SelectionSet)
			for _, conflict := range conflicts {
				conflict.addFieldsConflictMessage(addError)
			}
		})
		observers.OnField(func(walker *Walker, field *ast.Field) {
			if walker.CurrentOperation == nil {

				return
			}
			m.walker = walker
			conflicts := m.findConflictsWithinSelectionSet(field.SelectionSet)
			for _, conflict := range conflicts {
				conflict.addFieldsConflictMessage(addError)
			}
		})
		observers.OnInlineFragment(func(walker *Walker, inlineFragment *ast.InlineFragment) {
			m.walker = walker
			conflicts := m.findConflictsWithinSelectionSet(inlineFragment.SelectionSet)
			for _, conflict := range conflicts {
				conflict.addFieldsConflictMessage(addError)
			}
		})
		observers.OnFragment(func(walker *Walker, fragment *ast.FragmentDefinition) {
			m.walker = walker
			conflicts := m.findConflictsWithinSelectionSet(fragment.SelectionSet)
			for _, conflict := range conflicts {
				conflict.addFieldsConflictMessage(addError)
			}
		})
	},
}
View Source
var PossibleFragmentSpreadsRule = Rule{
	Name: "PossibleFragmentSpreads",
	RuleFunc: func(observers *Events, addError AddErrFunc) {
		validate := func(walker *Walker, parentDef *ast.Definition, fragmentName string, emitError func()) {
			if parentDef == nil {
				return
			}

			var parentDefs []*ast.Definition
			switch parentDef.Kind {
			case ast.Object:
				parentDefs = []*ast.Definition{parentDef}
			case ast.Interface, ast.Union:
				parentDefs = walker.Schema.GetPossibleTypes(parentDef)
			default:
				return
			}

			fragmentDefType := walker.Schema.Types[fragmentName]
			if fragmentDefType == nil {
				return
			}
			if !fragmentDefType.IsCompositeType() {

				return
			}
			fragmentDefs := walker.Schema.GetPossibleTypes(fragmentDefType)

			for _, fragmentDef := range fragmentDefs {
				for _, parentDef := range parentDefs {
					if parentDef.Name == fragmentDef.Name {
						return
					}
				}
			}

			emitError()
		}

		observers.OnInlineFragment(func(walker *Walker, inlineFragment *ast.InlineFragment) {
			validate(walker, inlineFragment.ObjectDefinition, inlineFragment.TypeCondition, func() {
				addError(
					Message(
						`Fragment cannot be spread here as objects of type "%s" can never be of type "%s".`,
						inlineFragment.ObjectDefinition.Name,
						inlineFragment.TypeCondition,
					),
					At(inlineFragment.Position),
				)
			})
		})

		observers.OnFragmentSpread(func(walker *Walker, fragmentSpread *ast.FragmentSpread) {
			if fragmentSpread.Definition == nil {
				return
			}
			validate(
				walker,
				fragmentSpread.ObjectDefinition,
				fragmentSpread.Definition.TypeCondition,
				func() {
					addError(
						Message(
							`Fragment "%s" cannot be spread here as objects of type "%s" can never be of type "%s".`,
							fragmentSpread.Name,
							fragmentSpread.ObjectDefinition.Name,
							fragmentSpread.Definition.TypeCondition,
						),
						At(fragmentSpread.Position),
					)
				},
			)
		})
	},
}
View Source
var ProvidedRequiredArgumentsRule = Rule{
	Name: "ProvidedRequiredArguments",
	RuleFunc: func(observers *Events, addError AddErrFunc) {
		observers.OnField(func(walker *Walker, field *ast.Field) {
			if field.Definition == nil {
				return
			}

		argDef:
			for _, argDef := range field.Definition.Arguments {
				if !argDef.Type.NonNull {
					continue
				}
				if argDef.DefaultValue != nil {
					continue
				}
				for _, arg := range field.Arguments {
					if arg.Name == argDef.Name {
						continue argDef
					}
				}

				addError(
					Message(`Field "%s" argument "%s" of type "%s" is required, but it was not provided.`, field.Name, argDef.Name, argDef.Type.String()),
					At(field.Position),
				)
			}
		})

		observers.OnDirective(func(walker *Walker, directive *ast.Directive) {
			if directive.Definition == nil {
				return
			}

		argDef:
			for _, argDef := range directive.Definition.Arguments {
				if !argDef.Type.NonNull {
					continue
				}
				if argDef.DefaultValue != nil {
					continue
				}
				for _, arg := range directive.Arguments {
					if arg.Name == argDef.Name {
						continue argDef
					}
				}

				addError(
					Message(`Directive "@%s" argument "%s" of type "%s" is required, but it was not provided.`, directive.Definition.Name, argDef.Name, argDef.Type.String()),
					At(directive.Position),
				)
			}
		})
	},
}
View Source
var ScalarLeafsRule = Rule{
	Name: "ScalarLeafs",
	RuleFunc: func(observers *Events, addError AddErrFunc) {
		ruleFuncScalarLeafs(observers, addError, false)
	},
}
View Source
var ScalarLeafsRuleWithoutSuggestions = Rule{
	Name: "ScalarLeafsWithoutSuggestions",
	RuleFunc: func(observers *Events, addError AddErrFunc) {
		ruleFuncScalarLeafs(observers, addError, true)
	},
}
View Source
var SingleFieldSubscriptionsRule = Rule{
	Name: "SingleFieldSubscriptions",
	RuleFunc: func(observers *Events, addError AddErrFunc) {
		observers.OnOperation(func(walker *Walker, operation *ast.OperationDefinition) {
			if walker.Schema.Subscription == nil || operation.Operation != ast.Subscription {
				return
			}

			fields := retrieveTopFieldNames(operation.SelectionSet)

			name := "Anonymous Subscription"
			if operation.Name != "" {
				name = `Subscription ` + strconv.Quote(operation.Name)
			}

			if len(fields) > 1 {
				addError(
					Message(`%s must select only one top level field.`, name),
					At(fields[1].position),
				)
			}

			for _, field := range fields {
				if strings.HasPrefix(field.name, "__") {
					addError(
						Message(`%s must not select an introspection top level field.`, name),
						At(field.position),
					)
				}
			}
		})
	},
}
View Source
var UniqueArgumentNamesRule = Rule{
	Name: "UniqueArgumentNames",
	RuleFunc: func(observers *Events, addError AddErrFunc) {
		observers.OnField(func(walker *Walker, field *ast.Field) {
			checkUniqueArgs(field.Arguments, addError)
		})

		observers.OnDirective(func(walker *Walker, directive *ast.Directive) {
			checkUniqueArgs(directive.Arguments, addError)
		})
	},
}
View Source
var UniqueDirectivesPerLocationRule = Rule{
	Name: "UniqueDirectivesPerLocation",
	RuleFunc: func(observers *Events, addError AddErrFunc) {
		observers.OnDirectiveList(func(walker *Walker, directives []*ast.Directive) {
			seen := map[string]bool{}

			for _, dir := range directives {
				if (dir.Definition == nil || !dir.Definition.IsRepeatable) && seen[dir.Name] {
					addError(
						Message(
							`The directive "@%s" can only be used once at this location.`,
							dir.Name,
						),
						At(dir.Position),
					)
				}
				seen[dir.Name] = true
			}
		})
	},
}
View Source
var UniqueFragmentNamesRule = Rule{
	Name: "UniqueFragmentNames",
	RuleFunc: func(observers *Events, addError AddErrFunc) {
		seenFragments := map[string]bool{}

		observers.OnFragment(func(walker *Walker, fragment *ast.FragmentDefinition) {
			if seenFragments[fragment.Name] {
				addError(
					Message(`There can be only one fragment named "%s".`, fragment.Name),
					At(fragment.Position),
				)
			}
			seenFragments[fragment.Name] = true
		})
	},
}
View Source
var UniqueInputFieldNamesRule = Rule{
	Name: "UniqueInputFieldNames",
	RuleFunc: func(observers *Events, addError AddErrFunc) {
		observers.OnValue(func(walker *Walker, value *ast.Value) {
			if value.Kind != ast.ObjectValue {
				return
			}

			seen := map[string]bool{}
			for _, field := range value.Children {
				if seen[field.Name] {
					addError(
						Message(`There can be only one input field named "%s".`, field.Name),
						At(field.Position),
					)
				}
				seen[field.Name] = true
			}
		})
	},
}
View Source
var UniqueOperationNamesRule = Rule{
	Name: "UniqueOperationNames",
	RuleFunc: func(observers *Events, addError AddErrFunc) {
		seen := map[string]bool{}

		observers.OnOperation(func(walker *Walker, operation *ast.OperationDefinition) {
			if seen[operation.Name] {
				addError(
					Message(`There can be only one operation named "%s".`, operation.Name),
					At(operation.Position),
				)
			}
			seen[operation.Name] = true
		})
	},
}
View Source
var UniqueVariableNamesRule = Rule{
	Name: "UniqueVariableNames",
	RuleFunc: func(observers *Events, addError AddErrFunc) {
		observers.OnOperation(func(walker *Walker, operation *ast.OperationDefinition) {
			seen := map[string]int{}
			for _, def := range operation.VariableDefinitions {

				if seen[def.Variable] == 1 {
					addError(
						Message(`There can be only one variable named "$%s".`, def.Variable),
						At(def.Position),
					)
				}
				seen[def.Variable]++
			}
		})
	},
}
View Source
var ValuesOfCorrectTypeRule = Rule{
	Name: "ValuesOfCorrectType",
	RuleFunc: func(observers *Events, addError AddErrFunc) {
		ruleFuncValuesOfCorrectType(observers, addError, false)
	},
}
View Source
var ValuesOfCorrectTypeRuleWithoutSuggestions = Rule{
	Name: "ValuesOfCorrectTypeWithoutSuggestions",
	RuleFunc: func(observers *Events, addError AddErrFunc) {
		ruleFuncValuesOfCorrectType(observers, addError, true)
	},
}
View Source
var VariablesAreInputTypesRule = Rule{
	Name: "VariablesAreInputTypes",
	RuleFunc: func(observers *Events, addError AddErrFunc) {
		observers.OnOperation(func(walker *Walker, operation *ast.OperationDefinition) {
			for _, def := range operation.VariableDefinitions {
				if def.Definition == nil {
					continue
				}
				if !def.Definition.IsInputType() {
					addError(
						Message(
							`Variable "$%s" cannot be non-input type "%s".`,
							def.Variable,
							def.Type.String(),
						),
						At(def.Position),
					)
				}
			}
		})
	},
}
View Source
var VariablesInAllowedPositionRule = Rule{
	Name: "VariablesInAllowedPosition",
	RuleFunc: func(observers *Events, addError AddErrFunc) {
		observers.OnValue(func(walker *Walker, value *ast.Value) {
			if value.Kind != ast.Variable || value.ExpectedType == nil ||
				value.VariableDefinition == nil ||
				walker.CurrentOperation == nil {
				return
			}

			tmp := *value.ExpectedType

			if value.VariableDefinition.DefaultValue != nil &&
				value.VariableDefinition.DefaultValue.Kind != ast.NullValue {
				if value.ExpectedType.NonNull {
					tmp.NonNull = false
				}
			}

			if value.ExpectedTypeHasDefault {
				tmp.NonNull = false
			}

			if !value.VariableDefinition.Type.IsCompatible(&tmp) {
				addError(
					Message(
						`Variable "%s" of type "%s" used in position expecting type "%s".`,
						value,
						value.VariableDefinition.Type.String(),
						value.ExpectedType.String(),
					),
					At(value.Position),
				)
			}
		})

		observers.OnValue(func(walker *Walker, value *ast.Value) {
			if value.Kind != ast.ObjectValue || value.Definition == nil {
				return
			}
			if value.Definition.Directives.ForName("oneOf") == nil {
				return
			}

			for _, child := range value.Children {
				fieldValue := child.Value
				if fieldValue == nil || fieldValue.Kind != ast.Variable ||
					fieldValue.VariableDefinition == nil {
					continue
				}
				if !fieldValue.VariableDefinition.Type.NonNull {
					addError(
						Message(
							`Variable "%s" is of type "%s" but must be non-nullable to be used for OneOf Input Object "%s".`,
							fieldValue,
							fieldValue.VariableDefinition.Type.String(),
							value.Definition.Name,
						),
						At(fieldValue.VariableDefinition.Position),
						At(fieldValue.Position),
					)
				}
			}
		})
	},
}

Functions

This section is empty.

Types

type ConflictMessage

type ConflictMessage struct {
	Message      string
	ResponseName string
	Names        []string
	SubMessage   []*ConflictMessage
	Position     *ast.Position
}

func (*ConflictMessage) String

func (m *ConflictMessage) String(buf *bytes.Buffer)

type Rules added in v2.5.29

type Rules struct {
	// contains filtered or unexported fields
}

Rules manages GraphQL validation rules.

func NewDefaultRules added in v2.5.29

func NewDefaultRules() *Rules

NewDefaultRules creates a Rules instance containing the default GraphQL validation rule set.

func NewRules added in v2.5.29

func NewRules(rs ...core.Rule) *Rules

NewRules creates a Rules instance with the specified rules.

func (*Rules) AddRule added in v2.5.29

func (r *Rules) AddRule(name string, ruleFunc core.RuleFunc)

AddRule adds a rule with the specified name and rule function to the rule set. If a rule with the same name already exists, it will not be added.

func (*Rules) GetInner added in v2.5.29

func (r *Rules) GetInner() map[string]core.RuleFunc

GetInner returns the internal rule map. If the map is not initialized, it returns an empty map. This returns a copy of the rules map, not the original map.

func (*Rules) RemoveRule added in v2.5.29

func (r *Rules) RemoveRule(name string)

RemoveRule removes a rule with the specified name from the rule set. If no rule with the specified name exists, it does nothing.

func (*Rules) ReplaceRule added in v2.5.29

func (r *Rules) ReplaceRule(name string, ruleFunc core.RuleFunc)

ReplaceRule replaces a rule with the specified name with a new rule function. If no rule with the specified name exists, it does nothing.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL