func (*NullSchema) Prop(key string) (interface{}, bool) {
	return nil, false
}
Prop doesn't return anything valuable for NullSchema.
package avro
import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"math"
	"reflect"
	"strings"
)
const (
	Record int = iota
	Enum
	Array
	Map
	Union
	Fixed
	String
	Bytes
	Int
	Long
	Float
	Double
	Boolean
	Null
	Recursive
)
const (
	typeRecord  = "record"
	typeUnion   = "union"
	typeEnum    = "enum"
	typeArray   = "array"
	typeMap     = "map"
	typeFixed   = "fixed"
	typeString  = "string"
	typeBytes   = "bytes"
	typeInt     = "int"
	typeLong    = "long"
	typeFloat   = "float"
	typeDouble  = "double"
	typeBoolean = "boolean"
	typeNull    = "null"
)
const (
	schemaAliasesField   = "aliases"
	schemaDefaultField   = "default"
	schemaDocField       = "doc"
	schemaFieldsField    = "fields"
	schemaItemsField     = "items"
	schemaNameField      = "name"
	schemaNamespaceField = "namespace"
	schemaSizeField      = "size"
	schemaSymbolsField   = "symbols"
	schemaTypeField      = "type"
	schemaValuesField    = "values"
)
type Schema interface {
	Type() int
	GetName() string
	Prop(key string) (interface{}, bool)
	String() string
	Validate(v reflect.Value) bool
}
type StringSchema struct{}
func (*StringSchema) String() string {
	return `{"type": "string"}`
}
func (*StringSchema) Type() int {
	return String
}
func (*StringSchema) GetName() string {
	return typeString
}
func (*StringSchema) Prop(key string) (interface{}, bool) {
	return nil, false
}
func (*StringSchema) Validate(v reflect.Value) bool {
	_, ok := dereference(v).Interface().(string)
	return ok
}
func (*StringSchema) MarshalJSON() ([]byte, error) {
	return []byte(`"string"`), nil
}
type BytesSchema struct{}
func (*BytesSchema) String() string {
	return `{"type": "bytes"}`
}
func (*BytesSchema) Type() int {
	return Bytes
}
func (*BytesSchema) GetName() string {
	return typeBytes
}
func (*BytesSchema) Prop(key string) (interface{}, bool) {
	return nil, false
}
func (*BytesSchema) Validate(v reflect.Value) bool {
	v = dereference(v)
	return v.Kind() == reflect.Slice && v.Type().Elem().Kind() == reflect.Uint8
}
func (*BytesSchema) MarshalJSON() ([]byte, error) {
	return []byte(`"bytes"`), nil
}
type IntSchema struct{}
func (*IntSchema) String() string {
	return `{"type": "int"}`
}
func (*IntSchema) Type() int {
	return Int
}
func (*IntSchema) GetName() string {
	return typeInt
}
func (*IntSchema) Prop(key string) (interface{}, bool) {
	return nil, false
}
func (*IntSchema) Validate(v reflect.Value) bool {
	return reflect.TypeOf(dereference(v).Interface()).Kind() == reflect.Int32
}
func (*IntSchema) MarshalJSON() ([]byte, error) {
	return []byte(`"int"`), nil
}
type LongSchema struct{}
func (*LongSchema) String() string {
	return `{"type": "long"}`
}
func (*LongSchema) Type() int {
	return Long
}
func (*LongSchema) GetName() string {
	return typeLong
}
func (*LongSchema) Prop(key string) (interface{}, bool) {
	return nil, false
}
func (*LongSchema) Validate(v reflect.Value) bool {
	return reflect.TypeOf(dereference(v).Interface()).Kind() == reflect.Int64
}
func (*LongSchema) MarshalJSON() ([]byte, error) {
	return []byte(`"long"`), nil
}
type FloatSchema struct{}
func (*FloatSchema) String() string {
	return `{"type": "float"}`
}
func (*FloatSchema) Type() int {
	return Float
}
func (*FloatSchema) GetName() string {
	return typeFloat
}
func (*FloatSchema) Prop(key string) (interface{}, bool) {
	return nil, false
}
func (*FloatSchema) Validate(v reflect.Value) bool {
	return reflect.TypeOf(dereference(v).Interface()).Kind() == reflect.Float32
}
func (*FloatSchema) MarshalJSON() ([]byte, error) {
	return []byte(`"float"`), nil
}
type DoubleSchema struct{}
func (*DoubleSchema) String() string {
	return `{"type": "double"}`
}
func (*DoubleSchema) Type() int {
	return Double
}
func (*DoubleSchema) GetName() string {
	return typeDouble
}
func (*DoubleSchema) Prop(key string) (interface{}, bool) {
	return nil, false
}
func (*DoubleSchema) Validate(v reflect.Value) bool {
	return reflect.TypeOf(dereference(v).Interface()).Kind() == reflect.Float64
}
func (*DoubleSchema) MarshalJSON() ([]byte, error) {
	return []byte(`"double"`), nil
}
type BooleanSchema struct{}
func (*BooleanSchema) String() string {
	return `{"type": "boolean"}`
}
func (*BooleanSchema) Type() int {
	return Boolean
}
func (*BooleanSchema) GetName() string {
	return typeBoolean
}
func (*BooleanSchema) Prop(key string) (interface{}, bool) {
	return nil, false
}
func (*BooleanSchema) Validate(v reflect.Value) bool {
	return reflect.TypeOf(dereference(v).Interface()).Kind() == reflect.Bool
}
func (*BooleanSchema) MarshalJSON() ([]byte, error) {
	return []byte(`"boolean"`), nil
}
type NullSchema struct{}
func (*NullSchema) String() string {
	return `{"type": "null"}`
}
func (*NullSchema) Type() int {
	return Null
}
func (*NullSchema) GetName() string {
	return typeNull
}