1
0
mirror of https://github.com/ipfs/kubo.git synced 2025-09-10 09:52:20 +08:00
Files
kubo/path/path.go
2015-04-26 22:32:12 -07:00

100 lines
1.9 KiB
Go

package path
import (
"errors"
"path"
"strings"
u "github.com/ipfs/go-ipfs/util"
b58 "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-base58"
mh "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multihash"
)
// ErrBadPath is returned when a given path is incorrectly formatted
var ErrBadPath = errors.New("invalid ipfs ref path")
// TODO: debate making this a private struct wrapped in a public interface
// would allow us to control creation, and cache segments.
type Path string
// FromString safely converts a string type to a Path type
func FromString(s string) Path {
return Path(s)
}
// FromKey safely converts a Key type to a Path type
func FromKey(k u.Key) Path {
return Path("/ipfs/" + k.String())
}
func (p Path) Segments() []string {
cleaned := path.Clean(string(p))
segments := strings.Split(cleaned, "/")
// Ignore leading slash
if len(segments[0]) == 0 {
segments = segments[1:]
}
return segments
}
func (p Path) String() string {
return string(p)
}
func FromSegments(seg ...string) Path {
var pref string
if seg[0] == "ipfs" || seg[0] == "ipns" {
pref = "/"
}
return Path(pref + strings.Join(seg, "/"))
}
func ParsePath(txt string) (Path, error) {
parts := strings.Split(txt, "/")
if len(parts) == 1 {
kp, err := ParseKeyToPath(txt)
if err == nil {
return kp, nil
}
}
if len(parts) < 3 {
return "", ErrBadPath
}
if parts[0] != "" {
return "", ErrBadPath
}
if parts[1] != "ipfs" && parts[1] != "ipns" {
return "", ErrBadPath
}
_, err := ParseKeyToPath(parts[2])
if err != nil {
return "", err
}
return Path(txt), nil
}
func ParseKeyToPath(txt string) (Path, error) {
chk := b58.Decode(txt)
if len(chk) == 0 {
return "", errors.New("not a key")
}
_, err := mh.Cast(chk)
if err != nil {
return "", err
}
return FromKey(u.Key(chk)), nil
}
func (p *Path) IsValid() error {
_, err := ParsePath(p.String())
return err
}