package parsekit // On checks if the current input matches the provided Matcher. // // This method is the start of a chain method in which multiple things can // be arranged in one go: // // 1) Checking whether or not there is a match (this is what On does) // // 2) Deciding what to do with the match (Stay(): do nothing, Skip(): only move // the cursor forward, Accept(): move cursor forward and add the match in // the parser string buffer) // // 3) Dedicing where to route to (e.g. using RouteTo() to route to a // StateHandler by name) // // 4) Followup routing after that, when applicable (.e.g using something like // RouteTo(...).ThenTo(...)) // // For every step of this chain, you can end the chain using the // End() method. This will return a boolean value, indicating whether or // not the initial On() method found a match in the input. // End() is not mandatory. It is merely provided as a means to use // a chain as an expression for a switch/case or if statement (since those // require a boolean expression). // // You can omit "what to do with the match" and go straight into a routing // method, e.g. // On(...).RouteTo(...) // This is functionally the same as using // On(...).Stay().RouteTo(...). // // Here's a complete example chain: // p.On(something).Accept().RouteTo(stateB).ThenTo(stateC).End() func (p *P) On(matcher Matcher) *matchAction { m := &MatchDialog{p: p} if matcher == nil { p.EmitError("internal parser error: matcher argument for On() is nil") return &matchAction{routeAction: routeAction{chainAction: chainAction{nil, false}}} } ok := matcher(m) // Keep track of the last match, to allow parser implementations // to access it in an easy way. Typical use would be something like: // if p.On(somethingBad).End() { // p.Errorf("This was bad: %s", p.LastMatch) // } p.LastMatch = string(m.runes) return &matchAction{ routeAction: routeAction{chainAction{p, ok}}, runes: m.runes, widths: m.widths, } } // chainAction is used for building method chains for the On() method. type chainAction struct { p *P ok bool } // End ends the method chain and returns a boolean indicating whether // or not a match was found in the input. func (a *chainAction) End() bool { return a.ok }