reflection work so far...
This commit is contained in:
173
funcs_fieldmap_tlsuri.go
Normal file
173
funcs_fieldmap_tlsuri.go
Normal file
@@ -0,0 +1,173 @@
|
||||
package cryptparse
|
||||
|
||||
import (
|
||||
`reflect`
|
||||
`sync`
|
||||
|
||||
`r00t2.io/goutils/multierr`
|
||||
`r00t2.io/goutils/structutils`
|
||||
)
|
||||
|
||||
/*
|
||||
FieldMapTlsURI returns TlsUri tu from struct, map, or slice s.
|
||||
|
||||
If a map, the keys should be the Param* tlsUriParam contants' *values*
|
||||
(e.g. map[string][]string{"ignore_missing": []string{"true"}}).
|
||||
If a slice, it should be a slice of strings (or nested other supported type)
|
||||
which follow the pattern `<key>=<value>` where `<key>` is one of the
|
||||
Param* tlsUriParam constants' *values*.
|
||||
Obviously in both these cases, the host/port will not be set.
|
||||
See the NOTE below.
|
||||
|
||||
The default is to recurse into e.g. nested structs and sub-structs
|
||||
unless they are tagged with the value "-".
|
||||
|
||||
This function operates on the struct tag `tlsUri` (e.g. `tlsUri:"-"`, `tlsUri:"ca"`, etc.).
|
||||
If you need to use an explicit/different struct tag name, use FieldMapTlsURIWithTag.
|
||||
|
||||
See the struct tags on TlsFlat for an example of usage.
|
||||
|
||||
NOTE: The host and port are not currently directly
|
||||
configurable via struct tags. These can be set
|
||||
via the SetHost, SetPort, SetPortStr, SetHostPort,
|
||||
and/or SetHostPortStr on the returned TlsUri.
|
||||
*/
|
||||
func FieldMapTlsURI[T any](s T) (tu *TlsUri, err error) {
|
||||
|
||||
if tu, err = FieldMapTlsURIWithTag(s, dfltStructTag); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// FieldMapTlsURIWithTag is exactly like FieldMapTlsURI but allows specifying an explict tag name.
|
||||
func FieldMapTlsURIWithTag[T any](s T, tagName string,) (tu *TlsUri, err error) {
|
||||
|
||||
var ptrVal reflect.Value
|
||||
var sVal reflect.Value = reflect.ValueOf(s)
|
||||
var sType reflect.Type = sVal.Type()
|
||||
var params *tlsUriParams
|
||||
|
||||
*params = make(map[tlsUriParam][]string)
|
||||
|
||||
if sVal.IsNil() || sVal.IsZero() || !sVal.IsValid() {
|
||||
return
|
||||
}
|
||||
ptrVal = sVal.Elem()
|
||||
|
||||
if err = fieldMapTlsURIStruct(params, ptrVal, tagName); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// TODO
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// fieldMapTlsURIStruct parses a reflect.Value and populates params with any matching fields found.
|
||||
func fieldMapTlsURIStruct(params *tlsUriParams, v reflect.Value, tagName string) (err error) {
|
||||
|
||||
var field reflect.StructField
|
||||
var fieldVal reflect.Value
|
||||
var wg sync.WaitGroup
|
||||
var errChan chan error
|
||||
var numJobs int
|
||||
var doneChan chan bool = make(chan bool, 1)
|
||||
var mErr *multierr.MultiError = multierr.NewMultiError(nil)
|
||||
var t reflect.Type = v.Type()
|
||||
var kind reflect.Kind = t.Kind()
|
||||
|
||||
if params == nil {
|
||||
err = ErrReqParams
|
||||
return
|
||||
}
|
||||
|
||||
if kind != reflect.Struct {
|
||||
err = ErrReqStruct
|
||||
return
|
||||
}
|
||||
|
||||
numJobs = v.NumField()
|
||||
wg.Add(numJobs)
|
||||
errChan = make(chan error, numJobs)
|
||||
|
||||
for i := 0; i < v.NumField(); i++ {
|
||||
field = t.Field(i)
|
||||
fieldVal = v.Field(i)
|
||||
|
||||
go func(f reflect.StructField, fv reflect.Value) {
|
||||
var fErr error
|
||||
|
||||
defer wg.Done()
|
||||
|
||||
if fErr = fieldMapTlsURIStructField(params, f, fv, tagName); fErr != nil {
|
||||
errChan <- fErr
|
||||
return
|
||||
}
|
||||
}(field, fieldVal)
|
||||
}
|
||||
|
||||
go func() {
|
||||
wg.Wait()
|
||||
close(errChan)
|
||||
doneChan <- true
|
||||
}()
|
||||
|
||||
<-doneChan
|
||||
|
||||
for i := 0; i < numJobs; i++ {
|
||||
if err = <-errChan; err != nil {
|
||||
mErr.AddError(err)
|
||||
err = nil
|
||||
}
|
||||
}
|
||||
|
||||
if !mErr.IsEmpty() {
|
||||
err = mErr
|
||||
return
|
||||
}
|
||||
|
||||
// TODO
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// fieldMapTlsURIStructField parses a single struct field.
|
||||
func fieldMapTlsURIStructField(params *tlsUriParams, field reflect.StructField, fv reflect.Value, tagName string) (err error) {
|
||||
|
||||
var parsedTagOpts map[string]bool
|
||||
|
||||
if params == nil {
|
||||
err = ErrReqParams
|
||||
return
|
||||
}
|
||||
|
||||
if !fv.CanSet() {
|
||||
return
|
||||
}
|
||||
|
||||
// Skip if explicitly instructed to do so.
|
||||
parsedTagOpts = structutils.TagToBoolMap(field, tagName, structutils.TagMapTrim)
|
||||
if parsedTagOpts["-"] {
|
||||
return
|
||||
}
|
||||
|
||||
if fv.Kind() == reflect.Ptr {
|
||||
err = fieldMapTlsURIStructField(params, field, fv.Elem(), tagName)
|
||||
} else {
|
||||
err = fieldMapTlsUriValue(params, fv, tagName)
|
||||
}
|
||||
|
||||
// TODO
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// fieldMapTlsUriValue is a type dispatcher for a reflected value.
|
||||
func fieldMapTlsUriValue(params *tlsUriParams, v reflect.Value, tagName string) (err error) {
|
||||
|
||||
// TODO
|
||||
|
||||
return
|
||||
}
|
||||
Reference in New Issue
Block a user