Esempio n. 1
0
// 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
}
Esempio n. 2
0
// ExtractAddWorkUnitItem converts an arbitrary object (which really
// should be a cborpc.PythonTuple or a list) into an AddWorkUnitItem.
func ExtractAddWorkUnitItem(obj interface{}) (result AddWorkUnitItem, err error) {
	var (
		decoder      *mapstructure.Decoder
		haveMetadata bool
		havePriority bool
		kvpList      []interface{}
		kvpMap       map[string]interface{}
		str          string
		bstr         []byte
		ok           bool
	)
	// If we got handed a string (or a byte string) turn it into
	// a work unit with no data
	if str, ok = obj.(string); ok {
		result.Key = str
		result.Data = make(map[string]interface{})
		return
	}
	if bstr, ok = obj.([]byte); ok {
		result.Key = string(bstr)
		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["metadata"] = kvpList[2]
		haveMetadata = true
	}
	if len(kvpList) >= 4 && kvpList[3] != nil {
		kvpMap["priority"] = kvpList[3]
		havePriority = true
	}
	// Now we can invoke mapstructure
	config := mapstructure.DecoderConfig{
		DecodeHook: cborrpc.DecodeBytesAsString,
		Result:     &result,
	}
	decoder, err = mapstructure.NewDecoder(&config)
	if err == nil {
		err = decoder.Decode(kvpMap)
	}
	if err == nil && haveMetadata && !havePriority {
		// See if the caller passed metadata["priority"]
		// instead of an explicit priority field.
		if priority, ok := result.Metadata["priority"]; ok {
			if result.Priority, ok = priority.(float64); !ok {
				err = ErrBadPriority
			}
		}
	}
	return
}