Code Monkey home page Code Monkey logo

set's Introduction

Go Reference Go Report Card Build Status codecov License: MIT

Package set is a performant reflect wrapper supporting loose type conversion, struct mapping and population, and slice building.

The godoc documentation has detailed information and many examples but following is the high-level view.

Type Coercion

Type coercion allows assignment from loosey-goosey sources -- for example incoming string data -- to strongly typed Go types.

var t T           // T is a target data type, t is a variable of that type.
var s S           // S is a source data type, s is a variable of that type.
set.V(&t).To(s)   // Sets s into t with a "best effort" approach.

Struct Population with Getter

set.Value has two methods, Fill and FillByTag, that use the set.Getter interface as the provider for data to populate a struct and its hierarchy.

For convenience:

  • set.GetterFunc allows plain functions to be used as a set.Getter similar to http.HandlerFunc.
  • set.MapGetter allows either map[string]T or map[interface{}]T to be used as a set.Getter.

Struct Mapping

set.Mapper is a powerful and highly configurable struct mapping facility.

A mapper will traverse a struct hiearchy and create a 1:1 mapping of friendly names to traversal information. The friendly names can then be used to target associated fields within a struct value and its hierarchy.

Example usages of a mapper are to map CSV column headings to struct fields, database column names to struct fields, or creating a generic struct copier to marshal structs across different domains or boundaries in your application architecture.

set.Mapper contains several configuration fields that can be used to fully customize the generated friendly names:

  • Choose how nested names are combined: VendorName, Vendor_Name, Vendor.Name, vendor_name, etc.
  • Specify multiple tags in order of preference: db tag values can have higher precedence than json tags
  • Elevate types into a higher namespace: see the Mapper example(s)
  • Specify types that are ignored and don't get mapped.
  • Specify types that are treated as scalars: useful for sql.Null* types or similar

BoundMapping and PreparedMapping

Once a set.Mapper (described above) is created it can return BoundMapping or PreparedMapping types that are bound to Go structs. In turn BoundMapping and PreparedMapping provide performant access to the bound data via the friendly names generated by the mapper.

A BoundMapping provides an adhoc access to struct fields; each method takes the mapped name of the field to access. An example use case for BoundMapping is populating data when some of the data may be missing and you may not set data for every possible mapped field.

A PreparedMapping is similar to a prepared SQL statement and the access plan must be set with a call to its Plan method. An example use case for PreparedMapping is populating CSV data or database rows where every row is guaranteed to access the same fields in the same order.

Performance Notes

Package reflect is always slower than code not using reflect. A considerable effort has been spent designing and implementing this package to reduce reflect overhead.

  • reflect data is generally only gathered once (via reflect.TypeOf, reflect.ValueOf) when first encountering a type. This data is cached and retrieved from cache on further encounters with repeated types.
  • Value assigning is generally attempted first with type switches and then falls back to reflect. This strategy is heavily used during type coercion.
  • Appropriate types in this package have a Rebind method. Rebind will swap a "bound" Go type with a new incoming instance without making additional expensive calls into reflect. The outgoing and incoming types must be compatible but this is the expected usage in tight loops building slices of data.

Additionally this package attempts to be low allocation so as not to overwhelm the garbage collector.

  • Some of the methods on BoundMapping and PreparedMapping allow a dest slice to be pre-allocated.
  • BoundMapping, PreparedMapping, and Value are created and returned as structs instead of pointers.

API Consistency and Breaking Changes

I am making a very concerted effort to break the API as little as possible while adding features or fixing bugs. However this software is currently in a pre-1.0.0 version and breaking changes are allowed under standard semver. As the API approaches a stable 1.0.0 release I will list any such breaking changes here and they will always be signaled by a bump in minor version.

  • 0.4.0 ⭢ 0.5.0

    • README-0.4.0-to-0.5.0.md outlines many of the package changes, reasoning, and benchmarks

    • Remove erroneous documentation for Value.To method.
      The documentation indicated that when Dst and Src are both pointers with same level of indirection that direct assignment was performed. This is not true. The Value type uses the values at the end of pointers and pointer chains and therefore does not perform direct assignment of pointer values.

  • 0.3.0 ⭢ 0.4.0
    set.Mapper has new field TaggedFieldsOnly. TaggedFieldsOnly=false means no change in behavior. TaggedFieldsOnly=true means set.Mapper only maps exported fields with struct tags.

  • 0.2.3 ⭢ 0.3.0
    set.BoundMapping.Assignables has a second argument allowing you to pre-allocate the slice that is returned; you can also set it to nil to keep current behavior.

set's People

Contributors

nofeaturesonlybugs avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.