Add support for parent/child TypeMatchers #86
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Going a different route from #73, this PR modifies the matchers interface to account for parent/child relationships between types. (I initially called the children
subtypes, as you can see from the branch name, but since that term's already used in the MIME code it would've been confusing as heck.)Modifications to existing code
matchers/matchers.goMatcherandTyperMatcherinterface requires a method,Match([]bytes), which returnstrueif the buffer matches the matching functionTyperinterface adds Type([]bytes), which returns the associatedtypes.Type` if the buffer matches the matching functionByteMatcherByteMatcherimplementsMatcherTypeMatcheris now a struct, containing atypes.Typeand aByteMatcherTypeMatcherimplements bothMatcherandTyperTypeMatcher.Match()checks whether the buffer matches the type or any of its child typesTypeMatcher.Type()checks the buffer against any child types, then the parent type, and returns the type on successful matchChildMatchersis amap[types.Type][]TypeMatcherwhich registers the parent-child relationship between aTypeand its childTypeMatchers(not directly betweenTypeMatchers)match.goMatch()andType()methods, instead of runningByteMatchersdirectly.filetype.goIs()andIsType()functions now useMatch()andType(), instead of runningByteMatchersdirectly. (Actually,Isnow just callsIsType, which checks the type'sTypeMatcher.Match().)Is()andIsType()will return true for both a buffer's specific type, and its parent type. (e.g.IsType(types.TypeZip)andIs("zip")are true for a buffer containing.docxbytes.)New source files
The new file
matchers/children.goadds storage for the the parent-child mappings:TypeMatcheris expanded with anAddChild(types.Type, ByteMatcher)method, to add a child of the matcher'sTypeAddChildType(parent, child types.Type, ByteMatcher)is also added, to create children for types that don't yet have aTypeMatcher. (This was necessary to keep thematchers.Map{}functionality working, sinceChildMatcherswill end up getting populated beforeMatchers.)Updates to existing data structures
Epub,Docx,Xlsx, andPptxare all made children ofTypeZipTesting
ChildMatcherfunctionalityNotes/Caveats
In theory this could be extended to support a multi-level hierarchy, with child types having children of their own. However, as that wasn't necessary to support current needs, only one level is implemented. The
Type()method ofTypeMatcherdoesn't use theType()method of its children to look up their matching types, it queries the child'sByteMatcherdirectly. RecursiveChildMatcherlookups would be necessary to support children of children.There's no way to support parent-child relationships in an arbitrary
MatchMap()call. Because it does run theByteMatchers it's passed directly, it will ignoreChildMatchersand can return incorrect results if it's passed amatchers.Mapcontaining overlapping matchers.Fixes #38, fixes #40