forked from Silverfish/proton-bridge
* Renaming GUI, CLI, no-impact config. * License header and documentation rebranding. * Rename app title and vendor. Impact: manual install * Migrating mac keychain and launch on startup. * Fix linter and linter renaming
94 lines
2.6 KiB
Go
94 lines
2.6 KiB
Go
// Copyright (c) 2022 Proton AG
|
|
//
|
|
// This file is part of Proton Mail Bridge.
|
|
//
|
|
// Proton Mail Bridge is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// Proton Mail Bridge is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
package parser
|
|
|
|
import "regexp"
|
|
|
|
type Walker struct {
|
|
root *Part
|
|
|
|
handlers []*handler
|
|
defaultHandler HandlerFunc
|
|
}
|
|
|
|
func newWalker(root *Part) *Walker {
|
|
return &Walker{
|
|
root: root,
|
|
defaultHandler: func(*Part) error { return nil },
|
|
}
|
|
}
|
|
|
|
func (w *Walker) Walk() (err error) {
|
|
return w.walkOverPart(w.root)
|
|
}
|
|
|
|
func (w *Walker) walkOverPart(p *Part) error {
|
|
if err := w.getHandlerFunc(p)(p); err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, child := range p.children {
|
|
if err := w.walkOverPart(child); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// RegisterDefaultHandler registers a handler that will be called on every part
|
|
// that doesn't match a registered content type/disposition handler.
|
|
func (w *Walker) RegisterDefaultHandler(fn HandlerFunc) *Walker {
|
|
w.defaultHandler = fn
|
|
return w
|
|
}
|
|
|
|
// RegisterContentTypeHandler registers a handler that will be called when a
|
|
// part's content type matches the given regular expression.
|
|
// If a part matches multiple handlers, the one registered first will be chosen.
|
|
func (w *Walker) RegisterContentTypeHandler(typeRegExp string, fn HandlerFunc) *Walker {
|
|
w.handlers = append(w.handlers, &handler{
|
|
typeRegExp: regexp.MustCompile(typeRegExp),
|
|
fn: fn,
|
|
})
|
|
|
|
return w
|
|
}
|
|
|
|
// RegisterContentDispositionHandler registers a handler that will be called
|
|
// when a part's content disposition matches the given regular expression.
|
|
// If a part matches multiple handlers, the one registered first will be chosen.
|
|
func (w *Walker) RegisterContentDispositionHandler(dispRegExp string, fn HandlerFunc) *Walker {
|
|
w.handlers = append(w.handlers, &handler{
|
|
dispRegExp: regexp.MustCompile(dispRegExp),
|
|
fn: fn,
|
|
})
|
|
|
|
return w
|
|
}
|
|
|
|
func (w *Walker) getHandlerFunc(p *Part) HandlerFunc {
|
|
for _, handler := range w.handlers {
|
|
if handler.matchPart(p) {
|
|
return handler.fn
|
|
}
|
|
}
|
|
|
|
return w.defaultHandler
|
|
}
|