github.com/storacha/go-ucanto@v0.7.2/core/schema/uri.go (about)

     1  package schema
     2  
     3  import (
     4  	"fmt"
     5  	"net/url"
     6  
     7  	"github.com/storacha/go-ucanto/core/result/failure"
     8  )
     9  
    10  type uriConfig struct {
    11  	protocol *string
    12  }
    13  
    14  type uriReader struct {
    15  	uc *uriConfig
    16  }
    17  
    18  type URIOption func(*uriConfig)
    19  
    20  func WithProtocol(protocol string) URIOption {
    21  	return func(uc *uriConfig) {
    22  		uc.protocol = &protocol
    23  	}
    24  }
    25  
    26  func (ur uriReader) Read(input any) (url.URL, failure.Failure) {
    27  	asString, stringOk := input.(string)
    28  	asUrl, urlOk := input.(url.URL)
    29  	if !stringOk && !urlOk {
    30  		return url.URL{}, NewSchemaError(fmt.Sprintf("Expected URI but got %T", input))
    31  	}
    32  	if !urlOk {
    33  		u, err := url.ParseRequestURI(asString)
    34  		if err != nil {
    35  			return url.URL{}, NewSchemaError("Invalid URI")
    36  		}
    37  		asUrl = *u
    38  	}
    39  	if ur.uc.protocol != nil && *ur.uc.protocol != asUrl.Scheme+":" {
    40  		return url.URL{}, NewSchemaError(fmt.Sprintf("Expected %s URI instead got %s", *ur.uc.protocol, asUrl.String()))
    41  	}
    42  	return asUrl, nil
    43  }
    44  
    45  func URI(opts ...URIOption) Reader[any, url.URL] {
    46  	uc := &uriConfig{}
    47  	for _, opt := range opts {
    48  		opt(uc)
    49  	}
    50  	return uriReader{uc}
    51  }