2023-02-16 19:28:05 +03:00
|
|
|
package pathx
|
|
|
|
|
|
|
|
// The package implements crossplatform structured
|
|
|
|
// paths.
|
|
|
|
|
|
|
|
import (
|
|
|
|
fp "path/filepath"
|
|
|
|
"path"
|
|
|
|
"strings"
|
|
|
|
)
|
|
|
|
|
|
|
|
type Value string
|
|
|
|
type Path struct {
|
|
|
|
Values []Value
|
2023-02-17 06:57:57 +03:00
|
|
|
IsAbs bool
|
2023-02-16 19:28:05 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
func (p Path) Append(values ...string) Path {
|
|
|
|
for _, v := range values {
|
|
|
|
p.Values = append(p.Values, Value(v))
|
|
|
|
}
|
|
|
|
return p
|
|
|
|
}
|
|
|
|
|
|
|
|
func From(p string) Path {
|
2023-02-17 06:57:57 +03:00
|
|
|
ret := Path{}
|
|
|
|
if len(p) == 0 {
|
|
|
|
return ret
|
|
|
|
}
|
|
|
|
|
2023-02-16 19:28:05 +03:00
|
|
|
p = path.Clean(p)
|
2023-02-17 06:57:57 +03:00
|
|
|
if p[0] == '/' {
|
|
|
|
ret.IsAbs = true
|
|
|
|
}
|
2023-02-16 19:28:05 +03:00
|
|
|
p, _ = strings.CutSuffix(p, "/")
|
|
|
|
svalues := strings.Split(p, "/")
|
|
|
|
|
|
|
|
values := make([]Value, len(svalues))
|
|
|
|
for i, s := range svalues {
|
|
|
|
values[i] = Value(s)
|
|
|
|
}
|
2023-02-17 06:57:57 +03:00
|
|
|
ret.Values = values
|
2023-02-16 19:28:05 +03:00
|
|
|
|
2023-02-17 06:57:57 +03:00
|
|
|
return ret
|
2023-02-16 19:28:05 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
func (v Value) IsValid() bool {
|
|
|
|
return v.Err() == nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (v Value) Err() error {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p Path) StringValues() []string {
|
2023-02-17 06:57:57 +03:00
|
|
|
ret := []string{}
|
|
|
|
if p.IsAbs {
|
|
|
|
ret = append(ret, "/")
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, v := range p.Values {
|
|
|
|
ret = append(ret, string(v))
|
2023-02-16 19:28:05 +03:00
|
|
|
}
|
|
|
|
|
2023-02-17 06:57:57 +03:00
|
|
|
return ret
|
2023-02-16 19:28:05 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
func (p Path) Real() string {
|
|
|
|
return fp.Join(p.StringValues()...)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p Path) String() string {
|
|
|
|
return path.Join(p.StringValues()...)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p Path) IsValid() bool {
|
|
|
|
for _, v := range p.Values {
|
|
|
|
if !v.IsValid() {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p Path) Err() error {
|
|
|
|
for _, v := range p.Values {
|
|
|
|
if !v.IsValid() {
|
|
|
|
return v.Err()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|