diff --git a/parser.go b/parser.go index e4ff88b..6ae246e 100644 --- a/parser.go +++ b/parser.go @@ -10,6 +10,8 @@ import ( "text/scanner" ) +//go:generate stringer -type=tokenType + type tokenType int const ( @@ -23,33 +25,46 @@ const ( tokenStatementEnd ) -// Rule is a string type that represents a CSS rule. -type Rule string - type tokenEntry struct { value string pos scanner.Position } -type tokenizer struct { - s *scanner.Scanner -} - -// Type returns the rule type, which can be a class, id or a tag. -func (rule Rule) Type() string { - if strings.HasPrefix(string(rule), ".") { - return "class" +func newTokenType(typ string) tokenType { + types := map[string]tokenType{ + "{": tokenBlockStart, + "}": tokenBlockEnd, + ":": tokenStyleSeparator, + ";": tokenStatementEnd, + ".": tokenSelector, + "#": tokenSelector, } - if strings.HasPrefix(string(rule), "#") { - return "id" + + result, ok := types[typ] + if ok { + return result } - return "tag" + + return tokenValue } func (e tokenEntry) typ() tokenType { return newTokenType(e.value) } +type tokenizer struct { + s *scanner.Scanner +} + +func newTokenizer(r io.Reader) *tokenizer { + s := &scanner.Scanner{} + s.Init(r) + + return &tokenizer{ + s: s, + } +} + func (t *tokenizer) next() (tokenEntry, error) { token := t.s.Scan() if token == scanner.EOF { @@ -57,7 +72,7 @@ func (t *tokenizer) next() (tokenEntry, error) { } value := t.s.TokenText() pos := t.s.Pos() - if newTokenType(value).String() == "STYLE_SEPARATOR" { + if newTokenType(value) == tokenStyleSeparator { t.s.IsIdentRune = func(ch rune, i int) bool { // property value can contain spaces if ch == -1 || ch == '\n' || ch == '\r' || ch == '\t' || ch == ':' || ch == ';' { return false @@ -78,44 +93,18 @@ func (t *tokenizer) next() (tokenEntry, error) { }, nil } -func (t tokenType) String() string { - switch t { - case tokenBlockStart: - return "BLOCK_START" - case tokenBlockEnd: - return "BLOCK_END" - case tokenStyleSeparator: - return "STYLE_SEPARATOR" - case tokenStatementEnd: - return "STATEMENT_END" - case tokenSelector: - return "SELECTOR" - } - return "VALUE" -} +// Rule is a string type that represents a CSS rule. +type Rule string -func newTokenType(typ string) tokenType { - switch typ { - case "{": - return tokenBlockStart - case "}": - return tokenBlockEnd - case ":": - return tokenStyleSeparator - case ";": - return tokenStatementEnd - case ".", "#": - return tokenSelector +// Type returns the rule type, which can be a class, id or a tag. +func (rule Rule) Type() string { + if strings.HasPrefix(string(rule), ".") { + return "class" } - return tokenValue -} - -func newTokenizer(r io.Reader) *tokenizer { - s := &scanner.Scanner{} - s.Init(r) - return &tokenizer{ - s: s, + if strings.HasPrefix(string(rule), "#") { + return "id" } + return "tag" } func buildList(r io.Reader) *list.List { diff --git a/parser_test.go b/parser_test.go index 938aa11..16ad22a 100644 --- a/parser_test.go +++ b/parser_test.go @@ -78,7 +78,7 @@ rule1 { } for _, tt := range cases { - t.Run("GoodCSS", func(t *testing.T) { + t.Run(tt.name, func(t *testing.T) { css, err := Unmarshal([]byte(tt.CSS)) if err != nil { t.Fatal(err) diff --git a/tokentype_string.go b/tokentype_string.go new file mode 100644 index 0000000..c6840e4 --- /dev/null +++ b/tokentype_string.go @@ -0,0 +1,31 @@ +// Code generated by "stringer -type=tokenType"; DO NOT EDIT. + +package css + +import "strconv" + +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[tokenFirstToken - -1] + _ = x[tokenBlockStart-0] + _ = x[tokenBlockEnd-1] + _ = x[tokenRuleName-2] + _ = x[tokenValue-3] + _ = x[tokenSelector-4] + _ = x[tokenStyleSeparator-5] + _ = x[tokenStatementEnd-6] +} + +const _tokenType_name = "tokenFirstTokentokenBlockStarttokenBlockEndtokenRuleNametokenValuetokenSelectortokenStyleSeparatortokenStatementEnd" + +var _tokenType_index = [...]uint8{0, 15, 30, 43, 56, 66, 79, 98, 115} + +func (i tokenType) String() string { + i -= -1 + if i < 0 || i >= tokenType(len(_tokenType_index)-1) { + return "tokenType(" + strconv.FormatInt(int64(i+-1), 10) + ")" + } + return _tokenType_name[_tokenType_index[i]:_tokenType_index[i+1]] +}