87 lines
1.8 KiB
Go
87 lines
1.8 KiB
Go
package bucket
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"net/url"
|
|
"strings"
|
|
)
|
|
|
|
type Bucket string
|
|
|
|
const bucketMetadataPrefix = "metadata/"
|
|
|
|
var ErrorInvalidBucket = errors.New("invalid bucket")
|
|
|
|
func (b Bucket) Validate() error {
|
|
// Ensure is URL
|
|
u, err := url.ParseRequestURI(string(b))
|
|
if err != nil {
|
|
return fmt.Errorf("%w: %v: %v", ErrorInvalidBucket, err.Error(), b)
|
|
}
|
|
if u.Scheme != "http" && u.Scheme != "https" {
|
|
return fmt.Errorf("%w: %v", ErrorInvalidBucket, b)
|
|
}
|
|
if u.Host == "" || !strings.HasSuffix(u.Path, "/") {
|
|
return fmt.Errorf("%w: %v", ErrorInvalidBucket, b)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (b Bucket) String() string {
|
|
return string(b)
|
|
}
|
|
|
|
func (b Bucket) URL(p Pathable) *url.URL {
|
|
u, _ := url.ParseRequestURI(string(b))
|
|
path := p.Path()
|
|
u.Path = pathJoin(u.Path, path.Path)
|
|
u.RawQuery = path.RawQuery
|
|
return u
|
|
}
|
|
|
|
func pathJoin(paths ...string) string {
|
|
cleanedPaths := make([]string, 0, len(paths))
|
|
for i, path := range paths {
|
|
cleanedPath := strings.TrimPrefix(path, "/")
|
|
if i != len(paths)-1 {
|
|
cleanedPath = strings.TrimSuffix(cleanedPath, "/")
|
|
}
|
|
if i == 0 && len(cleanedPath) == 0 {
|
|
continue
|
|
}
|
|
cleanedPaths = append(cleanedPaths, cleanedPath)
|
|
}
|
|
return "/" + strings.Join(cleanedPaths, "/")
|
|
}
|
|
|
|
type Pathable interface {
|
|
Path() *url.URL
|
|
}
|
|
|
|
type BucketMetadata string
|
|
|
|
func (b Bucket) Metadata(name string) BucketMetadata {
|
|
return BucketMetadata(bucketMetadataPrefix + name)
|
|
}
|
|
|
|
func (m BucketMetadata) String() string {
|
|
return string(m)
|
|
}
|
|
|
|
func (m BucketMetadata) Path() *url.URL {
|
|
return &url.URL{
|
|
Path: string(m),
|
|
}
|
|
}
|
|
|
|
func (b Bucket) MetadataTitle() BucketMetadata {
|
|
return b.Metadata("title")
|
|
}
|
|
func (b Bucket) MetadataDescription() BucketMetadata {
|
|
return b.Metadata("description")
|
|
}
|
|
func (b Bucket) MetadataOrdering() BucketMetadata {
|
|
return b.Metadata("ordering")
|
|
}
|