func()

in llpath/path.go [120:158]


func (p Path) GetFrom(source reflect.Value) (result reflect.Value, exists bool) {
	// nil values are handled specially. If we're fetching from a nil
	// there's one case where it exists, when comparing it to another nil.
	if (source.Kind() == reflect.Map || source.Kind() == reflect.Slice) && source.IsNil() {
		// since another nil would be scalar, we just check that the
		// path length is 0.
		return source, len(p) == 0
	}

	result = source
	exists = true
	for _, pc := range p {
		switch result.Kind() {
		case reflect.Map:
			result = llreflect.ChaseValue(result.MapIndex(reflect.ValueOf(pc.Key)))
			exists = result != reflect.Value{}
		case reflect.Slice, reflect.Array:
			if pc.Index < result.Len() {
				result = llreflect.ChaseValue(result.Index(pc.Index))
				exists = result != reflect.Value{}
			} else {
				result = reflect.ValueOf(nil)
				exists = false
			}
		default:
			// If this case has been reached this means the expected type, say a map,
			// is actually something else, like a string or an array. In this case we
			// simply say the result doesn't exist. From a practical perspective this is
			// the right behavior since it will cause validation to fail.
			return reflect.ValueOf(nil), false
		}

		if exists == false {
			return reflect.ValueOf(nil), exists
		}
	}

	return result, exists
}