forked from hashicorp/hcl
-
Notifications
You must be signed in to change notification settings - Fork 0
/
diagnostic_typeparams.go
42 lines (36 loc) · 1.3 KB
/
diagnostic_typeparams.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
//go:build go1.18
// +build go1.18
package hcl
// This file contains additional diagnostics-related symbols that use the
// Go 1.18 type parameters syntax and would therefore be incompatible with
// Go 1.17 and earlier.
// DiagnosticExtra attempts to retrieve an "extra value" of type T from the
// given diagnostic, if either the diag.Extra field directly contains a value
// of that type or the value implements DiagnosticExtraUnwrapper and directly
// or indirectly returns a value of that type.
//
// Type T should typically be an interface type, so that code which generates
// diagnostics can potentially return different implementations of the same
// interface dynamically as needed.
//
// If a value of type T is found, returns that value and true to indicate
// success. Otherwise, returns the zero value of T and false to indicate
// failure.
func DiagnosticExtra[T any](diag *Diagnostic) (T, bool) {
extra := diag.Extra
var zero T
for {
if ret, ok := extra.(T); ok {
return ret, true
}
if unwrap, ok := extra.(DiagnosticExtraUnwrapper); ok {
// If our "extra" implements DiagnosticExtraUnwrapper then we'll
// unwrap one level and try this again.
extra = unwrap.UnwrapDiagnosticExtra()
} else {
return zero, false
}
}
}