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 }