Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add FilterPriority to prioritize some set of options over another #36

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Commits on Aug 9, 2017

  1. Add Options to prioritize some set of options over another

    Added API:
    	Default() Option
    	FilterPriority(opts ...Option) Option
    
    FilterPriority returns a new Option where an option, opts[i],
    is only evaluated if no fundamental options remain after applying all filters
    in all prior options, opts[:i].
    
    In order to prevent further options from being evaluated, the Default option
    can be used to ensure that some fundamental option remains.
    
    Suppose you have a value tree T, where T1 and T2 are sub-trees within T.
    Prior to the addition of FilterPriority, it was impossible to do certain things.
    
    Example 1: You could not make the following compose together nicely.
    	* Have a set of options OT1 to affect only values under T1.
    	* Have a set of options OT2 to affect only values under T2.
    	* Have a set of options OT to affect only T, but not values under T1 and T2.
    	* Have a set of options O to affect all other values, but no those in T
    	  (and by extension those in T1 and T2).
    Solution 1:
    	FilterPriority(
    		// Since T1 and T2 do not overlap, they could be placed within the
    		// same priority level by grouping them in an Options group.
    		FilterTree(T1, OT1),
    		FilterTree(T2, OT2),
    		FilterTree(T, OT),
    		O,
    	)
    
    Example 2: You could not make the following compose together nicely.
    	* Have a set of options O apply on all nodes except those in T1 and T2.
    	* Instead, we want the default behavior of cmp on T1 and T2.
    Solution 2:
    	FilterPriority(
    		// Here we show how to group T1 and T2 together to be on the same
    		// priority level.
    		Options{
    			FilterTree(T1, Default()),
    			FilterTree(T2, Default()),
    		},
    		O,
    	)
    
    Example 3: You have this: type MyStruct struct { *pb.MyMessage; ... }
    	* Generally, you want to use Comparer(proto.Equal) to ensure
    	  that all proto.Messages within the struct are properly compared.
    	  However, this type has an embedded proto (generally a bad idea),
    	  which causes the MyStruct to satisfy the proto.Message interface
    	  and unintentionally causes Equal to use proto.Equal on MyStruct,
    	  which crashes.
    	* How can you have Comparer(proto.Equal) apply to all other
    	  proto.Message without applying just to MyStruct?
    Solution 3:
    	FilterPriority(
    		// Only for MyStruct, use the default behavior of Equal,
    		// which is to recurse into the structure of MyStruct.
    		FilterPath(func(p Path) bool {
    			return p.Last().Type() == reflect.TypeOf(MyStruct{})
    		}, Default()),
    
    		// Use proto.Equal for all other cases of proto.Message.
    		Comparer(proto.Equal),
    	)
    dsnet committed Aug 9, 2017
    Configuration menu
    Copy the full SHA
    5b174e0 View commit details
    Browse the repository at this point in the history