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.go
Matcher
andTyper
Matcher
interface requires a method,Match([]bytes)
, which returnstrue
if the buffer matches the matching functionTyper
interface adds Type([]bytes), which returns the associated
types.Type` if the buffer matches the matching functionByteMatcher
ByteMatcher
implementsMatcher
TypeMatcher
is now a struct, containing atypes.Type
and aByteMatcher
TypeMatcher
implements bothMatcher
andTyper
TypeMatcher.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 matchChildMatchers
is amap[types.Type][]TypeMatcher
which registers the parent-child relationship between aType
and its childTypeMatchers
(not directly betweenTypeMatchers
)match.go
Match()
andType()
methods, instead of runningByteMatchers
directly.filetype.go
Is()
andIsType()
functions now useMatch()
andType()
, instead of runningByteMatchers
directly. (Actually,Is
now 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.docx
bytes.)New source files
The new file
matchers/children.go
adds storage for the the parent-child mappings:TypeMatcher
is expanded with anAddChild(types.Type, ByteMatcher)
method, to add a child of the matcher'sType
AddChildType(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, sinceChildMatchers
will end up getting populated beforeMatchers
.)Updates to existing data structures
Epub
,Docx
,Xlsx
, andPptx
are all made children ofTypeZip
Testing
ChildMatcher
functionalityNotes/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 ofTypeMatcher
doesn't use theType()
method of its children to look up their matching types, it queries the child'sByteMatcher
directly. RecursiveChildMatcher
lookups 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 theByteMatcher
s it's passed directly, it will ignoreChildMatchers
and can return incorrect results if it's passed amatchers.Map
containing overlapping matchers.Fixes #38, fixes #40