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-
7972func (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+
113110func (p Path ) Rel (r Path ) (Path , error ) {
114111 rel , err := filepath .Rel (string (r ), string (p ))
115112 return Path (rel ), err
116113}
117114
118115func (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-
251247func (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+
310331func (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+
338401func (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+
347418func (p Path ) Stat () (fs.FileInfo , error ) {
348419 return os .Stat (string (p ))
349420}
@@ -364,3 +435,66 @@ func (p Path) SizeX() int64 {
364435func (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+ }
0 commit comments