github.com/qri-io/qri@v0.10.1-0.20220104210721-c771715036cb/lib/params.go (about) 1 package lib 2 3 import ( 4 "reflect" 5 6 "github.com/qri-io/qfs" 7 "github.com/qri-io/qri/dsref" 8 ) 9 10 // EmptyParams is for methods that don't need any input 11 type EmptyParams struct { 12 } 13 14 // NZDefaultSetter modifies zero values to non-zero defaults when called 15 type NZDefaultSetter interface { 16 SetNonZeroDefaults() 17 } 18 19 // normalizeInputParams will look at each field of the params, and modify filepaths so that 20 // they are absolute paths, making them safe to send across RPC to another process 21 func normalizeInputParams(param interface{}) interface{} { 22 typ := reflect.TypeOf(param) 23 val := reflect.ValueOf(param) 24 if typ.Kind() == reflect.Ptr { 25 typ = typ.Elem() 26 val = val.Elem() 27 } 28 if typ.Kind() == reflect.Struct { 29 num := typ.NumField() 30 for i := 0; i < num; i++ { 31 tfield := typ.Field(i) 32 vfield := val.Field(i) 33 qriTag := tfield.Tag.Get("qri") 34 if isQriStructTag(qriTag) { 35 normalizeFileField(vfield, qriTag) 36 } else if qriTag != "" { 37 log.Errorf("unknown qri struct tag %q", qriTag) 38 } 39 } 40 } 41 return param 42 } 43 44 // qri struct tags augment how fields are marshalled for dispatched methods 45 const ( 46 // QriStTagFspath means the field is a filesystem path and needs to be absolute 47 QriStTagFspath = "fspath" 48 // QriStTagRefOrPath means the field is either a dataset ref, or is a filesys path 49 QriStTagRefOrPath = "dsrefOrFspath" 50 ) 51 52 func isQriStructTag(text string) bool { 53 return text == QriStTagFspath || text == QriStTagRefOrPath 54 } 55 56 func normalizeFileField(vfield reflect.Value, qriTag string) { 57 interf := vfield.Interface() 58 if str, ok := interf.(string); ok { 59 if qriTag == QriStTagRefOrPath && dsref.IsRefString(str) { 60 return 61 } 62 if err := qfs.AbsPath(&str); err == nil { 63 vfield.SetString(str) 64 } 65 } 66 if strList, ok := interf.([]string); ok { 67 build := make([]string, 0, len(strList)) 68 for _, str := range strList { 69 if qriTag != QriStTagRefOrPath || !dsref.IsRefString(str) { 70 _ = qfs.AbsPath(&str) 71 } 72 build = append(build, str) 73 } 74 vfield.Set(reflect.ValueOf(build)) 75 } 76 }