2020-10-13 06:58:34 +03:00
// Copyright 2020 The Gitea Authors. All rights reserved.
2022-11-27 21:20:29 +03:00
// SPDX-License-Identifier: MIT
2020-10-13 06:58:34 +03:00
package storage
import (
2022-11-30 16:39:02 +03:00
"fmt"
"io"
"net/url"
"os"
2020-10-13 06:58:34 +03:00
"reflect"
2021-03-02 00:08:10 +03:00
2021-07-24 19:03:58 +03:00
"code.gitea.io/gitea/modules/json"
2020-10-13 06:58:34 +03:00
)
// Mappable represents an interface that can MapTo another interface
type Mappable interface {
MapTo ( v interface { } ) error
}
// toConfig will attempt to convert a given configuration cfg into the provided exemplar type.
//
// It will tolerate the cfg being passed as a []byte or string of a json representation of the
// exemplar or the correct type of the exemplar itself
func toConfig ( exemplar , cfg interface { } ) ( interface { } , error ) {
// First of all check if we've got the same type as the exemplar - if so it's all fine.
if reflect . TypeOf ( cfg ) . AssignableTo ( reflect . TypeOf ( exemplar ) ) {
return cfg , nil
}
// Now if not - does it provide a MapTo function we can try?
if mappable , ok := cfg . ( Mappable ) ; ok {
newVal := reflect . New ( reflect . TypeOf ( exemplar ) )
if err := mappable . MapTo ( newVal . Interface ( ) ) ; err == nil {
return newVal . Elem ( ) . Interface ( ) , nil
}
// MapTo has failed us ... let's try the json route ...
}
// OK we've been passed a byte array right?
configBytes , ok := cfg . ( [ ] byte )
if ! ok {
// oh ... it's a string then?
var configStr string
configStr , ok = cfg . ( string )
configBytes = [ ] byte ( configStr )
}
if ! ok {
// hmm ... can we marshal it to json?
var err error
configBytes , err = json . Marshal ( cfg )
2021-04-09 10:40:34 +03:00
ok = err == nil
2020-10-13 06:58:34 +03:00
}
if ! ok {
// no ... we've tried hard enough at this point - throw an error!
return nil , ErrInvalidConfiguration { cfg : cfg }
}
// OK unmarshal the byte array into a new copy of the exemplar
newVal := reflect . New ( reflect . TypeOf ( exemplar ) )
if err := json . Unmarshal ( configBytes , newVal . Interface ( ) ) ; err != nil {
// If we can't unmarshal it then return an error!
return nil , ErrInvalidConfiguration { cfg : cfg , err : err }
}
return newVal . Elem ( ) . Interface ( ) , nil
}
2022-11-30 16:39:02 +03:00
var uninitializedStorage = discardStorage ( "uninitialized storage" )
type discardStorage string
func ( s discardStorage ) Open ( _ string ) ( Object , error ) {
return nil , fmt . Errorf ( "%s" , s )
}
func ( s discardStorage ) Save ( _ string , _ io . Reader , _ int64 ) ( int64 , error ) {
return 0 , fmt . Errorf ( "%s" , s )
}
func ( s discardStorage ) Stat ( _ string ) ( os . FileInfo , error ) {
return nil , fmt . Errorf ( "%s" , s )
}
func ( s discardStorage ) Delete ( _ string ) error {
return fmt . Errorf ( "%s" , s )
}
func ( s discardStorage ) URL ( _ , _ string ) ( * url . URL , error ) {
return nil , fmt . Errorf ( "%s" , s )
}
2023-03-13 13:23:51 +03:00
func ( s discardStorage ) IterateObjects ( _ string , _ func ( string , Object ) error ) error {
2022-11-30 16:39:02 +03:00
return fmt . Errorf ( "%s" , s )
}