// lockKeys unmarshals an arbitrary object into a list of lists of // objects, flattening tuples into lists, or fails. func lockKeys(obj interface{}) ([][]interface{}, bool) { list, ok := cborrpc.Detuplify(obj) if !ok { return nil, ok } list2 := make([][]interface{}, len(list)) for i, item := range list { item2, ok := cborrpc.Detuplify(item) if !ok { return nil, ok } list2[i] = item2 } return list2, ok }
// ExtractAddWorkUnitItem converts an arbitrary object (which really // should be a cborpc.PythonTuple or a list) into an AddWorkUnitItem. func ExtractAddWorkUnitItem(obj interface{}, now time.Time) (result AddWorkUnitItem, err error) { var ( decoder *mapstructure.Decoder kvpList []interface{} kvpMap map[string]interface{} ok bool ) // If we got handed a string (or a byte string) turn it into // a work unit with no data if result.Key, ok = cborrpc.Destringify(obj); ok { result.Data = make(map[string]interface{}) return } // Otherwise obj must be a tuple (or a list) if kvpList, ok = cborrpc.Detuplify(obj); !ok { err = ErrWorkUnitNotList return } // Turn that list into a string-keyed map if len(kvpList) < 2 { err = ErrWorkUnitTooShort return } kvpMap = make(map[string]interface{}) kvpMap["key"] = kvpList[0] kvpMap["data"] = kvpList[1] if len(kvpList) >= 3 && kvpList[2] != nil { kvpMap["meta"] = kvpList[2] } // Now we can invoke mapstructure, on this modified struct var partial struct { Key string Data map[string]interface{} Meta AddWorkUnitMeta } config := mapstructure.DecoderConfig{ DecodeHook: cborrpc.DecodeBytesAsString, Result: &partial, } decoder, err = mapstructure.NewDecoder(&config) if err == nil { err = decoder.Decode(kvpMap) } // If that worked, copy data over to a real result if err == nil { result.Key = partial.Key result.Data = partial.Data result.Meta = partial.Meta.ToMeta(now) } // If a priority value was given in the list, that overrides // what got extracted if err == nil && len(kvpList) >= 4 && kvpList[3] != nil { if result.Meta.Priority, ok = kvpList[3].(float64); !ok { err = ErrBadPriority } } return }