From 726b5a377b49424835e50e61a6854050913ba2d9 Mon Sep 17 00:00:00 2001 From: Maurice Makaay Date: Wed, 19 Jun 2019 11:28:03 +0000 Subject: [PATCH] A bit of code cleanup, to let the date/time code better represent the ideas behind the followed methodology. --- value_datetime.go | 48 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 33 insertions(+), 15 deletions(-) diff --git a/value_datetime.go b/value_datetime.go index be2f186..25e7196 100644 --- a/value_datetime.go +++ b/value_datetime.go @@ -4,6 +4,7 @@ import ( "time" "git.makaay.nl/mauricem/go-parsekit/parse" + "git.makaay.nl/mauricem/go-parsekit/tokenize" ) var ( @@ -63,6 +64,8 @@ var ( tzTok = tok.Str("Z07:00", tz) // The full date/time parse format, based on the above definitions. + // The first token denotes the type of date/time value. + // The rest of the tokens contain layout fragments for time.Parse(). offsetDateTime = tok.Str(coffsetDateTime, c.Seq(dateTok, tdelimTok, timeTok, microTok, tzTok)) localDateTime = tok.Str(clocalDateTime, c.Seq(dateTok, tdelimTok, timeTok, microTok)) localDate = tok.Str(clocalDate, dateTok) @@ -71,21 +74,36 @@ var ( ) func (t *parser) startDateTime(p *parse.API) { - if p.Accept(datetime) { - tokens := p.Result().Tokens() - valueType := tokens[0].Type.(cmdType) - layout := "" - for _, l := range tokens[1:] { - layout += l.Type.(string) - } - input := string(tokens[0].Runes) - value, err := time.Parse(layout, input) - if err == nil { - t.emitCommand(valueType, value) - } else { - p.Error("Cannot parse value 0%s: %s", input, err) - } - } else { + if !p.Accept(datetime) { p.Expected("a date and/or time") + return + } + tokens := p.Result().Tokens() + valueType := getDateTimeValueType(&tokens) + input, value, err := getDateTimeValue(&tokens) + if err == nil { + t.emitCommand(valueType, value) + } else { + p.Error("Cannot parse value 0%s: %s", input, err) } } + +// The first token is a token that wraps the complete date/time input. +// Its type denotes the type of date/time value that it wraps. +func getDateTimeValueType(tokens *[]*tokenize.Token) cmdType { + return (*tokens)[0].Type.(cmdType) +} + +// The rest of the tokens contain fragments that can be used with +// time.Parse() to parse the provided date/time input. Here, these fragments +// are combined into a layout string, which is then used to parse +// the input string. +func getDateTimeValue(tokens *[]*tokenize.Token) (string, time.Time, error) { + layout := "" + for _, l := range (*tokens)[1:] { + layout += l.Type.(string) + } + input := string((*tokens)[0].Runes) + value, err := time.Parse(layout, input) + return input, value, err +}