xref: /aosp_15_r20/external/go-cmp/cmp/cmpopts/xform.go (revision 88d15eac089d7f20c739ff1001d56b91872b21a1)
1// Copyright 2018, The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package cmpopts
6
7import (
8	"github.com/google/go-cmp/cmp"
9)
10
11type xformFilter struct{ xform cmp.Option }
12
13func (xf xformFilter) filter(p cmp.Path) bool {
14	for _, ps := range p {
15		if t, ok := ps.(cmp.Transform); ok && t.Option() == xf.xform {
16			return false
17		}
18	}
19	return true
20}
21
22// AcyclicTransformer returns a Transformer with a filter applied that ensures
23// that the transformer cannot be recursively applied upon its own output.
24//
25// An example use case is a transformer that splits a string by lines:
26//
27//	AcyclicTransformer("SplitLines", func(s string) []string{
28//		return strings.Split(s, "\n")
29//	})
30//
31// Had this been an unfiltered Transformer instead, this would result in an
32// infinite cycle converting a string to []string to [][]string and so on.
33func AcyclicTransformer(name string, xformFunc interface{}) cmp.Option {
34	xf := xformFilter{cmp.Transformer(name, xformFunc)}
35	return cmp.FilterPath(xf.filter, xf.xform)
36}
37