internal/gitlab/asset_marshaller.go (69 lines of code) (raw):
package gitlab
import (
"encoding/json"
"fmt"
"strings"
"github.com/hashicorp/go-multierror"
)
// ConflictDirectAssetPathError is returned when both direct_asset_path and the deprecated filepath as specified for an asset link.
var ConflictDirectAssetPathError = fmt.Errorf("asset link can either specify `direct_asset_path` or `filepath` (`filepath` is deprecated).")
// AssetMarshaller parses asset links, either single instance of them or as an array.
func AssetMarshaller(assetLink []string) (*Assets, error) {
assets := &Assets{
Links: []*Link{},
}
if len(assetLink) == 0 {
return assets, nil
}
var result *multierror.Error
for _, asset := range assetLink {
dec := json.NewDecoder(strings.NewReader(asset))
t, _ := dec.Token()
var err error
switch t {
case json.Delim('['):
err = processMultipleAssets(asset, assets)
case json.Delim('{'):
err = processSingleAsset(asset, assets)
default:
err = fmt.Errorf("invalid delimiter for asset: %q", asset)
}
if err != nil {
result = multierror.Append(result, err)
}
}
return assets, result.ErrorOrNil()
}
// processSingleAsset parses a single asset link object.
func processSingleAsset(entry string, assets *Assets) error {
var link Link
if err := json.Unmarshal([]byte(entry), &link); err != nil {
return fmt.Errorf("invalid asset: %q %w", entry, err)
}
if err := ensureUsingDirectAssetPath(&link); err != nil {
return fmt.Errorf("invalid asset: %q %w", entry, err)
}
assets.Links = append(assets.Links, &link)
return nil
}
// processMultipleAssets parses an array of asset link objects.
func processMultipleAssets(entry string, assets *Assets) error {
var links []*Link
if err := json.Unmarshal([]byte(entry), &links); err != nil {
return fmt.Errorf("invalid array of assets: %q %w", entry, err)
}
for _, link := range links {
if err := ensureUsingDirectAssetPath(link); err != nil {
return fmt.Errorf("invalid array of assets: %q %w", entry, err)
}
}
assets.Links = append(assets.Links, links...)
return nil
}
func ensureUsingDirectAssetPath(link *Link) error {
if link.Filepath == "" {
// There is no deprecated filepath set, so we are good.
return nil
}
if link.DirectAssetPath != "" {
// Both, filepath and direct_asset_path are set, so we have a conflict
return ConflictDirectAssetPathError
}
// We use the set filepath as direct_asset_path
// and clear the filepath to net send it via API.
link.DirectAssetPath = link.Filepath
link.Filepath = ""
return nil
}