scanner

package
v1.1.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 25, 2018 License: MIT Imports: 6 Imported by: 0

Documentation

Overview

Package scanner provides Scanner interface and it's default implementation, which can be used to scan key-value pairs from property files or struct tags.

This scanner implementation is an alternative to "reflect".StructTag.Get(), more convenient to parse complex tag values.

It gives:

  • multiline tags,
  • custom separators between key and value parts,
  • custom quote characters,
  • custom escape character,
  • more relaxed syntax (have a look at tests to get an idea),
  • conventional syntax is also supported.

Instead of Get/Lookup interface, scanner returns a map of key-value pairs.

The same scanner can be used to parse short and simple property files, similar in syntax to Java property files. Though, this is not a main goal of this package. So, synatx only resambles one of Java property files, there can be many differencies.

Scanner should work with unicode within files/tags, but this is not tested yet.

Example (Ex)

Example_ex illustrates use of more relaxed syntax within struct tags.

package main

import (
	"fmt"
	"reflect"

	"github.com/nikolay-turpitko/structor/scanner"
)

func main() {
	type S struct {
		F string `
# this is an example of multiline tag
# with multiline values, custom quotation
# and field delimiter

species: "gopher"
color:   "blue"

multiline: blue\
gopher\
isn't it strange?

multiline2 = 'yet
another
way'

key-1='value-1', key-2="value-2"`

		F1 string `
			# more convenient formatting possible,
			# when you don't care about spaces in multiline tag values

			species: "gopher" color:"blue"
			key-1: "value-1"; key-2: "value-2"
		`
	}

	s := S{}
	st := reflect.TypeOf(s)
	field := st.Field(0)
	tags, _ := scanner.Default.Tags(field.Tag)
	fmt.Println(tags["color"], tags["species"])
	fmt.Println(tags["multiline"])
	fmt.Println(tags["multiline2"])
	fmt.Println(tags["key-1"], tags["key-2"])

	field = st.Field(1)
	tags, _ = scanner.Default.Tags(field.Tag)
	fmt.Println()
	fmt.Println(tags["color"], tags["species"])
	fmt.Println(tags["key-1"], tags["key-2"])

}
Output:
blue gopher
blue
gopher
isn't it strange?
yet
another
way
value-1 value-2

blue gopher
value-1 value-2
Example (Mix)

Example_mix illustrate mixed usage of "reflect" package and structor.Scanner on the same tags.

Tags for libs, which uses conventional syntax, could be placed on the first line and all other lines can be used by the structor.Scanner.

package main

import (
	"fmt"
	"reflect"

	"github.com/nikolay-turpitko/structor/scanner"
)

func main() {
	type S struct {
		F string `species:"gopher" color:"blue"
				  key-1: "value-1"
				  key-2: "value-2"`
	}

	s := S{}
	st := reflect.TypeOf(s)
	field := st.Field(0)
	fmt.Println(field.Tag.Get("color"), field.Tag.Get("species"))
	// standard lib won't see these fields, but won't panic either
	fmt.Println("'", field.Tag.Get("key-1"), field.Tag.Get("key-2"), "'")
	tags, _ := scanner.Default.Tags(field.Tag)
	fmt.Println(tags["color"], tags["species"])
	fmt.Println(tags["key-1"], tags["key-2"])

}
Output:
blue gopher
'   '
blue gopher
value-1 value-2
Example (Reflect_StructTag)

Example_reflect_StructTag is an example ported from "reflect" package to illustrate support of conventional syntax within tags.

package main

import (
	"fmt"
	"reflect"

	"github.com/nikolay-turpitko/structor/scanner"
)

func main() {
	type S struct {
		F string `species:"gopher" color:"blue"`
	}

	s := S{}
	st := reflect.TypeOf(s)
	field := st.Field(0)
	tags, _ := scanner.Default.Tags(field.Tag)
	fmt.Println(tags["color"], tags["species"])

}
Output:
blue gopher
Example (Reflect_StructTag_Lookup)

Example_reflect_StructTag_Lookup is an example ported from "reflect" package to illustrate support of conventional syntax within tags.

package main

import (
	"fmt"
	"reflect"

	"github.com/nikolay-turpitko/structor/scanner"
)

func main() {
	type S struct {
		F0 string `alias:"field_0"`
		F1 string `alias:""`
		F2 string
	}

	s := S{}
	st := reflect.TypeOf(s)
	for i := 0; i < st.NumField(); i++ {
		field := st.Field(i)
		tags, _ := scanner.Default.Tags(field.Tag)
		if alias, ok := tags["alias"]; ok {
			if alias == "" {
				fmt.Println("(blank)")
			} else {
				fmt.Println(alias)
			}
		} else {
			fmt.Println("(not specified)")
		}
	}

}
Output:
field_0
(blank)
(not specified)

Index

Examples

Constants

This section is empty.

Variables

View Source
var Default = New([]rune{':', '='}, []rune{'"', '\'', '`'}, '\\')

Default is an instance of Scanner with sensible defaults.

Functions

This section is empty.

Types

type Scanner

type Scanner interface {
	Tags(reflect.StructTag) (map[string]string, error)
	Scan(io.Reader) (map[string]string, error)
}

Scanner is an interface of key-value pairs scanner.

func New

func New(fieldSeparators, quotes []rune, escape rune) Scanner

New creates Scanner intstance with custom field separators, quotes and escape character.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL