renderStructField renders a single struct field to output, dispatching on its kind.
(field reflect.Value, fieldName string, tag consoleTag, maxFieldLen int, output *strings.Builder, depth int)
| 148 | |
| 149 | // renderStructField renders a single struct field to output, dispatching on its kind. |
| 150 | func renderStructField(field reflect.Value, fieldName string, tag consoleTag, maxFieldLen int, output *strings.Builder, depth int) { |
| 151 | // Dereference pointer to check underlying type |
| 152 | fieldToCheck := field |
| 153 | if field.Kind() == reflect.Pointer && !field.IsNil() { |
| 154 | fieldToCheck = field.Elem() |
| 155 | } |
| 156 | |
| 157 | subTitle := tag.title |
| 158 | if subTitle == "" { |
| 159 | subTitle = fieldName |
| 160 | } |
| 161 | |
| 162 | switch { |
| 163 | case fieldToCheck.Kind() == reflect.Struct && fieldToCheck.Type().String() != "time.Time": |
| 164 | // Nested struct – render recursively |
| 165 | renderValue(field, subTitle, output, depth+1) |
| 166 | case fieldToCheck.Kind() == reflect.Slice || fieldToCheck.Kind() == reflect.Array: |
| 167 | // Slice – render as table |
| 168 | renderValue(field, subTitle, output, depth+1) |
| 169 | case fieldToCheck.Kind() == reflect.Map: |
| 170 | // Map – render as headers |
| 171 | renderValue(field, subTitle, output, depth+1) |
| 172 | default: |
| 173 | // Simple field – render as key-value pair with alignment |
| 174 | paddedName := fmt.Sprintf("%-*s", maxFieldLen, fieldName) |
| 175 | fmt.Fprintf(output, " %s: %v\n", paddedName, formatFieldValueWithTag(field, tag)) |
| 176 | } |
| 177 | } |
| 178 | |
| 179 | // renderSlice renders a slice as a table using the console table renderer |
| 180 | func renderSlice(val reflect.Value, title string, output *strings.Builder, depth int) { |
no test coverage detected