1package basictracer
2
3import opentracing "github.com/opentracing/opentracing-go"
4
5type accessorPropagator struct {
6	tracer *tracerImpl
7}
8
9// DelegatingCarrier is a flexible carrier interface which can be implemented
10// by types which have a means of storing the trace metadata and already know
11// how to serialize themselves (for example, protocol buffers).
12type DelegatingCarrier interface {
13	SetState(traceID, spanID uint64, sampled bool)
14	State() (traceID, spanID uint64, sampled bool)
15	SetBaggageItem(key, value string)
16	GetBaggage(func(key, value string))
17}
18
19func (p *accessorPropagator) Inject(
20	spanContext opentracing.SpanContext,
21	carrier interface{},
22) error {
23	dc, ok := carrier.(DelegatingCarrier)
24	if !ok || dc == nil {
25		return opentracing.ErrInvalidCarrier
26	}
27	sc, ok := spanContext.(SpanContext)
28	if !ok {
29		return opentracing.ErrInvalidSpanContext
30	}
31	dc.SetState(sc.TraceID, sc.SpanID, sc.Sampled)
32	for k, v := range sc.Baggage {
33		dc.SetBaggageItem(k, v)
34	}
35	return nil
36}
37
38func (p *accessorPropagator) Extract(
39	carrier interface{},
40) (opentracing.SpanContext, error) {
41	dc, ok := carrier.(DelegatingCarrier)
42	if !ok || dc == nil {
43		return nil, opentracing.ErrInvalidCarrier
44	}
45
46	traceID, spanID, sampled := dc.State()
47	sc := SpanContext{
48		TraceID: traceID,
49		SpanID:  spanID,
50		Sampled: sampled,
51		Baggage: nil,
52	}
53	dc.GetBaggage(func(k, v string) {
54		if sc.Baggage == nil {
55			sc.Baggage = map[string]string{}
56		}
57		sc.Baggage[k] = v
58	})
59
60	return sc, nil
61}
62