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