github.com/puellanivis/breton@v0.2.16/lib/files/context.go (about)

     1  package files
     2  
     3  import (
     4  	"context"
     5  	"net/url"
     6  	"path/filepath"
     7  )
     8  
     9  type (
    10  	rootKey struct{}
    11  )
    12  
    13  // WithRootURL attaches a url.URL to a Context
    14  // and is used as the resolution reference for any files.Open() using that context.
    15  func WithRootURL(ctx context.Context, uri *url.URL) context.Context {
    16  	uriCopy := uri
    17  	uri = resolveFilename(ctx, uri)
    18  
    19  	// we got the same URL back, clone it so that it stays immutable to the original uri passed in.
    20  	if uriCopy == uri {
    21  		uriCopy = new(url.URL)
    22  		*uriCopy = *uri
    23  
    24  		if uri.User != nil {
    25  			uriCopy.User = new(url.Userinfo)
    26  			*uriCopy.User = *uri.User // gotta copy this pointer struct also.
    27  		}
    28  
    29  		uri = uriCopy
    30  	}
    31  
    32  	return context.WithValue(ctx, rootKey{}, uri)
    33  }
    34  
    35  // WithRoot stores either a URL or a local path to use as a root point when resolving filenames.
    36  func WithRoot(ctx context.Context, path string) (context.Context, error) {
    37  	if filepath.IsAbs(path) {
    38  		path = filepath.Clean(path)
    39  		return WithRootURL(ctx, makePath(path)), nil
    40  	}
    41  
    42  	uri, err := url.Parse(path)
    43  	if err != nil {
    44  		return ctx, err
    45  	}
    46  
    47  	return WithRootURL(ctx, uri), nil
    48  }
    49  
    50  func getRoot(ctx context.Context) (*url.URL, bool) {
    51  	root, ok := ctx.Value(rootKey{}).(*url.URL)
    52  	return root, ok
    53  }
    54  
    55  // GetRoot returns the currently attached string that is being used as the root for any invalid URLs.
    56  func GetRoot(ctx context.Context) (string, bool) {
    57  	root, ok := getRoot(ctx)
    58  	if !ok {
    59  		return "", false
    60  	}
    61  
    62  	if isPath(root) {
    63  		return getPath(root), true
    64  	}
    65  
    66  	return root.String(), true
    67  }