CanFormatDiffSlice reports whether we support custom formatting for nodes that are slices of primitive kinds or strings.
(v *valueNode)
| 20 | // CanFormatDiffSlice reports whether we support custom formatting for nodes |
| 21 | // that are slices of primitive kinds or strings. |
| 22 | func (opts formatOptions) CanFormatDiffSlice(v *valueNode) bool { |
| 23 | switch { |
| 24 | case opts.DiffMode != diffUnknown: |
| 25 | return false // Must be formatting in diff mode |
| 26 | case v.NumDiff == 0: |
| 27 | return false // No differences detected |
| 28 | case !v.ValueX.IsValid() || !v.ValueY.IsValid(): |
| 29 | return false // Both values must be valid |
| 30 | case v.NumIgnored > 0: |
| 31 | return false // Some ignore option was used |
| 32 | case v.NumTransformed > 0: |
| 33 | return false // Some transform option was used |
| 34 | case v.NumCompared > 1: |
| 35 | return false // More than one comparison was used |
| 36 | case v.NumCompared == 1 && v.Type.Name() != "": |
| 37 | // The need for cmp to check applicability of options on every element |
| 38 | // in a slice is a significant performance detriment for large []byte. |
| 39 | // The workaround is to specify Comparer(bytes.Equal), |
| 40 | // which enables cmp to compare []byte more efficiently. |
| 41 | // If they differ, we still want to provide batched diffing. |
| 42 | // The logic disallows named types since they tend to have their own |
| 43 | // String method, with nicer formatting than what this provides. |
| 44 | return false |
| 45 | } |
| 46 | |
| 47 | // Check whether this is an interface with the same concrete types. |
| 48 | t := v.Type |
| 49 | vx, vy := v.ValueX, v.ValueY |
| 50 | if t.Kind() == reflect.Interface && !vx.IsNil() && !vy.IsNil() && vx.Elem().Type() == vy.Elem().Type() { |
| 51 | vx, vy = vx.Elem(), vy.Elem() |
| 52 | t = vx.Type() |
| 53 | } |
| 54 | |
| 55 | // Check whether we provide specialized diffing for this type. |
| 56 | switch t.Kind() { |
| 57 | case reflect.String: |
| 58 | case reflect.Array, reflect.Slice: |
| 59 | // Only slices of primitive types have specialized handling. |
| 60 | switch t.Elem().Kind() { |
| 61 | case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, |
| 62 | reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr, |
| 63 | reflect.Bool, reflect.Float32, reflect.Float64, reflect.Complex64, reflect.Complex128: |
| 64 | default: |
| 65 | return false |
| 66 | } |
| 67 | |
| 68 | // Both slice values have to be non-empty. |
| 69 | if t.Kind() == reflect.Slice && (vx.Len() == 0 || vy.Len() == 0) { |
| 70 | return false |
| 71 | } |
| 72 | |
| 73 | // If a sufficient number of elements already differ, |
| 74 | // use specialized formatting even if length requirement is not met. |
| 75 | if v.NumDiff > v.NumSame { |
| 76 | return true |
| 77 | } |
| 78 | default: |
| 79 | return false |
no test coverage detected