package tagparser
import (
)
type Tag struct {
Name string
Options map[string]string
}
func ( *Tag) ( string) bool {
, := .Options[]
return
}
func ( string) *Tag {
:= &tagParser{
Parser: parser.NewString(),
}
.parseKey()
return &.Tag
}
type tagParser struct {
*parser.Parser
Tag Tag
hasName bool
key string
}
func ( *tagParser) (, string) {
= strings.TrimSpace()
= strings.TrimSpace()
if !.hasName {
.hasName = true
if == "" {
.Tag.Name =
return
}
}
if .Tag.Options == nil {
.Tag.Options = make(map[string]string)
}
if == "" {
.Tag.Options[] = ""
} else {
.Tag.Options[] =
}
}
func ( *tagParser) () {
.key = ""
var []byte
for .Valid() {
:= .Read()
switch {
case ',':
.Skip(' ')
.setTagOption("", string())
.()
return
case ':':
.key = string()
.parseValue()
return
case '\'':
.parseQuotedValue()
return
default:
= append(, )
}
}
if len() > 0 {
.setTagOption("", string())
}
}
func ( *tagParser) () {
const = '\''
:= .Peek()
if == {
.Skip()
.parseQuotedValue()
return
}
var []byte
for .Valid() {
= .Read()
switch {
case '\\':
= append(, .Read())
case '(':
= append(, )
= .readBrackets()
case ',':
.Skip(' ')
.setTagOption(.key, string())
.parseKey()
return
default:
= append(, )
}
}
.setTagOption(.key, string())
}
func ( *tagParser) ( []byte) []byte {
var int
:
for .Valid() {
:= .Read()
switch {
case '\\':
= append(, .Read())
case '(':
= append(, )
++
case ')':
= append(, )
--
if < 0 {
break
}
default:
= append(, )
}
}
return
}
func ( *tagParser) () {
const = '\''
var []byte
= append(, )
for .Valid() {
, := .ReadSep()
if ! {
= append(, ...)
break
}
if len() > 0 && [len()-1] == '\\' {
= append(, [:len()-1]...)
= append(, )
continue
}
= append(, ...)
= append(, )
break
}
.setTagOption(.key, string())
if .Skip(',') {
.Skip(' ')
}
.parseKey()
}
func ( string) (string, bool) {
const = '\''
if len() < 2 {
return , false
}
if [0] == && [len()-1] == {
return [1 : len()-1], true
}
return , false
}