Files
dolt/go/spec/absolute_path.go
T

101 lines
2.1 KiB
Go

// Copyright 2016 Attic Labs, Inc. All rights reserved.
// Licensed under the Apache License, version 2.0:
// http://www.apache.org/licenses/LICENSE-2.0
package spec
import (
"errors"
"fmt"
"regexp"
"github.com/attic-labs/noms/go/d"
"github.com/attic-labs/noms/go/datas"
"github.com/attic-labs/noms/go/dataset"
"github.com/attic-labs/noms/go/hash"
"github.com/attic-labs/noms/go/types"
)
var datasetCapturePrefixRe = regexp.MustCompile("^(" + dataset.DatasetRe.String() + ")")
type AbsolutePath struct {
dataset string
hash hash.Hash
path types.Path
}
func NewAbsolutePath(str string) (AbsolutePath, error) {
if len(str) == 0 {
return AbsolutePath{}, errors.New("Empty path")
}
var h hash.Hash
var dataset string
var pathStr string
if str[0] == '#' {
tail := str[1:]
if len(tail) < hash.StringLen {
return AbsolutePath{}, errors.New("Invalid hash: " + tail)
}
hashStr := tail[:hash.StringLen]
if h2, ok := hash.MaybeParse(hashStr); ok {
h = h2
} else {
return AbsolutePath{}, errors.New("Invalid hash: " + hashStr)
}
pathStr = tail[hash.StringLen:]
} else {
datasetParts := datasetCapturePrefixRe.FindStringSubmatch(str)
if datasetParts == nil {
return AbsolutePath{}, fmt.Errorf("Invalid dataset name: %s", str)
}
dataset = datasetParts[1]
pathStr = str[len(dataset):]
}
if len(pathStr) == 0 {
return AbsolutePath{hash: h, dataset: dataset}, nil
}
path, err := types.ParsePath(pathStr)
if err != nil {
return AbsolutePath{}, err
}
return AbsolutePath{hash: h, dataset: dataset, path: path}, nil
}
func (p AbsolutePath) Resolve(db datas.Database) (val types.Value) {
if len(p.dataset) > 0 {
var ok bool
if val, ok = db.MaybeHead(p.dataset); !ok {
val = nil
}
} else if !p.hash.IsEmpty() {
val = db.ReadValue(p.hash)
} else {
d.Chk.Fail("Unreachable")
}
if val != nil && p.path != nil {
val = p.path.Resolve(val)
}
return
}
func (p AbsolutePath) String() (str string) {
if len(p.dataset) > 0 {
str = p.dataset
} else if !p.hash.IsEmpty() {
str = "#" + p.hash.String()
} else {
d.Chk.Fail("Unreachable")
}
return str + p.path.String()
}