func IsZeroInFields(s interface{}, names ...string) (string, bool) {
	if s == nil || len(names) == 0 {
		return "", true
	}
	sv, err := structValue(s)
	if err != nil {
		return "", false
	}
	for _, name := range names {
		fv := sv.FieldByName(name)
		if !fv.IsValid() {
			continue
		}
		if isFieldZero(fv) {
			return name, true
		}
	}
	return "", false
}
IsZeroInFields method verifies the value for the given list of field names against
given struct. Method returns `Field Name` and `true` for the zero value field.
Otherwise method returns empty `string` and `false`.

Note:
[1] This method doesn't traverse nested and embedded `struct`, instead it just evaluates that `struct`.
[2] If given field is not exists in the struct, method moves on to next field

A "model" tag with the value of "-" is ignored by library for processing.
Example:

// Field is ignored by go-model processing
BookCount	int	`model:"-"`
BookCode	string	`model:"-"`
package model
import (
	"errors"
	"fmt"
	"net/http"
	"os"
	"reflect"
	"time"
)
type Converter func(in reflect.Value) (reflect.Value, error)
const (
	TagName = "model"
	OmitField = "-"
	OmitEmpty = "omitempty"
	NoTraverse = "notraverse"
)
var (
	Version = "1.1.0"
	noTraverseTypeList map[reflect.Type]bool
	converterMap map[reflect.Type]map[reflect.Type]Converter
	typeOfBytes     = reflect.TypeOf([]byte(nil))
	typeOfInterface = reflect.TypeOf((*interface{})(nil)).Elem()
)
func AddNoTraverseType(i ...interface{}) {
	for _, v := range i {
		t := reflect.TypeOf(v)
		if _, ok := noTraverseTypeList[t]; ok {
			continue
		}
		noTraverseTypeList[t] = true
	}
}
func RemoveNoTraverseType(i ...interface{}) {
	for _, v := range i {
		t := reflect.TypeOf(v)
		if _, ok := noTraverseTypeList[t]; ok {
			delete(noTraverseTypeList, t)
		}
	}
}
func AddConversion(in interface{}, out interface{}, converter Converter) {
	srcType := extractType(in)
	targetType := extractType(out)
	AddConversionByType(srcType, targetType, converter)
}
func AddConversionByType(srcType reflect.Type, targetType reflect.Type, converter Converter) {
	if _, ok := converterMap[srcType]; !ok {
		converterMap[srcType] = map[reflect.Type]Converter{}
	}
	converterMap[srcType][targetType] = converter
}
func RemoveConversion(in interface{}, out interface{}) {
	srcType := extractType(in)
	targetType := extractType(out)
	if _, ok := converterMap[srcType]; !ok {
		return
	}
	if _, ok := converterMap[srcType][targetType]; !ok {
		return
	}
	delete(converterMap[srcType], targetType)
}
func IsZero(s interface{}) bool {
	if s == nil {
		return true
	}
	sv, err := structValue(s)
	if err != nil {
		return false
	}
	fields := modelFields(sv)
	for _, f := range fields {
		fv := sv.FieldByName(f.Name)
		tag := newTag(f.Tag.Get(TagName))
		if tag.isOmitField() {
			continue
		}
		if isStruct(fv) {
			if isNoTraverseType(fv) || tag.isNoTraverse() {
				if !isFieldZero(fv) {
					return false
				}
				continue
			}
			if !IsZero(fv.Interface()) {
				return false
			}
			continue
		}
		if !isFieldZero(fv) {
			return false
		}
	}
	return true
}