1- // Copyright (c) 2021 Canonical Ltd
1+ // Copyright (c) 2024 Canonical Ltd
22//
33// Licensed under the Apache License, Version 2.0 (the "License");
44// you may not use this file except in compliance with the License.
@@ -90,10 +90,28 @@ type Plan struct {
9090 Sections map [string ]LayerSection `yaml:",inline,omitempty"`
9191}
9292
93- // Section retrieves a section from the plan. Returns nil if
94- // the field does not exist.
95- func (p * Plan ) Section (field string ) LayerSection {
96- return p .Sections [field ]
93+ // Section retrieves a section from the plan, if it exists.
94+ func (p * Plan ) Section (field string , out any ) error {
95+ if _ , found := layerExtensions [field ]; ! found {
96+ return fmt .Errorf ("cannot find registered extension for field %q" , field )
97+ }
98+
99+ outVal := reflect .ValueOf (out )
100+ if outVal .Kind () != reflect .Ptr || outVal .IsNil () {
101+ return fmt .Errorf ("cannot read non pointer to section interface type %q" , outVal .Kind ())
102+ }
103+
104+ section , exists := p .Sections [field ]
105+ if exists {
106+ sectionVal := reflect .ValueOf (section )
107+ sectionType := sectionVal .Type ()
108+ outValPtrType := outVal .Elem ().Type ()
109+ if ! sectionType .AssignableTo (outValPtrType ) {
110+ return fmt .Errorf ("cannot assign value of type %s to out argument of type %s" , sectionType , outValPtrType )
111+ }
112+ outVal .Elem ().Set (sectionVal )
113+ }
114+ return nil
97115}
98116
99117type Layer struct {
@@ -108,17 +126,6 @@ type Layer struct {
108126 Sections map [string ]LayerSection `yaml:",inline,omitempty"`
109127}
110128
111- // addSection adds a new section to the layer.
112- func (layer * Layer ) addSection (field string , section LayerSection ) {
113- layer .Sections [field ] = section
114- }
115-
116- // Section retrieves a layer section from a layer. Returns nil if
117- // the field does not exist.
118- func (layer * Layer ) Section (field string ) LayerSection {
119- return layer .Sections [field ]
120- }
121-
122129type Service struct {
123130 // Basic details
124131 Name string `yaml:"-"`
@@ -708,7 +715,7 @@ func CombineLayers(layers ...*Layer) (*Layer, error) {
708715 for field , extension := range layerExtensions {
709716 var sections []LayerSection
710717 for _ , layer := range layers {
711- if section := layer .Section ( field ) ; section != nil {
718+ if section := layer .Sections [ field ] ; section != nil {
712719 sections = append (sections , section )
713720 }
714721 }
@@ -723,7 +730,7 @@ func CombineLayers(layers ...*Layer) (*Layer, error) {
723730 }
724731 // We support the ability for a valid combine to result in an omitted section.
725732 if combinedSection != nil {
726- combined .addSection ( field , combinedSection )
733+ combined .Sections [ field ] = combinedSection
727734 }
728735 }
729736 }
@@ -1182,7 +1189,7 @@ func ParseLayer(order int, label string, data []byte) (*Layer, error) {
11821189 }
11831190 }
11841191 if extendedSection != nil {
1185- layer .addSection ( field , extendedSection )
1192+ layer .Sections [ field ] = extendedSection
11861193 }
11871194 } else {
11881195 // At the top level we do not ignore keys we do not understand.
0 commit comments