Skip to content

Commit 6db6f66

Browse files
committed
feat: add new methods: Segments, Exists, DoesNotExist, IsEmpty, HasPrefix, HasSuffix, HasExt, Contains, Clean, Normalize, HasQuery, TrimQuery, WithQuery, Query, QuerySet, QueryAdd, QueryDel, QueryHas
1 parent 2c42582 commit 6db6f66

File tree

2 files changed

+154
-80
lines changed

2 files changed

+154
-80
lines changed

path.go

Lines changed: 150 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"fmt"
66
"io"
77
"io/fs"
8+
"net/url"
89
"os"
910
"path/filepath"
1011
"runtime"
@@ -47,7 +48,7 @@ func (p Path) String() string {
4748
return string(p)
4849
}
4950

50-
func (p Path) S() string {
51+
func (p Path) Str() string {
5152
return string(p)
5253
}
5354

@@ -59,7 +60,7 @@ func (p Path) Join(v ...string) Path {
5960
return Path(filepath.Join(append([]string{string(p)}, v...)...))
6061
}
6162

62-
func (p Path) JoinP(v ...Path) Path {
63+
func (p Path) JoinPath(v ...Path) Path {
6364
s := make([]string, len(v))
6465
for i := range v {
6566
s[i] = string(v[i])
@@ -68,14 +69,6 @@ func (p Path) JoinP(v ...Path) Path {
6869
return p.Join(s...)
6970
}
7071

71-
func (p Path) Append(v ...string) Path {
72-
return p.Join(v...)
73-
}
74-
75-
func (p Path) Appendf(format string, args ...any) Path {
76-
return p.Append(fmt.Sprintf(format, args...))
77-
}
78-
7972
func (p Path) Base() Path {
8073
return Path(filepath.Base(string(p)))
8174
}
@@ -110,12 +103,20 @@ func (p Path) Split() (dir, file Path) {
110103
return Path(p1), Path(p2)
111104
}
112105

106+
func (p Path) Segments() []string {
107+
return filepath.SplitList(string(p))
108+
}
109+
113110
func (p Path) Rel(r Path) (Path, error) {
114111
rel, err := filepath.Rel(string(r), string(p))
115112
return Path(rel), err
116113
}
117114

118115
func (p Path) Abs() (Path, error) {
116+
if p.IsAbs() {
117+
return p, nil
118+
}
119+
119120
abs, err := filepath.Abs(string(p))
120121
return Path(abs), err
121122
}
@@ -158,7 +159,7 @@ func (p Path) Copy(dst Path) error {
158159
defer src.Close()
159160

160161
if dst.IsDir() {
161-
dst = dst.JoinP(p.Base())
162+
dst = dst.JoinPath(p.Base())
162163
}
163164
if err := dst.Dir().MkdirIfNotExist(); err != nil {
164165
return fmt.Errorf("create parent directory: %w", err)
@@ -243,11 +244,6 @@ func (p Path) ReadFile() ([]byte, error) {
243244
return os.ReadFile(string(p))
244245
}
245246

246-
func (p Path) ReadFileX() []byte {
247-
v, _ := p.ReadFile()
248-
return v
249-
}
250-
251247
func (p Path) WriteFile(data []byte) error {
252248
if p.IsDir() {
253249
return errors.New("can not write to a directory")
@@ -307,6 +303,31 @@ func (p Path) IsExist() bool {
307303
return err == nil
308304
}
309305

306+
func (p Path) Exists() bool {
307+
return p.IsExist()
308+
}
309+
310+
func (p Path) DoesNotExist() bool {
311+
return !p.IsExist()
312+
}
313+
314+
func (p Path) IsEqual(p2 Path) bool {
315+
if p == p2 {
316+
return true
317+
}
318+
319+
abs1, err := p.Abs()
320+
if err != nil {
321+
return false
322+
}
323+
ab2, err := p2.Abs()
324+
if err != nil {
325+
return false
326+
}
327+
328+
return abs1 == ab2
329+
}
330+
310331
func (p Path) IsWritable() bool {
311332
if !p.IsExist() {
312333
return false
@@ -335,6 +356,48 @@ func (p Path) IsWritable() bool {
335356
return true
336357
}
337358

359+
func (p Path) IsEmpty() bool {
360+
if p.DoesNotExist() {
361+
return true
362+
}
363+
364+
if p.IsDir() {
365+
entries, err := p.ReadDir()
366+
if err != nil {
367+
return false
368+
}
369+
return len(entries) == 0
370+
}
371+
372+
size, err := p.Size()
373+
if err != nil {
374+
return false
375+
}
376+
return size == 0
377+
}
378+
379+
func (p Path) HasPrefix(prefix string) bool {
380+
return strings.HasPrefix(string(p), prefix)
381+
}
382+
383+
func (p Path) HasSuffix(suffix string) bool {
384+
return strings.HasSuffix(string(p), suffix)
385+
}
386+
387+
func (p Path) HasExt(ext string) bool {
388+
if ext == "" {
389+
return true
390+
}
391+
if ext[0] != '.' {
392+
ext = "." + ext
393+
}
394+
return strings.HasSuffix(string(p), ext)
395+
}
396+
397+
func (p Path) Contains(sub string) bool {
398+
return strings.Contains(string(p), sub)
399+
}
400+
338401
func (p Path) Match(pattern string) bool {
339402
v, err := filepath.Match(pattern, string(p))
340403
return err == nil && v
@@ -344,6 +407,14 @@ func (p Path) VolumeName() string {
344407
return filepath.VolumeName(string(p))
345408
}
346409

410+
func (p Path) Clean() Path {
411+
return Path(filepath.Clean(string(p)))
412+
}
413+
414+
func (p Path) Normalize() Path {
415+
return p.Clean()
416+
}
417+
347418
func (p Path) Stat() (fs.FileInfo, error) {
348419
return os.Stat(string(p))
349420
}
@@ -364,3 +435,66 @@ func (p Path) SizeX() int64 {
364435
func (p Path) Walk(fn fs.WalkDirFunc) error {
365436
return filepath.WalkDir(string(p), fn)
366437
}
438+
439+
func (p Path) HasQuery() bool {
440+
return strings.Contains(string(p), "?")
441+
}
442+
443+
func (p Path) TrimQuery() Path {
444+
if !p.HasQuery() {
445+
return p
446+
}
447+
return Path(strings.Split(string(p), "?")[0])
448+
}
449+
450+
func (p Path) WithQuery(q string) Path {
451+
if q == "" {
452+
return p.TrimQuery()
453+
}
454+
return Path(string(p.TrimQuery()) + "?" + q)
455+
}
456+
457+
func (p Path) Query() string {
458+
if !p.HasQuery() {
459+
return ""
460+
}
461+
return strings.Split(string(p), "?")[1]
462+
}
463+
464+
func (p Path) QuerySet(k string, v any) Path {
465+
if q, err := url.ParseQuery(p.Query()); err == nil {
466+
q.Set(k, qval(v))
467+
return p.WithQuery(q.Encode())
468+
}
469+
return p
470+
}
471+
472+
func (p Path) QueryAdd(k string, v any) Path {
473+
if q, err := url.ParseQuery(p.Query()); err == nil {
474+
q.Add(k, qval(v))
475+
return p.WithQuery(q.Encode())
476+
}
477+
return p
478+
}
479+
480+
func (p Path) QueryDel(k string) Path {
481+
if q, err := url.ParseQuery(p.Query()); err == nil {
482+
q.Del(k)
483+
return p.WithQuery(q.Encode())
484+
}
485+
return p
486+
}
487+
488+
func (p Path) QueryHas(k string) bool {
489+
if q, err := url.ParseQuery(p.Query()); err == nil {
490+
return q.Has(k)
491+
}
492+
return false
493+
}
494+
495+
func qval(v any) string {
496+
if v == nil {
497+
return ""
498+
}
499+
return fmt.Sprint(v)
500+
}

path_test.go

Lines changed: 4 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -313,20 +313,6 @@ func TestMkdirIfNotExist(t *testing.T) {
313313
p.Delete()
314314
}
315315

316-
func TestReadFileX(t *testing.T) {
317-
p := New("testfile.txt")
318-
if err := p.WriteFile(testContent); err != nil {
319-
t.Errorf("WriteFile: %v", err)
320-
}
321-
322-
content := p.ReadFileX()
323-
if string(content) != string(testContent) {
324-
t.Errorf("expected %s, got %s", testContent, content)
325-
}
326-
327-
os.Remove(p.String())
328-
}
329-
330316
func TestSizeX(t *testing.T) {
331317
p := New("testfile.txt")
332318
if err := p.WriteFile(testContent); err != nil {
@@ -440,73 +426,27 @@ func TestJoinP(t *testing.T) {
440426
p := New("a", "b")
441427
p1 := New("c")
442428
p2 := New("d", "e")
443-
result := p.JoinP(p1, p2)
429+
result := p.JoinPath(p1, p2)
444430
expected := filepath.Join("a", "b", "c", "d", "e")
445431
if result.String() != expected {
446432
t.Errorf("expected %s, got %s", expected, result.String())
447433
}
448434

449435
// Test with no additional paths
450-
result = p.JoinP()
436+
result = p.JoinPath()
451437
expected = filepath.Join("a", "b")
452438
if result.String() != expected {
453439
t.Errorf("expected %s, got %s", expected, result.String())
454440
}
455441

456442
// Test with one additional path
457-
result = p.JoinP(p1)
443+
result = p.JoinPath(p1)
458444
expected = filepath.Join("a", "b", "c")
459445
if result.String() != expected {
460446
t.Errorf("expected %s, got %s", expected, result.String())
461447
}
462448
}
463449

464-
func TestAppend(t *testing.T) {
465-
p := New("a", "b")
466-
result := p.Append("c", "d")
467-
expected := filepath.Join("a", "b", "c", "d")
468-
if result.String() != expected {
469-
t.Errorf("expected %s, got %s", expected, result.String())
470-
}
471-
472-
// Test appending no additional strings
473-
result = p.Append()
474-
expected = filepath.Join("a", "b")
475-
if result.String() != expected {
476-
t.Errorf("expected %s, got %s", expected, result.String())
477-
}
478-
479-
// Test appending one additional string
480-
result = p.Append("c")
481-
expected = filepath.Join("a", "b", "c")
482-
if result.String() != expected {
483-
t.Errorf("expected %s, got %s", expected, result.String())
484-
}
485-
}
486-
487-
func TestAppendf(t *testing.T) {
488-
p := New("a", "b")
489-
result := p.Appendf("c%d", 1)
490-
expected := filepath.Join("a", "b", "c1")
491-
if result.String() != expected {
492-
t.Errorf("expected %s, got %s", expected, result.String())
493-
}
494-
495-
// Test appending with multiple format arguments
496-
result = p.Appendf("d%d_e%s", 2, "f")
497-
expected = filepath.Join("a", "b", "d2_ef")
498-
if result.String() != expected {
499-
t.Errorf("expected %s, got %s", expected, result.String())
500-
}
501-
502-
// Test appending with no format arguments
503-
result = p.Appendf("g")
504-
expected = filepath.Join("a", "b", "g")
505-
if result.String() != expected {
506-
t.Errorf("expected %s, got %s", expected, result.String())
507-
}
508-
}
509-
510450
func TestSourceFile(t *testing.T) {
511451
// Test that SourceFile returns the correct path of the current file
512452
expected := WD().Join("path_test.go").String()
@@ -691,7 +631,7 @@ func TestS(t *testing.T) {
691631
}
692632

693633
for _, test := range tests {
694-
result := test.input.S()
634+
result := test.input.Str()
695635
if result != test.expected {
696636
t.Errorf("expected %s, got %s", test.expected, result)
697637
}

0 commit comments

Comments
 (0)